@@ -15,10 +15,14 @@ PREFERRED_VERSION_linux-yocto-rt ?= "5.15%"
KERNEL_IMAGETYPE = "Image"
KERNEL_DEVICETREE = "arm/fvp-baser-aemv8r64.dtb"
+UBOOT_MACHINE ?= "vexpress_aemv8r_defconfig"
+
SERIAL_CONSOLES = "115200;ttyAMA0"
IMAGE_FSTYPES += "wic"
-WKS_FILE ?= "fvp-base.wks"
+WKS_FILE ?= "efi-disk.wks.in"
+EFI_PROVIDER ?= "grub-efi"
+MACHINE_FEATURES:append = " efi"
# As this is a virtual target that will not be used in the real world there is
# no need for real SSH keys. Disable rng-tools (which takes too long to
@@ -23,6 +23,9 @@ SRC_URI:append = " \
BOOT_WRAPPER_AARCH64_CMDLINE = "\
earlycon console=ttyAMA0 loglevel=8 rootfstype=ext4 root=/dev/vda1 rw"
-EXTRA_OECONF += "--enable-psci=hvc"
+EXTRA_OECONF += "--enable-psci=hvc --enable-keep-el"
TUNE_CCARGS = ""
+
+BOOT_WRAPPER_AARCH64_KERNEL = "u-boot.bin"
+do_deploy[depends] += "u-boot:do_deploy"
new file mode 100644
@@ -0,0 +1,109 @@
+From 114c554aae2a4554eb3ce0bcb59b019a9ec3f6e6 Mon Sep 17 00:00:00 2001
+From: Peter Hoyes <Peter.Hoyes@arm.com>
+Date: Tue, 19 Oct 2021 15:47:21 +0100
+Subject: [PATCH 01/11] doc: Add documentation for the Arm VExpress64 board
+ configs
+
+Create a new documentation section for Arm Ltd boards with a sub-page
+for the VExpress64 boards (FVP-A and Juno).
+
+Issue-Id: SCM-3533
+Upstream-Status: Backport [https://source.denx.de/u-boot/u-boot/-/commit/6c2f16b3c95a0bb7f5d6f65512dceb0dc75ac00a]
+Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
+Change-Id: I9e6244e9c4949c0a60acb32216fb71e933af40ed
+---
+ doc/board/armltd/index.rst | 9 ++++++
+ doc/board/armltd/vexpress64.rst | 51 +++++++++++++++++++++++++++++++++
+ doc/board/index.rst | 1 +
+ 3 files changed, 61 insertions(+)
+ create mode 100644 doc/board/armltd/index.rst
+ create mode 100644 doc/board/armltd/vexpress64.rst
+
+diff --git a/doc/board/armltd/index.rst b/doc/board/armltd/index.rst
+new file mode 100644
+index 0000000000..b6786c114f
+--- /dev/null
++++ b/doc/board/armltd/index.rst
+@@ -0,0 +1,9 @@
++.. SPDX-License-Identifier: GPL-2.0+
++
++Arm Ltd
++=============
++
++.. toctree::
++ :maxdepth: 2
++
++ vexpress64.rst
+diff --git a/doc/board/armltd/vexpress64.rst b/doc/board/armltd/vexpress64.rst
+new file mode 100644
+index 0000000000..b98b096544
+--- /dev/null
++++ b/doc/board/armltd/vexpress64.rst
+@@ -0,0 +1,51 @@
++.. SPDX-License-Identifier: GPL-2.0+
++
++Arm Versatile Express
++=====================
++
++The vexpress_* board configuration supports the following platforms:
++
++ * FVP_Base_RevC-2xAEMvA
++ * Juno development board
++
++Fixed Virtual Platforms
++-----------------------
++
++The Fixed Virtual Platforms (FVP) are complete simulations of an Arm system,
++including processor, memory and peripherals. They are set out in a "programmer's
++view", which gives a comprehensive model on which to build and test software.
++
++The supported FVPs are available free of charge and can be downloaded from the
++Arm developer site [1]_ (user registration might be required).
++
++Supported features:
++
++ * GICv3
++ * Generic timer
++ * PL011 UART
++
++The default configuration assumes that U-Boot is bootstrapped using a suitable
++bootloader, such as Trusted Firmware-A [4]_. The u-boot binary can be passed
++into the TF-A build: ``make PLAT=<platform> all fip BL33=u-boot.bin``
++
++The FVPs can be debugged using Arm Development Studio [2]_.
++
++Juno
++----
++
++Juno is an Arm development board with the following features:
++
++ * Arm Cortex-A72/A57 and Arm Cortex-A53 in a "big.LITTLE" configuration
++ * A PCIe Gen2.0 bus with 4 lanes
++ * 8GB of DRAM
++ * GICv2
++
++More details can be found in the board documentation [3]_.
++
++References
++----------
++
++.. [1] https://developer.arm.com/tools-and-software/simulation-models/fixed-virtual-platforms
++.. [2] https://developer.arm.com/tools-and-software/embedded/arm-development-studio
++.. [3] https://developer.arm.com/tools-and-software/development-boards/juno-development-board
++.. [4] https://trustedfirmware-a.readthedocs.io/
+\ No newline at end of file
+diff --git a/doc/board/index.rst b/doc/board/index.rst
+index 13f4db848e..d0a7838550 100644
+--- a/doc/board/index.rst
++++ b/doc/board/index.rst
+@@ -11,6 +11,7 @@ Board-specific doc
+ AndesTech/index
+ amlogic/index
+ apple/index
++ armltd/index
+ atmel/index
+ congatec/index
+ coreboot/index
+--
+2.25.1
+
new file mode 100644
@@ -0,0 +1,172 @@
+From f3a4efb6ca8780442d440ec9aeb8e2474e35aad6 Mon Sep 17 00:00:00 2001
+From: Peter Hoyes <Peter.Hoyes@arm.com>
+Date: Tue, 19 Oct 2021 15:39:52 +0100
+Subject: [PATCH 02/11] vexpress64: Refactor header file to make it easier to
+ add new FVPs
+
+Rename from vexpress_aemv8a.h -> vepxress_aemv8.h as new FVPs may not be
+v8-A. No change in behavior.
+
+This is towards future work to enable support for the FVP_BaseR.
+
+Issue-Id: SCM-3537
+Upstream-Status: Backport [https://source.denx.de/u-boot/u-boot/-/commit/17fe55fd6fe9d32270380f574b33ff0bc15bb47e]
+Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
+Change-Id: Ie992e69d1b51c6f8939b1bea22e35658e96df6c6
+---
+ board/armltd/vexpress64/Kconfig | 2 +-
+ doc/README.semihosting | 2 +-
+ .../{vexpress_aemv8a.h => vexpress_aemv8.h} | 48 ++++++++++---------
+ 3 files changed, 27 insertions(+), 25 deletions(-)
+ rename include/configs/{vexpress_aemv8a.h => vexpress_aemv8.h} (88%)
+
+diff --git a/board/armltd/vexpress64/Kconfig b/board/armltd/vexpress64/Kconfig
+index 1d13f542e6..4aab3f092e 100644
+--- a/board/armltd/vexpress64/Kconfig
++++ b/board/armltd/vexpress64/Kconfig
+@@ -7,7 +7,7 @@ config SYS_VENDOR
+ default "armltd"
+
+ config SYS_CONFIG_NAME
+- default "vexpress_aemv8a"
++ default "vexpress_aemv8"
+
+ config JUNO_DTB_PART
+ string "NOR flash partition holding DTB"
+diff --git a/doc/README.semihosting b/doc/README.semihosting
+index c019999bed..f382d0131e 100644
+--- a/doc/README.semihosting
++++ b/doc/README.semihosting
+@@ -25,7 +25,7 @@ or turning on CONFIG_BASE_FVP for the more full featured model.
+ Rather than create a new armv8 board similar to armltd/vexpress64, add
+ semihosting calls to the existing one, enabled with CONFIG_SEMIHOSTING
+ and CONFIG_BASE_FVP both set. Also reuse the existing board config file
+-vexpress_aemv8a.h but differentiate the two models by the presence or
++vexpress_aemv8.h but differentiate the two models by the presence or
+ absence of CONFIG_BASE_FVP. This change is tested and works on both the
+ Foundation and Base fastmodel simulators.
+
+diff --git a/include/configs/vexpress_aemv8a.h b/include/configs/vexpress_aemv8.h
+similarity index 88%
+rename from include/configs/vexpress_aemv8a.h
+rename to include/configs/vexpress_aemv8.h
+index df22584d9a..49517a60b0 100644
+--- a/include/configs/vexpress_aemv8a.h
++++ b/include/configs/vexpress_aemv8.h
+@@ -4,36 +4,37 @@
+ * configurations.
+ */
+
+-#ifndef __VEXPRESS_AEMV8A_H
+-#define __VEXPRESS_AEMV8A_H
++#ifndef __VEXPRESS_AEMV8_H
++#define __VEXPRESS_AEMV8_H
+
+ #define CONFIG_REMAKE_ELF
+
+ /* Link Definitions */
+-#ifdef CONFIG_TARGET_VEXPRESS64_BASE_FVP
++#ifdef CONFIG_TARGET_VEXPRESS64_JUNO
++#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x7fff0)
++#else
+ /* ATF loads u-boot here for BASE_FVP model */
+ #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x03f00000)
+-#elif CONFIG_TARGET_VEXPRESS64_JUNO
+-#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x7fff0)
+ #endif
+
+ #define CONFIG_SYS_BOOTM_LEN (64 << 20) /* Increase max gunzip size */
+
+ /* CS register bases for the original memory map. */
+-#define V2M_PA_CS0 0x00000000
+-#define V2M_PA_CS1 0x14000000
+-#define V2M_PA_CS2 0x18000000
+-#define V2M_PA_CS3 0x1c000000
+-#define V2M_PA_CS4 0x0c000000
+-#define V2M_PA_CS5 0x10000000
++#define V2M_BASE 0x80000000
++#define V2M_PA_BASE 0x00000000
++
++#define V2M_PA_CS0 (V2M_PA_BASE + 0x00000000)
++#define V2M_PA_CS1 (V2M_PA_BASE + 0x14000000)
++#define V2M_PA_CS2 (V2M_PA_BASE + 0x18000000)
++#define V2M_PA_CS3 (V2M_PA_BASE + 0x1c000000)
++#define V2M_PA_CS4 (V2M_PA_BASE + 0x0c000000)
++#define V2M_PA_CS5 (V2M_PA_BASE + 0x10000000)
+
+ #define V2M_PERIPH_OFFSET(x) (x << 16)
+ #define V2M_SYSREGS (V2M_PA_CS3 + V2M_PERIPH_OFFSET(1))
+ #define V2M_SYSCTL (V2M_PA_CS3 + V2M_PERIPH_OFFSET(2))
+ #define V2M_SERIAL_BUS_PCI (V2M_PA_CS3 + V2M_PERIPH_OFFSET(3))
+
+-#define V2M_BASE 0x80000000
+-
+ /* Common peripherals relative to CS7. */
+ #define V2M_AACI (V2M_PA_CS3 + V2M_PERIPH_OFFSET(4))
+ #define V2M_MMCI (V2M_PA_CS3 + V2M_PERIPH_OFFSET(5))
+@@ -72,23 +73,23 @@
+
+ /* Generic Interrupt Controller Definitions */
+ #ifdef CONFIG_GICV3
+-#define GICD_BASE (0x2f000000)
+-#define GICR_BASE (0x2f100000)
++#define GICD_BASE (V2M_PA_BASE + 0x2f000000)
++#define GICR_BASE (V2M_PA_BASE + 0x2f100000)
+ #else
+
+-#ifdef CONFIG_TARGET_VEXPRESS64_BASE_FVP
+-#define GICD_BASE (0x2f000000)
+-#define GICC_BASE (0x2c000000)
+-#elif CONFIG_TARGET_VEXPRESS64_JUNO
++#ifdef CONFIG_TARGET_VEXPRESS64_JUNO
+ #define GICD_BASE (0x2C010000)
+ #define GICC_BASE (0x2C02f000)
++#else
++#define GICD_BASE (V2M_PA_BASE + 0x2f000000)
++#define GICC_BASE (V2M_PA_BASE + 0x2c000000)
+ #endif
+ #endif /* !CONFIG_GICV3 */
+
+ #ifndef CONFIG_TARGET_VEXPRESS64_JUNO
+ /* The Vexpress64 simulators use SMSC91C111 */
+ #define CONFIG_SMC91111 1
+-#define CONFIG_SMC91111_BASE (0x01A000000)
++#define CONFIG_SMC91111_BASE (V2M_PA_BASE + 0x01A000000)
+ #endif
+
+ /* PL011 Serial Configuration */
+@@ -113,7 +114,7 @@
+ #ifdef CONFIG_TARGET_VEXPRESS64_JUNO
+ #define PHYS_SDRAM_2 (0x880000000)
+ #define PHYS_SDRAM_2_SIZE 0x180000000
+-#elif CONFIG_TARGET_VEXPRESS64_BASE_FVP && CONFIG_NR_DRAM_BANKS == 2
++#elif CONFIG_NR_DRAM_BANKS == 2
+ #define PHYS_SDRAM_2 (0x880000000)
+ #define PHYS_SDRAM_2_SIZE 0x80000000
+ #endif
+@@ -200,6 +201,7 @@
+ " booti $kernel_addr - $fdt_addr; " \
+ "fi"
+ #endif
++
+ #endif
+
+ /* Monitor Command Prompt */
+@@ -213,7 +215,7 @@
+ /* Store environment at top of flash in the same location as blank.img */
+ /* in the Juno firmware. */
+ #else
+-#define CONFIG_SYS_FLASH_BASE 0x0C000000
++#define CONFIG_SYS_FLASH_BASE (V2M_PA_BASE + 0x0C000000)
+ /* 256 x 256KiB sectors */
+ #define CONFIG_SYS_MAX_FLASH_SECT 256
+ /* Store environment at top of flash */
+@@ -230,4 +232,4 @@
+ #define CONFIG_SYS_FLASH_EMPTY_INFO /* flinfo indicates empty blocks */
+ #define FLASH_MAX_SECTOR_SIZE 0x00040000
+
+-#endif /* __VEXPRESS_AEMV8A_H */
++#endif /* __VEXPRESS_AEMV8_H */
+--
+2.25.1
+
new file mode 100644
@@ -0,0 +1,99 @@
+From 7b44a11479a5548d14f790df4515bebd80efcdef Mon Sep 17 00:00:00 2001
+From: Peter Hoyes <Peter.Hoyes@arm.com>
+Date: Tue, 19 Oct 2021 16:34:25 +0100
+Subject: [PATCH 03/11] vexpress64: Clean up BASE_FVP boot configuration
+
+Move env var address values to #defines so they can be reused elsewhere.
+
+Rename env var names to those recommended in the README.
+
+Fix issue where fdt is called with invalid arguments when booting
+without a ramdisk.
+
+Issue-Id: SCM-3537
+Upstream-Status: Backport [https://source.denx.de/u-boot/u-boot/-/commit/90f262a6951f530ec60bf78a681b117f625cbe3f]
+Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
+Change-Id: I2cd9a1245860302857b6ad6d738b8f7fc4d4d038
+---
+ include/configs/vexpress_aemv8.h | 50 ++++++++++++++++++++------------
+ 1 file changed, 31 insertions(+), 19 deletions(-)
+
+diff --git a/include/configs/vexpress_aemv8.h b/include/configs/vexpress_aemv8.h
+index 49517a60b0..897a7128bb 100644
+--- a/include/configs/vexpress_aemv8.h
++++ b/include/configs/vexpress_aemv8.h
+@@ -7,6 +7,8 @@
+ #ifndef __VEXPRESS_AEMV8_H
+ #define __VEXPRESS_AEMV8_H
+
++#include <linux/stringify.h>
++
+ #define CONFIG_REMAKE_ELF
+
+ /* Link Definitions */
+@@ -172,33 +174,43 @@
+ BOOTENV
+
+ #elif CONFIG_TARGET_VEXPRESS64_BASE_FVP
++
++#define VEXPRESS_KERNEL_ADDR 0x80080000
++#define VEXPRESS_FDT_ADDR 0x8fc00000
++#define VEXPRESS_BOOT_ADDR 0x8fd00000
++#define VEXPRESS_RAMDISK_ADDR 0x8fe00000
++
+ #define CONFIG_EXTRA_ENV_SETTINGS \
+ "kernel_name=Image\0" \
+- "kernel_addr=0x80080000\0" \
+- "initrd_name=ramdisk.img\0" \
+- "initrd_addr=0x88000000\0" \
+- "fdtfile=devtree.dtb\0" \
+- "fdt_addr=0x83000000\0" \
+- "boot_name=boot.img\0" \
+- "boot_addr=0x8007f800\0"
++ "kernel_addr_r=" __stringify(VEXPRESS_KERNEL_ADDR) "\0" \
++ "ramdisk_name=ramdisk.img\0" \
++ "ramdisk_addr_r=" __stringify(VEXPRESS_RAMDISK_ADDR) "\0" \
++ "fdtfile=devtree.dtb\0" \
++ "fdt_addr_r=" __stringify(VEXPRESS_FDT_ADDR) "\0" \
++ "boot_name=boot.img\0" \
++ "boot_addr_r=" __stringify(VEXPRESS_BOOT_ADDR) "\0"
+
+ #ifndef CONFIG_BOOTCOMMAND
+-#define CONFIG_BOOTCOMMAND "if smhload ${boot_name} ${boot_addr}; then " \
++#define CONFIG_BOOTCOMMAND "if smhload ${boot_name} ${boot_addr_r}; then " \
+ " set bootargs; " \
+- " abootimg addr ${boot_addr}; " \
+- " abootimg get dtb --index=0 fdt_addr; " \
+- " bootm ${boot_addr} ${boot_addr} " \
+- " ${fdt_addr}; " \
++ " abootimg addr ${boot_addr_r}; " \
++ " abootimg get dtb --index=0 fdt_addr_r; " \
++ " bootm ${boot_addr_r} ${boot_addr_r} " \
++ " ${fdt_addr_r}; " \
+ "else; " \
+ " set fdt_high 0xffffffffffffffff; " \
+ " set initrd_high 0xffffffffffffffff; " \
+- " smhload ${kernel_name} ${kernel_addr}; " \
+- " smhload ${fdtfile} ${fdt_addr}; " \
+- " smhload ${initrd_name} ${initrd_addr} "\
+- " initrd_end; " \
+- " fdt addr ${fdt_addr}; fdt resize; " \
+- " fdt chosen ${initrd_addr} ${initrd_end}; " \
+- " booti $kernel_addr - $fdt_addr; " \
++ " smhload ${kernel_name} ${kernel_addr_r}; " \
++ " smhload ${fdtfile} ${fdt_addr_r}; " \
++ " smhload ${ramdisk_name} ${ramdisk_addr_r} "\
++ " ramdisk_end; " \
++ " fdt addr ${fdt_addr_r}; fdt resize; " \
++ " if test -n ${ramdisk_end}; then "\
++ " fdt chosen ${ramdisk_addr_r} ${ramdisk_end}; " \
++ " else; " \
++ " fdt chosen; " \
++ " fi; " \
++ " booti $kernel_addr_r - $fdt_addr_r; " \
+ "fi"
+ #endif
+
+--
+2.25.1
+
new file mode 100644
@@ -0,0 +1,110 @@
+From e709f0e8ffe76ecab9a50ce39338fe38cc9d920f Mon Sep 17 00:00:00 2001
+From: Peter Hoyes <Peter.Hoyes@arm.com>
+Date: Mon, 4 Oct 2021 14:03:35 +0100
+Subject: [PATCH 04/11] vexpress64: Enable OF_CONTROL and OF_BOARD for
+ VExpress64
+
+Capture x0 in lowlevel_init.S as potential fdt address. Modify
+board_fdt_blob_setup to use fdt address from either vexpress_aemv8.h
+or lowlevel_init.S.
+
+Issue-Id: SCM-3534
+Upstream-Status: Backport [https://source.denx.de/u-boot/u-boot/-/commit/2661397464e47d45cd25bbc5e6b9de7594b3268d]
+Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
+Change-Id: If60e2fbcbda23613f591752ddfabe66fb44623c5
+---
+ board/armltd/vexpress64/Makefile | 5 +++++
+ board/armltd/vexpress64/lowlevel_init.S | 12 +++++++++++
+ board/armltd/vexpress64/vexpress64.c | 27 +++++++++++++++++++++++++
+ 3 files changed, 44 insertions(+)
+ create mode 100644 board/armltd/vexpress64/lowlevel_init.S
+
+diff --git a/board/armltd/vexpress64/Makefile b/board/armltd/vexpress64/Makefile
+index 868dc4f629..5703e75967 100644
+--- a/board/armltd/vexpress64/Makefile
++++ b/board/armltd/vexpress64/Makefile
+@@ -5,3 +5,8 @@
+
+ obj-y := vexpress64.o
+ obj-$(CONFIG_TARGET_VEXPRESS64_JUNO) += pcie.o
++ifdef CONFIG_OF_BOARD
++ifndef CONFIG_TARGET_VEXPRESS64_JUNO
++obj-y += lowlevel_init.o
++endif
++endif
+diff --git a/board/armltd/vexpress64/lowlevel_init.S b/board/armltd/vexpress64/lowlevel_init.S
+new file mode 100644
+index 0000000000..3dcfb85d0e
+--- /dev/null
++++ b/board/armltd/vexpress64/lowlevel_init.S
+@@ -0,0 +1,12 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++/*
++ * (C) Copyright 2021 Arm Limited
++ */
++
++.global save_boot_params
++save_boot_params:
++
++ adr x8, prior_stage_fdt_address
++ str x0, [x8]
++
++ b save_boot_params_ret
+diff --git a/board/armltd/vexpress64/vexpress64.c b/board/armltd/vexpress64/vexpress64.c
+index d2f307cca5..9a4d97afad 100644
+--- a/board/armltd/vexpress64/vexpress64.c
++++ b/board/armltd/vexpress64/vexpress64.c
+@@ -85,7 +85,15 @@ int dram_init_banksize(void)
+ return 0;
+ }
+
++/* Assigned in lowlevel_init.S
++ * Push the variable into the .data section so that it
++ * does not get cleared later.
++ */
++unsigned long __section(".data") prior_stage_fdt_address;
++
+ #ifdef CONFIG_OF_BOARD
++
++#ifdef CONFIG_TARGET_VEXPRESS64_JUNO
+ #define JUNO_FLASH_SEC_SIZE (256 * 1024)
+ static phys_addr_t find_dtb_in_nor_flash(const char *partname)
+ {
+@@ -131,8 +139,11 @@ static phys_addr_t find_dtb_in_nor_flash(const char *partname)
+ return ~0;
+ }
+
++#endif
++
+ void *board_fdt_blob_setup(int *err)
+ {
++#ifdef CONFIG_TARGET_VEXPRESS64_JUNO
+ phys_addr_t fdt_rom_addr = find_dtb_in_nor_flash(CONFIG_JUNO_DTB_PART);
+
+ *err = 0;
+@@ -142,6 +153,22 @@ void *board_fdt_blob_setup(int *err)
+ }
+
+ return (void *)fdt_rom_addr;
++#endif
++
++#ifdef VEXPRESS_FDT_ADDR
++ if (fdt_magic(VEXPRESS_FDT_ADDR) == FDT_MAGIC) {
++ *err = 0;
++ return (void *)VEXPRESS_FDT_ADDR;
++ }
++#endif
++
++ if (fdt_magic(prior_stage_fdt_address) == FDT_MAGIC) {
++ *err = 0;
++ return (void *)prior_stage_fdt_address;
++ }
++
++ *err = -ENXIO;
++ return NULL;
+ }
+ #endif
+
+--
+2.25.1
+
new file mode 100644
@@ -0,0 +1,62 @@
+From 1cf5f028ff96ee4f39921104492d87e58995d180 Mon Sep 17 00:00:00 2001
+From: Peter Hoyes <Peter.Hoyes@arm.com>
+Date: Mon, 11 Oct 2021 11:57:26 +0100
+Subject: [PATCH 05/11] vexpress64: Enable VIRTIO_NET network driver
+
+The SMSC driver is using the old driver model.
+
+Init the virtio system in vexpress64.c so that the network device is
+discovered.
+
+Issue-Id: SCM-3534
+Upstream-Status: Backport [https://source.denx.de/u-boot/u-boot/-/commit/439581dca4c786dbbdd2d6be024e0b907a3b0c80]
+Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
+Change-Id: I1b7d9eb142bf02dd88e99bcd7e44789a154885dd
+---
+ board/armltd/vexpress64/vexpress64.c | 7 +++++++
+ include/configs/vexpress_aemv8.h | 4 ++--
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/board/armltd/vexpress64/vexpress64.c b/board/armltd/vexpress64/vexpress64.c
+index 9a4d97afad..59a72588e0 100644
+--- a/board/armltd/vexpress64/vexpress64.c
++++ b/board/armltd/vexpress64/vexpress64.c
+@@ -18,6 +18,10 @@
+ #include <dm/platform_data/serial_pl01x.h>
+ #include "pcie.h"
+ #include <asm/armv8/mmu.h>
++#ifdef CONFIG_VIRTIO_NET
++#include <virtio_types.h>
++#include <virtio.h>
++#endif
+
+ DECLARE_GLOBAL_DATA_PTR;
+
+@@ -64,6 +68,9 @@ __weak void vexpress64_pcie_init(void)
+ int board_init(void)
+ {
+ vexpress64_pcie_init();
++#ifdef CONFIG_VIRTIO_NET
++ virtio_init();
++#endif
+ return 0;
+ }
+
+diff --git a/include/configs/vexpress_aemv8.h b/include/configs/vexpress_aemv8.h
+index 897a7128bb..ef271ea89b 100644
+--- a/include/configs/vexpress_aemv8.h
++++ b/include/configs/vexpress_aemv8.h
+@@ -88,8 +88,8 @@
+ #endif
+ #endif /* !CONFIG_GICV3 */
+
+-#ifndef CONFIG_TARGET_VEXPRESS64_JUNO
+-/* The Vexpress64 simulators use SMSC91C111 */
++#if defined(CONFIG_TARGET_VEXPRESS64_BASE_FVP) && !defined(CONFIG_DM_ETH)
++/* The Vexpress64 BASE_FVP simulator uses SMSC91C111 */
+ #define CONFIG_SMC91111 1
+ #define CONFIG_SMC91111_BASE (V2M_PA_BASE + 0x01A000000)
+ #endif
+--
+2.25.1
+
new file mode 100644
@@ -0,0 +1,259 @@
+From 313710181095d032921d9e4111bc4a575bf88147 Mon Sep 17 00:00:00 2001
+From: Peter Hoyes <Peter.Hoyes@arm.com>
+Date: Wed, 26 May 2021 17:41:10 +0100
+Subject: [PATCH 06/11] armv8: Add ARMv8 MPU configuration logic
+
+Detect whether an MMU is present at the current exception level. If
+not, initialize the MPU instead of the MMU during init, and clear the
+MPU regions before transition to Linux.
+
+The MSA in use at EL1&0 may be configurable but can only by determined
+by inspecting VTCR_EL2 at EL2, so assume that there is an MMU for
+backwards compatibility.
+
+Provide a default (blank) MPU memory map, which can be overridden by
+board configurations.
+
+Issue-Id: SCM-2443
+Upstream-Status: Inappropriate [other]
+ Temporary patch
+Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
+Change-Id: I0ee3879f9d7f03fe940664b3551c68eeaa458d17
+---
+ arch/arm/cpu/armv8/cache_v8.c | 101 ++++++++++++++++++++++++++++++-
+ arch/arm/include/asm/armv8/mpu.h | 59 ++++++++++++++++++
+ arch/arm/include/asm/system.h | 19 ++++++
+ 3 files changed, 176 insertions(+), 3 deletions(-)
+ create mode 100644 arch/arm/include/asm/armv8/mpu.h
+
+diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
+index 3de18c7675..f6e0ad0075 100644
+--- a/arch/arm/cpu/armv8/cache_v8.c
++++ b/arch/arm/cpu/armv8/cache_v8.c
+@@ -15,6 +15,7 @@
+ #include <asm/global_data.h>
+ #include <asm/system.h>
+ #include <asm/armv8/mmu.h>
++#include <asm/armv8/mpu.h>
+
+ DECLARE_GLOBAL_DATA_PTR;
+
+@@ -365,6 +366,91 @@ __weak u64 get_page_table_size(void)
+ return size;
+ }
+
++static void mpu_clear_regions(void)
++{
++ int i;
++
++ for (i = 0; mpu_mem_map[i].end || mpu_mem_map[i].attrs; i++) {
++ setup_el2_mpu_region(i, 0, 0);
++ }
++}
++
++static struct mpu_region default_mpu_mem_map[] = {{0,}};
++__weak struct mpu_region *mpu_mem_map = default_mpu_mem_map;
++
++static void mpu_setup(void)
++{
++ int i;
++
++ if (current_el() != 2) {
++ panic("MPU configuration is only supported at EL2");
++ }
++
++ set_sctlr(get_sctlr() & ~(CR_M | CR_WXN));
++
++ asm volatile("msr MAIR_EL2, %0" : : "r" MEMORY_ATTRIBUTES);
++
++ for (i = 0; mpu_mem_map[i].end || mpu_mem_map[i].attrs; i++) {
++ setup_el2_mpu_region(i,
++ PRBAR_ADDRESS(mpu_mem_map[i].start)
++ | PRBAR_OUTER_SH | PRBAR_AP_RW_ANY,
++ PRLAR_ADDRESS(mpu_mem_map[i].end)
++ | mpu_mem_map[i].attrs | PRLAR_EN_BIT
++ );
++ }
++
++ set_sctlr(get_sctlr() | CR_M);
++}
++
++static bool el_has_mmu(void)
++{
++ if (current_el() < 2) {
++ // We have no way of knowing, so assuming we have an MMU
++ return true;
++ }
++
++ uint64_t id_aa64mmfr0;
++ asm volatile("mrs %0, id_aa64mmfr0_el1"
++ : "=r" (id_aa64mmfr0) : : "cc");
++ uint64_t msa = id_aa64mmfr0 & ID_AA64MMFR0_EL1_MSA_MASK;
++ uint64_t msa_frac = id_aa64mmfr0 & ID_AA64MMFR0_EL1_MSA_FRAC_MASK;
++
++ switch (msa) {
++ case ID_AA64MMFR0_EL1_MSA_VMSA:
++ /*
++ * VMSA supported in all translation regimes.
++ * No support for PMSA.
++ */
++ return true;
++ case ID_AA64MMFR0_EL1_MSA_USE_FRAC:
++ /* See MSA_frac for the supported MSAs. */
++ switch (msa_frac) {
++ case ID_AA64MMFR0_EL1_MSA_FRAC_NO_PMSA:
++ /*
++ * PMSA not supported in any translation
++ * regime.
++ */
++ return true;
++ case ID_AA64MMFR0_EL1_MSA_FRAC_VMSA:
++ /*
++ * PMSA supported in all translation
++ * regimes. No support for VMSA.
++ */
++ case ID_AA64MMFR0_EL1_MSA_FRAC_PMSA:
++ /*
++ * PMSA supported in all translation
++ * regimes.
++ */
++ return false;
++ default:
++ panic("Unsupported id_aa64mmfr0_el1 " \
++ "MSA_frac value");
++ }
++ default:
++ panic("Unsupported id_aa64mmfr0_el1 MSA value");
++ }
++}
++
+ void setup_pgtables(void)
+ {
+ int i;
+@@ -479,8 +565,13 @@ void dcache_enable(void)
+ /* The data cache is not active unless the mmu is enabled */
+ if (!(get_sctlr() & CR_M)) {
+ invalidate_dcache_all();
+- __asm_invalidate_tlb_all();
+- mmu_setup();
++
++ if (el_has_mmu()) {
++ __asm_invalidate_tlb_all();
++ mmu_setup();
++ } else {
++ mpu_setup();
++ }
+ }
+
+ set_sctlr(get_sctlr() | CR_C);
+@@ -499,7 +590,11 @@ void dcache_disable(void)
+ set_sctlr(sctlr & ~(CR_C|CR_M));
+
+ flush_dcache_all();
+- __asm_invalidate_tlb_all();
++
++ if (el_has_mmu())
++ __asm_invalidate_tlb_all();
++ else
++ mpu_clear_regions();
+ }
+
+ int dcache_status(void)
+diff --git a/arch/arm/include/asm/armv8/mpu.h b/arch/arm/include/asm/armv8/mpu.h
+new file mode 100644
+index 0000000000..8de627cafd
+--- /dev/null
++++ b/arch/arm/include/asm/armv8/mpu.h
+@@ -0,0 +1,59 @@
++/*
++ * SPDX-License-Identifier: GPL-2.0+
++ *
++ * (C) Copyright 2021 Arm Limited
++ */
++
++#ifndef _ASM_ARMV8_MPU_H_
++#define _ASM_ARMV8_MPU_H_
++
++#include <asm/armv8/mmu.h>
++#include <linux/stringify.h>
++
++#define PRSELR_EL2 S3_4_c6_c2_1
++#define PRBAR_EL2 S3_4_c6_c8_0
++#define PRLAR_EL2 S3_4_c6_c8_1
++#define MPUIR_EL2 S3_4_c0_c0_4
++
++#define PRBAR_ADDRESS(addr) ((addr) & ~(0x3fULL))
++
++/* Access permissions */
++#define PRBAR_AP(val) (((val) & 0x3) << 2)
++#define PRBAR_AP_RW_HYP PRBAR_AP(0x0)
++#define PRBAR_AP_RW_ANY PRBAR_AP(0x1)
++#define PRBAR_AP_RO_HYP PRBAR_AP(0x2)
++#define PRBAR_AP_RO_ANY PRBAR_AP(0x3)
++
++/* Shareability */
++#define PRBAR_SH(val) (((val) & 0x3) << 4)
++#define PRBAR_NON_SH PRBAR_SH(0x0)
++#define PRBAR_OUTER_SH PRBAR_SH(0x2)
++#define PRBAR_INNER_SH PRBAR_SH(0x3)
++
++/* Memory attribute (MAIR idx) */
++#define PRLAR_ATTRIDX(val) (((val) & 0x7) << 1)
++#define PRLAR_EN_BIT (0x1)
++#define PRLAR_ADDRESS(addr) ((addr) & ~(0x3fULL))
++
++#ifndef __ASSEMBLY__
++
++static inline void setup_el2_mpu_region(uint8_t region, uint64_t base, uint64_t limit)
++{
++ asm volatile("msr " __stringify(PRSELR_EL2) ", %0" : : "r" (region));
++ asm volatile("msr " __stringify(PRBAR_EL2) ", %0" : : "r" (base));
++ asm volatile("msr " __stringify(PRLAR_EL2) ", %0" : : "r" (limit));
++
++ asm volatile("isb");
++}
++
++#endif
++
++struct mpu_region {
++ u64 start;
++ u64 end;
++ u64 attrs;
++};
++
++extern struct mpu_region *mpu_mem_map;
++
++#endif /* _ASM_ARMV8_MPU_H_ */
+diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
+index f75eea16b3..e4f5b4e4bc 100644
+--- a/arch/arm/include/asm/system.h
++++ b/arch/arm/include/asm/system.h
+@@ -94,6 +94,25 @@
+ auth algorithm */
+ #define ID_AA64ISAR1_EL1_APA (0xF << 4) /* QARMA address auth algorithm */
+
++/*
++ * ID_AA64MMFR0_EL1 bits definitions
++ */
++#define ID_AA64MMFR0_EL1_MSA_FRAC_MASK (0xFUL << 52) /* Memory system
++ architecture
++ frac */
++#define ID_AA64MMFR0_EL1_MSA_FRAC_VMSA (0x2UL << 52) /* EL1&0 supports
++ VMSA */
++#define ID_AA64MMFR0_EL1_MSA_FRAC_PMSA (0x1UL << 52) /* EL1&0 only
++ supports PMSA*/
++#define ID_AA64MMFR0_EL1_MSA_FRAC_NO_PMSA (0x0UL << 52) /* No PMSA
++ support */
++#define ID_AA64MMFR0_EL1_MSA_MASK (0xFUL << 48) /* Memory system
++ architecture */
++#define ID_AA64MMFR0_EL1_MSA_USE_FRAC (0xFUL << 48) /* Use MSA_FRAC */
++#define ID_AA64MMFR0_EL1_MSA_VMSA (0x0UL << 48) /* Memory system
++ architecture
++ is VMSA */
++
+ /*
+ * ID_AA64PFR0_EL1 bits definitions
+ */
+--
+2.25.1
+
new file mode 100644
@@ -0,0 +1,111 @@
+From c4e6818cca29af0ca7faa87a4f5f1e9f06c5e482 Mon Sep 17 00:00:00 2001
+From: Peter Hoyes <Peter.Hoyes@arm.com>
+Date: Fri, 10 Dec 2021 11:41:19 +0000
+Subject: [PATCH 07/11] armv8: Allow disabling exception vectors on non-SPL
+ builds
+
+On the BASER_FVP, U-Boot shares EL2 with another bootloader, so we do
+not wish to overide the exception vector, but we are also not using an
+SPL build.
+
+Therefore, add ARMV8_EXCEPTION_VECTORS, which disables exception vectors
+in a similar way to ARMV8_SPL_EXCEPTION_VECTORS.
+
+Rename ARMV8_SPL_EXCEPTION_VECTORS -> SPL_ARMV8_EXCEPTION_VECTORS so
+that both config flags be be targeted using CONFIG_IS_ENABLED.
+
+Issue-Id: SCM-3728
+Upstream-Status: Inappropriate [other]
+ Temporary patch
+Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
+Change-Id: I0cf0fc6d7ef4d45791411cf1f67c65e198cc8b2b
+---
+ arch/arm/cpu/armv8/Kconfig | 10 ++++++++--
+ arch/arm/cpu/armv8/Makefile | 6 ++----
+ arch/arm/cpu/armv8/start.S | 4 ++--
+ arch/arm/mach-imx/imx8ulp/Kconfig | 2 +-
+ 4 files changed, 13 insertions(+), 9 deletions(-)
+
+diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig
+index 0a3fdfa471..7c4a56f707 100644
+--- a/arch/arm/cpu/armv8/Kconfig
++++ b/arch/arm/cpu/armv8/Kconfig
+@@ -1,8 +1,8 @@
+ if ARM64
+
+-config ARMV8_SPL_EXCEPTION_VECTORS
++config ARMV8_EXCEPTION_VECTORS
+ bool "Install crash dump exception vectors"
+- depends on SPL
++ default y
+ help
+ The default exception vector table is only used for the crash
+ dump, but still takes quite a lot of space in the image size.
+@@ -10,6 +10,12 @@ config ARMV8_SPL_EXCEPTION_VECTORS
+ Say N here if you are running out of code space in the image
+ and want to save some space at the cost of less debugging info.
+
++config SPL_ARMV8_EXCEPTION_VECTORS
++ bool "Install crash dump exception vectors in the SPL"
++ depends on SPL
++ help
++ Same as ARMV8_EXCEPTION_VECTORS, but for SPL builds
++
+ config ARMV8_MULTIENTRY
+ bool "Enable multiple CPUs to enter into U-Boot"
+
+diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile
+index d85ddde430..be2a4b126c 100644
+--- a/arch/arm/cpu/armv8/Makefile
++++ b/arch/arm/cpu/armv8/Makefile
+@@ -13,10 +13,8 @@ ifndef CONFIG_$(SPL_)SYS_DCACHE_OFF
+ obj-y += cache_v8.o
+ obj-y += cache.o
+ endif
+-ifdef CONFIG_SPL_BUILD
+-obj-$(CONFIG_ARMV8_SPL_EXCEPTION_VECTORS) += exceptions.o
+-else
+-obj-y += exceptions.o
++obj-$(CONFIG_$(SPL_)ARMV8_EXCEPTION_VECTORS) += exceptions.o
++ifndef CONFIG_SPL_BUILD
+ obj-y += exception_level.o
+ endif
+ obj-y += tlb.o
+diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S
+index b3eef705a5..af70d0f6e7 100644
+--- a/arch/arm/cpu/armv8/start.S
++++ b/arch/arm/cpu/armv8/start.S
+@@ -108,7 +108,7 @@ pie_fixup_done:
+ bl reset_sctrl
+ #endif
+
+-#if defined(CONFIG_ARMV8_SPL_EXCEPTION_VECTORS) || !defined(CONFIG_SPL_BUILD)
++#if CONFIG_IS_ENABLED(ARMV8_EXCEPTION_VECTORS)
+ .macro set_vbar, regname, reg
+ msr \regname, \reg
+ .endm
+@@ -387,7 +387,7 @@ ENDPROC(smp_kick_all_cpus)
+ /*-----------------------------------------------------------------------*/
+
+ ENTRY(c_runtime_cpu_setup)
+-#if defined(CONFIG_ARMV8_SPL_EXCEPTION_VECTORS) || !defined(CONFIG_SPL_BUILD)
++#if CONFIG_IS_ENABLED(ARMV8_EXCEPTION_VECTORS)
+ /* Relocate vBAR */
+ adr x0, vectors
+ switch_el x1, 3f, 2f, 1f
+diff --git a/arch/arm/mach-imx/imx8ulp/Kconfig b/arch/arm/mach-imx/imx8ulp/Kconfig
+index 963fc93d34..6255711f12 100644
+--- a/arch/arm/mach-imx/imx8ulp/Kconfig
++++ b/arch/arm/mach-imx/imx8ulp/Kconfig
+@@ -2,7 +2,7 @@ if ARCH_IMX8ULP
+
+ config IMX8ULP
+ bool
+- select ARMV8_SPL_EXCEPTION_VECTORS
++ select SPL_ARMV8_EXCEPTION_VECTORS
+
+ config SYS_SOC
+ default "imx8ulp"
+--
+2.25.1
+
new file mode 100644
@@ -0,0 +1,163 @@
+From 754c5109286e31741952309cb4e8438192511a3b Mon Sep 17 00:00:00 2001
+From: Peter Hoyes <Peter.Hoyes@arm.com>
+Date: Wed, 14 Jul 2021 12:44:27 +0100
+Subject: [PATCH 08/11] armv8: ARMV8_SWITCH_TO_EL1 improvements
+
+Convert CONFIG_ARMV8_SWITCH_TO_EL1 to a Kconfig variable.
+
+Add support for switching to EL1 to bootefi.
+
+Add the environment variable armv8_switch_to_el1 to allow configuring
+whether to switch to EL1 at runtime. This overrides the compile-time
+option.
+
+Issue-Id: SCM-3728
+Upstream-Status: Inappropriate [other]
+ Temporary patch
+Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
+Change-Id: If98478148d6d8d1f732acac5439276700614815f
+---
+ arch/arm/cpu/armv8/Kconfig | 8 +++++++
+ arch/arm/cpu/armv8/exception_level.c | 21 ++++++++++++++--
+ arch/arm/lib/bootm.c | 36 ++++++++++++++++------------
+ scripts/config_whitelist.txt | 1 -
+ 4 files changed, 48 insertions(+), 18 deletions(-)
+
+diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig
+index bd595095ab..d7de36acfe 100644
+--- a/arch/arm/cpu/armv8/Kconfig
++++ b/arch/arm/cpu/armv8/Kconfig
+@@ -177,4 +177,12 @@ config ARMV8_SECURE_BASE
+
+ endif
+
++config ARMV8_SWITCH_TO_EL1
++ bool "Switch to EL1 before booting the operating system"
++ default n
++ help
++ Switch to EL1 before booting the operating system, if for example the
++ operating system does not support booting at EL2, or you wish to prevent
++ any hypervisors from running. Supported for bootm, booti and bootefi.
++
+ endif
+diff --git a/arch/arm/cpu/armv8/exception_level.c b/arch/arm/cpu/armv8/exception_level.c
+index b11936548f..4aad1550f4 100644
+--- a/arch/arm/cpu/armv8/exception_level.c
++++ b/arch/arm/cpu/armv8/exception_level.c
+@@ -40,19 +40,36 @@ static void entry_non_secure(struct jmp_buf_data *non_secure_jmp)
+ * trusted firmware being one embodiment). The operating system shall be
+ * started at exception level EL2. So here we check the exception level
+ * and switch it if necessary.
++ *
++ * If armv8_switch_to_el1 (config or env var) is enabled, also switch to EL1
++ * before booting the operating system.
+ */
+ void switch_to_non_secure_mode(void)
+ {
+ struct jmp_buf_data non_secure_jmp;
+
+ /* On AArch64 we need to make sure we call our payload in < EL3 */
+- if (current_el() == 3) {
++
++ int switch_to_el1 = env_get_yesno("armv8_switch_to_el1");
++#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
++ if (switch_to_el1 == -1) {
++ switch_to_el1 = 1;
++ }
++#endif
++
++ if (current_el() > 2) {
+ if (setjmp(&non_secure_jmp))
+ return;
+ dcache_disable(); /* flush cache before switch to EL2 */
+-
+ /* Move into EL2 and keep running there */
+ armv8_switch_to_el2((uintptr_t)&non_secure_jmp, 0, 0, 0,
+ (uintptr_t)entry_non_secure, ES_TO_AARCH64);
++ } else if (switch_to_el1 == 1 && current_el() > 1) {
++ if (setjmp(&non_secure_jmp))
++ return;
++ dcache_disable(); /* flush cache before switch to EL1 */
++ /* Move into EL1 and keep running there */
++ armv8_switch_to_el1((uintptr_t)&non_secure_jmp, 0, 0, 0,
++ (uintptr_t)entry_non_secure, ES_TO_AARCH64);
+ }
+ }
+diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
+index a59a5e6c0e..e2cf2e6ec4 100644
+--- a/arch/arm/lib/bootm.c
++++ b/arch/arm/lib/bootm.c
+@@ -272,7 +272,6 @@ __weak void update_os_arch_secondary_cores(uint8_t os_arch)
+ {
+ }
+
+-#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
+ static void switch_to_el1(void)
+ {
+ if ((IH_ARCH_DEFAULT == IH_ARCH_ARM64) &&
+@@ -287,7 +286,6 @@ static void switch_to_el1(void)
+ ES_TO_AARCH64);
+ }
+ #endif
+-#endif
+
+ /* Subcommand: GO */
+ static void boot_jump_linux(bootm_headers_t *images, int flag)
+@@ -314,21 +312,29 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
+
+ update_os_arch_secondary_cores(images->os.arch);
+
++ int armv8_switch_to_el1 = env_get_yesno("armv8_switch_to_el1");
+ #ifdef CONFIG_ARMV8_SWITCH_TO_EL1
+- armv8_switch_to_el2((u64)images->ft_addr, 0, 0, 0,
+- (u64)switch_to_el1, ES_TO_AARCH64);
+-#else
+- if ((IH_ARCH_DEFAULT == IH_ARCH_ARM64) &&
+- (images->os.arch == IH_ARCH_ARM))
+- armv8_switch_to_el2(0, (u64)gd->bd->bi_arch_number,
+- (u64)images->ft_addr, 0,
+- (u64)images->ep,
+- ES_TO_AARCH32);
+- else
+- armv8_switch_to_el2((u64)images->ft_addr, 0, 0, 0,
+- images->ep,
+- ES_TO_AARCH64);
++ if (armv8_switch_to_el1 == -1) {
++ armv8_switch_to_el1 = 1;
++ }
+ #endif
++ if (armv8_switch_to_el1 == 1) {
++ armv8_switch_to_el2((u64)images->ft_addr, 0, 0, 0,
++ (u64)switch_to_el1, ES_TO_AARCH64);
++ } else {
++ if ((IH_ARCH_DEFAULT == IH_ARCH_ARM64) &&
++ (images->os.arch == IH_ARCH_ARM))
++ armv8_switch_to_el2(0,
++ (u64)gd->bd->bi_arch_number,
++ (u64)images->ft_addr, 0,
++ (u64)images->ep,
++ ES_TO_AARCH32);
++ else
++ armv8_switch_to_el2((u64)images->ft_addr,
++ 0, 0, 0,
++ images->ep,
++ ES_TO_AARCH64);
++ }
+ }
+ #else
+ unsigned long machid = gd->bd->bi_arch_number;
+diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
+index b9c1c61e13..e6b5627447 100644
+--- a/scripts/config_whitelist.txt
++++ b/scripts/config_whitelist.txt
+@@ -21,7 +21,6 @@ CONFIG_ARC_MMU_VER
+ CONFIG_ARMV7_SECURE_BASE
+ CONFIG_ARMV7_SECURE_MAX_SIZE
+ CONFIG_ARMV7_SECURE_RESERVE_SIZE
+-CONFIG_ARMV8_SWITCH_TO_EL1
+ CONFIG_ARM_GIC_BASE_ADDRESS
+ CONFIG_ARP_TIMEOUT
+ CONFIG_AT91C_PQFP_UHPBUG
+--
+2.25.1
+
new file mode 100644
@@ -0,0 +1,73 @@
+From 6d8d8b3018bacc5b578ff567b2e20e6ec4abcd6c Mon Sep 17 00:00:00 2001
+From: Peter Hoyes <Peter.Hoyes@arm.com>
+Date: Fri, 10 Dec 2021 16:37:26 +0000
+Subject: [PATCH 09/11] armv8: Make disabling HVC configurable when switching
+ to EL1
+
+On the BASER_FVP there is no EL3, so HVC is used to provide PSCI
+services. Therefore we cannot disable hypercalls.
+
+Create CONFIG_ARMV8_DISABLE_HVC (dependent on CONFIG_ARMV8_TO_EL1) to
+control whether to disable HVC exceptions in HCR_EL2->HCD
+
+Issue-Id: SCM-3728
+Upstream-Status: Inappropriate [other]
+ Temporary patch
+Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
+Change-Id: I463d82f1db8a3cafcab40a9c0c208753569cc300
+---
+ arch/arm/cpu/armv8/Kconfig | 9 +++++++++
+ arch/arm/include/asm/macro.h | 10 ++++++++--
+ 2 files changed, 17 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig
+index d7de36acfe..704ed2b3d3 100644
+--- a/arch/arm/cpu/armv8/Kconfig
++++ b/arch/arm/cpu/armv8/Kconfig
+@@ -185,4 +185,13 @@ config ARMV8_SWITCH_TO_EL1
+ operating system does not support booting at EL2, or you wish to prevent
+ any hypervisors from running. Supported for bootm, booti and bootefi.
+
++config ARMV8_DISABLE_HVC
++ bool "Disable HVC calls before switching to EL1"
++ depends on ARMV8_SWITCH_TO_EL1
++ default y
++ help
++ If switching to EL1 before loading the operating system, disable taking
++ hypercalls back to EL2. May be disabled if, for example, PSCI services are
++ running at EL2.
++
+ endif
+diff --git a/arch/arm/include/asm/macro.h b/arch/arm/include/asm/macro.h
+index ec0171e0e6..6d267cbae2 100644
+--- a/arch/arm/include/asm/macro.h
++++ b/arch/arm/include/asm/macro.h
+@@ -311,9 +311,12 @@ lr .req x30
+ ldr \tmp2, =(ID_AA64ISAR1_EL1_GPI | ID_AA64ISAR1_EL1_GPA | \
+ ID_AA64ISAR1_EL1_API | ID_AA64ISAR1_EL1_APA)
+ tst \tmp, \tmp2
+- mov \tmp2, #(HCR_EL2_RW_AARCH64 | HCR_EL2_HCD_DIS)
++ mov \tmp2, #(HCR_EL2_RW_AARCH64)
+ orr \tmp, \tmp2, #(HCR_EL2_APK | HCR_EL2_API)
+ csel \tmp, \tmp2, \tmp, eq
++#ifdef CONFIG_ARMV8_DISABLE_HVC
++ orr \tmp, \tmp, #(HCR_EL2_HCD_DIS)
++#endif
+ msr hcr_el2, \tmp
+
+ /* Return to the EL1_SP1 mode from EL2 */
+@@ -326,7 +329,10 @@ lr .req x30
+
+ 1:
+ /* Initialize HCR_EL2 */
+- ldr \tmp, =(HCR_EL2_RW_AARCH32 | HCR_EL2_HCD_DIS)
++ ldr \tmp, =(HCR_EL2_RW_AARCH32)
++#ifdef CONFIG_ARMV8_DISABLE_HVC
++ orr \tmp, \tmp, #(HCR_EL2_HCD_DIS)
++#endif
+ msr hcr_el2, \tmp
+
+ /* Return to AArch32 Supervisor mode from EL2 */
+--
+2.25.1
+
new file mode 100644
@@ -0,0 +1,37 @@
+From 511f1b1a8534da8f4947561a70d0fbe9cea5b84c Mon Sep 17 00:00:00 2001
+From: Peter Hoyes <Peter.Hoyes@arm.com>
+Date: Fri, 10 Dec 2021 15:09:09 +0000
+Subject: [PATCH 10/11] vexpress64: Do not set COUNTER_FREQUENCY
+
+VExpress boards normally run as a second-stage bootloader so should not
+need to modify CNTFRQ_EL0. On the BASER_FVP, U-Boot can modify it if
+running at EL2, but shouldn't because it might be different from the
+value being used by the first-stage bootloader (which might be
+providing PSCI services).
+
+Issue-Id: SCM-3728
+Upstream-Status: Inappropriate [other]
+ Temporary patch
+Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
+Change-Id: I137473d721e58e4c348b9641f5b9778178d3bb65
+---
+ include/configs/vexpress_aemv8.h | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/include/configs/vexpress_aemv8.h b/include/configs/vexpress_aemv8.h
+index ef271ea89b..76935f3173 100644
+--- a/include/configs/vexpress_aemv8.h
++++ b/include/configs/vexpress_aemv8.h
+@@ -70,9 +70,6 @@
+ #define V2M_SYS_CFGCTRL (V2M_SYSREGS + 0x0a4)
+ #define V2M_SYS_CFGSTAT (V2M_SYSREGS + 0x0a8)
+
+-/* Generic Timer Definitions */
+-#define COUNTER_FREQUENCY 24000000 /* 24MHz */
+-
+ /* Generic Interrupt Controller Definitions */
+ #ifdef CONFIG_GICV3
+ #define GICD_BASE (V2M_PA_BASE + 0x2f000000)
+--
+2.25.1
+
new file mode 100644
@@ -0,0 +1,275 @@
+From fa244330cf56b4f512d110015a666641f94605b9 Mon Sep 17 00:00:00 2001
+From: Peter Hoyes <Peter.Hoyes@arm.com>
+Date: Mon, 24 May 2021 11:47:53 +0100
+Subject: [PATCH 11/11] vexpress64: Add BASER_FVP vexpress board variant
+
+The BASER_FVP board variant is implemented on top of the BASE_FVP board
+config (which, in turn, is based on the Juno Versatile Express board
+config). They all share a similar memory map - for BASER_FVP the map is
+inverted from the BASE_FVP
+(https://developer.arm.com/documentation/100964/1114/Base-Platform/Base---memory/BaseR-Platform-memory-map)
+
+ * Create new TARGET_VEXPRESS64_BASER_FVP target, which uses the same
+ board config as BASE_FVP and JUNO
+ * Implement inverted memory map in vexpress_aemv8.h
+ * Create vexpress_aemv8r defconfig
+ * Provide MPU and MMU memory maps for the BASER_FVP
+ * Provide default value for LNX_KRNL_IMG_TEXT_OFFSET_BASE
+ * Update vexpress64 documentation
+
+Issue-Id: SCM-3728
+Upstream-Status: Inappropriate [other]
+ Temporary patch
+Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
+Change-Id: Id173e52afad473abcf3f61c6bf374fc31f17edd3
+---
+ arch/arm/Kconfig | 8 +++++
+ board/armltd/vexpress64/Kconfig | 6 +++-
+ board/armltd/vexpress64/MAINTAINERS | 7 ++++
+ board/armltd/vexpress64/vexpress64.c | 52 ++++++++++++++++++++++++++++
+ configs/vexpress_aemv8r_defconfig | 27 +++++++++++++++
+ doc/board/armltd/vexpress64.rst | 1 +
+ include/configs/vexpress_aemv8.h | 42 ++++++++++++++++++++++
+ 7 files changed, 142 insertions(+), 1 deletion(-)
+ create mode 100644 configs/vexpress_aemv8r_defconfig
+
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index f7f03837fe..5b3643889b 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -1234,6 +1234,14 @@ config TARGET_VEXPRESS64_BASE_FVP
+ select PL01X_SERIAL
+ select SEMIHOSTING
+
++config TARGET_VEXPRESS64_BASER_FVP
++ bool "Support Versatile Express ARMv8r64 FVP BASE model"
++ select ARM64
++ select DM
++ select DM_SERIAL
++ select PL01X_SERIAL
++ select LINUX_KERNEL_IMAGE_HEADER
++
+ config TARGET_VEXPRESS64_JUNO
+ bool "Support Versatile Express Juno Development Platform"
+ select ARM64
+diff --git a/board/armltd/vexpress64/Kconfig b/board/armltd/vexpress64/Kconfig
+index 4aab3f092e..e824173fe1 100644
+--- a/board/armltd/vexpress64/Kconfig
++++ b/board/armltd/vexpress64/Kconfig
+@@ -1,4 +1,5 @@
+-if TARGET_VEXPRESS64_BASE_FVP || TARGET_VEXPRESS64_JUNO
++if TARGET_VEXPRESS64_BASE_FVP || TARGET_VEXPRESS64_JUNO || \
++ TARGET_VEXPRESS64_BASER_FVP
+
+ config SYS_BOARD
+ default "vexpress64"
+@@ -16,4 +17,7 @@ config JUNO_DTB_PART
+ The ARM partition name in the NOR flash memory holding the
+ device tree blob to configure U-Boot.
+
++config LNX_KRNL_IMG_TEXT_OFFSET_BASE
++ default 0x0
++
+ endif
+diff --git a/board/armltd/vexpress64/MAINTAINERS b/board/armltd/vexpress64/MAINTAINERS
+index 0ba044d7ff..e89d9711b8 100644
+--- a/board/armltd/vexpress64/MAINTAINERS
++++ b/board/armltd/vexpress64/MAINTAINERS
+@@ -14,3 +14,10 @@ JUNO DEVELOPMENT PLATFORM BOARD
+ M: Linus Walleij <linus.walleij@linaro.org>
+ S: Maintained
+ F: configs/vexpress_aemv8a_juno_defconfig
++
++VEXPRESS_AEMV8R BOARD
++M: Diego Sueiro <diego.sueiro@arm.com>
++M: Peter Hoyes <peter.hoyes@arm.com>
++R: Andre Przywara <andre.przywara@arm.com>
++S: Maintained
++F: configs/vexpress_aemv8r_defconfig
+diff --git a/board/armltd/vexpress64/vexpress64.c b/board/armltd/vexpress64/vexpress64.c
+index 59a72588e0..270618a0ff 100644
+--- a/board/armltd/vexpress64/vexpress64.c
++++ b/board/armltd/vexpress64/vexpress64.c
+@@ -18,6 +18,7 @@
+ #include <dm/platform_data/serial_pl01x.h>
+ #include "pcie.h"
+ #include <asm/armv8/mmu.h>
++#include <asm/armv8/mpu.h>
+ #ifdef CONFIG_VIRTIO_NET
+ #include <virtio_types.h>
+ #include <virtio.h>
+@@ -36,6 +37,56 @@ U_BOOT_DRVINFO(vexpress_serials) = {
+ .plat = &serial_plat,
+ };
+
++#ifdef CONFIG_TARGET_VEXPRESS64_BASER_FVP
++
++static struct mpu_region vexpress64_aemv8r_mem_map[] = {
++ {
++ .start = 0x0UL,
++ .end = 0x7fffffffUL,
++ .attrs = PRLAR_ATTRIDX(MT_NORMAL)
++ }, {
++ .start = 0x80000000UL,
++ .end = 0xffffffffUL,
++ .attrs = PRLAR_ATTRIDX(MT_DEVICE_NGNRNE)
++ }, {
++ .start = 0x100000000UL,
++ .end = 0xffffffffffUL,
++ .attrs = PRLAR_ATTRIDX(MT_NORMAL)
++ }, {
++ /* List terminator */
++ 0,
++ }
++};
++
++struct mpu_region *mpu_mem_map = vexpress64_aemv8r_mem_map;
++
++static struct mm_region vexpress64_mem_map[] = {
++ {
++ .virt = 0x0UL,
++ .phys = 0x0UL,
++ .size = 0x80000000UL,
++ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
++ PTE_BLOCK_INNER_SHARE
++ }, {
++ .virt = 0x80000000UL,
++ .phys = 0x80000000UL,
++ .size = 0x80000000UL,
++ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
++ PTE_BLOCK_NON_SHARE |
++ PTE_BLOCK_PXN | PTE_BLOCK_UXN
++ },
++ {
++ .virt = 0x100000000UL,
++ .phys = 0x100000000UL,
++ .size = 0xff00000000UL,
++ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
++ PTE_BLOCK_INNER_SHARE
++ }, {
++ /* List terminator */
++ 0,
++ }
++};
++#else
+ static struct mm_region vexpress64_mem_map[] = {
+ {
+ .virt = 0x0UL,
+@@ -55,6 +106,7 @@ static struct mm_region vexpress64_mem_map[] = {
+ 0,
+ }
+ };
++#endif
+
+ struct mm_region *mem_map = vexpress64_mem_map;
+
+diff --git a/configs/vexpress_aemv8r_defconfig b/configs/vexpress_aemv8r_defconfig
+new file mode 100644
+index 0000000000..37c393b66f
+--- /dev/null
++++ b/configs/vexpress_aemv8r_defconfig
+@@ -0,0 +1,27 @@
++CONFIG_ARM=y
++CONFIG_TARGET_VEXPRESS64_BASER_FVP=y
++CONFIG_SYS_TEXT_BASE=0x00080000
++CONFIG_POSITION_INDEPENDENT=y
++CONFIG_SYS_LOAD_ADDR=0x10000000
++CONFIG_SYS_MALLOC_F_LEN=0x2000
++CONFIG_NR_DRAM_BANKS=2
++CONFIG_ENV_SIZE=0x40000
++CONFIG_ENV_SECT_SIZE=0x40000
++CONFIG_IDENT_STRING=" vexpress_aemv8r64"
++CONFIG_DISTRO_DEFAULTS=y
++CONFIG_BOOTDELAY=3
++CONFIG_USE_BOOTARGS=y
++CONFIG_BOOTARGS="console=ttyAMA0 earlycon=pl011,0x9c090000 rootfstype=ext4 root=/dev/vda2 rw rootwait"
++# CONFIG_USE_BOOTCOMMAND is not set
++# CONFIG_DISPLAY_CPUINFO is not set
++CONFIG_SYS_PROMPT="VExpress64# "
++CONFIG_DM_ETH=y
++CONFIG_OF_CONTROL=y
++CONFIG_OF_BOARD=y
++CONFIG_VIRTIO_MMIO=y
++CONFIG_VIRTIO_BLK=y
++CONFIG_VIRTIO_NET=y
++CONFIG_ARMV8_SWITCH_TO_EL1=y
++CONFIG_ARMV8_DISABLE_HVC=n
++CONFIG_ARMV8_EXCEPTION_VECTORS=n
++CONFIG_ARCH_FIXUP_FDT_MEMORY=n
+diff --git a/doc/board/armltd/vexpress64.rst b/doc/board/armltd/vexpress64.rst
+index b98b096544..b8efbc1565 100644
+--- a/doc/board/armltd/vexpress64.rst
++++ b/doc/board/armltd/vexpress64.rst
+@@ -6,6 +6,7 @@ Arm Versatile Express
+ The vexpress_* board configuration supports the following platforms:
+
+ * FVP_Base_RevC-2xAEMvA
++ * FVP_BaseR_AEMv8R
+ * Juno development board
+
+ Fixed Virtual Platforms
+diff --git a/include/configs/vexpress_aemv8.h b/include/configs/vexpress_aemv8.h
+index 76935f3173..a9086879c9 100644
+--- a/include/configs/vexpress_aemv8.h
++++ b/include/configs/vexpress_aemv8.h
+@@ -22,8 +22,13 @@
+ #define CONFIG_SYS_BOOTM_LEN (64 << 20) /* Increase max gunzip size */
+
+ /* CS register bases for the original memory map. */
++#ifdef CONFIG_TARGET_VEXPRESS64_BASER_FVP
++#define V2M_BASE 0x00000000
++#define V2M_PA_BASE 0x80000000
++#else
+ #define V2M_BASE 0x80000000
+ #define V2M_PA_BASE 0x00000000
++#endif
+
+ #define V2M_PA_CS0 (V2M_PA_BASE + 0x00000000)
+ #define V2M_PA_CS1 (V2M_PA_BASE + 0x14000000)
+@@ -211,6 +216,43 @@
+ "fi"
+ #endif
+
++#elif CONFIG_TARGET_VEXPRESS64_BASER_FVP
++
++#define BOOTENV_DEV_MEM(devtypeu, devtypel, instance) \
++ "bootcmd_mem= " \
++ "source ${scriptaddr}; " \
++ "if test $? -eq 1; then " \
++ " env import -t ${scriptaddr}; " \
++ " if test -n $uenvcmd; then " \
++ " echo Running uenvcmd ...; " \
++ " run uenvcmd; " \
++ " fi; " \
++ "fi\0"
++#define BOOTENV_DEV_NAME_MEM(devtypeu, devtypel, instance) "mem "
++
++#define BOOT_TARGET_DEVICES(func) \
++ func(MEM, mem, na) \
++ func(VIRTIO, virtio, 0) \
++ func(PXE, pxe, na) \
++ func(DHCP, dhcp, na)
++
++#include <config_distro_bootcmd.h>
++
++#define VEXPRESS_KERNEL_ADDR 0x00200000
++#define VEXPRESS_PXEFILE_ADDR 0x0fb00000
++#define VEXPRESS_FDT_ADDR 0x0fc00000
++#define VEXPRESS_SCRIPT_ADDR 0x0fd00000
++#define VEXPRESS_RAMDISK_ADDR 0x0fe00000
++
++#define CONFIG_EXTRA_ENV_SETTINGS \
++ "kernel_addr_r=" __stringify(VEXPRESS_KERNEL_ADDR) "\0" \
++ "pxefile_addr_r=" __stringify(VEXPRESS_PXEFILE_ADDR) "\0" \
++ "fdt_addr_r=" __stringify(VEXPRESS_FDT_ADDR) "\0" \
++ "fdtfile=board.dtb\0" \
++ "scriptaddr=" __stringify(VEXPRESS_SCRIPT_ADDR) "\0" \
++ "ramdisk_addr_r=" __stringify(VEXPRESS_RAMDISK_ADDR) "\0" \
++ BOOTENV
++
+ #endif
+
+ /* Monitor Command Prompt */
+--
+2.25.1
+
@@ -74,6 +74,23 @@ SRC_URI:append:fvp-base = " file://bootargs.cfg"
#
SRC_URI:append:fvp-base-arm32 = " file://0001-Add-vexpress_aemv8a_aarch32-variant.patch"
+#
+# FVP BASER
+#
+SRC_URI:append:fvp-baser-aemv8r64 = " \
+ file://0001-doc-Add-documentation-for-the-Arm-VExpress64-board-c.patch \
+ file://0002-vexpress64-Refactor-header-file-to-make-it-easier-to.patch \
+ file://0003-vexpress64-Clean-up-BASE_FVP-boot-configuration.patch \
+ file://0004-vexpress64-Enable-OF_CONTROL-and-OF_BOARD-for-VExpre.patch \
+ file://0005-vexpress64-Enable-VIRTIO_NET-network-driver.patch \
+ file://0006-armv8-Add-ARMv8-MPU-configuration-logic.patch \
+ file://0007-armv8-Allow-disabling-exception-vectors-on-non-SPL-b.patch \
+ file://0008-armv8-ARMV8_SWITCH_TO_EL1-improvements.patch \
+ file://0009-armv8-Make-disabling-HVC-configurable-when-switching.patch \
+ file://0010-vexpress64-Do-not-set-COUNTER_FREQUENCY.patch \
+ file://0011-vexpress64-Add-BASER_FVP-vexpress-board-variant.patch \
+ "
+
#
# TC0 and TC1 MACHINES
#