The main comments about this patch is about the ELF Relocation Table
manipulation.
The code looks alright but I had to guess what some magic offsets were
meaning.

On 03/02/15 19:19, Ard Biesheuvel wrote:
> 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 <[email protected]>
> ---
>   .../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 <Chipset/AArch64.h>
> +
> +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 <AsmMacroIoLibV8.h>
> +#include <Base.h>
> +#include <Library/PcdLib.h>
> +#include <AutoGen.h>
> +
> +.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
Add a comment to explain where the '24' comes from (3 fields in Elf32_Rela)
> +  cmp   x12, #0x403    // R_AARCH64_RELATIVE
> +  bne   .Lreloc_loop
> +
> +  ldr   x12, [x9, #-8]
> +  add   x12, x12, x8
> +  str   x12, [x11, x8]
Add a comment to explain the different fields of the structure you are
manipulating.
> +  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.<BR>
> +#
> +#  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.<BR>
> +  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 <PiPei.h>
> +
> +#include <Library/PrePiLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/PeCoffGetEntryPointLib.h>
> +#include <Library/PrePiHobListPointerLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/PerformanceLib.h>
> +
> +#include <Ppi/GuidedSectionExtraction.h>
> +#include <Ppi/ArmMpCoreInfo.h>
> +#include <Guid/LzmaDecompress.h>
> +#include <Guid/ArmGlobalVariableHob.h>
> +
> +#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 <PiPei.h>
> +
> +#include <Library/PcdLib.h>
> +#include <Library/ArmLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/SerialPortLib.h>
> +#include <Library/ArmPlatformLib.h>
> +
> +#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
>
>


-- IMPORTANT NOTICE: The contents of this email and any attachments are 
confidential and may also be privileged. If you are not the intended recipient, 
please notify the sender immediately and do not disclose the contents to any 
other person, use it for any purpose, or store or copy the information in any 
medium.  Thank you.

ARM Limited, Registered office 110 Fulbourn Road, Cambridge CB1 9NJ, Registered 
in England & Wales, Company No:  2557590
ARM Holdings plc, Registered office 110 Fulbourn Road, Cambridge CB1 9NJ, 
Registered in England & Wales, Company No:  2548782


------------------------------------------------------------------------------
Dive into the World of Parallel Programming. The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net/
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to