From b854bc196f5c4b4e3299c0b0ee63cf828ece9e77 Mon Sep 17 00:00:00 2001 From: balrog Date: Sun, 4 Nov 2007 11:42:11 +0000 Subject: [PATCH] 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 --- hw/omap.c | 60 +++++++++++++++++++++++++++++++++++++++++----------------- hw/omap.h | 15 ++++++++++++--- hw/omap1_clk.c | 4 ++++ 3 files changed, 59 insertions(+), 20 deletions(-) diff --git a/hw/omap.c b/hw/omap.c index 0a77ee4..80d56b1 100644 --- a/hw/omap.c +++ b/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 diff --git a/hw/omap.h b/hw/omap.h index aced593..bceb458 100644 --- a/hw/omap.h +++ b/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 */ diff --git a/hw/omap1_clk.c b/hw/omap1_clk.c index 7888e41..c8540de 100644 --- a/hw/omap1_clk.c +++ b/hw/omap1_clk.c @@ -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); + } } -- 2.7.4