From 5bea69123349ef3c02e5d8a49ceaae971975ba90 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Fri, 7 Jun 2024 10:02:25 +0200 Subject: ArmVirtPkg/PrePi: Enable VFP before calling into C code When building ArmVirtQemuKernel with CLANGDWARF (which does not require a GCC workaround where -mgeneral-regs-only is needed to ensure -mstrict-align works as expected), the C code invoked from the PrePi startup code may contain instructions that access the FP/SIMD register file. This means that the FP/SIMD must be enabled before making such calls, and this is currently not the case. So fix that, by moving the call to ArmEnableVFP() early into the asm startup code. Signed-off-by: Ard Biesheuvel --- ArmVirtPkg/PrePi/AArch64/ArchPrePi.c | 5 ---- ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S | 41 +++++++++++++++++------------ 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/ArmVirtPkg/PrePi/AArch64/ArchPrePi.c b/ArmVirtPkg/PrePi/AArch64/ArchPrePi.c index 9cab88c..a02c2ad 100644 --- a/ArmVirtPkg/PrePi/AArch64/ArchPrePi.c +++ b/ArmVirtPkg/PrePi/AArch64/ArchPrePi.c @@ -15,11 +15,6 @@ ArchInitialize ( VOID ) { - // Enable Floating Point - if (FixedPcdGet32 (PcdVFPEnabled)) { - ArmEnableVFP (); - } - if (ArmReadCurrentEL () == AARCH64_EL2) { // Trap General Exceptions. All exceptions that would be routed to EL1 are routed to EL2 ArmWriteHcr (ARM_HCR_TGE); diff --git a/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S b/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S index 01623b6..fc06c28 100644 --- a/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S +++ b/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S @@ -9,6 +9,23 @@ #include ASM_FUNC(_ModuleEntryPoint) + // + // If we are booting from RAM using the Linux kernel boot protocol, x0 will + // point to the DTB image in memory. Otherwise, use the default value defined + // by the platform. + // + cbnz x0, 0f + ldr x0, PcdGet64 (PcdDeviceTreeInitialBaseAddress) + +0:mov x28, x0 // preserve DTB pointer + mov x27, x1 // preserve base of image pointer + +#if (FixedPcdGet32 (PcdVFPEnabled)) + // Enable Floating Point. This needs to be done before entering C code, which + // may use FP/SIMD registers. + bl ArmEnableVFP +#endif + bl ASM_PFX(DiscoverDramFromDt) // Get ID of this CPU in Multicore system @@ -95,28 +112,18 @@ _NeverReturn: // VOID // DiscoverDramFromDt ( -// VOID *DeviceTreeBaseAddress, // passed by loader in x0 -// VOID *ImageBase // passed by FDF trampoline in x1 +// VOID *DeviceTreeBaseAddress, // passed by loader in x0, preserved in x28 +// VOID *ImageBase // passed by FDF trampoline in x1, preserved in x27 // ); ASM_PFX(DiscoverDramFromDt): - // - // If we are booting from RAM using the Linux kernel boot protocol, x0 will - // point to the DTB image in memory. Otherwise, use the default value defined - // by the platform. - // - cbnz x0, 0f - ldr x0, PcdGet64 (PcdDeviceTreeInitialBaseAddress) - -0:mov x29, x30 // preserve LR - mov x28, x0 // preserve DTB pointer - mov x27, x1 // preserve base of image pointer + mov x29, x30 // preserve LR // - // The base of the runtime image has been preserved in x1. Check whether + // The base of the runtime image has been preserved in x27. Check whether // the expected magic number can be found in the header. // ldr w8, .LArm64LinuxMagic - ldr w9, [x1, #0x38] + ldr w9, [x27, #0x38] cmp w8, w9 bne .Lout @@ -132,8 +139,8 @@ ASM_PFX(DiscoverDramFromDt): ldr x6, [x8] ldr x7, [x9] sub x7, x7, x6 - add x7, x7, x1 - str x1, [x8] + add x7, x7, x27 + str x27, [x8] str x7, [x9] // -- cgit v1.1