Add support for exiting Gunyah hypervisor and switching to EL2 during
early boot. This is required for platforms that boot U-Boot in a
hypervisor guest environment where U-Boot needs to run at EL2 to
enable other hypervisors like KVM.

The switch is performed via TrustZone SMC call before EL register
configuration in start.S. The implementation:

- Checks current exception level and only executes at EL1
- Uses TrustZone SMC to exit Gunyah and transition to EL2
- Integrates with existing boot0.h workaround infrastructure

A new Kconfig option CONFIG_QCOM_EL2_GUNYAH_EXIT_SUPPORT enables this
functionality.

Signed-off-by: Aswin Murugan <[email protected]>
---
Change in v3:
- Corrected the logic to accurately detect the current Exception Level (EL)
  and fuction properly when U-Boot enters either EL2 or EL1.

Link to v2: 
https://lore.kernel.org/u-boot/[email protected]/

Change in v2:
- EL2 switch is made at early stage instead of doing at the very last stage in
  the previous version
- This change is based on the patch [1]

[1] https://lore.kernel.org/all/[email protected]/

Link to v1: 
https://lore.kernel.org/u-boot/[email protected]/
---
 arch/arm/mach-snapdragon/Kconfig              |  7 ++++
 arch/arm/mach-snapdragon/include/mach/boot0.h |  3 ++
 .../include/mach/gunyah_exit_boot0.h          | 35 +++++++++++++++++++
 3 files changed, 45 insertions(+)
 create mode 100644 arch/arm/mach-snapdragon/include/mach/gunyah_exit_boot0.h

diff --git a/arch/arm/mach-snapdragon/Kconfig b/arch/arm/mach-snapdragon/Kconfig
index f863daf6bb9..931d25c1023 100644
--- a/arch/arm/mach-snapdragon/Kconfig
+++ b/arch/arm/mach-snapdragon/Kconfig
@@ -56,6 +56,13 @@ config BOOT0_MSM8916_PSCI_WORKAROUND
        help
          Select this if you are building U-Boot proper for an msm8916 board 
that
          uses the buggy PSCI implementation.
+
+config QCOM_EL2_GUNYAH_EXIT_SUPPORT
+       bool "Enable early EL2 switch by exiting Gunyah"
+       help
+         Exit Gunyah hypervisor and switch to EL2 during early boot. This must
+         happen before EL register configuration in start.S so that U-Boot can
+         run properly at EL2.
 endchoice
 
 endif
diff --git a/arch/arm/mach-snapdragon/include/mach/boot0.h 
b/arch/arm/mach-snapdragon/include/mach/boot0.h
index b3c76d6d97d..032a9fbdb12 100644
--- a/arch/arm/mach-snapdragon/include/mach/boot0.h
+++ b/arch/arm/mach-snapdragon/include/mach/boot0.h
@@ -1,9 +1,12 @@
 /* SPDX-License-Identifier: GPL-2.0+ */
+
 #if defined(CONFIG_SPL_BUILD)
        b       reset
 #else
 #if defined(CONFIG_BOOT0_MSM8916_PSCI_WORKAROUND)
 #include "msm8916_boot0.h"
+#elif defined(CONFIG_QCOM_EL2_GUNYAH_EXIT_SUPPORT)
+#include "gunyah_exit_boot0.h"
 #else
        b       reset
 #endif
diff --git a/arch/arm/mach-snapdragon/include/mach/gunyah_exit_boot0.h 
b/arch/arm/mach-snapdragon/include/mach/gunyah_exit_boot0.h
new file mode 100644
index 00000000000..5c5bd3b6691
--- /dev/null
+++ b/arch/arm/mach-snapdragon/include/mach/gunyah_exit_boot0.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Early Gunyah Hypervisor Exit
+ *
+ * Exit Gunyah hypervisor and switch to EL2 during early boot. This must
+ * happen before EL register configuration in start.S so that U-Boot can
+ * run properly at EL2.
+ */
+
+#include <asm/macro.h>
+#include <linux/arm-smccc.h>
+
+/* TrustZone SMC IDs for hypervisor configuration */
+#define TZ_EL2_SWITCH_SMC_ID                   0x02000121
+#define TZ_EL2_SWITCH_PARAM_ID                 0x00000023
+#define TZ_EL2_SWITCH_PARAM2_EXIT_GUNYAH       0x1
+
+       /* Only perform hypervisor switch if we're at EL1 */
+       switch_el x9, 3f, 2f, 1f
+
+       /* Save FDT address before we modify x0 */
+1:     mov     x9, x0
+
+       /* Switch to EL2 (exit Gunyah) */
+       ldr     w0, =TZ_EL2_SWITCH_SMC_ID
+       ldr     w1, =TZ_EL2_SWITCH_PARAM_ID
+       mov     w2, wzr
+       mov     w3, wzr
+       ldr     w4, =TZ_EL2_SWITCH_PARAM2_EXIT_GUNYAH
+       smc     #0
+
+       /* Restore FDT address */
+       mov     x0, x9
+2:
+3:     b       reset
-- 
2.34.1

Reply via email to