bcm283* refactoring continues
[qemu/ar7.git] / hw / arm / bcm2836.c
blob3d7d5efd2307c7f79b2c618025dc94e01c8e05d2
1 #include "hw/arm/bcm2836.h"
2 #include "hw/arm/raspi_platform.h"
3 #include "hw/sysbus.h"
4 #include "sysemu/sysemu.h" /* for smp_cpus */
5 #include "exec/address-spaces.h"
7 #define DEFAULT_VCRAM_SIZE 0x4000000
9 static void bcm2836_init(Object *obj)
11 BCM2836State *s = BCM2836(obj);
12 SysBusDevice *dev;
13 int n;
15 /* TODO: probably shouldn't be using smp_cpus here */
16 assert(smp_cpus <= BCM2836_NCPUS);
17 for (n = 0; n < smp_cpus; n++) {
18 object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
19 "cortex-a15-" TYPE_ARM_CPU);
20 object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
21 &error_abort);
24 s->ic = dev = SYS_BUS_DEVICE(object_new("bcm2836_control"));
25 object_property_add_child(obj, "ic", OBJECT(dev), NULL);
26 qdev_set_parent_bus(DEVICE(dev), sysbus_get_default());
28 object_initialize(&s->peripherals, sizeof(s->peripherals),
29 TYPE_BCM2835_PERIPHERALS);
30 object_property_add_child(obj, "peripherals", OBJECT(&s->peripherals),
31 &error_abort);
32 qdev_set_parent_bus(DEVICE(&s->peripherals), sysbus_get_default());
35 static void bcm2836_realize(DeviceState *dev, Error **errp)
37 BCM2836State *s = BCM2836(dev);
38 Error *err = NULL;
39 int n;
41 /* common peripherals from bcm2835 */
42 object_property_set_bool(OBJECT(&s->peripherals), true, "realized", &err);
43 if (err) {
44 error_propagate(errp, err);
45 return;
48 sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->peripherals), 0,
49 BCM2836_PERI_BASE, 1);
51 /* bcm2836 interrupt controller (and mailboxes, etc.) */
52 object_property_set_bool(OBJECT(s->ic), true, "realized", &err);
53 if (err) {
54 error_propagate(errp, err);
55 return;
58 sysbus_mmio_map(SYS_BUS_DEVICE(s->ic), 0, BCM2836_CONTROL_BASE);
60 sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 0,
61 qdev_get_gpio_in_named(DEVICE(s->ic), "gpu_irq", 0));
62 sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 1,
63 qdev_get_gpio_in_named(DEVICE(s->ic), "gpu_fiq", 0));
65 /* TODO: probably shouldn't be using smp_cpus here */
66 assert(smp_cpus <= BCM2836_NCPUS);
67 for (n = 0; n < smp_cpus; n++) {
68 /* Mirror bcm2836, which has clusterid set to 0xf */
69 s->cpus[n].mp_affinity = 0xF00 | n;
71 /* set periphbase/CBAR value for CPU-local registers */
72 object_property_set_int(OBJECT(&s->cpus[n]),
73 BCM2836_PERI_BASE + MCORE_OFFSET,
74 "reset-cbar", &err);
75 if (err) {
76 error_report_err(err);
77 exit(1);
80 object_property_set_bool(OBJECT(&s->cpus[n]), true, "realized", &err);
81 if (err) {
82 error_report_err(err);
83 exit(1);
86 /* Connect irq/fiq outputs from the interrupt controller. */
87 qdev_connect_gpio_out_named(DEVICE(s->ic), "irq", n,
88 qdev_get_gpio_in(DEVICE(&s->cpus[n]),
89 ARM_CPU_IRQ));
90 qdev_connect_gpio_out_named(DEVICE(s->ic), "fiq", n,
91 qdev_get_gpio_in(DEVICE(&s->cpus[n]),
92 ARM_CPU_FIQ));
94 /* Connect timers from the CPU to the interrupt controller */
95 s->cpus[n].gt_timer_outputs[GTIMER_PHYS]
96 = qdev_get_gpio_in_named(DEVICE(s->ic), "cntpsirq", 0);
97 s->cpus[n].gt_timer_outputs[GTIMER_VIRT]
98 = qdev_get_gpio_in_named(DEVICE(s->ic), "cntvirq", 0);
102 static Property bcm2836_props[] = {
103 DEFINE_PROP_SIZE("vcram-size", BCM2836State, vcram_size, DEFAULT_VCRAM_SIZE),
104 DEFINE_PROP_END_OF_LIST()
107 static void bcm2836_class_init(ObjectClass *oc, void *data)
109 DeviceClass *dc = DEVICE_CLASS(oc);
111 dc->props = bcm2836_props;
112 dc->realize = bcm2836_realize;
115 * Reason: creates an ARM CPU, thus use after free(), see
116 * arm_cpu_class_init()
118 dc->cannot_destroy_with_object_finalize_yet = true;
121 static const TypeInfo bcm2836_type_info = {
122 .name = TYPE_BCM2836,
123 .parent = TYPE_SYS_BUS_DEVICE,
124 .instance_size = sizeof(BCM2836State),
125 .instance_init = bcm2836_init,
126 .class_init = bcm2836_class_init,
129 static void bcm2836_register_types(void)
131 type_register_static(&bcm2836_type_info);
134 type_init(bcm2836_register_types)