Merge branch 'master' into raspi
[qemu/ar7.git] / hw / arm / bcm2836.c.orig
blob3f48b9a68182388762bd998737a79630dfc146bc
1 /*
2  * Raspberry Pi emulation (c) 2012 Gregory Estrade
3  * Upstreaming code cleanup [including bcm2835_*] (c) 2013 Jan Petrous
4  *
5  * Rasperry Pi 2 emulation and refactoring Copyright (c) 2015, Microsoft
6  * Written by Andrew Baumann
7  *
8  * This code is licensed under the GNU GPLv2 and later.
9  */
11 #include "hw/arm/bcm2836.h"
12 #include "hw/arm/raspi_platform.h"
13 #include "hw/sysbus.h"
14 #include "sysemu/sysemu.h" /* for smp_cpus */
15 #include "exec/address-spaces.h"
17 <<<<<<< HEAD
18 =======
19 /* Peripheral base address seen by the CPU */
20 #define BCM2836_PERI_BASE       0x3F000000
22 /* "QA7" (Pi2) interrupt controller and mailboxes etc. */
23 #define BCM2836_CONTROL_BASE    0x40000000
25 >>>>>>> upstreaming-raspi
26 static void bcm2836_init(Object *obj)
28     BCM2836State *s = BCM2836(obj);
29     int n;
31     /* TODO: probably shouldn't be using smp_cpus here */
32     assert(smp_cpus <= BCM2836_NCPUS);
33     for (n = 0; n < smp_cpus; n++) {
34         object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
35                           "cortex-a15-" TYPE_ARM_CPU);
36         object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
37                                   &error_abort);
38     }
40     object_initialize(&s->ic, sizeof(s->ic), TYPE_BCM2836_CONTROL);
41     object_property_add_child(obj, "ic", OBJECT(&s->ic), NULL);
42     qdev_set_parent_bus(DEVICE(&s->ic), sysbus_get_default());
44     object_initialize(&s->peripherals, sizeof(s->peripherals),
45                       TYPE_BCM2835_PERIPHERALS);
46     object_property_add_child(obj, "peripherals", OBJECT(&s->peripherals),
47                               &error_abort);
48 <<<<<<< HEAD
49     object_property_add_alias(obj, "vcram-size", OBJECT(&s->peripherals),
50                               "vcram-size", &error_abort);
51 =======
52 >>>>>>> upstreaming-raspi
53     qdev_set_parent_bus(DEVICE(&s->peripherals), sysbus_get_default());
56 static void bcm2836_realize(DeviceState *dev, Error **errp)
58     BCM2836State *s = BCM2836(dev);
59 <<<<<<< HEAD
60 =======
61     Object *obj;
62 >>>>>>> upstreaming-raspi
63     Error *err = NULL;
64     int n;
66     /* common peripherals from bcm2835 */
67 <<<<<<< HEAD
68 =======
69     obj = object_property_get_link(OBJECT(dev), "ram", &err);
70     if (obj == NULL) {
71         error_setg(errp, "%s: required ram link not found: %s",
72                    __func__, error_get_pretty(err));
73         return;
74     }
76     object_property_add_const_link(OBJECT(&s->peripherals), "ram", obj, &err);
77     if (err) {
78         error_propagate(errp, err);
79         return;
80     }
82 >>>>>>> upstreaming-raspi
83     object_property_set_bool(OBJECT(&s->peripherals), true, "realized", &err);
84     if (err) {
85         error_propagate(errp, err);
86         return;
87     }
89     sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->peripherals), 0,
90                             BCM2836_PERI_BASE, 1);
92     /* bcm2836 interrupt controller (and mailboxes, etc.) */
93     object_property_set_bool(OBJECT(&s->ic), true, "realized", &err);
94     if (err) {
95         error_propagate(errp, err);
96         return;
97     }
99     sysbus_mmio_map(SYS_BUS_DEVICE(&s->ic), 0, BCM2836_CONTROL_BASE);
101     sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 0,
102                        qdev_get_gpio_in_named(DEVICE(&s->ic), "gpu_irq", 0));
103     sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 1,
104                        qdev_get_gpio_in_named(DEVICE(&s->ic), "gpu_fiq", 0));
106     /* TODO: probably shouldn't be using smp_cpus here */
107     assert(smp_cpus <= BCM2836_NCPUS);
108     for (n = 0; n < smp_cpus; n++) {
109         /* Mirror bcm2836, which has clusterid set to 0xf */
110         s->cpus[n].mp_affinity = 0xF00 | n;
112         /* set periphbase/CBAR value for CPU-local registers */
113         object_property_set_int(OBJECT(&s->cpus[n]),
114                                 BCM2836_PERI_BASE + MCORE_OFFSET,
115                                 "reset-cbar", &err);
116         if (err) {
117             error_report_err(err);
118             exit(1);
119         }
121         object_property_set_bool(OBJECT(&s->cpus[n]), true, "realized", &err);
122         if (err) {
123             error_report_err(err);
124             exit(1);
125         }
127         /* Connect irq/fiq outputs from the interrupt controller. */
128         qdev_connect_gpio_out_named(DEVICE(&s->ic), "irq", n,
129                                     qdev_get_gpio_in(DEVICE(&s->cpus[n]),
130                                                      ARM_CPU_IRQ));
131         qdev_connect_gpio_out_named(DEVICE(&s->ic), "fiq", n,
132                                     qdev_get_gpio_in(DEVICE(&s->cpus[n]),
133                                                      ARM_CPU_FIQ));
135         /* Connect timers from the CPU to the interrupt controller */
136         s->cpus[n].gt_timer_outputs[GTIMER_PHYS]
137             = qdev_get_gpio_in_named(DEVICE(&s->ic), "cntpsirq", 0);
138         s->cpus[n].gt_timer_outputs[GTIMER_VIRT]
139             = qdev_get_gpio_in_named(DEVICE(&s->ic), "cntvirq", 0);
140     }
143 static void bcm2836_class_init(ObjectClass *oc, void *data)
145     DeviceClass *dc = DEVICE_CLASS(oc);
147     dc->realize = bcm2836_realize;
149     /*
150      * Reason: creates an ARM CPU, thus use after free(), see
151      * arm_cpu_class_init()
152      */
153     dc->cannot_destroy_with_object_finalize_yet = true;
156 static const TypeInfo bcm2836_type_info = {
157     .name = TYPE_BCM2836,
158     .parent = TYPE_SYS_BUS_DEVICE,
159     .instance_size = sizeof(BCM2836State),
160     .instance_init = bcm2836_init,
161     .class_init = bcm2836_class_init,
164 static void bcm2836_register_types(void)
166     type_register_static(&bcm2836_type_info);
169 type_init(bcm2836_register_types)