diff options
Diffstat (limited to 'hw/intc')
-rw-r--r-- | hw/intc/arm_gic.c | 22 | ||||
-rw-r--r-- | hw/intc/armv7m_nvic.c | 5 | ||||
-rw-r--r-- | hw/intc/realview_gic.c | 7 | ||||
-rw-r--r-- | hw/intc/xics.c | 14 |
4 files changed, 34 insertions, 14 deletions
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index ea0323f969..34dc84ae81 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -543,7 +543,21 @@ static bool gic_eoi_split(GICState *s, int cpu, MemTxAttrs attrs) static void gic_deactivate_irq(GICState *s, int cpu, int irq, MemTxAttrs attrs) { int cm = 1 << cpu; - int group = gic_has_groups(s) && GIC_TEST_GROUP(irq, cm); + int group; + + if (irq >= s->num_irq) { + /* + * This handles two cases: + * 1. If software writes the ID of a spurious interrupt [ie 1023] + * to the GICC_DIR, the GIC ignores that write. + * 2. If software writes the number of a non-existent interrupt + * this must be a subcase of "value written is not an active interrupt" + * and so this is UNPREDICTABLE. We choose to ignore it. + */ + return; + } + + group = gic_has_groups(s) && GIC_TEST_GROUP(irq, cm); if (!gic_eoi_split(s, cpu, attrs)) { /* This is UNPREDICTABLE; we choose to ignore it */ @@ -737,7 +751,9 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr offset, MemTxAttrs attrs) if (irq >= s->num_irq) { goto bad_reg; } - if (irq >= 29 && irq <= 31) { + if (irq < 29 && s->revision == REV_11MPCORE) { + res = 0; + } else if (irq < GIC_INTERNAL) { res = cm; } else { res = GIC_TARGET(irq); @@ -1000,7 +1016,7 @@ static void gic_dist_writeb(void *opaque, hwaddr offset, if (irq >= s->num_irq) { goto bad_reg; } - if (irq < 29) { + if (irq < 29 && s->revision == REV_11MPCORE) { value = 0; } else if (irq < GIC_INTERNAL) { value = ALL_CPU_MASK; diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 661be8878a..7a5330f201 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -2296,9 +2296,8 @@ static void armv7m_nvic_instance_init(Object *obj) NVICState *nvic = NVIC(obj); SysBusDevice *sbd = SYS_BUS_DEVICE(obj); - object_initialize(&nvic->systick[M_REG_NS], - sizeof(nvic->systick[M_REG_NS]), TYPE_SYSTICK); - qdev_set_parent_bus(DEVICE(&nvic->systick[M_REG_NS]), sysbus_get_default()); + sysbus_init_child_obj(obj, "systick-reg-ns", &nvic->systick[M_REG_NS], + sizeof(nvic->systick[M_REG_NS]), TYPE_SYSTICK); /* We can't initialize the secure systick here, as we don't know * yet if we need it. */ diff --git a/hw/intc/realview_gic.c b/hw/intc/realview_gic.c index 50bbab66ee..7f2ff85c83 100644 --- a/hw/intc/realview_gic.c +++ b/hw/intc/realview_gic.c @@ -54,16 +54,13 @@ static void realview_gic_init(Object *obj) { SysBusDevice *sbd = SYS_BUS_DEVICE(obj); RealViewGICState *s = REALVIEW_GIC(obj); - DeviceState *gicdev; memory_region_init(&s->container, OBJECT(s), "realview-gic-container", 0x2000); sysbus_init_mmio(sbd, &s->container); - object_initialize(&s->gic, sizeof(s->gic), TYPE_ARM_GIC); - gicdev = DEVICE(&s->gic); - qdev_set_parent_bus(gicdev, sysbus_get_default()); - qdev_prop_set_uint32(gicdev, "num-cpu", 1); + sysbus_init_child_obj(obj, "gic", &s->gic, sizeof(s->gic), TYPE_ARM_GIC); + qdev_prop_set_uint32(DEVICE(&s->gic), "num-cpu", 1); } static void realview_gic_class_init(ObjectClass *oc, void *data) diff --git a/hw/intc/xics.c b/hw/intc/xics.c index b9f1a3c972..c90c893228 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -291,7 +291,7 @@ static const VMStateDescription vmstate_icp_server = { }, }; -static void icp_reset(void *dev) +static void icp_reset(DeviceState *dev) { ICPState *icp = ICP(dev); @@ -303,6 +303,13 @@ static void icp_reset(void *dev) qemu_set_irq(icp->output, 0); } +static void icp_reset_handler(void *dev) +{ + DeviceClass *dc = DEVICE_GET_CLASS(dev); + + dc->reset(dev); +} + static void icp_realize(DeviceState *dev, Error **errp) { ICPState *icp = ICP(dev); @@ -345,7 +352,7 @@ static void icp_realize(DeviceState *dev, Error **errp) return; } - qemu_register_reset(icp_reset, dev); + qemu_register_reset(icp_reset_handler, dev); vmstate_register(NULL, icp->cs->cpu_index, &vmstate_icp_server, icp); } @@ -354,7 +361,7 @@ static void icp_unrealize(DeviceState *dev, Error **errp) ICPState *icp = ICP(dev); vmstate_unregister(NULL, &vmstate_icp_server, icp); - qemu_unregister_reset(icp_reset, dev); + qemu_unregister_reset(icp_reset_handler, dev); } static void icp_class_init(ObjectClass *klass, void *data) @@ -363,6 +370,7 @@ static void icp_class_init(ObjectClass *klass, void *data) dc->realize = icp_realize; dc->unrealize = icp_unrealize; + dc->reset = icp_reset; } static const TypeInfo icp_info = { |