[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v3 09/27] ArmVirtualizationPkg: add a relocatable version of PrePi



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 <ard.biesheuvel@xxxxxxxxxx>
---
  .../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


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.