[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 10/18] armv7m: NVIC initialization
From: |
Michael Davidsaver |
Subject: |
[Qemu-devel] [PATCH 10/18] armv7m: NVIC initialization |
Date: |
Sun, 8 Nov 2015 20:11:37 -0500 |
Signed-off-by: Michael Davidsaver <address@hidden>
---
hw/intc/armv7m_nvic.c | 107 ++++++++++++++++++++++++--------------------------
1 file changed, 51 insertions(+), 56 deletions(-)
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index c860b36..8eaf677 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -827,7 +827,7 @@ int nvic_post_load(void *opaque, int version_id)
set_prio(s, i, s->vectors[i].raw_prio);
}
- nvic_irq_update(s, highest_runnable_prio(s->cpu));
+ nvic_irq_update(s, 0);
return 0;
}
@@ -883,66 +883,66 @@ static const VMStateDescription vmstate_nvic = {
}
};
+static Property props_nvic[] = {
+ DEFINE_PROP_UINT32("num-irq", nvic_state, num_irq, 64),
+ DEFINE_PROP_END_OF_LIST()
+};
+
static void armv7m_nvic_reset(DeviceState *dev)
{
nvic_state *s = NVIC(dev);
- NVICClass *nc = NVIC_GET_CLASS(s);
- nc->parent_reset(dev);
- /* Common GIC reset resets to disabled; the NVIC doesn't have
- * per-CPU interfaces so mark our non-existent CPU interface
- * as enabled by default, and with a priority mask which allows
- * all interrupts through.
- */
- s->gic.cpu_ctlr[0] = GICC_CTLR_EN_GRP0;
- s->gic.priority_mask[0] = 0x100;
- /* The NVIC as a whole is always enabled. */
- s->gic.ctlr = 1;
+
+ s->vectors[ARMV7M_EXCP_RESET].enabled = 1;
+ s->vectors[ARMV7M_EXCP_NMI].enabled = 1;
+ s->vectors[ARMV7M_EXCP_HARD].enabled = 1;
+ s->vectors[ARMV7M_EXCP_SVC].enabled = 1;
+ s->vectors[ARMV7M_EXCP_DEBUG].enabled = 1;
+ s->vectors[ARMV7M_EXCP_PENDSV].enabled = 1;
+
+ s->vectors[ARMV7M_EXCP_RESET].prio_group = -3;
+ s->vectors[ARMV7M_EXCP_NMI].prio_group = -2;
+ s->vectors[ARMV7M_EXCP_HARD].prio_group = -1;
+
systick_reset(s);
}
static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
{
nvic_state *s = NVIC(dev);
- NVICClass *nc = NVIC_GET_CLASS(s);
- Error *local_err = NULL;
-
- /* The NVIC always has only one CPU */
- s->gic.num_cpu = 1;
- /* Tell the common code we're an NVIC */
- s->gic.revision = 0xffffffff;
- s->num_irq = s->gic.num_irq;
- nc->parent_realize(dev, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
+
+ /* evil hack to get ARMCPU* ahead of time */
+ assert(cpus.tqh_first);
+ assert(!CPU_NEXT(cpus.tqh_first));
+ s->cpu = ARM_CPU(cpus.tqh_first);
+ assert(s->cpu);
+
+ if (s->num_irq > NVIC_MAX_IRQ) {
+ error_setg(errp, TYPE_NVIC " num_irq too large");
return;
}
- gic_init_irqs_and_distributor(&s->gic);
- /* The NVIC and system controller register area looks like this:
- * 0..0xff : system control registers, including systick
- * 0x100..0xcff : GIC-like registers
- * 0xd00..0xfff : system control registers
- * We use overlaying to put the GIC like registers
- * over the top of the system control register region.
- */
- memory_region_init(&s->container, OBJECT(s), "nvic", 0x1000);
- /* The system register region goes at the bottom of the priority
- * stack as it covers the whole page.
+
+ qdev_init_gpio_in(dev, set_irq_level, s->num_irq);
+
+ s->num_irq += 16; /* include space for internal exception vectors */
+
+ /* The NVIC and system controller register area starts at 0xe000e000
+ * and looks like this:
+ * 0x004 - ICTR
+ * 0x010 - 0x1c - systick
+ * 0x100..0x7ec - NVIC
+ * 0x7f0..0xcff - Reserved
+ * 0xd00..0xd3c - SCS registers
+ * 0xd40..0xeff - Reserved or Not implemented
+ * 0xf00 - STIR
*/
- memory_region_init_io(&s->sysregmem, OBJECT(s), &nvic_sysreg_ops, s,
+
+ memory_region_init_io(&s->iomem, OBJECT(s), &nvic_sysreg_ops, s,
"nvic_sysregs", 0x1000);
- memory_region_add_subregion(&s->container, 0, &s->sysregmem);
- /* Alias the GIC region so we can get only the section of it
- * we need, and layer it on top of the system register region.
- */
- memory_region_init_alias(&s->gic_iomem_alias, OBJECT(s),
- "nvic-gic", &s->gic.iomem,
- 0x100, 0xc00);
- memory_region_add_subregion_overlap(&s->container, 0x100,
- &s->gic_iomem_alias, 1);
+
/* Map the whole thing into system memory at the location required
* by the v7M architecture.
*/
- memory_region_add_subregion(get_system_memory(), 0xe000e000,
&s->container);
+ memory_region_add_subregion(get_system_memory(), 0xe000e000, &s->iomem);
s->systick.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, systick_timer_tick, s);
}
@@ -954,36 +954,31 @@ static void armv7m_nvic_instance_init(Object *obj)
* any user-specified property setting, so just modify the
* value in the GICState struct.
*/
- GICState *s = ARM_GIC_COMMON(obj);
DeviceState *dev = DEVICE(obj);
nvic_state *nvic = NVIC(obj);
- /* The ARM v7m may have anything from 0 to 496 external interrupt
- * IRQ lines. We default to 64. Other boards may differ and should
- * set the num-irq property appropriately.
- */
- s->num_irq = 64;
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+
+ sysbus_init_irq(sbd, &nvic->excpout);
qdev_init_gpio_out_named(dev, &nvic->sysresetreq, "SYSRESETREQ", 1);
}
static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
{
- NVICClass *nc = NVIC_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
- nc->parent_reset = dc->reset;
- nc->parent_realize = dc->realize;
dc->vmsd = &vmstate_nvic;
+ dc->props = props_nvic;
dc->reset = armv7m_nvic_reset;
dc->realize = armv7m_nvic_realize;
}
static const TypeInfo armv7m_nvic_info = {
.name = TYPE_NVIC,
- .parent = TYPE_ARM_GIC_COMMON,
+ .parent = TYPE_SYS_BUS_DEVICE,
.instance_init = armv7m_nvic_instance_init,
.instance_size = sizeof(nvic_state),
.class_init = armv7m_nvic_class_init,
- .class_size = sizeof(NVICClass),
+ .class_size = sizeof(SysBusDeviceClass),
};
static void armv7m_nvic_register_types(void)
--
2.1.4
- Re: [Qemu-devel] [PATCH 03/18] armv7m: Complain about incorrect exception table entries., (continued)
- [Qemu-devel] [PATCH 01/18] armv7m: MRS/MSR handle unprivileged access, Michael Davidsaver, 2015/11/08
- [Qemu-devel] [PATCH 02/18] armv7m: Undo armv7m.hack, Michael Davidsaver, 2015/11/08
- [Qemu-devel] [PATCH 08/18] armv7m: fix RETTOBASE, Michael Davidsaver, 2015/11/08
- [Qemu-devel] [PATCH 09/18] armv7m: NVIC update vmstate, Michael Davidsaver, 2015/11/08
- [Qemu-devel] [PATCH 12/18] armv7m: simpler/faster exception start, Michael Davidsaver, 2015/11/08
- [Qemu-devel] [PATCH 11/18] armv7m: fix I and F flag handling, Michael Davidsaver, 2015/11/08
- [Qemu-devel] [PATCH 10/18] armv7m: NVIC initialization,
Michael Davidsaver <=
- [Qemu-devel] [PATCH 14/18] armv7m: auto-clear FAULTMASK, Michael Davidsaver, 2015/11/08
- [Qemu-devel] [PATCH 07/18] armv7m: Update NVIC registers, Michael Davidsaver, 2015/11/08
- [Qemu-devel] [PATCH 17/18] armv7m: implement CCR, Michael Davidsaver, 2015/11/08
- [Qemu-devel] [PATCH 15/18] arm: gic: Remove references to NVIC, Michael Davidsaver, 2015/11/08
- [Qemu-devel] [PATCH 16/18] armv7m: check exception return consistency, Michael Davidsaver, 2015/11/08
- [Qemu-devel] [PATCH 13/18] armv7m: implement CFSR and HFSR, Michael Davidsaver, 2015/11/08
- [Qemu-devel] [PATCH 18/18] armv7m: prevent unprivileged write to STIR, Michael Davidsaver, 2015/11/08
- Re: [Qemu-devel] [PATCH 00/18] Fix exception handling and msr/mrs access, Peter Maydell, 2015/11/17