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