]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmVirtualizationPkg: add a relocatable version of PrePi
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Sat, 28 Feb 2015 20:26:20 +0000 (20:26 +0000)
committerlersek <lersek@Edk2>
Sat, 28 Feb 2015 20:26:20 +0000 (20:26 +0000)
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
Reviewed-by: Olivier Martin <olivier.martin@arm.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16961 6f19259b-4bc3-4df7-8a09-765794883524

ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ArchPrePi.c [new file with mode: 0644]
ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ModuleEntryPoint.S [new file with mode: 0644]
ArmPlatformPkg/ArmVirtualizationPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf [new file with mode: 0755]
ArmPlatformPkg/ArmVirtualizationPkg/PrePi/LzmaDecompress.h [new file with mode: 0644]
ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.c [new file with mode: 0755]
ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.h [new file with mode: 0644]
ArmPlatformPkg/ArmVirtualizationPkg/PrePi/Scripts/PrePi-PIE.lds [new file with mode: 0644]

diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ArchPrePi.c b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ArchPrePi.c
new file mode 100644 (file)
index 0000000..2179861
--- /dev/null
@@ -0,0 +1,33 @@
+/** @file\r
+*\r
+*  Copyright (c) 2011-2013, ARM Limited. All rights reserved.\r
+*\r
+*  This program and the accompanying materials\r
+*  are licensed and made available under the terms and conditions of the BSD License\r
+*  which accompanies this distribution.  The full text of the license may be found at\r
+*  http://opensource.org/licenses/bsd-license.php\r
+*\r
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+*\r
+**/\r
+\r
+#include "PrePi.h"\r
+\r
+#include <Chipset/AArch64.h>\r
+\r
+VOID\r
+ArchInitialize (\r
+  VOID\r
+  )\r
+{\r
+  // Enable Floating Point\r
+  if (FixedPcdGet32 (PcdVFPEnabled)) {\r
+    ArmEnableVFP ();\r
+  }\r
+\r
+  if (ArmReadCurrentEL () == AARCH64_EL2) {\r
+    // Trap General Exceptions. All exceptions that would be routed to EL1 are routed to EL2\r
+    ArmWriteHcr (ARM_HCR_TGE);\r
+  }\r
+}\r
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ModuleEntryPoint.S b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/AArch64/ModuleEntryPoint.S
new file mode 100644 (file)
index 0000000..568d008
--- /dev/null
@@ -0,0 +1,180 @@
+//\r
+//  Copyright (c) 2011-2013, ARM Limited. All rights reserved.\r
+//  Copyright (c) 2015, Linaro Limited. All rights reserved.\r
+//\r
+//  This program and the accompanying materials\r
+//  are licensed and made available under the terms and conditions of the BSD License\r
+//  which accompanies this distribution.  The full text of the license may be found at\r
+//  http://opensource.org/licenses/bsd-license.php\r
+//\r
+//  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+//  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+//\r
+//\r
+\r
+#include <AsmMacroIoLibV8.h>\r
+#include <Base.h>\r
+#include <Library/PcdLib.h>\r
+#include <AutoGen.h>\r
+\r
+.text\r
+.align 3\r
+\r
+GCC_ASM_IMPORT(ArmPlatformIsPrimaryCore)\r
+GCC_ASM_IMPORT(ArmReadMpidr)\r
+GCC_ASM_IMPORT(ArmPlatformPeiBootAction)\r
+GCC_ASM_IMPORT(ArmPlatformStackSet)\r
+GCC_ASM_EXPORT(_ModuleEntryPoint)\r
+\r
+StartupAddr:        .8byte ASM_PFX(CEntryPoint)\r
+\r
+ASM_PFX(_ModuleEntryPoint):\r
+  //\r
+  // We are built as a ET_DYN PIE executable, so we need to process all\r
+  // relative relocations regardless of whether or not we are executing from\r
+  // the same offset we were linked at. This is only possible if we are\r
+  // running from RAM.\r
+  //\r
+  adr   x8, __reloc_base\r
+  adr   x9, __reloc_start\r
+  adr   x10, __reloc_end\r
+\r
+.Lreloc_loop:\r
+  cmp   x9, x10\r
+  bhs   .Lreloc_done\r
+\r
+  //\r
+  // AArch64 uses the ELF64 RELA format, which means each entry in the\r
+  // relocation table consists of\r
+  //\r
+  //   UINT64 offset          : the relative offset of the value that needs to\r
+  //                            be relocated\r
+  //   UINT64 info            : relocation type and symbol index (the latter is\r
+  //                            not used for R_AARCH64_RELATIVE relocations)\r
+  //   UINT64 addend          : value to be added to the value being relocated\r
+  //\r
+  ldp   x11, x12, [x9], #24   // read offset into x11 and info into x12\r
+  cmp   x12, #0x403           // check info == R_AARCH64_RELATIVE?\r
+  bne   .Lreloc_loop          // not a relative relocation? then skip\r
+\r
+  ldr   x12, [x9, #-8]        // read addend into x12\r
+  add   x12, x12, x8          // add reloc base to addend to get relocated value\r
+  str   x12, [x11, x8]        // write relocated value at offset\r
+  b     .Lreloc_loop\r
+.Lreloc_done:\r
+\r
+  // Do early platform specific actions\r
+  bl    ASM_PFX(ArmPlatformPeiBootAction)\r
+\r
+  // Get ID of this CPU in Multicore system\r
+  bl    ASM_PFX(ArmReadMpidr)\r
+  // Keep a copy of the MpId register value\r
+  mov   x10, x0\r
+\r
+// Check if we can install the stack at the top of the System Memory or if we need\r
+// to install the stacks at the bottom of the Firmware Device (case the FD is located\r
+// at the top of the DRAM)\r
+_SetupStackPosition:\r
+  // Compute Top of System Memory\r
+  ldr   x1, PcdGet64 (PcdSystemMemoryBase)\r
+  ldr   x2, PcdGet64 (PcdSystemMemorySize)\r
+  sub   x2, x2, #1\r
+  add   x1, x1, x2      // x1 = SystemMemoryTop = PcdSystemMemoryBase + PcdSystemMemorySize\r
+\r
+  // Calculate Top of the Firmware Device\r
+  ldr   x2, PcdGet64 (PcdFdBaseAddress)\r
+  ldr   w3, PcdGet32 (PcdFdSize)\r
+  sub   x3, x3, #1\r
+  add   x3, x3, x2      // x3 = FdTop = PcdFdBaseAddress + PcdFdSize\r
+\r
+  // UEFI Memory Size (stacks are allocated in this region)\r
+  LoadConstantToReg (FixedPcdGet32(PcdSystemMemoryUefiRegionSize), x4)\r
+\r
+  //\r
+  // Reserve the memory for the UEFI region (contain stacks on its top)\r
+  //\r
+\r
+  // Calculate how much space there is between the top of the Firmware and the Top of the System Memory\r
+  subs  x0, x1, x3   // x0 = SystemMemoryTop - FdTop\r
+  b.mi  _SetupStack  // Jump if negative (FdTop > SystemMemoryTop). Case when the PrePi is in XIP memory outside of the DRAM\r
+  cmp   x0, x4\r
+  b.ge  _SetupStack\r
+\r
+  // Case the top of stacks is the FdBaseAddress\r
+  mov   x1, x2\r
+\r
+_SetupStack:\r
+  // x1 contains the top of the stack (and the UEFI Memory)\r
+\r
+  // Because the 'push' instruction is equivalent to 'stmdb' (decrement before), we need to increment\r
+  // one to the top of the stack. We check if incrementing one does not overflow (case of DRAM at the\r
+  // top of the memory space)\r
+  adds  x11, x1, #1\r
+  b.cs  _SetupOverflowStack\r
+\r
+_SetupAlignedStack:\r
+  mov   x1, x11\r
+  b     _GetBaseUefiMemory\r
+\r
+_SetupOverflowStack:\r
+  // Case memory at the top of the address space. Ensure the top of the stack is EFI_PAGE_SIZE\r
+  // aligned (4KB)\r
+  LoadConstantToReg (EFI_PAGE_MASK, x11)\r
+  and   x11, x11, x1\r
+  sub   x1, x1, x11\r
+\r
+_GetBaseUefiMemory:\r
+  // Calculate the Base of the UEFI Memory\r
+  sub   x11, x1, x4\r
+\r
+_GetStackBase:\r
+  // r1 = The top of the Mpcore Stacks\r
+  // Stack for the primary core = PrimaryCoreStack\r
+  LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), x2)\r
+  sub   x12, x1, x2\r
+\r
+  // Stack for the secondary core = Number of Cores - 1\r
+  LoadConstantToReg (FixedPcdGet32(PcdCoreCount), x0)\r
+  sub   x0, x0, #1\r
+  LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecondaryStackSize), x1)\r
+  mul   x1, x1, x0\r
+  sub   x12, x12, x1\r
+\r
+  // x12 = The base of the MpCore Stacks (primary stack & secondary stacks)\r
+  mov   x0, x12\r
+  mov   x1, x10\r
+  //ArmPlatformStackSet(StackBase, MpId, PrimaryStackSize, SecondaryStackSize)\r
+  LoadConstantToReg (FixedPcdGet32(PcdCPUCorePrimaryStackSize), x2)\r
+  LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecondaryStackSize), x3)\r
+  bl    ASM_PFX(ArmPlatformStackSet)\r
+\r
+  // Is it the Primary Core ?\r
+  mov   x0, x10\r
+  bl    ASM_PFX(ArmPlatformIsPrimaryCore)\r
+  cmp   x0, #1\r
+  bne   _PrepareArguments\r
+\r
+_ReserveGlobalVariable:\r
+  LoadConstantToReg (FixedPcdGet32(PcdPeiGlobalVariableSize), x0)\r
+  // InitializePrimaryStack($GlobalVariableSize, $Tmp1, $Tmp2)\r
+  InitializePrimaryStack(x0, x1, x2)\r
+\r
+_PrepareArguments:\r
+  mov   x0, x10\r
+  mov   x1, x11\r
+  mov   x2, x12\r
+  mov   x3, sp\r
+\r
+  // Move sec startup address into a data register\r
+  // Ensure we're jumping to FV version of the code (not boot remapped alias)\r
+  ldr   x4, StartupAddr\r
+\r
+  // Jump to PrePiCore C code\r
+  //    x0 = MpId\r
+  //    x1 = UefiMemoryBase\r
+  //    x2 = StacksBase\r
+  //    x3 = GlobalVariableBase\r
+  blr   x4\r
+\r
+_NeverReturn:\r
+  b _NeverReturn\r
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf
new file mode 100755 (executable)
index 0000000..86cf870
--- /dev/null
@@ -0,0 +1,108 @@
+#/** @file\r
+#\r
+#  Copyright (c) 2011-2014, ARM Ltd. All rights reserved.<BR>\r
+#  Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution.  The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#**/\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = ArmVirtPrePiUniCoreRelocatable\r
+  FILE_GUID                      = f7d9fd14-9335-4389-80c5-334d6abfcced\r
+  MODULE_TYPE                    = SEC\r
+  VALID_ARCHITECTURES            = AARCH64\r
+  VERSION_STRING                 = 1.0\r
+\r
+[Sources]\r
+  PrePi.c\r
+\r
+[Sources.AArch64]\r
+  AArch64/ArchPrePi.c\r
+  AArch64/ModuleEntryPoint.S\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  EmbeddedPkg/EmbeddedPkg.dec\r
+  ArmPkg/ArmPkg.dec\r
+  ArmPlatformPkg/ArmPlatformPkg.dec\r
+  ArmPlatformPkg/ArmVirtualizationPkg/ArmVirtualizationPkg.dec\r
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  DebugLib\r
+  ArmLib\r
+  IoLib\r
+  TimerLib\r
+  SerialPortLib\r
+  ExtractGuidedSectionLib\r
+  LzmaDecompressLib\r
+  PeCoffGetEntryPointLib\r
+  PrePiLib\r
+  ArmPlatformLib\r
+  ArmPlatformStackLib\r
+  MemoryAllocationLib\r
+  HobLib\r
+  PrePiHobListPointerLib\r
+  PlatformPeiLib\r
+  MemoryInitPeiLib\r
+\r
+[Ppis]\r
+  gArmMpCoreInfoPpiGuid\r
+\r
+[Guids]\r
+  gArmGlobalVariableGuid\r
+  gArmMpCoreInfoGuid\r
+\r
+[FeaturePcd]\r
+  gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob\r
+  gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores\r
+\r
+[FixedPcd]\r
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString\r
+\r
+  gArmTokenSpaceGuid.PcdVFPEnabled\r
+\r
+  gArmTokenSpaceGuid.PcdFdSize\r
+  gArmTokenSpaceGuid.PcdFvSize\r
+\r
+  gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize\r
+  gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize\r
+\r
+  gArmPlatformTokenSpaceGuid.PcdPeiGlobalVariableSize\r
+\r
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize\r
+\r
+  gArmPlatformTokenSpaceGuid.PcdCoreCount\r
+\r
+  gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize\r
+  gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize\r
+\r
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory\r
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS\r
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType\r
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData\r
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode\r
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode\r
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData\r
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode\r
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData\r
+\r
+[Pcd]\r
+  gArmTokenSpaceGuid.PcdSystemMemoryBase\r
+  gArmTokenSpaceGuid.PcdSystemMemorySize\r
+  gArmVirtualizationTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress\r
+  gArmTokenSpaceGuid.PcdFdBaseAddress\r
+  gArmTokenSpaceGuid.PcdFvBaseAddress\r
+\r
+[BuildOptions]\r
+  GCC:*_*_AARCH64_DLINK_FLAGS = -pie -T $(MODULE_DIR)/Scripts/PrePi-PIE.lds\r
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/LzmaDecompress.h b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/LzmaDecompress.h
new file mode 100644 (file)
index 0000000..a79ff34
--- /dev/null
@@ -0,0 +1,103 @@
+/** @file\r
+  LZMA Decompress Library header file\r
+\r
+  Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __LZMA_DECOMPRESS_H___\r
+#define __LZMA_DECOMPRESS_H___\r
+\r
+/**\r
+  Examines a GUIDed section and returns the size of the decoded buffer and the\r
+  size of an scratch buffer required to actually decode the data in a GUIDed section.\r
+\r
+  Examines a GUIDed section specified by InputSection.\r
+  If GUID for InputSection does not match the GUID that this handler supports,\r
+  then RETURN_UNSUPPORTED is returned.\r
+  If the required information can not be retrieved from InputSection,\r
+  then RETURN_INVALID_PARAMETER is returned.\r
+  If the GUID of InputSection does match the GUID that this handler supports,\r
+  then the size required to hold the decoded buffer is returned in OututBufferSize,\r
+  the size of an optional scratch buffer is returned in ScratchSize, and the Attributes field\r
+  from EFI_GUID_DEFINED_SECTION header of InputSection is returned in SectionAttribute.\r
+\r
+  If InputSection is NULL, then ASSERT().\r
+  If OutputBufferSize is NULL, then ASSERT().\r
+  If ScratchBufferSize is NULL, then ASSERT().\r
+  If SectionAttribute is NULL, then ASSERT().\r
+\r
+\r
+  @param[in]  InputSection       A pointer to a GUIDed section of an FFS formatted file.\r
+  @param[out] OutputBufferSize   A pointer to the size, in bytes, of an output buffer required\r
+                                 if the buffer specified by InputSection were decoded.\r
+  @param[out] ScratchBufferSize  A pointer to the size, in bytes, required as scratch space\r
+                                 if the buffer specified by InputSection were decoded.\r
+  @param[out] SectionAttribute   A pointer to the attributes of the GUIDed section. See the Attributes\r
+                                 field of EFI_GUID_DEFINED_SECTION in the PI Specification.\r
+\r
+  @retval  RETURN_SUCCESS            The information about InputSection was returned.\r
+  @retval  RETURN_UNSUPPORTED        The section specified by InputSection does not match the GUID this handler supports.\r
+  @retval  RETURN_INVALID_PARAMETER  The information can not be retrieved from the section specified by InputSection.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+LzmaGuidedSectionGetInfo (\r
+  IN  CONST VOID  *InputSection,\r
+  OUT UINT32      *OutputBufferSize,\r
+  OUT UINT32      *ScratchBufferSize,\r
+  OUT UINT16      *SectionAttribute\r
+  );\r
+\r
+/**\r
+  Decompress a LZAM compressed GUIDed section into a caller allocated output buffer.\r
+\r
+  Decodes the GUIDed section specified by InputSection.\r
+  If GUID for InputSection does not match the GUID that this handler supports, then RETURN_UNSUPPORTED is returned.\r
+  If the data in InputSection can not be decoded, then RETURN_INVALID_PARAMETER is returned.\r
+  If the GUID of InputSection does match the GUID that this handler supports, then InputSection\r
+  is decoded into the buffer specified by OutputBuffer and the authentication status of this\r
+  decode operation is returned in AuthenticationStatus.  If the decoded buffer is identical to the\r
+  data in InputSection, then OutputBuffer is set to point at the data in InputSection.  Otherwise,\r
+  the decoded data will be placed in caller allocated buffer specified by OutputBuffer.\r
+\r
+  If InputSection is NULL, then ASSERT().\r
+  If OutputBuffer is NULL, then ASSERT().\r
+  If ScratchBuffer is NULL and this decode operation requires a scratch buffer, then ASSERT().\r
+  If AuthenticationStatus is NULL, then ASSERT().\r
+\r
+\r
+  @param[in]  InputSection  A pointer to a GUIDed section of an FFS formatted file.\r
+  @param[out] OutputBuffer  A pointer to a buffer that contains the result of a decode operation.\r
+  @param[out] ScratchBuffer A caller allocated buffer that may be required by this function\r
+                            as a scratch buffer to perform the decode operation.\r
+  @param[out] AuthenticationStatus\r
+                            A pointer to the authentication status of the decoded output buffer.\r
+                            See the definition of authentication status in the EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI\r
+                            section of the PI Specification. EFI_AUTH_STATUS_PLATFORM_OVERRIDE must\r
+                            never be set by this handler.\r
+\r
+  @retval  RETURN_SUCCESS            The buffer specified by InputSection was decoded.\r
+  @retval  RETURN_UNSUPPORTED        The section specified by InputSection does not match the GUID this handler supports.\r
+  @retval  RETURN_INVALID_PARAMETER  The section specified by InputSection can not be decoded.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+LzmaGuidedSectionExtraction (\r
+  IN CONST  VOID    *InputSection,\r
+  OUT       VOID    **OutputBuffer,\r
+  OUT       VOID    *ScratchBuffer,        OPTIONAL\r
+  OUT       UINT32  *AuthenticationStatus\r
+  );\r
+\r
+#endif // __LZMADECOMPRESS_H__\r
+\r
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.c b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.c
new file mode 100755 (executable)
index 0000000..0772805
--- /dev/null
@@ -0,0 +1,203 @@
+/** @file\r
+*\r
+*  Copyright (c) 2011-2014, ARM Limited. All rights reserved.\r
+*\r
+*  This program and the accompanying materials\r
+*  are licensed and made available under the terms and conditions of the BSD License\r
+*  which accompanies this distribution.  The full text of the license may be found at\r
+*  http://opensource.org/licenses/bsd-license.php\r
+*\r
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+*\r
+**/\r
+\r
+#include <PiPei.h>\r
+\r
+#include <Library/PrePiLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/PeCoffGetEntryPointLib.h>\r
+#include <Library/PrePiHobListPointerLib.h>\r
+#include <Library/TimerLib.h>\r
+#include <Library/PerformanceLib.h>\r
+\r
+#include <Ppi/GuidedSectionExtraction.h>\r
+#include <Ppi/ArmMpCoreInfo.h>\r
+#include <Guid/LzmaDecompress.h>\r
+#include <Guid/ArmGlobalVariableHob.h>\r
+\r
+#include "PrePi.h"\r
+#include "LzmaDecompress.h"\r
+\r
+// Not used when PrePi in run in XIP mode\r
+UINTN mGlobalVariableBase = 0;\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+ExtractGuidedSectionLibConstructor (\r
+  VOID\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+LzmaDecompressLibConstructor (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+EFIAPI\r
+BuildGlobalVariableHob (\r
+  IN EFI_PHYSICAL_ADDRESS         GlobalVariableBase,\r
+  IN UINT32                       GlobalVariableSize\r
+  )\r
+{\r
+  ARM_HOB_GLOBAL_VARIABLE  *Hob;\r
+\r
+  Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, sizeof (ARM_HOB_GLOBAL_VARIABLE));\r
+  ASSERT(Hob != NULL);\r
+\r
+  CopyGuid (&(Hob->Header.Name), &gArmGlobalVariableGuid);\r
+  Hob->GlobalVariableBase = GlobalVariableBase;\r
+  Hob->GlobalVariableSize = GlobalVariableSize;\r
+}\r
+\r
+EFI_STATUS\r
+GetPlatformPpi (\r
+  IN  EFI_GUID  *PpiGuid,\r
+  OUT VOID      **Ppi\r
+  )\r
+{\r
+  UINTN                   PpiListSize;\r
+  UINTN                   PpiListCount;\r
+  EFI_PEI_PPI_DESCRIPTOR  *PpiList;\r
+  UINTN                   Index;\r
+\r
+  PpiListSize = 0;\r
+  ArmPlatformGetPlatformPpiList (&PpiListSize, &PpiList);\r
+  PpiListCount = PpiListSize / sizeof(EFI_PEI_PPI_DESCRIPTOR);\r
+  for (Index = 0; Index < PpiListCount; Index++, PpiList++) {\r
+    if (CompareGuid (PpiList->Guid, PpiGuid) == TRUE) {\r
+      *Ppi = PpiList->Ppi;\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+VOID\r
+PrePiMain (\r
+  IN  UINTN                     UefiMemoryBase,\r
+  IN  UINTN                     StacksBase,\r
+  IN  UINTN                     GlobalVariableBase,\r
+  IN  UINT64                    StartTimeStamp\r
+  )\r
+{\r
+  EFI_HOB_HANDOFF_INFO_TABLE*   HobList;\r
+  EFI_STATUS                    Status;\r
+  CHAR8                         Buffer[100];\r
+  UINTN                         CharCount;\r
+  UINTN                         StacksSize;\r
+\r
+  // Initialize the architecture specific bits\r
+  ArchInitialize ();\r
+\r
+  // Initialize the Serial Port\r
+  SerialPortInitialize ();\r
+  CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"UEFI firmware (version %s built at %a on %a)\n\r",\r
+    (CHAR16*)PcdGetPtr(PcdFirmwareVersionString), __TIME__, __DATE__);\r
+  SerialPortWrite ((UINT8 *) Buffer, CharCount);\r
+\r
+  // Declare the PI/UEFI memory region\r
+  HobList = HobConstructor (\r
+    (VOID*)UefiMemoryBase,\r
+    FixedPcdGet32 (PcdSystemMemoryUefiRegionSize),\r
+    (VOID*)UefiMemoryBase,\r
+    (VOID*)StacksBase  // The top of the UEFI Memory is reserved for the stacks\r
+    );\r
+  PrePeiSetHobList (HobList);\r
+\r
+  // Initialize MMU and Memory HOBs (Resource Descriptor HOBs)\r
+  Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  // Create the Stacks HOB (reserve the memory for all stacks)\r
+  StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize);\r
+  BuildStackHob (StacksBase, StacksSize);\r
+\r
+  // Declare the Global Variable HOB\r
+  BuildGlobalVariableHob (GlobalVariableBase, FixedPcdGet32 (PcdPeiGlobalVariableSize));\r
+\r
+  //TODO: Call CpuPei as a library\r
+  BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize));\r
+\r
+  // Set the Boot Mode\r
+  SetBootMode (ArmPlatformGetBootMode ());\r
+\r
+  // Initialize Platform HOBs (CpuHob and FvHob)\r
+  Status = PlatformPeim ();\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  // Now, the HOB List has been initialized, we can register performance information\r
+  PERF_START (NULL, "PEI", NULL, StartTimeStamp);\r
+\r
+  // SEC phase needs to run library constructors by hand.\r
+  ExtractGuidedSectionLibConstructor ();\r
+  LzmaDecompressLibConstructor ();\r
+\r
+  // Build HOBs to pass up our version of stuff the DXE Core needs to save space\r
+  BuildPeCoffLoaderHob ();\r
+  BuildExtractSectionHob (\r
+    &gLzmaCustomDecompressGuid,\r
+    LzmaGuidedSectionGetInfo,\r
+    LzmaGuidedSectionExtraction\r
+    );\r
+\r
+  // Assume the FV that contains the SEC (our code) also contains a compressed FV.\r
+  Status = DecompressFirstFv ();\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  // Load the DXE Core and transfer control to it\r
+  Status = LoadDxeCoreFromFv (NULL, 0);\r
+  ASSERT_EFI_ERROR (Status);\r
+}\r
+\r
+VOID\r
+CEntryPoint (\r
+  IN  UINTN                     MpId,\r
+  IN  UINTN                     UefiMemoryBase,\r
+  IN  UINTN                     StacksBase,\r
+  IN  UINTN                     GlobalVariableBase\r
+  )\r
+{\r
+  UINT64   StartTimeStamp;\r
+\r
+  // Initialize the platform specific controllers\r
+  ArmPlatformInitialize (MpId);\r
+\r
+  if (PerformanceMeasurementEnabled ()) {\r
+    // Initialize the Timer Library to setup the Timer HW controller\r
+    TimerConstructor ();\r
+    // We cannot call yet the PerformanceLib because the HOB List has not been initialized\r
+    StartTimeStamp = GetPerformanceCounter ();\r
+  } else {\r
+    StartTimeStamp = 0;\r
+  }\r
+\r
+  // Data Cache enabled on Primary core when MMU is enabled.\r
+  ArmDisableDataCache ();\r
+  // Invalidate Data cache\r
+  ArmInvalidateDataCache ();\r
+  // Invalidate instruction cache\r
+  ArmInvalidateInstructionCache ();\r
+  // Enable Instruction Caches on all cores.\r
+  ArmEnableInstructionCache ();\r
+\r
+  // Define the Global Variable region\r
+  mGlobalVariableBase = GlobalVariableBase;\r
+\r
+  PrePiMain (UefiMemoryBase, StacksBase, GlobalVariableBase, StartTimeStamp);\r
+\r
+  // DXE Core should always load and never return\r
+  ASSERT (FALSE);\r
+}\r
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.h b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/PrePi.h
new file mode 100644 (file)
index 0000000..517429f
--- /dev/null
@@ -0,0 +1,77 @@
+/** @file\r
+*\r
+*  Copyright (c) 2011-2012, ARM Limited. All rights reserved.\r
+*\r
+*  This program and the accompanying materials\r
+*  are licensed and made available under the terms and conditions of the BSD License\r
+*  which accompanies this distribution.  The full text of the license may be found at\r
+*  http://opensource.org/licenses/bsd-license.php\r
+*\r
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+*\r
+**/\r
+\r
+#ifndef _PREPI_H_\r
+#define _PREPI_H_\r
+\r
+#include <PiPei.h>\r
+\r
+#include <Library/PcdLib.h>\r
+#include <Library/ArmLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/SerialPortLib.h>\r
+#include <Library/ArmPlatformLib.h>\r
+\r
+#define SerialPrint(txt)  SerialPortWrite (txt, AsciiStrLen(txt)+1);\r
+\r
+RETURN_STATUS\r
+EFIAPI\r
+TimerConstructor (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+PrePiMain (\r
+  IN  UINTN                     UefiMemoryBase,\r
+  IN  UINTN                     StacksBase,\r
+  IN  UINTN                     GlobalVariableBase,\r
+  IN  UINT64                    StartTimeStamp\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+MemoryPeim (\r
+  IN EFI_PHYSICAL_ADDRESS       UefiMemoryBase,\r
+  IN UINT64                     UefiMemorySize\r
+  );\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+PlatformPeim (\r
+  VOID\r
+  );\r
+\r
+// Either implemented by PrePiLib or by MemoryInitPei\r
+VOID\r
+BuildMemoryTypeInformationHob (\r
+  VOID\r
+  );\r
+\r
+EFI_STATUS\r
+GetPlatformPpi (\r
+  IN  EFI_GUID  *PpiGuid,\r
+  OUT VOID      **Ppi\r
+  );\r
+\r
+// Initialize the Architecture specific controllers\r
+VOID\r
+ArchInitialize (\r
+  VOID\r
+  );\r
+\r
+#endif /* _PREPI_H_ */\r
diff --git a/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/Scripts/PrePi-PIE.lds b/ArmPlatformPkg/ArmVirtualizationPkg/PrePi/Scripts/PrePi-PIE.lds
new file mode 100644 (file)
index 0000000..32af069
--- /dev/null
@@ -0,0 +1,42 @@
+#/** @file\r
+#\r
+#  Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution.  The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#**/\r
+\r
+SECTIONS\r
+{\r
+  .text 0x0 : {\r
+    PROVIDE(__reloc_base = .);\r
+\r
+    *(.text .text*)\r
+    *(.got .got*)\r
+    *(.rodata .rodata*)\r
+    *(.data .data*)\r
+\r
+    . = ALIGN(0x20);\r
+    PROVIDE(__reloc_start = .);\r
+    *(.rela .rela*)\r
+    PROVIDE(__reloc_end = .);\r
+  }\r
+  .bss ALIGN(0x20) : { *(.bss .bss*) }\r
+\r
+  /DISCARD/ : {\r
+    *(.note.GNU-stack)\r
+    *(.gnu_debuglink)\r
+    *(.interp)\r
+    *(.dynamic)\r
+    *(.dynsym)\r
+    *(.dynstr)\r
+    *(.hash)\r
+    *(.comment)\r
+  }\r
+}\r