[2/3] arm-bsp/u-boot: fvp-baser-aemv8r64 cache_state_modelled fixes

Message ID 20220607080807.976725-2-peter.hoyes@arm.com
State New
Headers show
Series [1/3] arm-bsp/u-boot: Update fvp-baser-aemv8r64 patches for v2022.04 | expand

Commit Message

Peter Hoyes June 7, 2022, 8:08 a.m. UTC
From: Peter Hoyes <Peter.Hoyes@arm.com>

Running the FVP_Base_AEMv8R model with the cache_state_modelled
parameter enabled exposed some defects in the U-Boot BSP patches for the
fvp-baser-aemv8r64:
 * The MPU memory attributes are inconsistent with the existing MMU
   attributes, causing a model hang when sending packets using
   virtio-net in U-Boot.
 * The instruction cache was left disabled after booting an EFI payload
   at S-EL1, causing some EFI apps (e.g. Grub) to hang when attempting
   to use dynamically loaded modules.

The cache_state_modelled FVP parameter is enabled by default in the
model (for simulation accuracy) but is disabled by default in the
machine conf (for simulation speed).

Add two additional machine-specific U-Boot patches to fix the above
issues.

Issue-Id: SCM-4641
Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
Change-Id: I5ab13c9fdadd82456ac3f3e3703df36590d52fb7
---
 ...RBAR-MPU-attributes-to-be-configured.patch | 105 ++++++++++++++++++
 ...che-when-switching-exception-levels-.patch |  63 +++++++++++
 .../recipes-bsp/u-boot/u-boot_%.bbappend      |   2 +
 3 files changed, 170 insertions(+)
 create mode 100644 meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0009-armv8-Allow-PRBAR-MPU-attributes-to-be-configured.patch
 create mode 100644 meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0010-armv8-Enable-icache-when-switching-exception-levels-.patch

Patch

diff --git a/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0009-armv8-Allow-PRBAR-MPU-attributes-to-be-configured.patch b/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0009-armv8-Allow-PRBAR-MPU-attributes-to-be-configured.patch
new file mode 100644
index 0000000..94ac806
--- /dev/null
+++ b/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0009-armv8-Allow-PRBAR-MPU-attributes-to-be-configured.patch
@@ -0,0 +1,105 @@ 
+From c4abb74e62817c5adf32c011db93f6bfc2deabaf Mon Sep 17 00:00:00 2001
+From: Peter Hoyes <Peter.Hoyes@arm.com>
+Date: Wed, 18 May 2022 15:24:19 +0100
+Subject: [PATCH 1/2] armv8: Allow PRBAR MPU attributes to be configured
+
+In a previous patch, support was added to initialize an S-EL2 MPU on
+armv8r64 machines. This implementation allowed the PRLAR attribute
+index to be configured, but not the shareability and access permission
+attributes in PRBAR. These attributes were hard-coded as "outer
+shareable" and "read/write at EL1 and EL0".
+
+Add separate prlar_attrs and prbar_attrs to the MPU region struct so
+that these attributes can be configured on a per-region basis.
+
+For the BASER_FVP, ensure the MPU memory attributes match those in the
+existing vexpress64 board MMU configuration ("non shareable" for device
+memory and "inner shareable" for normal memory).
+
+Issue-Id: SCM-4641
+Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
+Upstream-Status: Inappropriate [other]
+  Implementation pending further discussion
+Change-Id: I6b72aead91ad12412262aa32c61a53e12eab3984
+---
+ arch/arm/cpu/armv8/cache_v8.c        | 12 ++++++++----
+ arch/arm/include/asm/armv8/mpu.h     |  3 ++-
+ board/armltd/vexpress64/vexpress64.c |  9 ++++++---
+ 3 files changed, 16 insertions(+), 8 deletions(-)
+
+diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
+index f6e0ad0075..981aca4a0f 100644
+--- a/arch/arm/cpu/armv8/cache_v8.c
++++ b/arch/arm/cpu/armv8/cache_v8.c
+@@ -370,7 +370,9 @@ static void mpu_clear_regions(void)
+ {
+ 	int i;
+ 
+-	for (i = 0; mpu_mem_map[i].end || mpu_mem_map[i].attrs; i++) {
++	for (i = 0; mpu_mem_map[i].end ||
++	     mpu_mem_map[i].prbar_attrs ||
++	     mpu_mem_map[i].prlar_attrs; i++) {
+ 		setup_el2_mpu_region(i, 0, 0);
+ 	}
+ }
+@@ -390,12 +392,14 @@ static void mpu_setup(void)
+ 
+ 	asm volatile("msr MAIR_EL2, %0" : : "r" MEMORY_ATTRIBUTES);
+ 
+-	for (i = 0; mpu_mem_map[i].end || mpu_mem_map[i].attrs; i++) {
++	for (i = 0; mpu_mem_map[i].end ||
++	     mpu_mem_map[i].prbar_attrs ||
++	     mpu_mem_map[i].prlar_attrs; i++) {
+ 		setup_el2_mpu_region(i,
+ 			PRBAR_ADDRESS(mpu_mem_map[i].start)
+-				| PRBAR_OUTER_SH | PRBAR_AP_RW_ANY,
++				| mpu_mem_map[i].prbar_attrs,
+ 			PRLAR_ADDRESS(mpu_mem_map[i].end)
+-				| mpu_mem_map[i].attrs | PRLAR_EN_BIT
++				| mpu_mem_map[i].prlar_attrs | PRLAR_EN_BIT
+ 			);
+ 	}
+ 
+diff --git a/arch/arm/include/asm/armv8/mpu.h b/arch/arm/include/asm/armv8/mpu.h
+index 8de627cafd..dd4c689ea6 100644
+--- a/arch/arm/include/asm/armv8/mpu.h
++++ b/arch/arm/include/asm/armv8/mpu.h
+@@ -51,7 +51,8 @@ static inline void setup_el2_mpu_region(uint8_t region, uint64_t base, uint64_t
+ struct mpu_region {
+ 	u64 start;
+ 	u64 end;
+-	u64 attrs;
++	u64 prbar_attrs;
++	u64 prlar_attrs;
+ };
+ 
+ extern struct mpu_region *mpu_mem_map;
+diff --git a/board/armltd/vexpress64/vexpress64.c b/board/armltd/vexpress64/vexpress64.c
+index 3f1ac04bac..31ff2f7b2d 100644
+--- a/board/armltd/vexpress64/vexpress64.c
++++ b/board/armltd/vexpress64/vexpress64.c
+@@ -41,15 +41,18 @@ static struct mpu_region vexpress64_aemv8r_mem_map[] = {
+        {
+                .start = 0x0UL,
+                .end = 0x7fffffffUL,
+-               .attrs = PRLAR_ATTRIDX(MT_NORMAL)
++	       .prbar_attrs = PRBAR_INNER_SH | PRBAR_AP_RW_ANY,
++	       .prlar_attrs = PRLAR_ATTRIDX(MT_NORMAL)
+        }, {
+                .start = 0x80000000UL,
+                .end = 0xffffffffUL,
+-               .attrs = PRLAR_ATTRIDX(MT_DEVICE_NGNRNE)
++	       .prbar_attrs = PRBAR_OUTER_SH | PRBAR_AP_RW_ANY,
++	       .prlar_attrs = PRLAR_ATTRIDX(MT_DEVICE_NGNRNE)
+        }, {
+                .start = 0x100000000UL,
+                .end = 0xffffffffffUL,
+-               .attrs = PRLAR_ATTRIDX(MT_NORMAL)
++	       .prbar_attrs = PRBAR_INNER_SH | PRBAR_AP_RW_ANY,
++	       .prlar_attrs = PRLAR_ATTRIDX(MT_NORMAL)
+        }, {
+                /* List terminator */
+                0,
+-- 
+2.25.1
+
diff --git a/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0010-armv8-Enable-icache-when-switching-exception-levels-.patch b/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0010-armv8-Enable-icache-when-switching-exception-levels-.patch
new file mode 100644
index 0000000..6264cc0
--- /dev/null
+++ b/meta-arm-bsp/recipes-bsp/u-boot/u-boot/fvp-baser-aemv8r64/0010-armv8-Enable-icache-when-switching-exception-levels-.patch
@@ -0,0 +1,63 @@ 
+From a5790fe98179b2490500cde629f7a48fbbe341df Mon Sep 17 00:00:00 2001
+From: Peter Hoyes <Peter.Hoyes@arm.com>
+Date: Thu, 19 May 2022 09:02:32 +0100
+Subject: [PATCH 2/2] armv8: Enable icache when switching exception levels in
+ bootefi
+
+bootefi calls the function switch_to_non_secure_mode before calling the
+UEFI payload to handle the case where U-Boot is running at EL3.
+
+For AArch64, the UEFI specification states that:
+   The core will be configured as follows:
+     * MMU enabled
+     * Instruction and data caches enabled
+
+These requirements should be followed when switching exception levels
+for EFI applications.
+
+This function already disables and re-enables the data cache prior to
+switching exception levels, but omits the instruction cache, meaning
+the function returns with the instruction cache disabled at the new
+exception level. Fix this by calling icache_disable prior to switching
+exception levels and icache_enable afterwards.
+
+Issue-Id: SCM-4641
+Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
+Upstream-Status: Inappropriate [other]
+  Implementation pending further discussion
+Change-Id: I678cd5ba39b56e124ab7854608289cd14651ce65
+---
+ arch/arm/cpu/armv8/exception_level.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm/cpu/armv8/exception_level.c b/arch/arm/cpu/armv8/exception_level.c
+index 4aad1550f4..0a3e5428e7 100644
+--- a/arch/arm/cpu/armv8/exception_level.c
++++ b/arch/arm/cpu/armv8/exception_level.c
+@@ -27,6 +27,7 @@
+ static void entry_non_secure(struct jmp_buf_data *non_secure_jmp)
+ {
+ 	dcache_enable();
++	icache_enable();
+ 	debug("Reached non-secure mode\n");
+ 
+ 	/* Restore stack and registers saved in switch_to_non_secure_mode() */
+@@ -61,6 +62,7 @@ void switch_to_non_secure_mode(void)
+ 		if (setjmp(&non_secure_jmp))
+ 			return;
+ 		dcache_disable();	/* flush cache before switch to EL2 */
++		icache_disable();
+ 		/* 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);
+@@ -68,6 +70,7 @@ void switch_to_non_secure_mode(void)
+ 		if (setjmp(&non_secure_jmp))
+ 			return;
+ 		dcache_disable();	/* flush cache before switch to EL1 */
++		icache_disable();
+ 		/* 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);
+-- 
+2.25.1
+
diff --git a/meta-arm-bsp/recipes-bsp/u-boot/u-boot_%.bbappend b/meta-arm-bsp/recipes-bsp/u-boot/u-boot_%.bbappend
index 91f794c..3de0d7c 100644
--- a/meta-arm-bsp/recipes-bsp/u-boot/u-boot_%.bbappend
+++ b/meta-arm-bsp/recipes-bsp/u-boot/u-boot_%.bbappend
@@ -68,6 +68,8 @@  SRC_URI:append:fvp-baser-aemv8r64 = " \
     file://0006-vexpress64-Do-not-set-COUNTER_FREQUENCY.patch \
     file://0007-vexpress64-Configure-memory-using-device-tree.patch \
     file://0008-vexpress64-Enable-LIBFDT_OVERLAY-in-the-vexpress_aem.patch \
+    file://0009-armv8-Allow-PRBAR-MPU-attributes-to-be-configured.patch \
+    file://0010-armv8-Enable-icache-when-switching-exception-levels-.patch \
     "
 
 #