Make accesses with wrong width also work as apparently real hardware allows them when the fault is disabled.
Fix DMA register writes if target_phys_addr_t is 64-bit. Make more functions static. A timer hack to make PalmOS run in finite time (uses very short timer periods, much shorter than clocksource tick). Re-calculate internal clock rates on start-up. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3527 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									e616a7e821
								
							
						
					
					
						commit
						b854bc196f
					
				
							
								
								
									
										60
									
								
								hw/omap.c
								
								
								
								
							
							
						
						
									
										60
									
								
								hw/omap.c
								
								
								
								
							| 
						 | 
				
			
			@ -27,38 +27,51 @@ uint32_t omap_badwidth_read8(void *opaque, target_phys_addr_t addr)
 | 
			
		|||
    uint8_t ret;
 | 
			
		||||
 | 
			
		||||
    OMAP_8B_REG(addr);
 | 
			
		||||
    cpu_physical_memory_read(addr, &ret, 1);
 | 
			
		||||
    cpu_physical_memory_read(addr, (void *) &ret, 1);
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void omap_badwidth_write8(void *opaque, target_phys_addr_t addr,
 | 
			
		||||
                uint32_t value)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t val8 = value;
 | 
			
		||||
 | 
			
		||||
    OMAP_8B_REG(addr);
 | 
			
		||||
    cpu_physical_memory_write(addr, (void *) &val8, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t omap_badwidth_read16(void *opaque, target_phys_addr_t addr)
 | 
			
		||||
{
 | 
			
		||||
    uint16_t ret;
 | 
			
		||||
 | 
			
		||||
    OMAP_16B_REG(addr);
 | 
			
		||||
    return 0;
 | 
			
		||||
    cpu_physical_memory_read(addr, (void *) &ret, 2);
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void omap_badwidth_write16(void *opaque, target_phys_addr_t addr,
 | 
			
		||||
                uint32_t value)
 | 
			
		||||
{
 | 
			
		||||
    uint16_t val16 = value;
 | 
			
		||||
 | 
			
		||||
    OMAP_16B_REG(addr);
 | 
			
		||||
    cpu_physical_memory_write(addr, (void *) &val16, 2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t omap_badwidth_read32(void *opaque, target_phys_addr_t addr)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t ret;
 | 
			
		||||
 | 
			
		||||
    OMAP_32B_REG(addr);
 | 
			
		||||
    return 0;
 | 
			
		||||
    cpu_physical_memory_read(addr, (void *) &ret, 4);
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,
 | 
			
		||||
                uint32_t value)
 | 
			
		||||
{
 | 
			
		||||
    OMAP_32B_REG(addr);
 | 
			
		||||
    cpu_physical_memory_write(addr, (void *) &value, 4);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Interrupt Handlers */
 | 
			
		||||
| 
						 | 
				
			
			@ -787,7 +800,7 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s,
 | 
			
		|||
 | 
			
		||||
    case 0x0a:	/* SYS_DMA_CSSA_U_CH0 */
 | 
			
		||||
        s->ch[ch].addr[0] &= 0x0000ffff;
 | 
			
		||||
        s->ch[ch].addr[0] |= value << 16;
 | 
			
		||||
        s->ch[ch].addr[0] |= (uint32_t) value << 16;
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case 0x0c:	/* SYS_DMA_CDSA_L_CH0 */
 | 
			
		||||
| 
						 | 
				
			
			@ -797,7 +810,7 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s,
 | 
			
		|||
 | 
			
		||||
    case 0x0e:	/* SYS_DMA_CDSA_U_CH0 */
 | 
			
		||||
        s->ch[ch].addr[1] &= 0x0000ffff;
 | 
			
		||||
        s->ch[ch].addr[1] |= value << 16;
 | 
			
		||||
        s->ch[ch].addr[1] |= (uint32_t) value << 16;
 | 
			
		||||
        break;
 | 
			
		||||
 | 
			
		||||
    case 0x10:	/* SYS_DMA_CEN_CH0 */
 | 
			
		||||
| 
						 | 
				
			
			@ -1033,37 +1046,37 @@ struct omap_dma_s *omap_dma_init(target_phys_addr_t base,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
/* DMA ports */
 | 
			
		||||
int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
 | 
			
		||||
static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
 | 
			
		||||
                target_phys_addr_t addr)
 | 
			
		||||
{
 | 
			
		||||
    return addr >= OMAP_EMIFF_BASE && addr < OMAP_EMIFF_BASE + s->sdram_size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
 | 
			
		||||
static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
 | 
			
		||||
                target_phys_addr_t addr)
 | 
			
		||||
{
 | 
			
		||||
    return addr >= OMAP_EMIFS_BASE && addr < OMAP_EMIFF_BASE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int omap_validate_imif_addr(struct omap_mpu_state_s *s,
 | 
			
		||||
static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
 | 
			
		||||
                target_phys_addr_t addr)
 | 
			
		||||
{
 | 
			
		||||
    return addr >= OMAP_IMIF_BASE && addr < OMAP_IMIF_BASE + s->sram_size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
 | 
			
		||||
static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
 | 
			
		||||
                target_phys_addr_t addr)
 | 
			
		||||
{
 | 
			
		||||
    return addr >= 0xfffb0000 && addr < 0xffff0000;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int omap_validate_local_addr(struct omap_mpu_state_s *s,
 | 
			
		||||
static int omap_validate_local_addr(struct omap_mpu_state_s *s,
 | 
			
		||||
                target_phys_addr_t addr)
 | 
			
		||||
{
 | 
			
		||||
    return addr >= OMAP_LOCALBUS_BASE && addr < OMAP_LOCALBUS_BASE + 0x1000000;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
 | 
			
		||||
static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
 | 
			
		||||
                target_phys_addr_t addr)
 | 
			
		||||
{
 | 
			
		||||
    return addr >= 0xe1010000 && addr < 0xe1020004;
 | 
			
		||||
| 
						 | 
				
			
			@ -1110,9 +1123,23 @@ static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
 | 
			
		|||
 | 
			
		||||
    if (timer->enable && timer->st && timer->rate) {
 | 
			
		||||
        timer->val = timer->reset_val;	/* Should skip this on clk enable */
 | 
			
		||||
        expires = timer->time + muldiv64(timer->val << (timer->ptv + 1),
 | 
			
		||||
        expires = muldiv64(timer->val << (timer->ptv + 1),
 | 
			
		||||
                        ticks_per_sec, timer->rate);
 | 
			
		||||
        qemu_mod_timer(timer->timer, expires);
 | 
			
		||||
 | 
			
		||||
        /* If timer expiry would be sooner than in about 1 ms and
 | 
			
		||||
         * auto-reload isn't set, then fire immediately.  This is a hack
 | 
			
		||||
         * to make systems like PalmOS run in acceptable time.  PalmOS
 | 
			
		||||
         * sets the interval to a very low value and polls the status bit
 | 
			
		||||
         * in a busy loop when it wants to sleep just a couple of CPU
 | 
			
		||||
         * ticks.  */
 | 
			
		||||
        if (expires > (ticks_per_sec >> 10) || timer->ar)
 | 
			
		||||
            qemu_mod_timer(timer->timer, timer->time + expires);
 | 
			
		||||
        else {
 | 
			
		||||
            timer->val = 0;
 | 
			
		||||
            timer->st = 0;
 | 
			
		||||
            if (timer->it_ena)
 | 
			
		||||
                qemu_irq_raise(timer->irq);
 | 
			
		||||
        }
 | 
			
		||||
    } else
 | 
			
		||||
        qemu_del_timer(timer->timer);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -3502,12 +3529,11 @@ static void omap_pwl_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
 | 
			
		|||
{
 | 
			
		||||
    int iomemtype;
 | 
			
		||||
 | 
			
		||||
    s->pwl.base = base;
 | 
			
		||||
    omap_pwl_reset(s);
 | 
			
		||||
 | 
			
		||||
    iomemtype = cpu_register_io_memory(0, omap_pwl_readfn,
 | 
			
		||||
                    omap_pwl_writefn, s);
 | 
			
		||||
    cpu_register_physical_memory(s->pwl.base, 0x800, iomemtype);
 | 
			
		||||
    cpu_register_physical_memory(base, 0x800, iomemtype);
 | 
			
		||||
 | 
			
		||||
    omap_clk_adduser(clk, qemu_allocate_irqs(omap_pwl_clk_update, s, 1)[0]);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -3597,13 +3623,12 @@ static void omap_pwt_init(target_phys_addr_t base, struct omap_mpu_state_s *s,
 | 
			
		|||
{
 | 
			
		||||
    int iomemtype;
 | 
			
		||||
 | 
			
		||||
    s->pwt.base = base;
 | 
			
		||||
    s->pwt.clk = clk;
 | 
			
		||||
    omap_pwt_reset(s);
 | 
			
		||||
 | 
			
		||||
    iomemtype = cpu_register_io_memory(0, omap_pwt_readfn,
 | 
			
		||||
                    omap_pwt_writefn, s);
 | 
			
		||||
    cpu_register_physical_memory(s->pwt.base, 0x800, iomemtype);
 | 
			
		||||
    cpu_register_physical_memory(base, 0x800, iomemtype);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Real-time Clock module */
 | 
			
		||||
| 
						 | 
				
			
			@ -4207,6 +4232,7 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
 | 
			
		|||
     * USB Host		fffba000 - fffba7ff
 | 
			
		||||
     * FAC		fffba800 - fffbafff
 | 
			
		||||
     * HDQ/1-Wire	fffbc000 - fffbc7ff
 | 
			
		||||
     * TIPB switches	fffbc800 - fffbcfff
 | 
			
		||||
     * LED1		fffbd000 - fffbd7ff
 | 
			
		||||
     * LED2		fffbd800 - fffbdfff
 | 
			
		||||
     * Mailbox		fffcf000 - fffcf7ff
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										15
									
								
								hw/omap.h
								
								
								
								
							
							
						
						
									
										15
									
								
								hw/omap.h
								
								
								
								
							| 
						 | 
				
			
			@ -646,14 +646,23 @@ void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,
 | 
			
		|||
# define OMAP_RO_REG(paddr)		\
 | 
			
		||||
        printf("%s: Read-only register " OMAP_FMT_plx "\n",	\
 | 
			
		||||
                        __FUNCTION__, paddr)
 | 
			
		||||
# define OMAP_8B_REG(paddr)		\
 | 
			
		||||
 | 
			
		||||
# define TCMI_VERBOSE			1
 | 
			
		||||
 | 
			
		||||
# ifdef TCMI_VERBOSE
 | 
			
		||||
#  define OMAP_8B_REG(paddr)		\
 | 
			
		||||
        printf("%s: 8-bit register " OMAP_FMT_plx "\n",	\
 | 
			
		||||
                        __FUNCTION__, paddr)
 | 
			
		||||
# define OMAP_16B_REG(paddr)		\
 | 
			
		||||
#  define OMAP_16B_REG(paddr)		\
 | 
			
		||||
        printf("%s: 16-bit register " OMAP_FMT_plx "\n",	\
 | 
			
		||||
                        __FUNCTION__, paddr)
 | 
			
		||||
# define OMAP_32B_REG(paddr)		\
 | 
			
		||||
#  define OMAP_32B_REG(paddr)		\
 | 
			
		||||
        printf("%s: 32-bit register " OMAP_FMT_plx "\n",	\
 | 
			
		||||
                        __FUNCTION__, paddr)
 | 
			
		||||
# else
 | 
			
		||||
#  define OMAP_8B_REG(paddr)
 | 
			
		||||
#  define OMAP_16B_REG(paddr)
 | 
			
		||||
#  define OMAP_32B_REG(paddr)
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
#endif /* hw_omap_h */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -742,4 +742,8 @@ void omap_clk_init(struct omap_mpu_state_s *mpu)
 | 
			
		|||
            j->multiplier = j->multiplier ?: 1;
 | 
			
		||||
            j ++;
 | 
			
		||||
        }
 | 
			
		||||
    for (j = mpu->clks; count --; j ++) {
 | 
			
		||||
        omap_clk_update(j);
 | 
			
		||||
        omap_clk_rate_update(j);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue