2 * Raspberry Pi emulation (c) 2012 Gregory Estrade
3 * Upstreaming code cleanup [including bcm2835_*] (c) 2013 Jan Petrous
5 * Rasperry Pi 2 emulation and refactoring Copyright (c) 2015, Microsoft
6 * Written by Andrew Baumann
8 * This work is licensed under the terms of the GNU GPL, version 2 or later.
9 * See the COPYING file in the top-level directory.
12 #include "qemu/osdep.h"
13 #include "qapi/error.h"
14 #include "qemu/module.h"
15 #include "hw/arm/bcm2836.h"
16 #include "hw/arm/raspi_platform.h"
17 #include "hw/sysbus.h"
18 #include "target/arm/cpu-qom.h"
19 #include "target/arm/gtimer.h"
21 static Property bcm2836_enabled_cores_property
=
22 DEFINE_PROP_UINT32("enabled-cpus", BCM283XBaseState
, enabled_cpus
, 0);
24 static void bcm283x_base_init(Object
*obj
)
26 BCM283XBaseState
*s
= BCM283X_BASE(obj
);
27 BCM283XBaseClass
*bc
= BCM283X_BASE_GET_CLASS(obj
);
30 for (n
= 0; n
< bc
->core_count
; n
++) {
31 object_initialize_child(obj
, "cpu[*]", &s
->cpu
[n
].core
,
34 if (bc
->core_count
> 1) {
35 qdev_property_add_static(DEVICE(obj
), &bcm2836_enabled_cores_property
);
36 qdev_prop_set_uint32(DEVICE(obj
), "enabled-cpus", bc
->core_count
);
40 object_initialize_child(obj
, "control", &s
->control
,
41 TYPE_BCM2836_CONTROL
);
45 static void bcm283x_init(Object
*obj
)
47 BCM283XState
*s
= BCM283X(obj
);
49 object_initialize_child(obj
, "peripherals", &s
->peripherals
,
50 TYPE_BCM2835_PERIPHERALS
);
51 object_property_add_alias(obj
, "board-rev", OBJECT(&s
->peripherals
),
53 object_property_add_alias(obj
, "command-line", OBJECT(&s
->peripherals
),
55 object_property_add_alias(obj
, "vcram-size", OBJECT(&s
->peripherals
),
57 object_property_add_alias(obj
, "vcram-base", OBJECT(&s
->peripherals
),
61 bool bcm283x_common_realize(DeviceState
*dev
, BCMSocPeripheralBaseState
*ps
,
64 BCM283XBaseState
*s
= BCM283X_BASE(dev
);
65 BCM283XBaseClass
*bc
= BCM283X_BASE_GET_CLASS(dev
);
68 /* common peripherals from bcm2835 */
70 obj
= object_property_get_link(OBJECT(dev
), "ram", &error_abort
);
72 object_property_add_const_link(OBJECT(ps
), "ram", obj
);
74 if (!sysbus_realize(SYS_BUS_DEVICE(ps
), errp
)) {
78 object_property_add_alias(OBJECT(s
), "sd-bus", OBJECT(ps
), "sd-bus");
80 sysbus_mmio_map_overlap(SYS_BUS_DEVICE(ps
), 0, bc
->peri_base
, 1);
84 static void bcm2835_realize(DeviceState
*dev
, Error
**errp
)
86 BCM283XState
*s
= BCM283X(dev
);
87 BCM283XBaseState
*s_base
= BCM283X_BASE(dev
);
88 BCMSocPeripheralBaseState
*ps_base
89 = BCM_SOC_PERIPHERALS_BASE(&s
->peripherals
);
91 if (!bcm283x_common_realize(dev
, ps_base
, errp
)) {
95 if (!qdev_realize(DEVICE(&s_base
->cpu
[0].core
), NULL
, errp
)) {
99 /* Connect irq/fiq outputs from the interrupt controller. */
100 sysbus_connect_irq(SYS_BUS_DEVICE(&s
->peripherals
), 0,
101 qdev_get_gpio_in(DEVICE(&s_base
->cpu
[0].core
), ARM_CPU_IRQ
));
102 sysbus_connect_irq(SYS_BUS_DEVICE(&s
->peripherals
), 1,
103 qdev_get_gpio_in(DEVICE(&s_base
->cpu
[0].core
), ARM_CPU_FIQ
));
106 static void bcm2836_realize(DeviceState
*dev
, Error
**errp
)
109 BCM283XState
*s
= BCM283X(dev
);
110 BCM283XBaseState
*s_base
= BCM283X_BASE(dev
);
111 BCM283XBaseClass
*bc
= BCM283X_BASE_GET_CLASS(dev
);
112 BCMSocPeripheralBaseState
*ps_base
113 = BCM_SOC_PERIPHERALS_BASE(&s
->peripherals
);
115 if (!bcm283x_common_realize(dev
, ps_base
, errp
)) {
119 /* bcm2836 interrupt controller (and mailboxes, etc.) */
120 if (!sysbus_realize(SYS_BUS_DEVICE(&s_base
->control
), errp
)) {
124 sysbus_mmio_map(SYS_BUS_DEVICE(&s_base
->control
), 0, bc
->ctrl_base
);
126 sysbus_connect_irq(SYS_BUS_DEVICE(&s
->peripherals
), 0,
127 qdev_get_gpio_in_named(DEVICE(&s_base
->control
), "gpu-irq", 0));
128 sysbus_connect_irq(SYS_BUS_DEVICE(&s
->peripherals
), 1,
129 qdev_get_gpio_in_named(DEVICE(&s_base
->control
), "gpu-fiq", 0));
131 for (n
= 0; n
< BCM283X_NCPUS
; n
++) {
132 object_property_set_int(OBJECT(&s_base
->cpu
[n
].core
), "mp-affinity",
133 (bc
->clusterid
<< 8) | n
, &error_abort
);
135 /* set periphbase/CBAR value for CPU-local registers */
136 object_property_set_int(OBJECT(&s_base
->cpu
[n
].core
), "reset-cbar",
137 bc
->peri_base
, &error_abort
);
139 /* start powered off if not enabled */
140 object_property_set_bool(OBJECT(&s_base
->cpu
[n
].core
),
142 n
>= s_base
->enabled_cpus
, &error_abort
);
144 if (!qdev_realize(DEVICE(&s_base
->cpu
[n
].core
), NULL
, errp
)) {
148 /* Connect irq/fiq outputs from the interrupt controller. */
149 qdev_connect_gpio_out_named(DEVICE(&s_base
->control
), "irq", n
,
150 qdev_get_gpio_in(DEVICE(&s_base
->cpu
[n
].core
), ARM_CPU_IRQ
));
151 qdev_connect_gpio_out_named(DEVICE(&s_base
->control
), "fiq", n
,
152 qdev_get_gpio_in(DEVICE(&s_base
->cpu
[n
].core
), ARM_CPU_FIQ
));
154 /* Connect timers from the CPU to the interrupt controller */
155 qdev_connect_gpio_out(DEVICE(&s_base
->cpu
[n
].core
), GTIMER_PHYS
,
156 qdev_get_gpio_in_named(DEVICE(&s_base
->control
), "cntpnsirq", n
));
157 qdev_connect_gpio_out(DEVICE(&s_base
->cpu
[n
].core
), GTIMER_VIRT
,
158 qdev_get_gpio_in_named(DEVICE(&s_base
->control
), "cntvirq", n
));
159 qdev_connect_gpio_out(DEVICE(&s_base
->cpu
[n
].core
), GTIMER_HYP
,
160 qdev_get_gpio_in_named(DEVICE(&s_base
->control
), "cnthpirq", n
));
161 qdev_connect_gpio_out(DEVICE(&s_base
->cpu
[n
].core
), GTIMER_SEC
,
162 qdev_get_gpio_in_named(DEVICE(&s_base
->control
), "cntpsirq", n
));
166 static void bcm283x_base_class_init(ObjectClass
*oc
, void *data
)
168 DeviceClass
*dc
= DEVICE_CLASS(oc
);
170 /* Reason: Must be wired up in code (see raspi_init() function) */
171 dc
->user_creatable
= false;
174 static void bcm2835_class_init(ObjectClass
*oc
, void *data
)
176 DeviceClass
*dc
= DEVICE_CLASS(oc
);
177 BCM283XBaseClass
*bc
= BCM283X_BASE_CLASS(oc
);
179 bc
->cpu_type
= ARM_CPU_TYPE_NAME("arm1176");
181 bc
->peri_base
= 0x20000000;
182 dc
->realize
= bcm2835_realize
;
185 static void bcm2836_class_init(ObjectClass
*oc
, void *data
)
187 DeviceClass
*dc
= DEVICE_CLASS(oc
);
188 BCM283XBaseClass
*bc
= BCM283X_BASE_CLASS(oc
);
190 bc
->cpu_type
= ARM_CPU_TYPE_NAME("cortex-a7");
191 bc
->core_count
= BCM283X_NCPUS
;
192 bc
->peri_base
= 0x3f000000;
193 bc
->ctrl_base
= 0x40000000;
195 dc
->realize
= bcm2836_realize
;
198 #ifdef TARGET_AARCH64
199 static void bcm2837_class_init(ObjectClass
*oc
, void *data
)
201 DeviceClass
*dc
= DEVICE_CLASS(oc
);
202 BCM283XBaseClass
*bc
= BCM283X_BASE_CLASS(oc
);
204 bc
->cpu_type
= ARM_CPU_TYPE_NAME("cortex-a53");
205 bc
->core_count
= BCM283X_NCPUS
;
206 bc
->peri_base
= 0x3f000000;
207 bc
->ctrl_base
= 0x40000000;
209 dc
->realize
= bcm2836_realize
;
213 static const TypeInfo bcm283x_types
[] = {
215 .name
= TYPE_BCM2835
,
216 .parent
= TYPE_BCM283X
,
217 .class_init
= bcm2835_class_init
,
219 .name
= TYPE_BCM2836
,
220 .parent
= TYPE_BCM283X
,
221 .class_init
= bcm2836_class_init
,
222 #ifdef TARGET_AARCH64
224 .name
= TYPE_BCM2837
,
225 .parent
= TYPE_BCM283X
,
226 .class_init
= bcm2837_class_init
,
229 .name
= TYPE_BCM283X
,
230 .parent
= TYPE_BCM283X_BASE
,
231 .instance_size
= sizeof(BCM283XState
),
232 .instance_init
= bcm283x_init
,
235 .name
= TYPE_BCM283X_BASE
,
236 .parent
= TYPE_DEVICE
,
237 .instance_size
= sizeof(BCM283XBaseState
),
238 .instance_init
= bcm283x_base_init
,
239 .class_size
= sizeof(BCM283XBaseClass
),
240 .class_init
= bcm283x_base_class_init
,
245 DEFINE_TYPES(bcm283x_types
)