root / hw / intc / realview_gic.c @ ce31825d
History | View | Annotate | Download (2.5 kB)
1 |
/*
|
---|---|
2 |
* ARM RealView Emulation Baseboard Interrupt Controller
|
3 |
*
|
4 |
* Copyright (c) 2006-2007 CodeSourcery.
|
5 |
* Written by Paul Brook
|
6 |
*
|
7 |
* This code is licensed under the GPL.
|
8 |
*/
|
9 |
|
10 |
#include "hw/intc/realview_gic.h" |
11 |
|
12 |
static void realview_gic_set_irq(void *opaque, int irq, int level) |
13 |
{ |
14 |
RealViewGICState *s = (RealViewGICState *)opaque; |
15 |
|
16 |
qemu_set_irq(qdev_get_gpio_in(DEVICE(&s->gic), irq), level); |
17 |
} |
18 |
|
19 |
static void realview_gic_realize(DeviceState *dev, Error **errp) |
20 |
{ |
21 |
SysBusDevice *sbd = SYS_BUS_DEVICE(dev); |
22 |
RealViewGICState *s = REALVIEW_GIC(dev); |
23 |
SysBusDevice *busdev; |
24 |
Error *err = NULL;
|
25 |
/* The GICs on the RealView boards have a fixed nonconfigurable
|
26 |
* number of interrupt lines, so we don't need to expose this as
|
27 |
* a qdev property.
|
28 |
*/
|
29 |
int numirq = 96; |
30 |
|
31 |
qdev_prop_set_uint32(DEVICE(&s->gic), "num-irq", numirq);
|
32 |
object_property_set_bool(OBJECT(&s->gic), true, "realized", &err); |
33 |
if (err != NULL) { |
34 |
error_propagate(errp, err); |
35 |
return;
|
36 |
} |
37 |
busdev = SYS_BUS_DEVICE(&s->gic); |
38 |
|
39 |
/* Pass through outbound IRQ lines from the GIC */
|
40 |
sysbus_pass_irq(sbd, busdev); |
41 |
|
42 |
/* Pass through inbound GPIO lines to the GIC */
|
43 |
qdev_init_gpio_in(dev, realview_gic_set_irq, numirq - 32);
|
44 |
|
45 |
memory_region_add_subregion(&s->container, 0,
|
46 |
sysbus_mmio_get_region(busdev, 1));
|
47 |
memory_region_add_subregion(&s->container, 0x1000,
|
48 |
sysbus_mmio_get_region(busdev, 0));
|
49 |
} |
50 |
|
51 |
static void realview_gic_init(Object *obj) |
52 |
{ |
53 |
SysBusDevice *sbd = SYS_BUS_DEVICE(obj); |
54 |
RealViewGICState *s = REALVIEW_GIC(obj); |
55 |
DeviceState *gicdev; |
56 |
|
57 |
memory_region_init(&s->container, OBJECT(s), |
58 |
"realview-gic-container", 0x2000); |
59 |
sysbus_init_mmio(sbd, &s->container); |
60 |
|
61 |
object_initialize(&s->gic, sizeof(s->gic), TYPE_ARM_GIC);
|
62 |
gicdev = DEVICE(&s->gic); |
63 |
qdev_set_parent_bus(gicdev, sysbus_get_default()); |
64 |
qdev_prop_set_uint32(gicdev, "num-cpu", 1); |
65 |
} |
66 |
|
67 |
static void realview_gic_class_init(ObjectClass *oc, void *data) |
68 |
{ |
69 |
DeviceClass *dc = DEVICE_CLASS(oc); |
70 |
|
71 |
dc->realize = realview_gic_realize; |
72 |
} |
73 |
|
74 |
static const TypeInfo realview_gic_info = { |
75 |
.name = TYPE_REALVIEW_GIC, |
76 |
.parent = TYPE_SYS_BUS_DEVICE, |
77 |
.instance_size = sizeof(RealViewGICState),
|
78 |
.instance_init = realview_gic_init, |
79 |
.class_init = realview_gic_class_init, |
80 |
}; |
81 |
|
82 |
static void realview_gic_register_types(void) |
83 |
{ |
84 |
type_register_static(&realview_gic_info); |
85 |
} |
86 |
|
87 |
type_init(realview_gic_register_types) |