blob: 81758fce711f969d8820b8ba6ce49ffe228df432 [file] [log] [blame]
Andrew Geisslerea144b032023-01-27 16:03:57 -06001From 30405f59881c73946b6b0ffdbf25804f9fbf1585 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
4Subject: [PATCH 4/9] armv8: ARMV8_SWITCH_TO_EL1 improvements
5
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
19---
Brad Bishopbec4ebc2022-08-03 09:55:16 -040020 arch/arm/cpu/armv8/exception_level.c | 21 ++++++++++++++--
21 arch/arm/lib/bootm.c | 36 ++++++++++++++++------------
22 configs/vexpress_aemv8r_defconfig | 1 +
Andrew Geisslerea144b032023-01-27 16:03:57 -060023 3 files changed, 41 insertions(+), 17 deletions(-)
Brad Bishopbec4ebc2022-08-03 09:55:16 -040024
Brad Bishopbec4ebc2022-08-03 09:55:16 -040025diff --git a/arch/arm/cpu/armv8/exception_level.c b/arch/arm/cpu/armv8/exception_level.c
26index b11936548f..4aad1550f4 100644
27--- a/arch/arm/cpu/armv8/exception_level.c
28+++ b/arch/arm/cpu/armv8/exception_level.c
29@@ -40,19 +40,36 @@ static void entry_non_secure(struct jmp_buf_data *non_secure_jmp)
30 * trusted firmware being one embodiment). The operating system shall be
31 * started at exception level EL2. So here we check the exception level
32 * and switch it if necessary.
33+ *
34+ * If armv8_switch_to_el1 (config or env var) is enabled, also switch to EL1
35+ * before booting the operating system.
36 */
37 void switch_to_non_secure_mode(void)
38 {
39 struct jmp_buf_data non_secure_jmp;
40
41 /* On AArch64 we need to make sure we call our payload in < EL3 */
42- if (current_el() == 3) {
43+
44+ int switch_to_el1 = env_get_yesno("armv8_switch_to_el1");
45+#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
46+ if (switch_to_el1 == -1) {
47+ switch_to_el1 = 1;
48+ }
49+#endif
50+
51+ if (current_el() > 2) {
52 if (setjmp(&non_secure_jmp))
53 return;
54 dcache_disable(); /* flush cache before switch to EL2 */
55-
56 /* Move into EL2 and keep running there */
57 armv8_switch_to_el2((uintptr_t)&non_secure_jmp, 0, 0, 0,
58 (uintptr_t)entry_non_secure, ES_TO_AARCH64);
59+ } else if (switch_to_el1 == 1 && current_el() > 1) {
60+ if (setjmp(&non_secure_jmp))
61+ return;
62+ dcache_disable(); /* flush cache before switch to EL1 */
63+ /* Move into EL1 and keep running there */
64+ armv8_switch_to_el1((uintptr_t)&non_secure_jmp, 0, 0, 0,
65+ (uintptr_t)entry_non_secure, ES_TO_AARCH64);
66 }
67 }
68diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
Andrew Geisslerea144b032023-01-27 16:03:57 -060069index 9f086f3b90..b044aeca88 100644
Brad Bishopbec4ebc2022-08-03 09:55:16 -040070--- a/arch/arm/lib/bootm.c
71+++ b/arch/arm/lib/bootm.c
Andrew Geisslerea144b032023-01-27 16:03:57 -060072@@ -270,7 +270,6 @@ __weak void update_os_arch_secondary_cores(uint8_t os_arch)
Brad Bishopbec4ebc2022-08-03 09:55:16 -040073 {
74 }
75
76-#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
77 static void switch_to_el1(void)
78 {
79 if ((IH_ARCH_DEFAULT == IH_ARCH_ARM64) &&
Andrew Geisslerea144b032023-01-27 16:03:57 -060080@@ -285,7 +284,6 @@ static void switch_to_el1(void)
Brad Bishopbec4ebc2022-08-03 09:55:16 -040081 ES_TO_AARCH64);
82 }
83 #endif
84-#endif
85
86 /* Subcommand: GO */
87 static void boot_jump_linux(bootm_headers_t *images, int flag)
Andrew Geisslerea144b032023-01-27 16:03:57 -060088@@ -312,21 +310,29 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
Brad Bishopbec4ebc2022-08-03 09:55:16 -040089
90 update_os_arch_secondary_cores(images->os.arch);
91
92+ int armv8_switch_to_el1 = env_get_yesno("armv8_switch_to_el1");
93 #ifdef CONFIG_ARMV8_SWITCH_TO_EL1
94- armv8_switch_to_el2((u64)images->ft_addr, 0, 0, 0,
95- (u64)switch_to_el1, ES_TO_AARCH64);
96-#else
97- if ((IH_ARCH_DEFAULT == IH_ARCH_ARM64) &&
98- (images->os.arch == IH_ARCH_ARM))
99- armv8_switch_to_el2(0, (u64)gd->bd->bi_arch_number,
100- (u64)images->ft_addr, 0,
101- (u64)images->ep,
102- ES_TO_AARCH32);
103- else
104- armv8_switch_to_el2((u64)images->ft_addr, 0, 0, 0,
105- images->ep,
106- ES_TO_AARCH64);
107+ if (armv8_switch_to_el1 == -1) {
108+ armv8_switch_to_el1 = 1;
109+ }
110 #endif
111+ if (armv8_switch_to_el1 == 1) {
112+ armv8_switch_to_el2((u64)images->ft_addr, 0, 0, 0,
113+ (u64)switch_to_el1, ES_TO_AARCH64);
114+ } else {
115+ if ((IH_ARCH_DEFAULT == IH_ARCH_ARM64) &&
116+ (images->os.arch == IH_ARCH_ARM))
117+ armv8_switch_to_el2(0,
118+ (u64)gd->bd->bi_arch_number,
119+ (u64)images->ft_addr, 0,
120+ (u64)images->ep,
121+ ES_TO_AARCH32);
122+ else
123+ armv8_switch_to_el2((u64)images->ft_addr,
124+ 0, 0, 0,
125+ images->ep,
126+ ES_TO_AARCH64);
127+ }
128 }
129 #else
130 unsigned long machid = gd->bd->bi_arch_number;
131diff --git a/configs/vexpress_aemv8r_defconfig b/configs/vexpress_aemv8r_defconfig
Andrew Geisslerea144b032023-01-27 16:03:57 -0600132index 683d983c36..6044f82b00 100644
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400133--- a/configs/vexpress_aemv8r_defconfig
134+++ b/configs/vexpress_aemv8r_defconfig
Andrew Geisslerea144b032023-01-27 16:03:57 -0600135@@ -17,3 +17,4 @@ CONFIG_SYS_PBSIZE=541
Brad Bishopbec4ebc2022-08-03 09:55:16 -0400136 # CONFIG_MMC is not set
137 CONFIG_VIRTIO_MMIO=y
138 CONFIG_ARMV8_EXCEPTION_VECTORS=n
139+CONFIG_ARMV8_SWITCH_TO_EL1=y
140--
1412.25.1
142