[PATCH] armv8: Handle EL2 Host mode

On implementations that support VHE, the layout of the CPTR_EL2 register depends on whether HCR_EL2.E2H is set. Check this bit and and set the aprropriate bits to enable access to the FP/SIMD registers. This allows U-Boot to run on systems that pass control to U-Boot in EL2 with EL2 Host mode enabled such as machine with Apple's M1 SoC.
Signed-off-by: Mark Kettenis kettenis@openbsd.org --- arch/arm/cpu/armv8/start.S | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S index 662449156b..a259717e67 100644 --- a/arch/arm/cpu/armv8/start.S +++ b/arch/arm/cpu/armv8/start.S @@ -133,9 +133,15 @@ pie_fixup_done: #endif b 0f 2: set_vbar vbar_el2, x0 + mrs x0, hcr_el2 + tbnz x0, #34, el2_host /* HCR_EL2.E2H */ mov x0, #0x33ff msr cptr_el2, x0 /* Enable FP/SIMD */ b 0f +el2_host: + mov x0, #3 << 20 + msr cptr_el2, x0 /* Enable FP/SIMD */ + b 0f 1: set_vbar vbar_el1, x0 mov x0, #3 << 20 msr cpacr_el1, x0 /* Enable FP/SIMD */

On Sat, 30 Jan 2021 13:12:32 +0100 Mark Kettenis kettenis@openbsd.org wrote:
On implementations that support VHE, the layout of the CPTR_EL2 register depends on whether HCR_EL2.E2H is set. Check this bit and and set the aprropriate bits to enable access to the FP/SIMD registers. This allows U-Boot to run on systems that pass control to U-Boot in EL2 with EL2 Host mode enabled such as machine with Apple's M1 SoC.
That looks correct, I compared the bits against the manual. TCR_EL2 and CNTHCTL_EL2 are also different, have you checked that U-Boot's usage of it is compatible with E2H=1?
And we should probably allow SVE for non-VHE systems as well, but this is probably another patch.
One nit below.
Signed-off-by: Mark Kettenis kettenis@openbsd.org
arch/arm/cpu/armv8/start.S | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S index 662449156b..a259717e67 100644 --- a/arch/arm/cpu/armv8/start.S +++ b/arch/arm/cpu/armv8/start.S @@ -133,9 +133,15 @@ pie_fixup_done: #endif b 0f 2: set_vbar vbar_el2, x0
- mrs x0, hcr_el2
- tbnz x0, #34, el2_host /* HCR_EL2.E2H */
el2_host sounds a bit ambiguous, can we use el2_vhe instead? That would also point to the term "VHE", which is more known (and searchable) than the "E2H" bit.
Cheers, Andre
mov x0, #0x33ff msr cptr_el2, x0 /* Enable FP/SIMD */ b 0f +el2_host:
- mov x0, #3 << 20
- msr cptr_el2, x0 /* Enable FP/SIMD */
- b 0f
1: set_vbar vbar_el1, x0 mov x0, #3 << 20 msr cpacr_el1, x0 /* Enable FP/SIMD */

Date: Sat, 30 Jan 2021 13:41:34 +0000 From: Andre Przywara andre.przywara@arm.com
On Sat, 30 Jan 2021 13:12:32 +0100 Mark Kettenis kettenis@openbsd.org wrote:
On implementations that support VHE, the layout of the CPTR_EL2 register depends on whether HCR_EL2.E2H is set. Check this bit and and set the aprropriate bits to enable access to the FP/SIMD registers. This allows U-Boot to run on systems that pass control to U-Boot in EL2 with EL2 Host mode enabled such as machine with Apple's M1 SoC.
That looks correct, I compared the bits against the manual. TCR_EL2 and CNTHCTL_EL2 are also different, have you checked that U-Boot's usage of it is compatible with E2H=1?
I did now:
TCR_EL2 looks ok; U-Boot will set TCR_EL2.EPD1 but since U-Boot only uses TTBR0_ELx, this should be fine.
CNTHCTL_EL2 is only used when CONFIG_ARMV8_SWITCH_TO_EL1 is set, which is generally not what you want, and defenitely not relevant to my use case. (Which is using U-Boot as an EFI implementation such that I can run OpenBSD).
I have some further diffs that allow me to boot up to a framebuffer console on the Apple M1 Mac mini. But I need to add some actually hardware driver support before it makes sense to integrate those.
And we should probably allow SVE for non-VHE systems as well, but this is probably another patch.
One nit below.
Signed-off-by: Mark Kettenis kettenis@openbsd.org
arch/arm/cpu/armv8/start.S | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/arch/arm/cpu/armv8/start.S b/arch/arm/cpu/armv8/start.S index 662449156b..a259717e67 100644 --- a/arch/arm/cpu/armv8/start.S +++ b/arch/arm/cpu/armv8/start.S @@ -133,9 +133,15 @@ pie_fixup_done: #endif b 0f 2: set_vbar vbar_el2, x0
- mrs x0, hcr_el2
- tbnz x0, #34, el2_host /* HCR_EL2.E2H */
el2_host sounds a bit ambiguous, can we use el2_vhe instead? That would also point to the term "VHE", which is more known (and searchable) than the "E2H" bit.
No problem. I'll roll a v2 later today.
Thanks,
Mark
participants (3)
-
Andre Przywara
-
Mark Kettenis
-
Mark Kettenis