blob: 50bbab66eed7f44a56731ff4918afc0babc0966c [file] [log] [blame]
pbrook9ee6e8b2007-11-11 00:04:49 +00001/*
2 * ARM RealView Emulation Baseboard Interrupt Controller
3 *
4 * Copyright (c) 2006-2007 CodeSourcery.
5 * Written by Paul Brook
6 *
Matthew Fernandez8e31bf32011-06-26 12:21:35 +10007 * This code is licensed under the GPL.
pbrook9ee6e8b2007-11-11 00:04:49 +00008 */
9
Peter Maydell8ef94f02016-01-26 18:17:05 +000010#include "qemu/osdep.h"
Markus Armbrusterda34e652016-03-14 09:01:28 +010011#include "qapi/error.h"
Andreas Färberce318252013-08-19 00:48:55 +020012#include "hw/intc/realview_gic.h"
Paul Brookfe7e8752009-05-14 22:35:08 +010013
Peter Maydellfbbd05d2012-04-13 11:39:08 +000014static void realview_gic_set_irq(void *opaque, int irq, int level)
pbrook9ee6e8b2007-11-11 00:04:49 +000015{
Peter Maydellfbbd05d2012-04-13 11:39:08 +000016 RealViewGICState *s = (RealViewGICState *)opaque;
Andreas Färber612daf02013-08-19 00:37:07 +020017
18 qemu_set_irq(qdev_get_gpio_in(DEVICE(&s->gic), irq), level);
pbrook9ee6e8b2007-11-11 00:04:49 +000019}
Paul Brookfe7e8752009-05-14 22:35:08 +010020
Andreas Färber612daf02013-08-19 00:37:07 +020021static void realview_gic_realize(DeviceState *dev, Error **errp)
Paul Brookfe7e8752009-05-14 22:35:08 +010022{
Andreas Färber612daf02013-08-19 00:37:07 +020023 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
Andreas Färberb09a6f72013-07-26 20:34:29 +020024 RealViewGICState *s = REALVIEW_GIC(dev);
Peter Maydellfbbd05d2012-04-13 11:39:08 +000025 SysBusDevice *busdev;
Andreas Färber612daf02013-08-19 00:37:07 +020026 Error *err = NULL;
Mark Langsdorfa32134a2012-01-17 10:54:07 +000027 /* The GICs on the RealView boards have a fixed nonconfigurable
28 * number of interrupt lines, so we don't need to expose this as
29 * a qdev property.
30 */
Peter Maydellfbbd05d2012-04-13 11:39:08 +000031 int numirq = 96;
32
Andreas Färber612daf02013-08-19 00:37:07 +020033 qdev_prop_set_uint32(DEVICE(&s->gic), "num-irq", numirq);
34 object_property_set_bool(OBJECT(&s->gic), true, "realized", &err);
35 if (err != NULL) {
36 error_propagate(errp, err);
37 return;
38 }
39 busdev = SYS_BUS_DEVICE(&s->gic);
Peter Maydellfbbd05d2012-04-13 11:39:08 +000040
41 /* Pass through outbound IRQ lines from the GIC */
Andreas Färberb09a6f72013-07-26 20:34:29 +020042 sysbus_pass_irq(sbd, busdev);
Peter Maydellfbbd05d2012-04-13 11:39:08 +000043
44 /* Pass through inbound GPIO lines to the GIC */
Andreas Färberb09a6f72013-07-26 20:34:29 +020045 qdev_init_gpio_in(dev, realview_gic_set_irq, numirq - 32);
Peter Maydellfbbd05d2012-04-13 11:39:08 +000046
Peter Maydellfbbd05d2012-04-13 11:39:08 +000047 memory_region_add_subregion(&s->container, 0,
48 sysbus_mmio_get_region(busdev, 1));
49 memory_region_add_subregion(&s->container, 0x1000,
50 sysbus_mmio_get_region(busdev, 0));
Paul Brookfe7e8752009-05-14 22:35:08 +010051}
52
Andreas Färber612daf02013-08-19 00:37:07 +020053static void realview_gic_init(Object *obj)
Anthony Liguori999e12b2012-01-24 13:12:29 -060054{
Andreas Färber612daf02013-08-19 00:37:07 +020055 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
56 RealViewGICState *s = REALVIEW_GIC(obj);
57 DeviceState *gicdev;
Anthony Liguori999e12b2012-01-24 13:12:29 -060058
Andreas Färber612daf02013-08-19 00:37:07 +020059 memory_region_init(&s->container, OBJECT(s),
60 "realview-gic-container", 0x2000);
61 sysbus_init_mmio(sbd, &s->container);
62
63 object_initialize(&s->gic, sizeof(s->gic), TYPE_ARM_GIC);
64 gicdev = DEVICE(&s->gic);
65 qdev_set_parent_bus(gicdev, sysbus_get_default());
66 qdev_prop_set_uint32(gicdev, "num-cpu", 1);
67}
68
69static void realview_gic_class_init(ObjectClass *oc, void *data)
70{
71 DeviceClass *dc = DEVICE_CLASS(oc);
72
73 dc->realize = realview_gic_realize;
Anthony Liguori999e12b2012-01-24 13:12:29 -060074}
75
Andreas Färber8c43a6f2013-01-10 16:19:07 +010076static const TypeInfo realview_gic_info = {
Andreas Färberb09a6f72013-07-26 20:34:29 +020077 .name = TYPE_REALVIEW_GIC,
Anthony Liguori39bffca2011-12-07 21:34:16 -060078 .parent = TYPE_SYS_BUS_DEVICE,
79 .instance_size = sizeof(RealViewGICState),
Andreas Färber612daf02013-08-19 00:37:07 +020080 .instance_init = realview_gic_init,
Anthony Liguori39bffca2011-12-07 21:34:16 -060081 .class_init = realview_gic_class_init,
Anthony Liguori999e12b2012-01-24 13:12:29 -060082};
83
Andreas Färber83f7d432012-02-09 15:20:55 +010084static void realview_gic_register_types(void)
Paul Brookfe7e8752009-05-14 22:35:08 +010085{
Anthony Liguori39bffca2011-12-07 21:34:16 -060086 type_register_static(&realview_gic_info);
Paul Brookfe7e8752009-05-14 22:35:08 +010087}
88
Andreas Färber83f7d432012-02-09 15:20:55 +010089type_init(realview_gic_register_types)