Except we alter the device tree blob, the 4B is just another raspi model. Signed-off-by: Philippe Mathieu-Daudé <philmd@xxxxxxxxxx> --- hw/arm/raspi.c | 114 ++++++++++++++++++++++++++++++++++++- hw/arm/raspi4b.c | 136 --------------------------------------------- hw/arm/meson.build | 2 +- 3 files changed, 114 insertions(+), 138 deletions(-) delete mode 100644 hw/arm/raspi4b.c diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index 508f90479e2..3fa382d62ce 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -8,6 +8,10 @@ * Raspberry Pi 3 emulation Copyright (c) 2018 Zoltán Baldaszti * Upstream code cleanup (c) 2018 Pekka Enberg * + * Raspberry Pi 4 emulation Copyright (C) 2022 Ovchinnikov Vitalii + * + * SPDX-License-Identifier: GPL-2.0-or-later + * * This work is licensed under the terms of the GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. */ @@ -16,20 +20,27 @@ #include "qemu/units.h" #include "qemu/cutils.h" #include "qapi/error.h" +#include "qapi/visitor.h" #include "hw/arm/boot.h" #include "hw/arm/bcm2836.h" #include "hw/arm/bcm2838.h" #include "hw/arm/raspi_platform.h" +#include "hw/display/bcm2835_fb.h" #include "hw/registerfields.h" #include "qemu/error-report.h" #include "hw/boards.h" #include "hw/loader.h" #include "hw/arm/boot.h" #include "qom/object.h" +#include "system/device_tree.h" +#include <libfdt.h> #define TYPE_RASPI_MACHINE MACHINE_TYPE_NAME("raspi-common") OBJECT_DECLARE_SIMPLE_TYPE(RaspiMachineState, RASPI_MACHINE) +#define TYPE_RASPI4B_MACHINE MACHINE_TYPE_NAME("raspi4b") +OBJECT_DECLARE_SIMPLE_TYPE(Raspi4bMachineState, RASPI4B_MACHINE) + #define SMPBOOT_ADDR 0x300 /* this should leave enough space for ATAGS */ #define MVBAR_ADDR 0x400 /* secure vectors */ #define BOARDSETUP_ADDR (MVBAR_ADDR + 0x20) /* board setup code */ @@ -44,6 +55,11 @@ struct RaspiMachineState { BCM283XState soc; }; +struct Raspi4bMachineState { + RaspiBaseMachineState parent_obj; + BCM2838State soc; +}; + /* * Board revision codes: * www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/ @@ -301,6 +317,83 @@ void raspi_base_machine_init(MachineState *machine, boot_ram_size); } +#ifdef TARGET_AARCH64 +/* + * Add second memory region if board RAM amount exceeds VC base address + * (see https://datasheets.raspberrypi.com/bcm2711/bcm2711-peripherals.pdf + * 1.2 Address Map) + */ +static int raspi4_add_memory_node(void *fdt, hwaddr mem_base, hwaddr mem_len) +{ + int ret; + uint32_t acells, scells; + char *nodename = g_strdup_printf("/memory@%" PRIx64, mem_base); + + acells = qemu_fdt_getprop_cell(fdt, "/", "#address-cells", + NULL, &error_fatal); + scells = qemu_fdt_getprop_cell(fdt, "/", "#size-cells", + NULL, &error_fatal); + if (acells == 0 || scells == 0) { + fprintf(stderr, "dtb file invalid (#address-cells or #size-cells 0)\n"); + ret = -1; + } else { + qemu_fdt_add_subnode(fdt, nodename); + qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory"); + ret = qemu_fdt_setprop_sized_cells(fdt, nodename, "reg", + acells, mem_base, + scells, mem_len); + } + + g_free(nodename); + return ret; +} + +static void raspi4_modify_dtb(const struct arm_boot_info *info, void *fdt) +{ + uint64_t ram_size; + + /* Temporarily disable following devices until they are implemented */ + const char *nodes_to_remove[] = { + "brcm,bcm2711-pcie", + "brcm,bcm2711-rng200", + "brcm,bcm2711-thermal", + "brcm,bcm2711-genet-v5", + }; + + for (int i = 0; i < ARRAY_SIZE(nodes_to_remove); i++) { + const char *dev_str = nodes_to_remove[i]; + + int offset = fdt_node_offset_by_compatible(fdt, -1, dev_str); + if (offset >= 0) { + if (!fdt_nop_node(fdt, offset)) { + warn_report("bcm2711 dtc: %s has been disabled!", dev_str); + } + } + } + + ram_size = board_ram_size(info->board_id); + + if (info->ram_size > UPPER_RAM_BASE) { + raspi4_add_memory_node(fdt, UPPER_RAM_BASE, ram_size - UPPER_RAM_BASE); + } +} + +static void raspi4b_machine_init(MachineState *machine) +{ + Raspi4bMachineState *s = RASPI4B_MACHINE(machine); + RaspiBaseMachineState *s_base = RASPI_BASE_MACHINE(machine); + RaspiBaseMachineClass *mc = RASPI_BASE_MACHINE_GET_CLASS(machine); + BCM2838State *soc = &s->soc; + + s_base->binfo.modify_dtb = raspi4_modify_dtb; + s_base->binfo.board_id = mc->board_rev; + + object_initialize_child(OBJECT(machine), "soc", soc, + board_soc_type(mc->board_rev)); + raspi_base_machine_init(machine, BCM283X_BASE(soc)); +} +#endif /* TARGET_AARCH64 */ + void raspi_machine_init(MachineState *machine) { RaspiMachineState *s = RASPI_MACHINE(machine); @@ -382,6 +475,20 @@ static void raspi3b_machine_class_init(ObjectClass *oc, void *data) rmc->board_rev = 0xa02082; raspi_machine_class_init(mc, rmc->board_rev); }; + +static void raspi4b_machine_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + RaspiBaseMachineClass *rmc = RASPI_BASE_MACHINE_CLASS(oc); + +#if HOST_LONG_BITS == 32 + rmc->board_rev = 0xa03111; /* Revision 1.1, 1 Gb RAM */ +#else + rmc->board_rev = 0xb03115; /* Revision 1.5, 2 Gb RAM */ +#endif + raspi_machine_class_common_init(mc, rmc->board_rev); + mc->init = raspi4b_machine_init; +} #endif /* TARGET_AARCH64 */ static const TypeInfo raspi_machine_types[] = { @@ -406,7 +513,12 @@ static const TypeInfo raspi_machine_types[] = { .name = MACHINE_TYPE_NAME("raspi3b"), .parent = TYPE_RASPI_MACHINE, .class_init = raspi3b_machine_class_init, -#endif + }, { + .name = MACHINE_TYPE_NAME("raspi4"), + .parent = TYPE_RASPI_BASE_MACHINE, + .instance_size = sizeof(Raspi4bMachineState), + .class_init = raspi4b_machine_class_init, +#endif /* TARGET_AARCH64 */ }, { .name = TYPE_RASPI_MACHINE, .parent = TYPE_RASPI_BASE_MACHINE, diff --git a/hw/arm/raspi4b.c b/hw/arm/raspi4b.c deleted file mode 100644 index 9b08a598f39..00000000000 --- a/hw/arm/raspi4b.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Raspberry Pi 4B emulation - * - * Copyright (C) 2022 Ovchinnikov Vitalii <vitalii.ovchinnikov@xxxxxxxxxx> - * - * SPDX-License-Identifier: GPL-2.0-or-later - */ - -#include "qemu/osdep.h" -#include "qemu/units.h" -#include "qemu/cutils.h" -#include "qapi/error.h" -#include "qapi/visitor.h" -#include "hw/arm/raspi_platform.h" -#include "hw/display/bcm2835_fb.h" -#include "hw/registerfields.h" -#include "qemu/error-report.h" -#include "system/device_tree.h" -#include "hw/boards.h" -#include "hw/loader.h" -#include "hw/arm/boot.h" -#include "qom/object.h" -#include "hw/arm/bcm2838.h" -#include <libfdt.h> - -#define TYPE_RASPI4B_MACHINE MACHINE_TYPE_NAME("raspi4b") -OBJECT_DECLARE_SIMPLE_TYPE(Raspi4bMachineState, RASPI4B_MACHINE) - -struct Raspi4bMachineState { - RaspiBaseMachineState parent_obj; - BCM2838State soc; -}; - -/* - * Add second memory region if board RAM amount exceeds VC base address - * (see https://datasheets.raspberrypi.com/bcm2711/bcm2711-peripherals.pdf - * 1.2 Address Map) - */ -static int raspi_add_memory_node(void *fdt, hwaddr mem_base, hwaddr mem_len) -{ - int ret; - uint32_t acells, scells; - char *nodename = g_strdup_printf("/memory@%" PRIx64, mem_base); - - acells = qemu_fdt_getprop_cell(fdt, "/", "#address-cells", - NULL, &error_fatal); - scells = qemu_fdt_getprop_cell(fdt, "/", "#size-cells", - NULL, &error_fatal); - if (acells == 0 || scells == 0) { - fprintf(stderr, "dtb file invalid (#address-cells or #size-cells 0)\n"); - ret = -1; - } else { - qemu_fdt_add_subnode(fdt, nodename); - qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory"); - ret = qemu_fdt_setprop_sized_cells(fdt, nodename, "reg", - acells, mem_base, - scells, mem_len); - } - - g_free(nodename); - return ret; -} - -static void raspi4_modify_dtb(const struct arm_boot_info *info, void *fdt) -{ - uint64_t ram_size; - - /* Temporarily disable following devices until they are implemented */ - const char *nodes_to_remove[] = { - "brcm,bcm2711-pcie", - "brcm,bcm2711-rng200", - "brcm,bcm2711-thermal", - "brcm,bcm2711-genet-v5", - }; - - for (int i = 0; i < ARRAY_SIZE(nodes_to_remove); i++) { - const char *dev_str = nodes_to_remove[i]; - - int offset = fdt_node_offset_by_compatible(fdt, -1, dev_str); - if (offset >= 0) { - if (!fdt_nop_node(fdt, offset)) { - warn_report("bcm2711 dtc: %s has been disabled!", dev_str); - } - } - } - - ram_size = board_ram_size(info->board_id); - - if (info->ram_size > UPPER_RAM_BASE) { - raspi_add_memory_node(fdt, UPPER_RAM_BASE, ram_size - UPPER_RAM_BASE); - } -} - -static void raspi4b_machine_init(MachineState *machine) -{ - Raspi4bMachineState *s = RASPI4B_MACHINE(machine); - RaspiBaseMachineState *s_base = RASPI_BASE_MACHINE(machine); - RaspiBaseMachineClass *mc = RASPI_BASE_MACHINE_GET_CLASS(machine); - BCM2838State *soc = &s->soc; - - s_base->binfo.modify_dtb = raspi4_modify_dtb; - s_base->binfo.board_id = mc->board_rev; - - object_initialize_child(OBJECT(machine), "soc", soc, - board_soc_type(mc->board_rev)); - - raspi_base_machine_init(machine, BCM283X_BASE(soc)); -} - -static void raspi4b_machine_class_init(ObjectClass *oc, void *data) -{ - MachineClass *mc = MACHINE_CLASS(oc); - RaspiBaseMachineClass *rmc = RASPI_BASE_MACHINE_CLASS(oc); - -#if HOST_LONG_BITS == 32 - rmc->board_rev = 0xa03111; /* Revision 1.1, 1 Gb RAM */ -#else - rmc->board_rev = 0xb03115; /* Revision 1.5, 2 Gb RAM */ -#endif - raspi_machine_class_common_init(mc, rmc->board_rev); - mc->init = raspi4b_machine_init; -} - -static const TypeInfo raspi4b_machine_type = { - .name = TYPE_RASPI4B_MACHINE, - .parent = TYPE_RASPI_BASE_MACHINE, - .instance_size = sizeof(Raspi4bMachineState), - .class_init = raspi4b_machine_class_init, -}; - -static void raspi4b_machine_register_type(void) -{ - type_register_static(&raspi4b_machine_type); -} - -type_init(raspi4b_machine_register_type) diff --git a/hw/arm/meson.build b/hw/arm/meson.build index 490234b3b84..5177260d42b 100644 --- a/hw/arm/meson.build +++ b/hw/arm/meson.build @@ -27,7 +27,7 @@ arm_ss.add(when: 'CONFIG_ALLWINNER_A10', if_true: files('allwinner-a10.c', 'cubi arm_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3.c', 'orangepi.c')) arm_ss.add(when: 'CONFIG_ALLWINNER_R40', if_true: files('allwinner-r40.c', 'bananapi_m2u.c')) arm_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2836.c', 'raspi.c')) -arm_ss.add(when: ['CONFIG_RASPI', 'TARGET_AARCH64'], if_true: files('bcm2838.c', 'raspi4b.c')) +arm_ss.add(when: ['CONFIG_RASPI', 'TARGET_AARCH64'], if_true: files('bcm2838.c')) arm_ss.add(when: 'CONFIG_STM32F100_SOC', if_true: files('stm32f100_soc.c')) arm_ss.add(when: 'CONFIG_STM32F205_SOC', if_true: files('stm32f205_soc.c')) arm_ss.add(when: 'CONFIG_STM32F405_SOC', if_true: files('stm32f405_soc.c')) -- 2.47.1