aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2012-04-13 11:39:09 +0000
committerPeter Maydell <peter.maydell@linaro.org>2012-04-13 12:29:04 +0000
commitaecff6924dab0197b6c8f132e44502b25fd98a38 (patch)
tree5c0ca23b4fcf03f271b2bf62074c4cd00149f79f
parent2e9dfe20a62d93f145ea12a1b4755bb9cd61c327 (diff)
hw/arm_gic: Make gic_reset a sysbus reset function
Make gic_reset a sysbus reset function, so we actually reset the GIC on system reset rather than only at init. For the NVIC this requires us also to implement reset of the SysTick. Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/arm_gic.c5
-rw-r--r--hw/armv7m_nvic.c16
2 files changed, 19 insertions, 2 deletions
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index b54357033b..81858c3971 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -741,8 +741,9 @@ static const MemoryRegionOps gic_cpu_ops = {
};
#endif
-static void gic_reset(gic_state *s)
+static void gic_reset(DeviceState *dev)
{
+ gic_state *s = FROM_SYSBUS(gic_state, sysbus_from_qdev(dev));
int i;
memset(s->irq_state, 0, GIC_MAXIRQ * sizeof(gic_irq_state));
for (i = 0 ; i < NUM_CPU(s); i++) {
@@ -905,7 +906,6 @@ static void gic_init(gic_state *s, int num_irq)
}
#endif
- gic_reset(s);
register_savevm(NULL, "arm_gic", -1, 2, gic_save, gic_load, s);
}
@@ -938,6 +938,7 @@ static void arm_gic_class_init(ObjectClass *klass, void *data)
SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
sbc->init = arm_gic_init;
dc->props = arm_gic_properties;
+ dc->reset = gic_reset;
dc->no_user = 1;
}
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index 79cf448678..5cfa971cab 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -76,6 +76,14 @@ static void systick_timer_tick(void * opaque)
}
}
+static void systick_reset(nvic_state *s)
+{
+ s->systick.control = 0;
+ s->systick.reload = 0;
+ s->systick.tick = 0;
+ qemu_del_timer(s->systick.timer);
+}
+
/* The external routines use the hardware vector numbering, ie. the first
IRQ is #16. The internal GIC routines use #32 as the first IRQ. */
void armv7m_nvic_set_pending(void *opaque, int irq)
@@ -371,6 +379,13 @@ static const VMStateDescription vmstate_nvic = {
}
};
+static void armv7m_nvic_reset(DeviceState *dev)
+{
+ nvic_state *s = FROM_SYSBUSGIC(nvic_state, sysbus_from_qdev(dev));
+ gic_reset(&s->gic.busdev.qdev);
+ systick_reset(s);
+}
+
static int armv7m_nvic_init(SysBusDevice *dev)
{
nvic_state *s= FROM_SYSBUSGIC(nvic_state, dev);
@@ -400,6 +415,7 @@ static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
sdc->init = armv7m_nvic_init;
dc->vmsd = &vmstate_nvic;
+ dc->reset = armv7m_nvic_reset;
dc->props = armv7m_nvic_properties;
}