[PATCH v6 25/37] board: emulation: Add QEMU sbsa support

Simon Glass sjg at chromium.org
Thu Oct 3 00:55:34 CEST 2024


Hi Patrick,

On Wed, 2 Oct 2024 at 03:52, Patrick Rudolph
<patrick.rudolph at 9elements.com> wrote:
>
> Add support for Arm sbsa [1] v0.3+ that is supported by QEMU [2].
>
> Unlike other Arm based platforms the machine only provides a minimal
> FDT that contains number of CPUs, ammount of memory and machine-version.
> The boot firmware has to provide ACPI tables to the OS.
> Due to this design a full DTB is added here as well that allows U-Boot's
> driver to properly function. The DTB is appended at the end of the U-Boot
> image and will be merged with the QEMU provided DTB.
>
> In addition provide documentation how to use, enable binman to fabricate both
> ROMs that are required to boot and add ACPI tables to make it full compatible
> to the EDK2 reference implementation.
>
> The board was tested using Fedora 40 Aarch64 Workstation. It's able
> to boot from USB and AHCI or network.
>
> Tested and found working:
> - serial
> - PCI
> - xHCI
> - Bochs display
> - AHCI
> - network using e1000e
> - CPU init
> - Booting Fedora 40
>
> 1: Server Base System Architecture (SBSA)
> 2: https://www.qemu.org/docs/master/system/arm/sbsa.html
>
> Signed-off-by: Patrick Rudolph <patrick.rudolph at 9elements.com>
> Cc: Peter Robinson <pbrobinson at gmail.com>
> Cc: Simon Glass <sjg at chromium.org>
> Cc: Tom Rini <trini at konsulko.com>
> ---
> Changelog v3:
> - Add GIC and GIC-ITS to devicetree
> - Select GICv3 driver
> - Drop acpi_fill_madt and use driver model instead
> Changelog v4:
> - Drop CPU platform code
> - Enhance the DT to allow MADT generation from DT
> Changelog v5:
> - Add full DT and place it at the end of U-Boot
> - Merge DT with QEMU's DT
> - Drop DT generation code
> - Fix flash region length
> - Drop enable_caches()
> - Support platforms that do not pass FDT in x0
> Changelog v6:
> - Update header order
> - Drop pad-byte from DT
> - select BINMAN_FDT
> - select E1000_NO_NVM
> - drop config.h include
> - drop a few CFG_ defines that were used for SPL
>
> ---
>  arch/arm/Kconfig                            |   3 +-
>  arch/arm/dts/qemu-sbsa.dts                  | 136 ++++++
>  arch/arm/include/asm/arch-qemu-sbsa/boot0.h |  34 ++
>  arch/arm/mach-qemu/Kconfig                  |  36 +-
>  board/emulation/qemu-arm/MAINTAINERS        |   2 +
>  board/emulation/qemu-sbsa/Kconfig           |  57 +++
>  board/emulation/qemu-sbsa/Makefile          |   8 +
>  board/emulation/qemu-sbsa/acpi.c            | 192 ++++++++
>  board/emulation/qemu-sbsa/dsdt.asl          | 483 ++++++++++++++++++++
>  board/emulation/qemu-sbsa/lowlevel_init.S   |  22 +
>  board/emulation/qemu-sbsa/qemu-sbsa.c       | 311 +++++++++++++
>  board/emulation/qemu-sbsa/qemu-sbsa.env     |  14 +
>  board/emulation/qemu-sbsa/qemu-sbsa.h       |  38 ++
>  board/emulation/qemu-sbsa/smc.c             |  71 +++
>  configs/qemu-arm-sbsa_defconfig             |  10 +
>  doc/board/emulation/index.rst               |   1 +
>  doc/board/emulation/qemu-sbsa.rst           |  98 ++++
>  doc/develop/driver-model/virtio.rst         |   1 +
>  include/configs/qemu-sbsa.h                 |  95 ++++
>  19 files changed, 1605 insertions(+), 7 deletions(-)
>  create mode 100644 arch/arm/dts/qemu-sbsa.dts
>  create mode 100644 arch/arm/include/asm/arch-qemu-sbsa/boot0.h
>  create mode 100644 board/emulation/qemu-sbsa/Kconfig
>  create mode 100644 board/emulation/qemu-sbsa/Makefile
>  create mode 100644 board/emulation/qemu-sbsa/acpi.c
>  create mode 100644 board/emulation/qemu-sbsa/dsdt.asl
>  create mode 100644 board/emulation/qemu-sbsa/lowlevel_init.S
>  create mode 100644 board/emulation/qemu-sbsa/qemu-sbsa.c
>  create mode 100644 board/emulation/qemu-sbsa/qemu-sbsa.env
>  create mode 100644 board/emulation/qemu-sbsa/qemu-sbsa.h
>  create mode 100644 board/emulation/qemu-sbsa/smc.c
>  create mode 100644 configs/qemu-arm-sbsa_defconfig
>  create mode 100644 doc/board/emulation/qemu-sbsa.rst
>  create mode 100644 include/configs/qemu-sbsa.h

With the tweaks below:

Reviewed-by: Simon Glass <sjg at chromium.org>

[..]

> diff --git a/arch/arm/dts/qemu-sbsa.dts b/arch/arm/dts/qemu-sbsa.dts
> new file mode 100644
> index 0000000000..f743ea3863
> --- /dev/null
> +++ b/arch/arm/dts/qemu-sbsa.dts
> @@ -0,0 +1,136 @@
> +// SPDX-License-Identifier: GPL-2.0+ OR MIT
> +/*
> + * Devicetree with onboard devices for qemu_sbsa-ref for internal use only!
> + * DO NOT PASS TO THE OS!
> + *
> + * As QEMU provides only a minimal devicetree this one is merged with
> + * it and then fixed at runtime.
> + *
> + * Copyright 2024 9elements GmbH
> + */
> +#include "configs/qemu-sbsa.h"
> +
> +/dts-v1/;
> +
> +#define MAKE_PROP(x) (x>>32) (x&0xffffffff)
> +
> +/ {
> +       #address-cells = <2>;
> +       #size-cells = <2>;
> +       interrupt-parent = <&intc>;
> +       compatible = "linux,sbsa-ref";
> +
> +       binman: binman {
> +               multiple-images;
> +       };
> +
> +       cpus {
> +               /* Filled by fdtdec_board_setup() */
> +       };
> +
> +       memory {
> +               /* Filled by fdtdec_board_setup() */
> +       };
> +
> +       soc {
> +               compatible = "simple-bus";
> +               #address-cells = <2>;
> +               #size-cells = <2>;
> +               ranges;
> +
> +               uart0 {
> +                       compatible = "arm,pl011";
> +                       status = "okay";
> +                       reg = <MAKE_PROP(SBSA_UART_BASE_ADDR)

Can you use

reg = /bits 64/ <0x60000000>

instead?

Same for those below.

> +                              MAKE_PROP(SBSA_UART_LENGTH)>;
> +               };
> +
> +               ahci {
> +                       compatible = "generic-ahci";
> +                       status = "okay";
> +                       reg = <MAKE_PROP(SBSA_AHCI_BASE_ADDR)
> +                              MAKE_PROP(SBSA_AHCI_LENGTH)>;
> +               };
> +
> +               xhci {
> +                       compatible = "generic-xhci";
> +                       status = "okay";
> +                       reg = <MAKE_PROP(SBSA_XHCI_BASE_ADDR)
> +                              MAKE_PROP(SBSA_XHCI_LENGTH)>;
> +               };
> +
> +               pci {
> +                       #address-cells = <3>;
> +                       #size-cells = <2>;
> +                       compatible = "pci-host-ecam-generic";
> +                       device_type = "pci";
> +                       status = "okay";
> +                       reg = <MAKE_PROP(SBSA_PCIE_ECAM_BASE_ADDR)
> +                              MAKE_PROP(SBSA_PCIE_ECAM_LENGTH)>;
> +                       bus-range = <0 0xff>;
> +                       ranges = <0x01000000 0 0
> +                                 MAKE_PROP(SBSA_PIO_BASE_ADDR)
> +                                 MAKE_PROP(SBSA_PIO_LENGTH)>,
> +                                <0x02000000 MAKE_PROP(SBSA_PCIE_MMIO_BASE_ADDR)
> +                                 MAKE_PROP(SBSA_PCIE_MMIO_BASE_ADDR)
> +                                 MAKE_PROP(SBSA_PCIE_MMIO_LENGTH)>,
> +                                <0x43000000 MAKE_PROP(SBSA_PCIE_MMIO_HIGH_BASE_ADDR)
> +                                 MAKE_PROP(SBSA_PCIE_MMIO_HIGH_BASE_ADDR)
> +                                 MAKE_PROP(SBSA_PCIE_MMIO_HIGH_LENGTH)>;
> +               };
> +       };
> +
> +       intc: interrupt-controller {
> +               compatible = "arm,gic-v3";
> +               #interrupt-cells = <1>;
> +               status = "okay";
> +               interrupt-controller;
> +               interrupts = <25>;
> +               reg = <MAKE_PROP(SBSA_GIC_DIST_BASE_ADDR)
> +                       MAKE_PROP(SBSA_GIC_DIST_LENGTH)>,
> +                       <MAKE_PROP(SBSA_GIC_REDIST_BASE_ADDR)
> +                       MAKE_PROP(SBSA_GIC_REDIST_LENGTH)>,
> +                       <0 0 0 0>,
> +                       <MAKE_PROP(SBSA_GIC_HBASE_ADDR)
> +                       MAKE_PROP(SBSA_GIC_HBASE_LENGTH)>,
> +                       <MAKE_PROP(SBSA_GIC_VBASE_ADDR)
> +                       MAKE_PROP(SBSA_GIC_VBASE_LENGTH)>;
> +       };
> +
> +       its {
> +               compatible = "arm,gic-v3-its";
> +               status = "disabled";
> +       };
> +};
> +
> +&binman {
> +       secure-world {
> +               filename = "secure-world.rom";
> +               size = <SBSA_SECURE_FLASH_LENGTH>;
> +
> +               bl1 {
> +                       offset = <0x0>;
> +                       description = "ARM Trusted Firmware BL1";
> +                       filename = "bl1.bin";

We should create a new entry type for this, like atf-bl31 - but that
can come later.

> +                       type = "blob-ext";
> +               };
> +
> +               fip {
> +                       offset = <0x12000>;
> +                       description = "ARM Trusted Firmware FIP";
> +                       filename = "fip.bin";

Normally binman would create the fip, but  for now this is fine.

> +                       type = "blob-ext";
> +               };
> +       };
> +
> +       unsecure-world {
> +               filename = "unsecure-world.rom";
> +               size = <SBSA_FLASH_LENGTH>;
> +
> +               u-boot {
> +               };
> +               u-boot-dtb {
> +                       compress = "lz4";
> +               };
> +       };
> +};

[..]

> diff --git a/doc/develop/driver-model/virtio.rst b/doc/develop/driver-model/virtio.rst
> index 8ac9c94caf..31b94d0467 100644
> --- a/doc/develop/driver-model/virtio.rst
> +++ b/doc/develop/driver-model/virtio.rst
> @@ -34,6 +34,7 @@ The following QEMU targets are supported.
>
>    - qemu_arm_defconfig
>    - qemu_arm64_defconfig
> +  - qemu-arm-sbsa_defconfig
>    - qemu-riscv32_defconfig
>    - qemu-riscv64_defconfig
>    - qemu-x86_defconfig
> diff --git a/include/configs/qemu-sbsa.h b/include/configs/qemu-sbsa.h
> new file mode 100644
> index 0000000000..efc96981d3
> --- /dev/null
> +++ b/include/configs/qemu-sbsa.h
> @@ -0,0 +1,95 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2024 9elements GmbH
> + */
> +
> +#ifndef __CONFIG_H
> +#define __CONFIG_H
> +
> +/* Physical memory map */
> +
> +/* SECURE_FLASH */
> +#define SBSA_SECURE_FLASH_BASE_ADDR    0x00000000
> +#define SBSA_SECURE_FLASH_LENGTH       0x10000000
> +
> +/* FLASH */
> +#define SBSA_FLASH_BASE_ADDR           0x10000000
> +#define SBSA_FLASH_LENGTH              0x10000000
> +
> +/* PERIPH */
> +#define SBSA_PERIPH_BASE_ADDR          0x40000000
> +
> +/* GIC_DIST */
> +#define SBSA_GIC_DIST_BASE_ADDR                0x40060000
> +#define SBSA_GIC_DIST_LENGTH           0x00020000
> +
> +#define SBSA_GIC_VBASE_ADDR            0x2c020000
> +#define SBSA_GIC_VBASE_LENGTH          0x00010000
> +
> +#define SBSA_GIC_HBASE_ADDR            0x2c010000
> +#define SBSA_GIC_HBASE_LENGTH          0x00010000
> +
> +/* GIC_REDIST */
> +#define SBSA_GIC_REDIST_BASE_ADDR      0x40080000
> +#define SBSA_GIC_REDIST_LENGTH         0x04000000
> +
> +/* GIC_ITS */
> +#define SBSA_GIC_ITS_BASE_ADDR         0x44081000
> +
> +/* UART */
> +#define SBSA_UART_BASE_ADDR            0x60000000
> +#define SBSA_UART_LENGTH               0x00001000
> +
> +/* RTC */
> +#define SBSA_RTC_BASE_ADDR             0x60010000
> +
> +/* GPIO */
> +#define SBSA_GPIO_BASE_ADDR            0x60020000
> +
> +/* SMMU */
> +#define SBSA_SMMU_BASE_ADDR            0x60050000
> +
> +/* SATA */
> +#define SBSA_AHCI_BASE_ADDR            0x60100000
> +#define SBSA_AHCI_LENGTH               0x00010000
> +
> +/* xHCI */
> +#define SBSA_XHCI_BASE_ADDR            0x60110000
> +#define SBSA_XHCI_LENGTH               0x00010000
> +
> +/* PIO */
> +#define SBSA_PIO_BASE_ADDR             0x7fff0000
> +#define SBSA_PIO_LENGTH                        0x00010000
> +
> +/* PCIE_MMIO */
> +#define SBSA_PCIE_MMIO_BASE_ADDR       0x80000000
> +#define SBSA_PCIE_MMIO_LENGTH          0x70000000
> +#define SBSA_PCIE_MMIO_END             0xefffffff
> +
> +/* PCIE_ECAM */
> +#define SBSA_PCIE_ECAM_BASE_ADDR       0xf0000000
> +#define SBSA_PCIE_ECAM_LENGTH          0x10000000
> +#define SBSA_PCIE_ECAM_END             0xffffffff
> +
> +/* PCIE_MMIO_HIGH */
> +#ifdef __ACPI__
> +#define SBSA_PCIE_MMIO_HIGH_BASE_ADDR  0x100000000
> +#define SBSA_PCIE_MMIO_HIGH_LENGTH     0xFF00000000
> +#define SBSA_PCIE_MMIO_HIGH_END                0xFFFFFFFFFF
> +#else
> +#define SBSA_PCIE_MMIO_HIGH_BASE_ADDR  0x100000000ULL
> +#define SBSA_PCIE_MMIO_HIGH_LENGTH     0xFF00000000ULL
> +#define SBSA_PCIE_MMIO_HIGH_END                0xFFFFFFFFFFULL
> +#endif
> +
> +/* MEM */
> +#ifdef __ACPI__
> +#define SBSA_MEM_BASE_ADDR             0x10000000000
> +#else
> +#define SBSA_MEM_BASE_ADDR             0x10000000000ULL
> +#endif
> +
> +#define CFG_SYS_INIT_RAM_ADDR          SBSA_MEM_BASE_ADDR
> +#define CFG_SYS_INIT_RAM_SIZE          0x1000000

Can you move these to the file that needs them? We are trying to keep
this file empty.

> +
> +#endif /* __CONFIG_H */
> --
> 2.46.2
>

Regards,
Simon


More information about the U-Boot mailing list