xref: /openbmc/qemu/hw/arm/bcm2838.c (revision dcf1d8cd)
1 /*
2  * BCM2838 SoC emulation
3  *
4  * Copyright (C) 2022 Ovchinnikov Vitalii <vitalii.ovchinnikov@auriga.com>
5  *
6  * SPDX-License-Identifier: GPL-2.0-or-later
7  */
8 
9 #include "qemu/osdep.h"
10 #include "qapi/error.h"
11 #include "qemu/module.h"
12 #include "hw/arm/raspi_platform.h"
13 #include "hw/sysbus.h"
14 #include "hw/arm/bcm2838.h"
15 #include "trace.h"
16 
17 #define VIRTUAL_PMU_IRQ 7
18 
19 static void bcm2838_init(Object *obj)
20 {
21     BCM2838State *s = BCM2838(obj);
22 
23     object_initialize_child(obj, "peripherals", &s->peripherals,
24                             TYPE_BCM2838_PERIPHERALS);
25     object_property_add_alias(obj, "board-rev", OBJECT(&s->peripherals),
26                               "board-rev");
27     object_property_add_alias(obj, "vcram-size", OBJECT(&s->peripherals),
28                               "vcram-size");
29     object_property_add_alias(obj, "command-line", OBJECT(&s->peripherals),
30                               "command-line");
31 }
32 
33 static void bcm2838_realize(DeviceState *dev, Error **errp)
34 {
35     int n;
36     BCM2838State *s = BCM2838(dev);
37     BCM283XBaseState *s_base = BCM283X_BASE(dev);
38     BCM283XBaseClass *bc_base = BCM283X_BASE_GET_CLASS(dev);
39     BCM2838PeripheralState *ps = BCM2838_PERIPHERALS(&s->peripherals);
40     BCMSocPeripheralBaseState *ps_base =
41         BCM_SOC_PERIPHERALS_BASE(&s->peripherals);
42 
43     if (!bcm283x_common_realize(dev, ps_base, errp)) {
44         return;
45     }
46     sysbus_mmio_map_overlap(SYS_BUS_DEVICE(ps), 1, BCM2838_PERI_LOW_BASE, 1);
47 
48     /* bcm2836 interrupt controller (and mailboxes, etc.) */
49     if (!sysbus_realize(SYS_BUS_DEVICE(&s_base->control), errp)) {
50         return;
51     }
52     sysbus_mmio_map(SYS_BUS_DEVICE(&s_base->control), 0, bc_base->ctrl_base);
53 
54     /* Create cores */
55     for (n = 0; n < bc_base->core_count; n++) {
56 
57         object_property_set_int(OBJECT(&s_base->cpu[n].core), "mp-affinity",
58                                 (bc_base->clusterid << 8) | n, &error_abort);
59 
60         /* start powered off if not enabled */
61         object_property_set_bool(OBJECT(&s_base->cpu[n].core),
62                                  "start-powered-off",
63                                  n >= s_base->enabled_cpus, &error_abort);
64 
65         if (!qdev_realize(DEVICE(&s_base->cpu[n].core), NULL, errp)) {
66             return;
67         }
68     }
69 }
70 
71 static void bcm2838_class_init(ObjectClass *oc, void *data)
72 {
73     DeviceClass *dc = DEVICE_CLASS(oc);
74     BCM283XBaseClass *bc_base = BCM283X_BASE_CLASS(oc);
75 
76     bc_base->cpu_type = ARM_CPU_TYPE_NAME("cortex-a72");
77     bc_base->core_count = BCM283X_NCPUS;
78     bc_base->peri_base = 0xfe000000;
79     bc_base->ctrl_base = 0xff800000;
80     bc_base->clusterid = 0x0;
81     dc->realize = bcm2838_realize;
82 }
83 
84 static const TypeInfo bcm2838_type = {
85     .name           = TYPE_BCM2838,
86     .parent         = TYPE_BCM283X_BASE,
87     .instance_size  = sizeof(BCM2838State),
88     .instance_init  = bcm2838_init,
89     .class_size     = sizeof(BCM283XBaseClass),
90     .class_init     = bcm2838_class_init,
91 };
92 
93 static void bcm2838_register_types(void)
94 {
95     type_register_static(&bcm2838_type);
96 }
97 
98 type_init(bcm2838_register_types);
99