#include "qemu-timer.h"
#include "arm-misc.h"
-#define GIC_NIRQ 64
+/* 32 internal lines (16 used for system exceptions) plus 64 external
+ interrupt lines. */
+#define GIC_NIRQ 96
#define NCPU 1
#define NVIC 1
#define SYSTICK_CLKSOURCE (1 << 2)
#define SYSTICK_COUNTFLAG (1 << 16)
-/* Conversion factor from qemu timer to SysTick frequencies.
- QEMU uses a base of 1GHz, so these give 20MHz and 1MHz for core and
- reference frequencies. */
+int system_clock_scale;
+/* Conversion factor from qemu timer to SysTick frequencies. */
static inline int64_t systick_scale(nvic_state *s)
{
if (s->systick.control & SYSTICK_CLKSOURCE)
- return 50;
+ return system_clock_scale;
else
return 1000;
}
}
}
+static void nvic_save(QEMUFile *f, void *opaque)
+{
+ nvic_state *s = (nvic_state *)opaque;
+
+ qemu_put_be32(f, s->systick.control);
+ qemu_put_be32(f, s->systick.reload);
+ qemu_put_be64(f, s->systick.tick);
+ qemu_put_timer(f, s->systick.timer);
+}
+
+static int nvic_load(QEMUFile *f, void *opaque, int version_id)
+{
+ nvic_state *s = (nvic_state *)opaque;
+
+ if (version_id != 1)
+ return -EINVAL;
+
+ s->systick.control = qemu_get_be32(f);
+ s->systick.reload = qemu_get_be32(f);
+ s->systick.tick = qemu_get_be64(f);
+ qemu_get_timer(f, s->systick.timer);
+
+ return 0;
+}
+
qemu_irq *armv7m_nvic_init(CPUState *env)
{
nvic_state *s;
if (env->v7m.nvic)
cpu_abort(env, "CPU can only have one NVIC\n");
env->v7m.nvic = s;
+ register_savevm("armv7m_nvic", -1, 1, nvic_save, nvic_load, s);
return s->gic->in;
}