From a071d15784c37dbab9f7852f77ae7cae45561398 Mon Sep 17 00:00:00 2001 From: Mikhail Krichanov Date: Mon, 21 Oct 2024 17:51:52 +0300 Subject: [PATCH] Ring3: Added support for AARCH64 EL2&0 translation regime. --- ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S | 9 +++ .../Library/ArmMmuLib/AArch64/ArmMmuLibCore.c | 56 +++++++++++-------- ArmVirtPkg/ArmVirt.dsc.inc | 2 +- .../Dxe/SysCall/AARCH64/CoreBootServices.S | 25 ++++----- .../Core/Dxe/SysCall/AARCH64/InitializeMsr.c | 5 ++ MdePkg/Include/AArch64/AArch64.h | 4 ++ MdePkg/Include/Library/ArmLib.h | 4 +- 7 files changed, 66 insertions(+), 39 deletions(-) diff --git a/ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S b/ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S index d35730704d..0a25ed5b39 100644 --- a/ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S +++ b/ArmPkg/Library/ArmLib/AArch64/ArmLibSupport.S @@ -133,6 +133,15 @@ ASM_FUNC(ArmInvalidateTlb) isb ret +ASM_FUNC(ArmWriteCptr) + EL1_OR_EL2_OR_EL3(x1) +1:ret +2:msr cptr_el2, x0 + b 4f +3:msr cptr_el3, x0 // EL3 Coprocessor Trap Reg (CPTR) +4:isb + ret + ASM_FUNC(ArmCallWFE) wfe ret diff --git a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c index 03d0925566..3f89ad4816 100644 --- a/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c +++ b/ArmPkg/Library/ArmMmuLib/AArch64/ArmMmuLibCore.c @@ -63,6 +63,7 @@ ArmMemoryAttributeToPageAttribute ( } break; + default: Permissions = 0; break; @@ -479,29 +480,24 @@ GcdAttributeToPageAttribute ( PageAttributes |= TT_AF; } - if ((GcdAttributes & EFI_MEMORY_USER) != 0) { - PageAttributes |= TT_PXN_MASK; - - if ((GcdAttributes & EFI_MEMORY_RO) != 0) { - PageAttributes |= TT_AP_RO_RO; - } else { - PageAttributes |= TT_AP_RW_RW; - } - } else { - if (ArmReadCurrentEL () == AARCH64_EL1) { - // - // TODO: Add EL2&0 support. - // - PageAttributes |= TT_UXN_MASK; - } - - if ((GcdAttributes & EFI_MEMORY_RO) != 0) { - PageAttributes |= TT_AP_NO_RO; - } else { - PageAttributes |= TT_AP_NO_RW; - } - } - + if ((GcdAttributes & EFI_MEMORY_USER) != 0) { + PageAttributes |= TT_PXN_MASK; + + if ((GcdAttributes & EFI_MEMORY_RO) != 0) { + PageAttributes |= TT_AP_RO_RO; + } else { + PageAttributes |= TT_AP_RW_RW; + } + } else { + PageAttributes |= TT_UXN_MASK; + + if ((GcdAttributes & EFI_MEMORY_RO) != 0) { + PageAttributes |= TT_AP_NO_RO; + } else { + PageAttributes |= TT_AP_NO_RW; + } + } + return PageAttributes; } @@ -603,6 +599,7 @@ ArmConfigureMmu ( UINTN RootTableEntryCount; UINT64 TCR; EFI_STATUS Status; + UINTN Hcr; ASSERT (ArmReadCurrentEL () < AARCH64_EL3); if (ArmReadCurrentEL () == AARCH64_EL3) { @@ -627,6 +624,19 @@ ArmConfigureMmu ( T0SZ = 64 - MaxAddressBits; RootTableEntryCount = GetRootTableEntryCount (T0SZ); + if (ArmReadCurrentEL () == AARCH64_EL2) { + // + // Switch to EL2&0 translation regime. + // + Hcr = ArmReadHcr (); + Hcr |= ARM_HCR_E2H | ARM_HCR_TGE; + ArmWriteHcr (Hcr); + // + // Allow access to the Advanced SIMD and floating-point registers. + // + ArmWriteCptr (AARCH64_CPTR_FPEN); + } + // // Set TCR that allows us to retrieve T0SZ in the subsequent functions // diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index 2d93f0a17e..19a874645a 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -107,7 +107,7 @@ CpuExceptionHandlerLib|ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.inf ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf ArmHvcLib|ArmPkg/Library/ArmHvcLib/ArmHvcLib.inf - ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerVirtCounterLib/ArmGenericTimerVirtCounterLib.inf + ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf PlatformPeiLib|ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.inf MemoryInitPeiLib|ArmVirtPkg/Library/ArmVirtMemoryInitPeiLib/ArmVirtMemoryInitPeiLib.inf diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S index 3618257a82..5bc80d9966 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/CoreBootServices.S @@ -88,24 +88,23 @@ ASM_FUNC(ArmCallRing3) // Disable interrupts. msr daifset, #0xf isb + // Copy PSTATE to SPSR. + mrs x6, nzcv + mrs x7, pan + orr x6, x6, x7 // Prepare Ring3 SP and EntryPoint. msr sp_el0, x1 - msr elr_el1, x2 + EL1_OR_EL2(x1) +1:msr elr_el1, x2 + msr spsr_el1, x6 + b 3f +2:msr elr_el2, x2 + msr spsr_el2, x6 // Save Core SP and switch to CoreSysCall Stack. - mov x5, sp +3:mov x5, sp str x5, [x4] mov sp, x3 - // Copy PSTATE to SPSR. - mrs x1, nzcv - mrs x2, pan - orr x1, x1, x2 - // - // M[3:0], bits [3:0] AArch64 Exception level and selected Stack Pointer. - // 0b0000 - EL0. - // 0b0100 - EL1 with SP_EL0 (ELt). - // 0b0101 - EL1 with SP_EL1 (EL1h). - // - msr spsr_el1, x1 + isb eret diff --git a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c index 531a3d6bf3..85a0edf599 100644 --- a/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c +++ b/MdeModulePkg/Core/Dxe/SysCall/AARCH64/InitializeMsr.c @@ -97,6 +97,7 @@ InitializeMsr ( ) { UINTN Tcr; + UINTN Sctlr; // // If HCR_EL2.NV is 1 and the current Exception level is EL1, // then EL1 read accesses to the CurrentEL register return a value of 0x2 in bits[3:2]. @@ -115,6 +116,10 @@ InitializeMsr ( // // Enable Privileged Access Never feature. // + Sctlr = ArmReadSctlr (); + Sctlr |= SCTLR_EPAN; + ArmWriteSctlr (Sctlr); + ArmSetPan (); } diff --git a/MdePkg/Include/AArch64/AArch64.h b/MdePkg/Include/AArch64/AArch64.h index c30282defa..36f8e95cbf 100644 --- a/MdePkg/Include/AArch64/AArch64.h +++ b/MdePkg/Include/AArch64/AArch64.h @@ -25,6 +25,7 @@ #define AARCH64_CPTR_TFP (1 << 10) #define AARCH64_CPTR_RES1 0x33ff #define AARCH64_CPTR_DEFAULT AARCH64_CPTR_RES1 +#define AARCH64_CPTR_FPEN (3 << 20) // ID_AA64MMFR1 - AArch64 Memory Model Feature Register 0 definitions #define AARCH64_MMFR1_VH (0xF << 8) @@ -46,6 +47,9 @@ #define SCR_FW (1 << 4) #define SCR_AW (1 << 5) +// SCTLR - System Control Register definitions +#define SCTLR_EPAN BIT57 + // MIDR - Main ID Register definitions #define ARM_CPU_TYPE_SHIFT 4 #define ARM_CPU_TYPE_MASK 0xFFF diff --git a/MdePkg/Include/Library/ArmLib.h b/MdePkg/Include/Library/ArmLib.h index aaa3355b7e..11874c4caa 100644 --- a/MdePkg/Include/Library/ArmLib.h +++ b/MdePkg/Include/Library/ArmLib.h @@ -497,7 +497,7 @@ ArmEnableVFP ( VOID ); -UINT32 +UINTN EFIAPI ArmReadSctlr ( VOID @@ -506,7 +506,7 @@ ArmReadSctlr ( VOID EFIAPI ArmWriteSctlr ( - IN UINT32 Value + IN UINTN Value ); UINTN