aboutsummaryrefslogtreecommitdiffstats
path: root/roms/edk2/ArmVirtPkg/PrePi
diff options
context:
space:
mode:
Diffstat (limited to 'roms/edk2/ArmVirtPkg/PrePi')
-rw-r--r--roms/edk2/ArmVirtPkg/PrePi/AArch64/ArchPrePi.c27
-rw-r--r--roms/edk2/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S177
-rw-r--r--roms/edk2/ArmVirtPkg/PrePi/Arm/ArchPrePi.c20
-rw-r--r--roms/edk2/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S182
-rwxr-xr-xroms/edk2/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf98
-rw-r--r--roms/edk2/ArmVirtPkg/PrePi/FdtParser.c84
-rwxr-xr-xroms/edk2/ArmVirtPkg/PrePi/PrePi.c165
-rw-r--r--roms/edk2/ArmVirtPkg/PrePi/PrePi.h63
8 files changed, 816 insertions, 0 deletions
diff --git a/roms/edk2/ArmVirtPkg/PrePi/AArch64/ArchPrePi.c b/roms/edk2/ArmVirtPkg/PrePi/AArch64/ArchPrePi.c
new file mode 100644
index 000000000..9cab88ca0
--- /dev/null
+++ b/roms/edk2/ArmVirtPkg/PrePi/AArch64/ArchPrePi.c
@@ -0,0 +1,27 @@
+/** @file
+*
+* Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#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/roms/edk2/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S b/roms/edk2/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S
new file mode 100644
index 000000000..01623b6b3
--- /dev/null
+++ b/roms/edk2/ArmVirtPkg/PrePi/AArch64/ModuleEntryPoint.S
@@ -0,0 +1,177 @@
+//
+// Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+// Copyright (c) 2015-2016, Linaro Limited. All rights reserved.
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+
+#include <AsmMacroIoLibV8.h>
+
+ASM_FUNC(_ModuleEntryPoint)
+ bl ASM_PFX(DiscoverDramFromDt)
+
+ // Get ID of this CPU in Multicore system
+ bl ASM_PFX(ArmReadMpidr)
+ // Keep a copy of the MpId register value
+ mov x20, x0
+
+// Check if we can install the stack at the top of the System Memory or if we need
+// to install the stacks at the bottom of the Firmware Device (case the FD is located
+// 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)
+ MOV32 (w3, FixedPcdGet32 (PcdFdSize) - 1)
+ add x3, x3, x2 // x3 = FdTop = PcdFdBaseAddress + PcdFdSize
+
+ // UEFI Memory Size (stacks are allocated in this region)
+ MOV32 (x4, FixedPcdGet32(PcdSystemMemoryUefiRegionSize))
+
+ //
+ // 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 x21, x1, #1
+ b.cs _SetupOverflowStack
+
+_SetupAlignedStack:
+ mov x1, x21
+ b _GetBaseUefiMemory
+
+_SetupOverflowStack:
+ // Case memory at the top of the address space. Ensure the top of the stack is EFI_PAGE_SIZE
+ // aligned (4KB)
+ and x1, x1, ~EFI_PAGE_MASK
+
+_GetBaseUefiMemory:
+ // Calculate the Base of the UEFI Memory
+ sub x21, x1, x4
+
+_GetStackBase:
+ // r1 = The top of the Mpcore Stacks
+ mov sp, x1
+
+ // Stack for the primary core = PrimaryCoreStack
+ MOV32 (x2, FixedPcdGet32(PcdCPUCorePrimaryStackSize))
+ sub x22, x1, x2
+
+ mov x0, x20
+ mov x1, x21
+ mov x2, x22
+
+ // Set the frame pointer to NULL so any backtraces terminate here
+ mov x29, xzr
+
+ // Jump to PrePiCore C code
+ // x0 = MpId
+ // x1 = UefiMemoryBase
+ // x2 = StacksBase
+ bl ASM_PFX(CEntryPoint)
+
+_NeverReturn:
+ b _NeverReturn
+
+// VOID
+// DiscoverDramFromDt (
+// VOID *DeviceTreeBaseAddress, // passed by loader in x0
+// VOID *ImageBase // passed by FDF trampoline in x1
+// );
+ASM_PFX(DiscoverDramFromDt):
+ //
+ // If we are booting from RAM using the Linux kernel boot protocol, x0 will
+ // point to the DTB image in memory. Otherwise, use the default value defined
+ // by the platform.
+ //
+ cbnz x0, 0f
+ ldr x0, PcdGet64 (PcdDeviceTreeInitialBaseAddress)
+
+0:mov x29, x30 // preserve LR
+ mov x28, x0 // preserve DTB pointer
+ mov x27, x1 // preserve base of image pointer
+
+ //
+ // The base of the runtime image has been preserved in x1. Check whether
+ // the expected magic number can be found in the header.
+ //
+ ldr w8, .LArm64LinuxMagic
+ ldr w9, [x1, #0x38]
+ cmp w8, w9
+ bne .Lout
+
+ //
+ //
+ // OK, so far so good. We have confirmed that we likely have a DTB and are
+ // booting via the arm64 Linux boot protocol. Update the base-of-image PCD
+ // to the actual relocated value, and add the shift of PcdFdBaseAddress to
+ // PcdFvBaseAddress as well
+ //
+ adr x8, PcdGet64 (PcdFdBaseAddress)
+ adr x9, PcdGet64 (PcdFvBaseAddress)
+ ldr x6, [x8]
+ ldr x7, [x9]
+ sub x7, x7, x6
+ add x7, x7, x1
+ str x1, [x8]
+ str x7, [x9]
+
+ //
+ // The runtime address may be different from the link time address so fix
+ // up the PE/COFF relocations. Since we are calling a C function, use the
+ // window at the beginning of the FD image as a temp stack.
+ //
+ mov x0, x7
+ adr x1, PeCoffLoaderImageReadFromMemory
+ mov sp, x7
+ bl RelocatePeCoffImage
+
+ //
+ // Discover the memory size and offset from the DTB, and record in the
+ // respective PCDs. This will also return false if a corrupt DTB is
+ // encountered.
+ //
+ mov x0, x28
+ adr x1, PcdGet64 (PcdSystemMemoryBase)
+ adr x2, PcdGet64 (PcdSystemMemorySize)
+ bl FindMemnode
+ cbz x0, .Lout
+
+ //
+ // Copy the DTB to the slack space right after the 64 byte arm64/Linux style
+ // image header at the base of this image (defined in the FDF), and record the
+ // pointer in PcdDeviceTreeInitialBaseAddress.
+ //
+ adr x8, PcdGet64 (PcdDeviceTreeInitialBaseAddress)
+ add x27, x27, #0x40
+ str x27, [x8]
+
+ mov x0, x27
+ mov x1, x28
+ bl CopyFdt
+
+.Lout:
+ ret x29
+
+.LArm64LinuxMagic:
+ .byte 0x41, 0x52, 0x4d, 0x64
diff --git a/roms/edk2/ArmVirtPkg/PrePi/Arm/ArchPrePi.c b/roms/edk2/ArmVirtPkg/PrePi/Arm/ArchPrePi.c
new file mode 100644
index 000000000..bb074b819
--- /dev/null
+++ b/roms/edk2/ArmVirtPkg/PrePi/Arm/ArchPrePi.c
@@ -0,0 +1,20 @@
+/** @file
+*
+* Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include "PrePi.h"
+
+VOID
+ArchInitialize (
+ VOID
+ )
+{
+ // Enable Floating Point
+ if (FixedPcdGet32 (PcdVFPEnabled)) {
+ ArmEnableVFP ();
+ }
+}
diff --git a/roms/edk2/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S b/roms/edk2/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S
new file mode 100644
index 000000000..f0536c65e
--- /dev/null
+++ b/roms/edk2/ArmVirtPkg/PrePi/Arm/ModuleEntryPoint.S
@@ -0,0 +1,182 @@
+//
+// Copyright (c) 2011-2013, ARM Limited. All rights reserved.
+// Copyright (c) 2015-2016, Linaro Limited. All rights reserved.
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+
+#include <AsmMacroIoLib.h>
+
+ASM_FUNC(_ModuleEntryPoint)
+ // 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 r10, r0
+
+// 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
+ LDRL (r1, PcdGet64 (PcdSystemMemoryBase))
+ ADRL (r12, PcdGet64 (PcdSystemMemorySize))
+ ldrd r2, r3, [r12]
+
+ // calculate the top of memory
+ adds r2, r2, r1
+ sub r2, r2, #1
+ addcs r3, r3, #1
+
+ // truncate the memory used by UEFI to 4 GB range
+ teq r3, #0
+ movne r1, #-1
+ moveq r1, r2
+
+ // Calculate Top of the Firmware Device
+ LDRL (r2, PcdGet64 (PcdFdBaseAddress))
+ MOV32 (r3, FixedPcdGet32 (PcdFdSize) - 1)
+ add r3, r3, r2 // r3 = FdTop = PcdFdBaseAddress + PcdFdSize
+
+ // UEFI Memory Size (stacks are allocated in this region)
+ MOV32 (r4, FixedPcdGet32(PcdSystemMemoryUefiRegionSize))
+
+ //
+ // 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 r0, r1, r3 // r0 = SystemMemoryTop - FdTop
+ bmi _SetupStack // Jump if negative (FdTop > SystemMemoryTop). Case when the PrePi is in XIP memory outside of the DRAM
+ cmp r0, r4
+ bge _SetupStack
+
+ // Case the top of stacks is the FdBaseAddress
+ mov r1, r2
+
+_SetupStack:
+ // r1 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 r11, r1, #1
+ bcs _SetupOverflowStack
+
+_SetupAlignedStack:
+ mov r1, r11
+ b _GetBaseUefiMemory
+
+_SetupOverflowStack:
+ // Case memory at the top of the address space. Ensure the top of the stack is EFI_PAGE_SIZE
+ // aligned (4KB)
+ MOV32 (r11, (~EFI_PAGE_MASK) & 0xffffffff)
+ and r1, r1, r11
+
+_GetBaseUefiMemory:
+ // Calculate the Base of the UEFI Memory
+ sub r11, r1, r4
+
+_GetStackBase:
+ // r1 = The top of the Mpcore Stacks
+ mov sp, r1
+
+ // Stack for the primary core = PrimaryCoreStack
+ MOV32 (r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize))
+ sub r9, r1, r2
+
+ mov r0, r10
+ mov r1, r11
+ mov r2, r9
+
+ // Jump to PrePiCore C code
+ // r0 = MpId
+ // r1 = UefiMemoryBase
+ // r2 = StacksBase
+ bl ASM_PFX(CEntryPoint)
+
+_NeverReturn:
+ b _NeverReturn
+
+ASM_PFX(ArmPlatformPeiBootAction):
+ //
+ // If we are booting from RAM using the Linux kernel boot protocol, r0 will
+ // point to the DTB image in memory. Otherwise, use the default value defined
+ // by the platform.
+ //
+ teq r0, #0
+ bne 0f
+ LDRL (r0, PcdGet64 (PcdDeviceTreeInitialBaseAddress))
+
+0:mov r11, r14 // preserve LR
+ mov r10, r0 // preserve DTB pointer
+ mov r9, r1 // preserve base of image pointer
+
+ //
+ // The base of the runtime image has been preserved in r1. Check whether
+ // the expected magic number can be found in the header.
+ //
+ ldr r8, .LArm32LinuxMagic
+ ldr r7, [r1, #0x24]
+ cmp r7, r8
+ bne .Lout
+
+ //
+ //
+ // OK, so far so good. We have confirmed that we likely have a DTB and are
+ // booting via the ARM Linux boot protocol. Update the base-of-image PCD
+ // to the actual relocated value, and add the shift of PcdFdBaseAddress to
+ // PcdFvBaseAddress as well
+ //
+ ADRL (r8, PcdGet64 (PcdFdBaseAddress))
+ ADRL (r7, PcdGet64 (PcdFvBaseAddress))
+ ldr r6, [r8]
+ ldr r5, [r7]
+ sub r5, r5, r6
+ add r5, r5, r1
+ str r1, [r8]
+ str r5, [r7]
+
+ //
+ // The runtime address may be different from the link time address so fix
+ // up the PE/COFF relocations. Since we are calling a C function, use the
+ // window at the beginning of the FD image as a temp stack.
+ //
+ mov r0, r5
+ ADRL (r1, PeCoffLoaderImageReadFromMemory)
+ mov sp, r5
+ bl RelocatePeCoffImage
+
+ //
+ // Discover the memory size and offset from the DTB, and record in the
+ // respective PCDs. This will also return false if a corrupt DTB is
+ // encountered.
+ //
+ mov r0, r10
+ ADRL (r1, PcdGet64 (PcdSystemMemoryBase))
+ ADRL (r2, PcdGet64 (PcdSystemMemorySize))
+ bl FindMemnode
+ teq r0, #0
+ beq .Lout
+
+ //
+ // Copy the DTB to the slack space right after the 64 byte arm64/Linux style
+ // image header at the base of this image (defined in the FDF), and record the
+ // pointer in PcdDeviceTreeInitialBaseAddress.
+ //
+ ADRL (r8, PcdGet64 (PcdDeviceTreeInitialBaseAddress))
+ add r9, r9, #0x40
+ str r9, [r8]
+
+ mov r0, r9
+ mov r1, r10
+ bl CopyFdt
+
+.Lout:
+ bx r11
+
+.LArm32LinuxMagic:
+ .byte 0x18, 0x28, 0x6f, 0x01
diff --git a/roms/edk2/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf b/roms/edk2/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf
new file mode 100755
index 000000000..7edf50180
--- /dev/null
+++ b/roms/edk2/ArmVirtPkg/PrePi/ArmVirtPrePiUniCoreRelocatable.inf
@@ -0,0 +1,98 @@
+#/** @file
+#
+# Copyright (c) 2011-2015, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[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]
+ FdtParser.c
+ PrePi.c
+ PrePi.h
+
+[Sources.AArch64]
+ AArch64/ArchPrePi.c
+ AArch64/ModuleEntryPoint.S
+
+[Sources.ARM]
+ Arm/ArchPrePi.c
+ Arm/ModuleEntryPoint.S
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ ArmVirtPkg/ArmVirtPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ FdtLib
+ ArmLib
+ IoLib
+ TimerLib
+ SerialPortLib
+ ExtractGuidedSectionLib
+ LzmaDecompressLib
+ PeCoffLib
+ PrePiLib
+ MemoryAllocationLib
+ HobLib
+ PrePiHobListPointerLib
+ PlatformPeiLib
+ MemoryInitPeiLib
+ CacheMaintenanceLib
+
+[Ppis]
+ gArmMpCoreInfoPpiGuid
+
+[Guids]
+ gArmMpCoreInfoGuid
+
+[FeaturePcd]
+ gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
+ gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores
+
+[FixedPcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
+
+ gArmTokenSpaceGuid.PcdVFPEnabled
+
+ gArmTokenSpaceGuid.PcdFdSize
+ gArmTokenSpaceGuid.PcdFvSize
+
+ gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize
+ gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize
+
+ gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
+
+ 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
+ gArmVirtTokenSpaceGuid.PcdDeviceTreeInitialBaseAddress
+ gArmTokenSpaceGuid.PcdFdBaseAddress
+ gArmTokenSpaceGuid.PcdFvBaseAddress
diff --git a/roms/edk2/ArmVirtPkg/PrePi/FdtParser.c b/roms/edk2/ArmVirtPkg/PrePi/FdtParser.c
new file mode 100644
index 000000000..4754cba55
--- /dev/null
+++ b/roms/edk2/ArmVirtPkg/PrePi/FdtParser.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2015, Linaro Ltd. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ */
+
+#include <Uefi.h>
+#include <Include/libfdt.h>
+
+BOOLEAN
+FindMemnode (
+ IN VOID *DeviceTreeBlob,
+ OUT UINT64 *SystemMemoryBase,
+ OUT UINT64 *SystemMemorySize
+ )
+{
+ INT32 MemoryNode;
+ INT32 AddressCells;
+ INT32 SizeCells;
+ INT32 Length;
+ CONST INT32 *Prop;
+
+ if (fdt_check_header (DeviceTreeBlob) != 0) {
+ return FALSE;
+ }
+
+ //
+ // Look for a node called "memory" at the lowest level of the tree
+ //
+ MemoryNode = fdt_path_offset (DeviceTreeBlob, "/memory");
+ if (MemoryNode <= 0) {
+ return FALSE;
+ }
+
+ //
+ // Retrieve the #address-cells and #size-cells properties
+ // from the root node, or use the default if not provided.
+ //
+ AddressCells = 1;
+ SizeCells = 1;
+
+ Prop = fdt_getprop (DeviceTreeBlob, 0, "#address-cells", &Length);
+ if (Length == 4) {
+ AddressCells = fdt32_to_cpu (*Prop);
+ }
+
+ Prop = fdt_getprop (DeviceTreeBlob, 0, "#size-cells", &Length);
+ if (Length == 4) {
+ SizeCells = fdt32_to_cpu (*Prop);
+ }
+
+ //
+ // Now find the 'reg' property of the /memory node, and read the first
+ // range listed.
+ //
+ Prop = fdt_getprop (DeviceTreeBlob, MemoryNode, "reg", &Length);
+
+ if (Length < (AddressCells + SizeCells) * sizeof (INT32)) {
+ return FALSE;
+ }
+
+ *SystemMemoryBase = fdt32_to_cpu (Prop[0]);
+ if (AddressCells > 1) {
+ *SystemMemoryBase = (*SystemMemoryBase << 32) | fdt32_to_cpu (Prop[1]);
+ }
+ Prop += AddressCells;
+
+ *SystemMemorySize = fdt32_to_cpu (Prop[0]);
+ if (SizeCells > 1) {
+ *SystemMemorySize = (*SystemMemorySize << 32) | fdt32_to_cpu (Prop[1]);
+ }
+
+ return TRUE;
+}
+
+VOID
+CopyFdt (
+ IN VOID *FdtDest,
+ IN VOID *FdtSource
+ )
+{
+ fdt_pack(FdtSource);
+ CopyMem (FdtDest, FdtSource, fdt_totalsize (FdtSource));
+}
diff --git a/roms/edk2/ArmVirtPkg/PrePi/PrePi.c b/roms/edk2/ArmVirtPkg/PrePi/PrePi.c
new file mode 100755
index 000000000..4f0c3f98b
--- /dev/null
+++ b/roms/edk2/ArmVirtPkg/PrePi/PrePi.c
@@ -0,0 +1,165 @@
+/** @file
+*
+* Copyright (c) 2011-2014, ARM Limited. All rights reserved.
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include <PiPei.h>
+#include <Pi/PiBootMode.h>
+
+#include <Library/PeCoffLib.h>
+#include <Library/PrePiLib.h>
+#include <Library/PrintLib.h>
+#include <Library/PrePiHobListPointerLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/CacheMaintenanceLib.h>
+
+#include <Ppi/GuidedSectionExtraction.h>
+#include <Ppi/ArmMpCoreInfo.h>
+
+#include "PrePi.h"
+
+VOID
+EFIAPI
+ProcessLibraryConstructorList (
+ VOID
+ );
+
+VOID
+PrePiMain (
+ IN UINTN UefiMemoryBase,
+ IN UINTN StacksBase,
+ 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 ();
+
+ // 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);
+
+ //
+ // Ensure that the loaded image is invalidated in the caches, so that any
+ // modifications we made with the caches and MMU off (such as the applied
+ // relocations) don't become invisible once we turn them on.
+ //
+ InvalidateDataCacheRange((VOID *)(UINTN)PcdGet64 (PcdFdBaseAddress), PcdGet32 (PcdFdSize));
+
+ // Initialize MMU and Memory HOBs (Resource Descriptor HOBs)
+ Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
+ ASSERT_EFI_ERROR (Status);
+
+ // 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);
+
+ // Create the Stacks HOB (reserve the memory for all stacks)
+ StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize);
+ BuildStackHob (StacksBase, StacksSize);
+
+ //TODO: Call CpuPei as a library
+ BuildCpuHob (ArmGetPhysicalAddressBits (), PcdGet8 (PcdPrePiCpuIoSize));
+
+ // Set the Boot Mode
+ SetBootMode (BOOT_WITH_FULL_CONFIGURATION);
+
+ // 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.
+ ProcessLibraryConstructorList ();
+
+ // 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
+ )
+{
+ UINT64 StartTimeStamp;
+
+ 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 instruction cache
+ ArmInvalidateInstructionCache ();
+ // Enable Instruction Caches on all cores.
+ ArmEnableInstructionCache ();
+
+ PrePiMain (UefiMemoryBase, StacksBase, StartTimeStamp);
+
+ // DXE Core should always load and never return
+ ASSERT (FALSE);
+}
+
+VOID
+RelocatePeCoffImage (
+ IN EFI_PEI_FV_HANDLE FwVolHeader,
+ IN PE_COFF_LOADER_READ_FILE ImageRead
+ )
+{
+ EFI_PEI_FILE_HANDLE FileHandle;
+ VOID *SectionData;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+ EFI_STATUS Status;
+
+ FileHandle = NULL;
+ Status = FfsFindNextFile (EFI_FV_FILETYPE_SECURITY_CORE, FwVolHeader,
+ &FileHandle);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = FfsFindSectionData (EFI_SECTION_PE32, FileHandle, &SectionData);
+ if (EFI_ERROR (Status)) {
+ Status = FfsFindSectionData (EFI_SECTION_TE, FileHandle, &SectionData);
+ }
+ ASSERT_EFI_ERROR (Status);
+
+ ZeroMem (&ImageContext, sizeof ImageContext);
+
+ ImageContext.Handle = (EFI_HANDLE)SectionData;
+ ImageContext.ImageRead = ImageRead;
+ PeCoffLoaderGetImageInfo (&ImageContext);
+
+ if (ImageContext.ImageAddress != (UINTN)SectionData) {
+ ImageContext.ImageAddress = (UINTN)SectionData;
+ PeCoffLoaderRelocateImage (&ImageContext);
+ }
+}
diff --git a/roms/edk2/ArmVirtPkg/PrePi/PrePi.h b/roms/edk2/ArmVirtPkg/PrePi/PrePi.h
new file mode 100644
index 000000000..cc7a49238
--- /dev/null
+++ b/roms/edk2/ArmVirtPkg/PrePi/PrePi.h
@@ -0,0 +1,63 @@
+/** @file
+*
+* Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#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>
+
+#define SerialPrint(txt) SerialPortWrite (txt, AsciiStrLen(txt)+1);
+
+RETURN_STATUS
+EFIAPI
+TimerConstructor (
+ VOID
+ );
+
+VOID
+PrePiMain (
+ IN UINTN UefiMemoryBase,
+ IN UINTN StacksBase,
+ 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
+ );
+
+// Initialize the Architecture specific controllers
+VOID
+ArchInitialize (
+ VOID
+ );
+
+#endif /* _PREPI_H_ */