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