aboutsummaryrefslogtreecommitdiff
path: root/hw/omap.c
diff options
context:
space:
mode:
authorbalrog <balrog@c046a42c-6fe2-441c-8c8c-71466251a162>2007-11-04 11:42:11 +0000
committerbalrog <balrog@c046a42c-6fe2-441c-8c8c-71466251a162>2007-11-04 11:42:11 +0000
commitb854bc196f5c4b4e3299c0b0ee63cf828ece9e77 (patch)
tree8a8025f3f6b6bbae44a46fd34d43017d5a7d8fe0 /hw/omap.c
parente616a7e821c477fdb88cc422a8d925e0028e93b5 (diff)
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
Diffstat (limited to 'hw/omap.c')
-rw-r--r--hw/omap.c60
1 files changed, 43 insertions, 17 deletions
diff --git a/hw/omap.c b/hw/omap.c
index 0a77ee4e64..80d56b1e71 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