X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=ArmVirtPkg%2FPrePi%2FAArch64%2FModuleEntryPoint.S;h=99658b9abc7b2cc45fc85539b5edd893cd4ac15d;hb=81c6f1dfbac18d6469686f99ee0d9fb944de0350;hp=f0cf865b3c9375a8cd5eecef59c3a9b801967bd5;hpb=03931908e2e03240ede1ca509d6beda22a855d54;p=mirror_edk2.git diff --git a/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S b/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S index f0cf865b3c..99658b9abc 100644 --- a/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S +++ b/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S @@ -1,6 +1,6 @@ // // Copyright (c) 2011-2013, ARM Limited. All rights reserved. -// Copyright (c) 2015, Linaro Limited. All rights reserved. +// Copyright (c) 2015-2016, Linaro Limited. All rights reserved. // // This program and the accompanying materials // are licensed and made available under the terms and conditions of the BSD License @@ -13,24 +13,8 @@ // #include -#include -#include -#include -.text -.align 3 - -GCC_ASM_IMPORT(ArmPlatformIsPrimaryCore) -GCC_ASM_IMPORT(ArmReadMpidr) -GCC_ASM_IMPORT(ArmPlatformPeiBootAction) -GCC_ASM_IMPORT(ArmPlatformStackSet) -GCC_ASM_EXPORT(_ModuleEntryPoint) -ASM_GLOBAL ASM_PFX(mSystemMemoryEnd) - -StartupAddr: .8byte ASM_PFX(CEntryPoint) -ASM_PFX(mSystemMemoryEnd): .8byte 0 - -ASM_PFX(_ModuleEntryPoint): +ASM_FUNC(_ModuleEntryPoint) // // We are built as a ET_DYN PIE executable, so we need to process all // relative relocations regardless of whether or not we are executing from @@ -65,13 +49,12 @@ ASM_PFX(_ModuleEntryPoint): b .Lreloc_loop .Lreloc_done: - // Do early platform specific actions - bl ASM_PFX(ArmPlatformPeiBootAction) + bl ASM_PFX(DiscoverDramFromDt) // Get ID of this CPU in Multicore system bl ASM_PFX(ArmReadMpidr) // Keep a copy of the MpId register value - mov x10, x0 + mov x20, x0 // Check if we can install the stack at the top of the System Memory or if we need // to install the stacks at the bottom of the Firmware Device (case the FD is located @@ -82,17 +65,14 @@ _SetupStackPosition: ldr x2, PcdGet64 (PcdSystemMemorySize) sub x2, x2, #1 add x1, x1, x2 // x1 = SystemMemoryTop = PcdSystemMemoryBase + PcdSystemMemorySize - adr x2, mSystemMemoryEnd - str x1, [x2] // Calculate Top of the Firmware Device ldr x2, PcdGet64 (PcdFdBaseAddress) - ldr w3, PcdGet32 (PcdFdSize) - sub x3, x3, #1 + MOV32 (w3, FixedPcdGet32 (PcdFdSize) - 1) add x3, x3, x2 // x3 = FdTop = PcdFdBaseAddress + PcdFdSize // UEFI Memory Size (stacks are allocated in this region) - LoadConstantToReg (FixedPcdGet32(PcdSystemMemoryUefiRegionSize), x4) + MOV32 (x4, FixedPcdGet32(PcdSystemMemoryUefiRegionSize)) // // Reserve the memory for the UEFI region (contain stacks on its top) @@ -113,72 +93,116 @@ _SetupStack: // Because the 'push' instruction is equivalent to 'stmdb' (decrement before), we need to increment // one to the top of the stack. We check if incrementing one does not overflow (case of DRAM at the // top of the memory space) - adds x11, x1, #1 + adds x21, x1, #1 b.cs _SetupOverflowStack _SetupAlignedStack: - mov x1, x11 + mov x1, x21 b _GetBaseUefiMemory _SetupOverflowStack: // Case memory at the top of the address space. Ensure the top of the stack is EFI_PAGE_SIZE // aligned (4KB) - LoadConstantToReg (EFI_PAGE_MASK, x11) - and x11, x11, x1 - sub x1, x1, x11 + and x1, x1, ~EFI_PAGE_MASK _GetBaseUefiMemory: // Calculate the Base of the UEFI Memory - sub x11, x1, x4 + sub x21, x1, x4 _GetStackBase: // r1 = The top of the Mpcore Stacks + mov sp, x1 + // Stack for the primary core = PrimaryCoreStack - LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), x2) - sub x12, x1, x2 - - // Stack for the secondary core = Number of Cores - 1 - LoadConstantToReg (FixedPcdGet32(PcdCoreCount), x0) - sub x0, x0, #1 - LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecondaryStackSize), x1) - mul x1, x1, x0 - sub x12, x12, x1 - - // x12 = The base of the MpCore Stacks (primary stack & secondary stacks) - mov x0, x12 - mov x1, x10 - //ArmPlatformStackSet(StackBase, MpId, PrimaryStackSize, SecondaryStackSize) - LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), x2) - LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecondaryStackSize), x3) - bl ASM_PFX(ArmPlatformStackSet) - - // Is it the Primary Core ? - mov x0, x10 - bl ASM_PFX(ArmPlatformIsPrimaryCore) - cmp x0, #1 - bne _PrepareArguments - -_ReserveGlobalVariable: - LoadConstantToReg (FixedPcdGet32(PcdPeiGlobalVariableSize), x0) - // InitializePrimaryStack($GlobalVariableSize, $Tmp1, $Tmp2) - InitializePrimaryStack(x0, x1, x2) - -_PrepareArguments: - mov x0, x10 - mov x1, x11 - mov x2, x12 - mov x3, sp - - // Move sec startup address into a data register - // Ensure we're jumping to FV version of the code (not boot remapped alias) - ldr x4, StartupAddr + MOV32 (x2, FixedPcdGet32(PcdCPUCorePrimaryStackSize)) + sub x22, x1, x2 + + mov x0, x20 + mov x1, x21 + mov x2, x22 + + // Set the frame pointer to NULL so any backtraces terminate here + mov x29, xzr // Jump to PrePiCore C code // x0 = MpId // x1 = UefiMemoryBase // x2 = StacksBase - // x3 = GlobalVariableBase - blr x4 + bl ASM_PFX(CEntryPoint) _NeverReturn: b _NeverReturn + +// VOID +// DiscoverDramFromDt ( +// VOID *DeviceTreeBaseAddress, // passed by loader in x0 +// VOID *ImageBase // passed by FDF trampoline in x1 +// ); +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 + + // + // The base of the runtime image has been preserved in x1. Check whether + // the expected magic number can be found in the header. + // + ldr w8, .LArm64LinuxMagic + ldr w9, [x1, #0x38] + cmp w8, w9 + bne .Lout + + // + // + // OK, so far so good. We have confirmed that we likely have a DTB and are + // booting via the arm64 Linux boot protocol. Update the base-of-image PCD + // to the actual relocated value, and add the shift of PcdFdBaseAddress to + // PcdFvBaseAddress as well + // + adr x8, PcdGet64 (PcdFdBaseAddress) + adr x9, PcdGet64 (PcdFvBaseAddress) + ldr x6, [x8] + ldr x7, [x9] + sub x7, x7, x6 + add x7, x7, x1 + str x1, [x8] + str x7, [x9] + + // + // Discover the memory size and offset from the DTB, and record in the + // respective PCDs. This will also return false if a corrupt DTB is + // encountered. Since we are calling a C function, use the window at the + // beginning of the FD image as a temp stack. + // + adr x1, PcdGet64 (PcdSystemMemoryBase) + adr x2, PcdGet64 (PcdSystemMemorySize) + mov sp, x7 + bl FindMemnode + cbz x0, .Lout + + // + // Copy the DTB to the slack space right after the 64 byte arm64/Linux style + // image header at the base of this image (defined in the FDF), and record the + // pointer in PcdDeviceTreeInitialBaseAddress. + // + adr x8, PcdGet64 (PcdDeviceTreeInitialBaseAddress) + add x27, x27, #0x40 + str x27, [x8] + + mov x0, x27 + mov x1, x28 + bl CopyFdt + +.Lout: + ret x29 + +.LArm64LinuxMagic: + .byte 0x41, 0x52, 0x4d, 0x64