aboutsummaryrefslogtreecommitdiff
path: root/hw/musicpal.c
diff options
context:
space:
mode:
authorJan Kiszka <jan.kiszka@web.de>2009-09-18 20:51:23 +0200
committerAnthony Liguori <aliguori@us.ibm.com>2009-10-05 09:32:43 -0500
commitc88d6bded69804617f412a60c7375cc93f8687a5 (patch)
treea99c6ee21625977cc289a4997b7441ea548b8335 /hw/musicpal.c
parent267c48404faab5a53334a884f4bb8627ffbdd031 (diff)
musicpal: Make PIT emulation more robust
Stop the periodic timers of the PIT on reset, disabling via the control register and invalid parameters. Signed-off-by: Jan Kiszka <jan.kiszka@web.de> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'hw/musicpal.c')
-rw-r--r--hw/musicpal.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/hw/musicpal.c b/hw/musicpal.c
index d4e797aac6..eca4a28443 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -696,7 +696,6 @@ typedef struct mv88w8618_timer_state {
typedef struct mv88w8618_pit_state {
SysBusDevice busdev;
mv88w8618_timer_state timer[4];
- uint32_t control;
} mv88w8618_pit_state;
static void mv88w8618_timer_tick(void *opaque)
@@ -744,16 +743,22 @@ static void mv88w8618_pit_write(void *opaque, target_phys_addr_t offset,
case MP_PIT_TIMER1_LENGTH ... MP_PIT_TIMER4_LENGTH:
t = &s->timer[offset >> 2];
t->limit = value;
- ptimer_set_limit(t->ptimer, t->limit, 1);
+ if (t->limit > 0) {
+ ptimer_set_limit(t->ptimer, t->limit, 1);
+ } else {
+ ptimer_stop(t->ptimer);
+ }
break;
case MP_PIT_CONTROL:
for (i = 0; i < 4; i++) {
- if (value & 0xf) {
- t = &s->timer[i];
+ t = &s->timer[i];
+ if (value & 0xf && t->limit > 0) {
ptimer_set_limit(t->ptimer, t->limit, 0);
ptimer_set_freq(t->ptimer, t->freq);
ptimer_run(t->ptimer, 0);
+ } else {
+ ptimer_stop(t->ptimer);
}
value >>= 4;
}
@@ -767,6 +772,17 @@ static void mv88w8618_pit_write(void *opaque, target_phys_addr_t offset,
}
}
+static void mv88w8618_pit_reset(void *opaque)
+{
+ mv88w8618_pit_state *s = opaque;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ ptimer_stop(s->timer[i].ptimer);
+ s->timer[i].limit = 0;
+ }
+}
+
static CPUReadMemoryFunc * const mv88w8618_pit_readfn[] = {
mv88w8618_pit_read,
mv88w8618_pit_read,
@@ -797,6 +813,13 @@ static int mv88w8618_pit_init(SysBusDevice *dev)
return 0;
}
+static SysBusDeviceInfo mv88w8618_pit_info = {
+ .init = mv88w8618_pit_init,
+ .qdev.name = "mv88w8618_pit",
+ .qdev.size = sizeof(mv88w8618_pit_state),
+ .qdev.reset = mv88w8618_pit_reset,
+};
+
/* Flash config register offsets */
#define MP_FLASHCFG_CFGR0 0x04
@@ -1448,8 +1471,7 @@ static void musicpal_register_devices(void)
{
sysbus_register_dev("mv88w8618_pic", sizeof(mv88w8618_pic_state),
mv88w8618_pic_init);
- sysbus_register_dev("mv88w8618_pit", sizeof(mv88w8618_pit_state),
- mv88w8618_pit_init);
+ sysbus_register_withprop(&mv88w8618_pit_info);
sysbus_register_dev("mv88w8618_flashcfg", sizeof(mv88w8618_flashcfg_state),
mv88w8618_flashcfg_init);
sysbus_register_dev("mv88w8618_eth", sizeof(mv88w8618_eth_state),