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