From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ard Biesheuvel Subject: [PATCH v3 09/27] ArmVirtualizationPkg: add a relocatable version of PrePi Date: Tue, 3 Feb 2015 19:19:54 +0000 Message-ID: <1422991212-9257-10-git-send-email-ard.biesheuvel@linaro.org> References: <1422991212-9257-1-git-send-email-ard.biesheuvel@linaro.org> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1422991212-9257-1-git-send-email-ard.biesheuvel@linaro.org> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: edk2-devel@lists.sourceforge.net, lersek@redhat.com, olivier.martin@arm.com, roy.franz@linaro.org, leif.lindholm@linaro.org, stefano.stabellini@eu.citrix.com, ian.campbell@citrix.com, anthony.perard@citrix.com, christoffer.dall@linaro.org, xen-devel@lists.xen.org, ilias.biris@linaro.org, julien.grall@linaro.org Cc: Ard Biesheuvel List-Id: xen-devel@lists.xenproject.org This patch introduces a relocatable PrePi, which can execute from arbitrary offsets in RAM. This is intendend to be run from a boot loader which passes a description of the actual platform in a device tree, for instance. This module is based on the PrePi implementations residing under ArmPlatformPkg. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel --- .../ArmVirtualizationPkg/PrePi/AArch64/ArchPrePi.c | 33 ++++ .../PrePi/AArch64/ModuleEntryPoint.S | 170 +++++++++++++++++ .../PrePi/ArmVirtPrePiUniCoreRelocatable.inf | 107 +++++++++++ .../ArmVirtualizationPkg/PrePi/LzmaDecompress.h | 103 +++++++++++ ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.c | 203 +++++++++++++++++++++ ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.h | 77 ++++++++ .../PrePi/Scripts/PrePi-PIE.lds | 28 +++ 7 files changed, 721 insertions(+) create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ArchPrePi.c create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ModuleEntryPoint.S create mode 100755 ArmPlatformPkg/ArmVirtualizationPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/PrePi/LzmaDecompress.h create mode 100755 ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.c create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.h create mode 100644 ArmPlatformPkg/ArmVirtualizationPkg/PrePi/Scripts/PrePi-PIE.lds diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ArchPrePi.c b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ArchPrePi.c new file mode 100644 index 000000000000..217986107e44 --- /dev/null +++ b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ArchPrePi.c @@ -0,0 +1,33 @@ +/** @file +* +* Copyright (c) 2011-2013, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#include "PrePi.h" + +#include + +VOID +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/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ModuleEntryPoint.S b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ModuleEntryPoint.S new file mode 100644 index 000000000000..963249626d2c --- /dev/null +++ b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ModuleEntryPoint.S @@ -0,0 +1,170 @@ +// +// Copyright (c) 2011-2013, ARM Limited. All rights reserved. +// +// This program and the accompanying materials +// are licensed and made available under the terms and conditions of the BSD License +// which accompanies this distribution. The full text of the license may be found at +// http://opensource.org/licenses/bsd-license.php +// +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +// +// + +#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) + +StartupAddr: .8byte ASM_PFX(CEntryPoint) + +ASM_PFX(_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 + // the same offset we were linked at. This is only possible if we are + // running from RAM. + // + adr x8, __reloc_base + adr x9, __reloc_start + adr x10, __reloc_end + +.Lreloc_loop: + cmp x9, x10 + bhs .Lreloc_done + + ldp x11, x12, [x9], #24 + cmp x12, #0x403 // R_AARCH64_RELATIVE + bne .Lreloc_loop + + ldr x12, [x9, #-8] + add x12, x12, x8 + str x12, [x11, x8] + b .Lreloc_loop +.Lreloc_done: + + // Do early platform specific actions + bl ASM_PFX(ArmPlatformPeiBootAction) + + // Get ID of this CPU in Multicore system + bl ASM_PFX(ArmReadMpidr) + // Keep a copy of the MpId register value + mov x10, x0 + +_SetSVCMode: +// 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 +// at the top of the DRAM) +_SetupStackPosition: + // Compute Top of System Memory + ldr x1, PcdGet64 (PcdSystemMemoryBase) + ldr x2, PcdGet64 (PcdSystemMemorySize) + sub x2, x2, #1 + add x1, x1, x2 // x1 = SystemMemoryTop = PcdSystemMemoryBase + PcdSystemMemorySize + + // Calculate Top of the Firmware Device + ldr x2, PcdGet64 (PcdFdBaseAddress) + ldr w3, PcdGet32 (PcdFdSize) + sub x3, x3, #1 + add x3, x3, x2 // x3 = FdTop = PcdFdBaseAddress + PcdFdSize + + // UEFI Memory Size (stacks are allocated in this region) + LoadConstantToReg (FixedPcdGet32(PcdSystemMemoryUefiRegionSize), x4) + + // + // Reserve the memory for the UEFI region (contain stacks on its top) + // + + // Calculate how much space there is between the top of the Firmware and the Top of the System Memory + subs x0, x1, x3 // x0 = SystemMemoryTop - FdTop + b.mi _SetupStack // Jump if negative (FdTop > SystemMemoryTop). Case when the PrePi is in XIP memory outside of the DRAM + cmp x0, x4 + b.ge _SetupStack + + // Case the top of stacks is the FdBaseAddress + mov x1, x2 + +_SetupStack: + // x1 contains the top of the stack (and the UEFI Memory) + + // 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 + b.cs _SetupOverflowStack + +_SetupAlignedStack: + mov x1, x11 + 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 + +_GetBaseUefiMemory: + // Calculate the Base of the UEFI Memory + sub x11, x1, x4 + +_GetStackBase: + // r1 = The top of the Mpcore Stacks + // 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 + + // Jump to PrePiCore C code + // x0 = MpId + // x1 = UefiMemoryBase + // x2 = StacksBase + // x3 = GlobalVariableBase + blr x4 + +_NeverReturn: + b _NeverReturn diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf new file mode 100755 index 000000000000..f8b06898ec0c --- /dev/null +++ b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf @@ -0,0 +1,107 @@ +#/** @file +# +# Copyright (c) 2011-2014, ARM Ltd. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = ArmVirtPrePiUniCoreRelocatable + FILE_GUID = f7d9fd14-9335-4389-80c5-334d6abfcced + MODULE_TYPE = SEC + VALID_ARCHITECTURES = AARCH64 + VERSION_STRING = 1.0 + +[Sources] + PrePi.c + +[Sources.AArch64] + AArch64/ArchPrePi.c + AArch64/ModuleEntryPoint.S + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec + IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec + +[LibraryClasses] + BaseLib + DebugLib + ArmLib + IoLib + TimerLib + SerialPortLib + ExtractGuidedSectionLib + LzmaDecompressLib + PeCoffGetEntryPointLib + PrePiLib + ArmPlatformLib + ArmPlatformStackLib + MemoryAllocationLib + HobLib + PrePiHobListPointerLib + PlatformPeiLib + MemoryInitPeiLib + +[Ppis] + gArmMpCoreInfoPpiGuid + +[Guids] + gArmGlobalVariableGuid + gArmMpCoreInfoGuid + +[FeaturePcd] + gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob + gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores + +[FixedPcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString + + gArmTokenSpaceGuid.PcdVFPEnabled + + gArmTokenSpaceGuid.PcdFdSize + gArmTokenSpaceGuid.PcdFvSize + + gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize + gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize + + gArmPlatformTokenSpaceGuid.PcdPeiGlobalVariableSize + + gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize + + gArmPlatformTokenSpaceGuid.PcdCoreCount + + gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize + gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize + + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode + gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData + +[Pcd] + gArmTokenSpaceGuid.PcdSystemMemoryBase + gArmTokenSpaceGuid.PcdSystemMemorySize + gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress + gArmTokenSpaceGuid.PcdFdBaseAddress + gArmTokenSpaceGuid.PcdFvBaseAddress + +[BuildOptions] + GCC:*_*_AARCH64_DLINK_FLAGS = -pie -T $(MODULE_DIR)/Scripts/PrePi-PIE.lds diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/LzmaDecompress.h b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/LzmaDecompress.h new file mode 100644 index 000000000000..a79ff343d231 --- /dev/null +++ b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/LzmaDecompress.h @@ -0,0 +1,103 @@ +/** @file + LZMA Decompress Library header file + + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __LZMA_DECOMPRESS_H___ +#define __LZMA_DECOMPRESS_H___ + +/** + Examines a GUIDed section and returns the size of the decoded buffer and the + size of an scratch buffer required to actually decode the data in a GUIDed section. + + Examines a GUIDed section specified by InputSection. + If GUID for InputSection does not match the GUID that this handler supports, + then RETURN_UNSUPPORTED is returned. + If the required information can not be retrieved from InputSection, + then RETURN_INVALID_PARAMETER is returned. + If the GUID of InputSection does match the GUID that this handler supports, + then the size required to hold the decoded buffer is returned in OututBufferSize, + the size of an optional scratch buffer is returned in ScratchSize, and the Attributes field + from EFI_GUID_DEFINED_SECTION header of InputSection is returned in SectionAttribute. + + If InputSection is NULL, then ASSERT(). + If OutputBufferSize is NULL, then ASSERT(). + If ScratchBufferSize is NULL, then ASSERT(). + If SectionAttribute is NULL, then ASSERT(). + + + @param[in] InputSection A pointer to a GUIDed section of an FFS formatted file. + @param[out] OutputBufferSize A pointer to the size, in bytes, of an output buffer required + if the buffer specified by InputSection were decoded. + @param[out] ScratchBufferSize A pointer to the size, in bytes, required as scratch space + if the buffer specified by InputSection were decoded. + @param[out] SectionAttribute A pointer to the attributes of the GUIDed section. See the Attributes + field of EFI_GUID_DEFINED_SECTION in the PI Specification. + + @retval RETURN_SUCCESS The information about InputSection was returned. + @retval RETURN_UNSUPPORTED The section specified by InputSection does not match the GUID this handler supports. + @retval RETURN_INVALID_PARAMETER The information can not be retrieved from the section specified by InputSection. + +**/ +RETURN_STATUS +EFIAPI +LzmaGuidedSectionGetInfo ( + IN CONST VOID *InputSection, + OUT UINT32 *OutputBufferSize, + OUT UINT32 *ScratchBufferSize, + OUT UINT16 *SectionAttribute + ); + +/** + Decompress a LZAM compressed GUIDed section into a caller allocated output buffer. + + Decodes the GUIDed section specified by InputSection. + If GUID for InputSection does not match the GUID that this handler supports, then RETURN_UNSUPPORTED is returned. + If the data in InputSection can not be decoded, then RETURN_INVALID_PARAMETER is returned. + If the GUID of InputSection does match the GUID that this handler supports, then InputSection + is decoded into the buffer specified by OutputBuffer and the authentication status of this + decode operation is returned in AuthenticationStatus. If the decoded buffer is identical to the + data in InputSection, then OutputBuffer is set to point at the data in InputSection. Otherwise, + the decoded data will be placed in caller allocated buffer specified by OutputBuffer. + + If InputSection is NULL, then ASSERT(). + If OutputBuffer is NULL, then ASSERT(). + If ScratchBuffer is NULL and this decode operation requires a scratch buffer, then ASSERT(). + If AuthenticationStatus is NULL, then ASSERT(). + + + @param[in] InputSection A pointer to a GUIDed section of an FFS formatted file. + @param[out] OutputBuffer A pointer to a buffer that contains the result of a decode operation. + @param[out] ScratchBuffer A caller allocated buffer that may be required by this function + as a scratch buffer to perform the decode operation. + @param[out] AuthenticationStatus + A pointer to the authentication status of the decoded output buffer. + See the definition of authentication status in the EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI + section of the PI Specification. EFI_AUTH_STATUS_PLATFORM_OVERRIDE must + never be set by this handler. + + @retval RETURN_SUCCESS The buffer specified by InputSection was decoded. + @retval RETURN_UNSUPPORTED The section specified by InputSection does not match the GUID this handler supports. + @retval RETURN_INVALID_PARAMETER The section specified by InputSection can not be decoded. + +**/ +RETURN_STATUS +EFIAPI +LzmaGuidedSectionExtraction ( + IN CONST VOID *InputSection, + OUT VOID **OutputBuffer, + OUT VOID *ScratchBuffer, OPTIONAL + OUT UINT32 *AuthenticationStatus + ); + +#endif // __LZMADECOMPRESS_H__ + diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.c b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.c new file mode 100755 index 000000000000..0772805890f2 --- /dev/null +++ b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.c @@ -0,0 +1,203 @@ +/** @file +* +* Copyright (c) 2011-2014, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "PrePi.h" +#include "LzmaDecompress.h" + +// Not used when PrePi in run in XIP mode +UINTN mGlobalVariableBase = 0; + +EFI_STATUS +EFIAPI +ExtractGuidedSectionLibConstructor ( + VOID + ); + +EFI_STATUS +EFIAPI +LzmaDecompressLibConstructor ( + VOID + ); + +VOID +EFIAPI +BuildGlobalVariableHob ( + IN EFI_PHYSICAL_ADDRESS GlobalVariableBase, + IN UINT32 GlobalVariableSize + ) +{ + ARM_HOB_GLOBAL_VARIABLE *Hob; + + Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, sizeof (ARM_HOB_GLOBAL_VARIABLE)); + ASSERT(Hob != NULL); + + CopyGuid (&(Hob->Header.Name), &gArmGlobalVariableGuid); + Hob->GlobalVariableBase = GlobalVariableBase; + Hob->GlobalVariableSize = GlobalVariableSize; +} + +EFI_STATUS +GetPlatformPpi ( + IN EFI_GUID *PpiGuid, + OUT VOID **Ppi + ) +{ + UINTN PpiListSize; + UINTN PpiListCount; + EFI_PEI_PPI_DESCRIPTOR *PpiList; + UINTN Index; + + PpiListSize = 0; + ArmPlatformGetPlatformPpiList (&PpiListSize, &PpiList); + PpiListCount = PpiListSize / sizeof(EFI_PEI_PPI_DESCRIPTOR); + for (Index = 0; Index < PpiListCount; Index++, PpiList++) { + if (CompareGuid (PpiList->Guid, PpiGuid) == TRUE) { + *Ppi = PpiList->Ppi; + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} + +VOID +PrePiMain ( + IN UINTN UefiMemoryBase, + IN UINTN StacksBase, + IN UINTN GlobalVariableBase, + IN UINT64 StartTimeStamp + ) +{ + EFI_HOB_HANDOFF_INFO_TABLE* HobList; + EFI_STATUS Status; + CHAR8 Buffer[100]; + UINTN CharCount; + UINTN StacksSize; + + // Initialize the architecture specific bits + ArchInitialize (); + + // Initialize the Serial Port + SerialPortInitialize (); + CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"UEFI firmware (version %s built at %a on %a)\n\r", + (CHAR16*)PcdGetPtr(PcdFirmwareVersionString), __TIME__, __DATE__); + SerialPortWrite ((UINT8 *) Buffer, CharCount); + + // Declare the PI/UEFI memory region + HobList = HobConstructor ( + (VOID*)UefiMemoryBase, + FixedPcdGet32 (PcdSystemMemoryUefiRegionSize), + (VOID*)UefiMemoryBase, + (VOID*)StacksBase // The top of the UEFI Memory is reserved for the stacks + ); + PrePeiSetHobList (HobList); + + // Initialize MMU and Memory HOBs (Resource Descriptor HOBs) + Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)); + ASSERT_EFI_ERROR (Status); + + // Create the Stacks HOB (reserve the memory for all stacks) + StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize); + BuildStackHob (StacksBase, StacksSize); + + // Declare the Global Variable HOB + BuildGlobalVariableHob (GlobalVariableBase, FixedPcdGet32 (PcdPeiGlobalVariableSize)); + + //TODO: Call CpuPei as a library + BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize)); + + // Set the Boot Mode + SetBootMode (ArmPlatformGetBootMode ()); + + // Initialize Platform HOBs (CpuHob and FvHob) + Status = PlatformPeim (); + ASSERT_EFI_ERROR (Status); + + // Now, the HOB List has been initialized, we can register performance information + PERF_START (NULL, "PEI", NULL, StartTimeStamp); + + // SEC phase needs to run library constructors by hand. + ExtractGuidedSectionLibConstructor (); + LzmaDecompressLibConstructor (); + + // Build HOBs to pass up our version of stuff the DXE Core needs to save space + BuildPeCoffLoaderHob (); + BuildExtractSectionHob ( + &gLzmaCustomDecompressGuid, + LzmaGuidedSectionGetInfo, + LzmaGuidedSectionExtraction + ); + + // Assume the FV that contains the SEC (our code) also contains a compressed FV. + Status = DecompressFirstFv (); + ASSERT_EFI_ERROR (Status); + + // Load the DXE Core and transfer control to it + Status = LoadDxeCoreFromFv (NULL, 0); + ASSERT_EFI_ERROR (Status); +} + +VOID +CEntryPoint ( + IN UINTN MpId, + IN UINTN UefiMemoryBase, + IN UINTN StacksBase, + IN UINTN GlobalVariableBase + ) +{ + UINT64 StartTimeStamp; + + // Initialize the platform specific controllers + ArmPlatformInitialize (MpId); + + if (PerformanceMeasurementEnabled ()) { + // Initialize the Timer Library to setup the Timer HW controller + TimerConstructor (); + // We cannot call yet the PerformanceLib because the HOB List has not been initialized + StartTimeStamp = GetPerformanceCounter (); + } else { + StartTimeStamp = 0; + } + + // Data Cache enabled on Primary core when MMU is enabled. + ArmDisableDataCache (); + // Invalidate Data cache + ArmInvalidateDataCache (); + // Invalidate instruction cache + ArmInvalidateInstructionCache (); + // Enable Instruction Caches on all cores. + ArmEnableInstructionCache (); + + // Define the Global Variable region + mGlobalVariableBase = GlobalVariableBase; + + PrePiMain (UefiMemoryBase, StacksBase, GlobalVariableBase, StartTimeStamp); + + // DXE Core should always load and never return + ASSERT (FALSE); +} diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.h b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.h new file mode 100644 index 000000000000..517429fab9a4 --- /dev/null +++ b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.h @@ -0,0 +1,77 @@ +/** @file +* +* Copyright (c) 2011-2012, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#ifndef _PREPI_H_ +#define _PREPI_H_ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SerialPrint(txt) SerialPortWrite (txt, AsciiStrLen(txt)+1); + +RETURN_STATUS +EFIAPI +TimerConstructor ( + VOID + ); + +VOID +PrePiMain ( + IN UINTN UefiMemoryBase, + IN UINTN StacksBase, + IN UINTN GlobalVariableBase, + IN UINT64 StartTimeStamp + ); + +EFI_STATUS +EFIAPI +MemoryPeim ( + IN EFI_PHYSICAL_ADDRESS UefiMemoryBase, + IN UINT64 UefiMemorySize + ); + +EFI_STATUS +EFIAPI +PlatformPeim ( + VOID + ); + +// Either implemented by PrePiLib or by MemoryInitPei +VOID +BuildMemoryTypeInformationHob ( + VOID + ); + +EFI_STATUS +GetPlatformPpi ( + IN EFI_GUID *PpiGuid, + OUT VOID **Ppi + ); + +// Initialize the Architecture specific controllers +VOID +ArchInitialize ( + VOID + ); + +#endif /* _PREPI_H_ */ diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/Scripts/PrePi-PIE.lds b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/Scripts/PrePi-PIE.lds new file mode 100644 index 000000000000..880f9b114ddd --- /dev/null +++ b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/Scripts/PrePi-PIE.lds @@ -0,0 +1,28 @@ +SECTIONS +{ + .text 0x0 : { + PROVIDE(__reloc_base = .); + + *(.text .text*) + *(.got .got*) + *(.rodata .rodata*) + *(.data .data*) + + . = ALIGN(0x20); + PROVIDE(__reloc_start = .); + *(.rela .rela*) + PROVIDE(__reloc_end = .); + } + .bss ALIGN(0x20) : { *(.bss .bss*) } + + /DISCARD/ : { + *(.note.GNU-stack) + *(.gnu_debuglink) + *(.interp) + *(.dynamic) + *(.dynsym) + *(.dynstr) + *(.hash) + *(.comment) + } +} -- 1.8.3.2