blob: 157a15d7df07e2cbebc3d5696ff53d1843475cb1 [file] [log] [blame]
Andrew Geissler2edf0642023-09-11 08:24:07 -04001From 14e204ffca5870d6bfd238627937a2028c88589d Mon Sep 17 00:00:00 2001
Brad Bishopbec4ebc2022-08-03 09:55:16 -04002From: Peter Hoyes <Peter.Hoyes@arm.com>
3Date: Wed, 14 Jul 2021 12:44:27 +0100
Andrew Geissler2edf0642023-09-11 08:24:07 -04004Subject: [PATCH] armv8: ARMV8_SWITCH_TO_EL1 improvements
Brad Bishopbec4ebc2022-08-03 09:55:16 -04005
6Convert CONFIG_ARMV8_SWITCH_TO_EL1 to a Kconfig variable.
7
8Add support for switching to EL1 to bootefi.
9
10Add the environment variable armv8_switch_to_el1 to allow configuring
11whether to switch to EL1 at runtime. This overrides the compile-time
12option.
13
14Issue-Id: SCM-3728
15Upstream-Status: Inappropriate [other]
16 Implementation pending further discussion
17Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
18Change-Id: If98478148d6d8d1f732acac5439276700614815f
Andrew Geissler2edf0642023-09-11 08:24:07 -040019
Brad Bishopbec4ebc2022-08-03 09:55:16 -040020---
Brad Bishopbec4ebc2022-08-03 09:55:16 -040021 arch/arm/cpu/armv8/exception_level.c | 21 ++++++++++++++--
22 arch/arm/lib/bootm.c | 36 ++++++++++++++++------------
23 configs/vexpress_aemv8r_defconfig | 1 +
Andrew Geisslerea144b032023-01-27 16:03:57 -060024 3 files changed, 41 insertions(+), 17 deletions(-)
Brad Bishopbec4ebc2022-08-03 09:55:16 -040025
Brad Bishopbec4ebc2022-08-03 09:55:16 -040026diff --git a/arch/arm/cpu/armv8/exception_level.c b/arch/arm/cpu/armv8/exception_level.c
27index b11936548f..4aad1550f4 100644
28--- a/arch/arm/cpu/armv8/exception_level.c
29+++ b/arch/arm/cpu/armv8/exception_level.c
30@@ -40,19 +40,36 @@ static void entry_non_secure(struct jmp_buf_data *non_secure_jmp)
31 * trusted firmware being one embodiment). The operating system shall be
32 * started at exception level EL2. So here we check the exception level
33 * and switch it if necessary.
34+ *
35+ * If armv8_switch_to_el1 (config or env var) is enabled, also switch to EL1
36+ * before booting the operating system.
37 */
38 void switch_to_non_secure_mode(void)
39 {
40 struct jmp_buf_data non_secure_jmp;
41
42 /* On AArch64 we need to make sure we call our payload in < EL3 */
43- if (current_el() == 3) {
44+
45+ int switch_to_el1 = env_get_yesno("armv8_switch_to_el1");
46+#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
47+ if (switch_to_el1 == -1) {
48+ switch_to_el1 = 1;
49+ }
50+#endif
51+
52+ if (current_el() > 2) {
53 if (setjmp(&non_secure_jmp))
54 return;
55 dcache_disable(); /* flush cache before switch to EL2 */
56-
57 /* Move into EL2 and keep running there */
58 armv8_switch_to_el2((uintptr_t)&non_secure_jmp, 0, 0, 0,
59 (uintptr_t)entry_non_secure, ES_TO_AARCH64);
60+ } else if (switch_to_el1 == 1 && current_el() > 1) {
61+ if (setjmp(&non_secure_jmp))
62+ return;
63+ dcache_disable(); /* flush cache before switch to EL1 */
64+ /* Move into EL1 and keep running there */
65+ armv8_switch_to_el1((uintptr_t)&non_secure_jmp, 0, 0, 0,
66+ (uintptr_t)entry_non_secure, ES_TO_AARCH64);
67 }
68 }
69diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
Andrew Geissler2edf0642023-09-11 08:24:07 -040070index e414ef8267..9a86c17d2a 100644
Brad Bishopbec4ebc2022-08-03 09:55:16 -040071--- a/arch/arm/lib/bootm.c
72+++ b/arch/arm/lib/bootm.c
Andrew Geisslerea144b032023-01-27 16:03:57 -060073@@ -270,7 +270,6 @@ __weak void update_os_arch_secondary_cores(uint8_t os_arch)
Brad Bishopbec4ebc2022-08-03 09:55:16 -040074 {
75 }
76
77-#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
78 static void switch_to_el1(void)
79 {
80 if ((IH_ARCH_DEFAULT == IH_ARCH_ARM64) &&
Andrew Geisslerea144b032023-01-27 16:03:57 -060081@@ -285,7 +284,6 @@ static void switch_to_el1(void)
Brad Bishopbec4ebc2022-08-03 09:55:16 -040082 ES_TO_AARCH64);
83 }
84 #endif
85-#endif
86
87 /* Subcommand: GO */
Andrew Geissler2edf0642023-09-11 08:24:07 -040088 static void boot_jump_linux(struct bootm_headers *images, int flag)
89@@ -312,21 +310,29 @@ static void boot_jump_linux(struct bootm_headers *images, int flag)
Brad Bishopbec4ebc2022-08-03 09:55:16 -040090
91 update_os_arch_secondary_cores(images->os.arch);
92
93+ int armv8_switch_to_el1 = env_get_yesno("armv8_switch_to_el1");
94 #ifdef CONFIG_ARMV8_SWITCH_TO_EL1
95- armv8_switch_to_el2((u64)images->ft_addr, 0, 0, 0,
96- (u64)switch_to_el1, ES_TO_AARCH64);
97-#else
98- if ((IH_ARCH_DEFAULT == IH_ARCH_ARM64) &&
99- (images->os.arch == IH_ARCH_ARM))
100- armv8_switch_to_el2(0, (u64)gd->bd->bi_arch_number,
101- (u64)images->ft_addr, 0,
102- (u64)images->ep,
103- ES_TO_AARCH32);
104- else
105- armv8_switch_to_el2((u64)images->ft_addr, 0, 0, 0,
106- images->ep,
107- ES_TO_AARCH64);
108+ if (armv8_switch_to_el1 == -1) {
109+ armv8_switch_to_el1 = 1;
110+ }
111 #endif
112+ if (armv8_switch_to_el1 == 1) {
113+ armv8_switch_to_el2((u64)images->ft_addr, 0, 0, 0,
114+ (u64)switch_to_el1, ES_TO_AARCH64);
115+ } else {
116+ if ((IH_ARCH_DEFAULT == IH_ARCH_ARM64) &&
117+ (images->os.arch == IH_ARCH_ARM))
118+ armv8_switch_to_el2(0,
119+ (u64)gd->bd->bi_arch_number,
120+ (u64)images->ft_addr, 0,
121+ (u64)images->ep,
122+ ES_TO_AARCH32);
123+ else
124+ armv8_switch_to_el2((u64)images->ft_addr,
125+ 0, 0, 0,
126+ images->ep,
127+ ES_TO_AARCH64);
128+ }
129 }
130 #else
131 unsigned long machid = gd->bd->bi_arch_number;
132diff --git a/configs/vexpress_aemv8r_defconfig b/configs/vexpress_aemv8r_defconfig
Andrew Geisslerea144b032023-01-27 16:03:57 -0600133index 683d983c36..6044f82b00 100644
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400134--- a/configs/vexpress_aemv8r_defconfig
135+++ b/configs/vexpress_aemv8r_defconfig
Andrew Geisslerea144b032023-01-27 16:03:57 -0600136@@ -17,3 +17,4 @@ CONFIG_SYS_PBSIZE=541
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400137 # CONFIG_MMC is not set
138 CONFIG_VIRTIO_MMIO=y
139 CONFIG_ARMV8_EXCEPTION_VECTORS=n
140+CONFIG_ARMV8_SWITCH_TO_EL1=y