aboutsummaryrefslogtreecommitdiffstats
path: root/roms/edk2/ArmPlatformPkg/PrePi
diff options
context:
space:
mode:
authorAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
committerAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
commitaf1a266670d040d2f4083ff309d732d648afba2a (patch)
tree2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/edk2/ArmPlatformPkg/PrePi
parente02cda008591317b1625707ff8e115a4841aa889 (diff)
Add submodule dependency filesHEADmaster
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/edk2/ArmPlatformPkg/PrePi')
-rw-r--r--roms/edk2/ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c34
-rw-r--r--roms/edk2/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S116
-rw-r--r--roms/edk2/ArmPlatformPkg/PrePi/Arm/ArchPrePi.c23
-rw-r--r--roms/edk2/ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.S124
-rw-r--r--roms/edk2/ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.asm142
-rw-r--r--roms/edk2/ArmPlatformPkg/PrePi/MainMPCore.c99
-rw-r--r--roms/edk2/ArmPlatformPkg/PrePi/MainUniCore.c32
-rw-r--r--roms/edk2/ArmPlatformPkg/PrePi/PeiMPCore.inf107
-rw-r--r--roms/edk2/ArmPlatformPkg/PrePi/PeiUniCore.inf103
-rw-r--r--roms/edk2/ArmPlatformPkg/PrePi/PrePi.c214
-rw-r--r--roms/edk2/ArmPlatformPkg/PrePi/PrePi.h90
11 files changed, 1084 insertions, 0 deletions
diff --git a/roms/edk2/ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c b/roms/edk2/ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c
new file mode 100644
index 000000000..9a172212a
--- /dev/null
+++ b/roms/edk2/ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c
@@ -0,0 +1,34 @@
+/** @file
+*
+* Copyright (c) 2011-2017, 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);
+
+ /* Enable Timer access for non-secure EL1 and EL0
+ The cnthctl_el2 register bits are architecturally
+ UNKNOWN on reset.
+ Disable event stream as it is not in use at this stage
+ */
+ ArmWriteCntHctl (CNTHCTL_EL2_EL1PCTEN | CNTHCTL_EL2_EL1PCEN);
+ }
+}
diff --git a/roms/edk2/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S b/roms/edk2/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S
new file mode 100644
index 000000000..4929ca42e
--- /dev/null
+++ b/roms/edk2/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S
@@ -0,0 +1,116 @@
+//
+// Copyright (c) 2011-2015, ARM Limited. All rights reserved.
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+
+#include <AsmMacroIoLibV8.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 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)
+_SystemMemoryEndInit:
+ ldr x1, mSystemMemoryEnd
+
+_SetupStackPosition:
+ // r1 = SystemMemoryTop
+
+ // Calculate Top of the Firmware Device
+ MOV64 (x2, FixedPcdGet64(PcdFdBaseAddress))
+ MOV32 (x3, FixedPcdGet32(PcdFdSize) - 1)
+ sub x3, x3, #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 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)
+ and x1, x1, ~EFI_PAGE_MASK
+
+_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
+ MOV32 (x2, FixedPcdGet32(PcdCPUCorePrimaryStackSize))
+ sub x12, x1, x2
+
+ // Stack for the secondary core = Number of Cores - 1
+ MOV32 (x1, (FixedPcdGet32(PcdCoreCount) - 1) * FixedPcdGet32(PcdCPUCoreSecondaryStackSize))
+ 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)
+ MOV32 (x2, FixedPcdGet32(PcdCPUCorePrimaryStackSize))
+ MOV32 (x3, FixedPcdGet32(PcdCPUCoreSecondaryStackSize))
+ bl ASM_PFX(ArmPlatformStackSet)
+
+ // Is it the Primary Core ?
+ mov x0, x10
+ bl ASM_PFX(ArmPlatformIsPrimaryCore)
+ cmp x0, #1
+ bne _PrepareArguments
+
+_PrepareArguments:
+ mov x0, x10
+ mov x1, x11
+ mov x2, x12
+
+ // Move sec startup address into a data register
+ // Ensure we're jumping to FV version of the code (not boot remapped alias)
+ ldr x4, =ASM_PFX(CEntryPoint)
+
+ // 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
+ blr x4
+
+_NeverReturn:
+ b _NeverReturn
diff --git a/roms/edk2/ArmPlatformPkg/PrePi/Arm/ArchPrePi.c b/roms/edk2/ArmPlatformPkg/PrePi/Arm/ArchPrePi.c
new file mode 100644
index 000000000..250b622f4
--- /dev/null
+++ b/roms/edk2/ArmPlatformPkg/PrePi/Arm/ArchPrePi.c
@@ -0,0 +1,23 @@
+/** @file
+*
+* Copyright (c) 2011 - 2013, ARM Limited. All rights reserved.
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include "PrePi.h"
+
+VOID
+ArchInitialize (
+ VOID
+ )
+{
+ // Enable program flow prediction, if supported.
+ ArmEnableBranchPrediction ();
+
+ if (FixedPcdGet32 (PcdVFPEnabled)) {
+ ArmEnableVFP ();
+ }
+}
+
diff --git a/roms/edk2/ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.S b/roms/edk2/ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.S
new file mode 100644
index 000000000..ff7e3a454
--- /dev/null
+++ b/roms/edk2/ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.S
@@ -0,0 +1,124 @@
+//
+// Copyright (c) 2011-2015, ARM Limited. All rights reserved.
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+
+#include <AsmMacroIoLib.h>
+
+#include <Chipset/ArmV7.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 r8, r0
+
+_SetSVCMode:
+ // Enter SVC mode, Disable FIQ and IRQ
+ mov r1, #(CPSR_MODE_SVC | CPSR_IRQ | CPSR_FIQ)
+ msr CPSR_c, r1
+
+// 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)
+_SystemMemoryEndInit:
+ ADRL (r1, mSystemMemoryEnd)
+ ldrd r2, r3, [r1]
+ teq r3, #0
+ moveq r1, r2
+ mvnne r1, #0
+
+_SetupStackPosition:
+ // r1 = SystemMemoryTop
+
+ // Calculate Top of the Firmware Device
+ MOV32 (r2, FixedPcdGet32(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 r9, r1, #1
+ bcs _SetupOverflowStack
+
+_SetupAlignedStack:
+ mov r1, r9
+ 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 (r9, ~EFI_PAGE_MASK & 0xFFFFFFFF)
+ and r1, r1, r9
+
+_GetBaseUefiMemory:
+ // Calculate the Base of the UEFI Memory
+ sub r9, r1, r4
+
+_GetStackBase:
+ // r1 = The top of the Mpcore Stacks
+ // Stack for the primary core = PrimaryCoreStack
+ MOV32 (r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize))
+ sub r10, r1, r2
+
+ // Stack for the secondary core = Number of Cores - 1
+ MOV32 (r1, (FixedPcdGet32(PcdCoreCount) - 1) * FixedPcdGet32(PcdCPUCoreSecondaryStackSize))
+ sub r10, r10, r1
+
+ // r10 = The base of the MpCore Stacks (primary stack & secondary stacks)
+ mov r0, r10
+ mov r1, r8
+ //ArmPlatformStackSet(StackBase, MpId, PrimaryStackSize, SecondaryStackSize)
+ MOV32 (r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize))
+ MOV32 (r3, FixedPcdGet32(PcdCPUCoreSecondaryStackSize))
+ bl ASM_PFX(ArmPlatformStackSet)
+
+ // Is it the Primary Core ?
+ mov r0, r8
+ bl ASM_PFX(ArmPlatformIsPrimaryCore)
+ cmp r0, #1
+ bne _PrepareArguments
+
+_PrepareArguments:
+ mov r0, r8
+ mov r1, r9
+ mov r2, r10
+ mov r3, sp
+
+ // Move sec startup address into a data register
+ // Ensure we're jumping to FV version of the code (not boot remapped alias)
+ ldr r4, =ASM_PFX(CEntryPoint)
+
+ // Jump to PrePiCore C code
+ // r0 = MpId
+ // r1 = UefiMemoryBase
+ // r2 = StacksBase
+ blx r4
+
+_NeverReturn:
+ b _NeverReturn
diff --git a/roms/edk2/ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.asm b/roms/edk2/ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.asm
new file mode 100644
index 000000000..3da789205
--- /dev/null
+++ b/roms/edk2/ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.asm
@@ -0,0 +1,142 @@
+//
+// Copyright (c) 2011-2015, ARM Limited. All rights reserved.
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+
+#include <AutoGen.h>
+#include <Chipset/ArmV7.h>
+
+ INCLUDE AsmMacroIoLib.inc
+
+ IMPORT CEntryPoint
+ IMPORT ArmPlatformIsPrimaryCore
+ IMPORT ArmReadMpidr
+ IMPORT ArmPlatformPeiBootAction
+ IMPORT ArmPlatformStackSet
+ IMPORT mSystemMemoryEnd
+
+ EXPORT _ModuleEntryPoint
+
+ PRESERVE8
+ AREA PrePiCoreEntryPoint, CODE, READONLY
+
+StartupAddr DCD CEntryPoint
+
+_ModuleEntryPoint
+ // Do early platform specific actions
+ bl ArmPlatformPeiBootAction
+
+ // Get ID of this CPU in Multicore system
+ bl ArmReadMpidr
+ // Keep a copy of the MpId register value
+ mov r8, r0
+
+_SetSVCMode
+ // Enter SVC mode, Disable FIQ and IRQ
+ mov r1, #(CPSR_MODE_SVC :OR: CPSR_IRQ :OR: CPSR_FIQ)
+ msr CPSR_c, r1
+
+// 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)
+_SystemMemoryEndInit
+ adrll r1, mSystemMemoryEnd
+ ldrd r2, r3, [r1]
+ teq r3, #0
+ moveq r1, r2
+ mvnne r1, #0
+
+_SetupStackPosition
+ // r1 = SystemMemoryTop
+
+ // Calculate Top of the Firmware Device
+ mov32 r2, FixedPcdGet32(PcdFdBaseAddress)
+ mov32 r3, FixedPcdGet32(PcdFdSize)
+ sub r3, r3, #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 r9, r1, #1
+ bcs _SetupOverflowStack
+
+_SetupAlignedStack
+ mov r1, r9
+ 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 r9, EFI_PAGE_MASK
+ and r9, r9, r1
+ sub r1, r1, r9
+
+_GetBaseUefiMemory
+ // Calculate the Base of the UEFI Memory
+ sub r9, r1, r4
+
+_GetStackBase
+ // r1 = The top of the Mpcore Stacks
+ // Stack for the primary core = PrimaryCoreStack
+ mov32 r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize)
+ sub r10, r1, r2
+
+ // Stack for the secondary core = Number of Cores - 1
+ mov32 r1, (FixedPcdGet32(PcdCoreCount) - 1) * FixedPcdGet32(PcdCPUCoreSecondaryStackSize)
+ sub r10, r10, r1
+
+ // r10 = The base of the MpCore Stacks (primary stack & secondary stacks)
+ mov r0, r10
+ mov r1, r8
+ //ArmPlatformStackSet(StackBase, MpId, PrimaryStackSize, SecondaryStackSize)
+ mov32 r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize)
+ mov32 r3, FixedPcdGet32(PcdCPUCoreSecondaryStackSize)
+ bl ArmPlatformStackSet
+
+ // Is it the Primary Core ?
+ mov r0, r8
+ bl ArmPlatformIsPrimaryCore
+ cmp r0, #1
+ bne _PrepareArguments
+
+_PrepareArguments
+ mov r0, r8
+ mov r1, r9
+ mov r2, r10
+
+ // Move sec startup address into a data register
+ // Ensure we're jumping to FV version of the code (not boot remapped alias)
+ ldr r4, StartupAddr
+
+ // Jump to PrePiCore C code
+ // r0 = MpId
+ // r1 = UefiMemoryBase
+ // r2 = StacksBase
+ blx r4
+
+_NeverReturn
+ b _NeverReturn
+
+ END
diff --git a/roms/edk2/ArmPlatformPkg/PrePi/MainMPCore.c b/roms/edk2/ArmPlatformPkg/PrePi/MainMPCore.c
new file mode 100644
index 000000000..31cf085b6
--- /dev/null
+++ b/roms/edk2/ArmPlatformPkg/PrePi/MainMPCore.c
@@ -0,0 +1,99 @@
+/** @file
+*
+* Copyright (c) 2011-2014, ARM Limited. All rights reserved.
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include "PrePi.h"
+
+#include <Library/ArmGicLib.h>
+
+#include <Ppi/ArmMpCoreInfo.h>
+
+VOID
+PrimaryMain (
+ IN UINTN UefiMemoryBase,
+ IN UINTN StacksBase,
+ IN UINT64 StartTimeStamp
+ )
+{
+ // Enable the GIC Distributor
+ ArmGicEnableDistributor(PcdGet64(PcdGicDistributorBase));
+
+ // In some cases, the secondary cores are waiting for an SGI from the next stage boot loader to resume their initialization
+ if (!FixedPcdGet32(PcdSendSgiToBringUpSecondaryCores)) {
+ // Sending SGI to all the Secondary CPU interfaces
+ ArmGicSendSgiTo (PcdGet64(PcdGicDistributorBase), ARM_GIC_ICDSGIR_FILTER_EVERYONEELSE, 0x0E, PcdGet32 (PcdGicSgiIntId));
+ }
+
+ PrePiMain (UefiMemoryBase, StacksBase, StartTimeStamp);
+
+ // We must never return
+ ASSERT(FALSE);
+}
+
+VOID
+SecondaryMain (
+ IN UINTN MpId
+ )
+{
+ EFI_STATUS Status;
+ ARM_MP_CORE_INFO_PPI *ArmMpCoreInfoPpi;
+ UINTN Index;
+ UINTN ArmCoreCount;
+ ARM_CORE_INFO *ArmCoreInfoTable;
+ UINT32 ClusterId;
+ UINT32 CoreId;
+ VOID (*SecondaryStart)(VOID);
+ UINTN SecondaryEntryAddr;
+ UINTN AcknowledgeInterrupt;
+ UINTN InterruptId;
+
+ ClusterId = GET_CLUSTER_ID(MpId);
+ CoreId = GET_CORE_ID(MpId);
+
+ // On MP Core Platform we must implement the ARM MP Core Info PPI (gArmMpCoreInfoPpiGuid)
+ Status = GetPlatformPpi (&gArmMpCoreInfoPpiGuid, (VOID**)&ArmMpCoreInfoPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ ArmCoreCount = 0;
+ Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable);
+ ASSERT_EFI_ERROR (Status);
+
+ // Find the core in the ArmCoreTable
+ for (Index = 0; Index < ArmCoreCount; Index++) {
+ if ((ArmCoreInfoTable[Index].ClusterId == ClusterId) && (ArmCoreInfoTable[Index].CoreId == CoreId)) {
+ break;
+ }
+ }
+
+ // The ARM Core Info Table must define every core
+ ASSERT (Index != ArmCoreCount);
+
+ // Clear Secondary cores MailBox
+ MmioWrite32 (ArmCoreInfoTable[Index].MailboxClearAddress, ArmCoreInfoTable[Index].MailboxClearValue);
+
+ do {
+ ArmCallWFI ();
+
+ // Read the Mailbox
+ SecondaryEntryAddr = MmioRead32 (ArmCoreInfoTable[Index].MailboxGetAddress);
+
+ // Acknowledge the interrupt and send End of Interrupt signal.
+ AcknowledgeInterrupt = ArmGicAcknowledgeInterrupt (PcdGet64 (PcdGicInterruptInterfaceBase), &InterruptId);
+ // Check if it is a valid interrupt ID
+ if (InterruptId < ArmGicGetMaxNumInterrupts (PcdGet64 (PcdGicDistributorBase))) {
+ // Got a valid SGI number hence signal End of Interrupt
+ ArmGicEndOfInterrupt (PcdGet64 (PcdGicInterruptInterfaceBase), AcknowledgeInterrupt);
+ }
+ } while (SecondaryEntryAddr == 0);
+
+ // Jump to secondary core entry point.
+ SecondaryStart = (VOID (*)())SecondaryEntryAddr;
+ SecondaryStart();
+
+ // The secondaries shouldn't reach here
+ ASSERT(FALSE);
+}
diff --git a/roms/edk2/ArmPlatformPkg/PrePi/MainUniCore.c b/roms/edk2/ArmPlatformPkg/PrePi/MainUniCore.c
new file mode 100644
index 000000000..fb2f7efd9
--- /dev/null
+++ b/roms/edk2/ArmPlatformPkg/PrePi/MainUniCore.c
@@ -0,0 +1,32 @@
+/** @file
+*
+* Copyright (c) 2011, ARM Limited. All rights reserved.
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include "PrePi.h"
+
+VOID
+PrimaryMain (
+ IN UINTN UefiMemoryBase,
+ IN UINTN StacksBase,
+ IN UINT64 StartTimeStamp
+ )
+{
+ PrePiMain (UefiMemoryBase, StacksBase, StartTimeStamp);
+
+ // We must never return
+ ASSERT(FALSE);
+}
+
+VOID
+SecondaryMain (
+ IN UINTN MpId
+ )
+{
+ // We must never get into this function on UniCore system
+ ASSERT(FALSE);
+}
+
diff --git a/roms/edk2/ArmPlatformPkg/PrePi/PeiMPCore.inf b/roms/edk2/ArmPlatformPkg/PrePi/PeiMPCore.inf
new file mode 100644
index 000000000..053f9fd9e
--- /dev/null
+++ b/roms/edk2/ArmPlatformPkg/PrePi/PeiMPCore.inf
@@ -0,0 +1,107 @@
+#/** @file
+#
+# (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
+# Copyright (c) 2011-2017, ARM Ltd. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ArmPlatformPrePiMPCore
+ FILE_GUID = d959e387-7b91-452c-90e0-a1dbac90ddb8
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+
+[Sources]
+ PrePi.h
+ PrePi.c
+ MainMPCore.c
+
+[Sources.ARM]
+ Arm/ArchPrePi.c
+ Arm/ModuleEntryPoint.S | GCC
+ Arm/ModuleEntryPoint.asm | RVCT
+
+[Sources.AArch64]
+ AArch64/ArchPrePi.c
+ AArch64/ModuleEntryPoint.S
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ CacheMaintenanceLib
+ DebugLib
+ DebugAgentLib
+ ArmLib
+ ArmGicLib
+ IoLib
+ TimerLib
+ SerialPortLib
+ ExtractGuidedSectionLib
+ LzmaDecompressLib
+ DebugAgentLib
+ PrePiLib
+ ArmPlatformLib
+ ArmPlatformStackLib
+ MemoryAllocationLib
+ HobLib
+ PrePiHobListPointerLib
+ PlatformPeiLib
+ MemoryInitPeiLib
+
+[Ppis]
+ gArmMpCoreInfoPpiGuid
+
+[Guids]
+ gArmMpCoreInfoGuid
+ gEfiFirmwarePerformanceGuid
+
+[FeaturePcd]
+ gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
+ gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdVFPEnabled
+
+ gArmTokenSpaceGuid.PcdFdBaseAddress
+ gArmTokenSpaceGuid.PcdFdSize
+
+ gArmTokenSpaceGuid.PcdFvBaseAddress
+ gArmTokenSpaceGuid.PcdFvSize
+
+ gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize
+ gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize
+
+ gArmTokenSpaceGuid.PcdGicDistributorBase
+ gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
+ gArmTokenSpaceGuid.PcdGicSgiIntId
+
+ gArmTokenSpaceGuid.PcdSystemMemoryBase
+ gArmTokenSpaceGuid.PcdSystemMemorySize
+ gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
+
+ gArmPlatformTokenSpaceGuid.PcdCoreCount
+
+ gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize
+
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData
+
diff --git a/roms/edk2/ArmPlatformPkg/PrePi/PeiUniCore.inf b/roms/edk2/ArmPlatformPkg/PrePi/PeiUniCore.inf
new file mode 100644
index 000000000..78d218ae0
--- /dev/null
+++ b/roms/edk2/ArmPlatformPkg/PrePi/PeiUniCore.inf
@@ -0,0 +1,103 @@
+#/** @file
+#
+# (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
+# Copyright (c) 2011-2017, ARM Ltd. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ArmPlatformPrePiUniCore
+ FILE_GUID = d959e387-7b91-452c-90e0-a1dbac90ddb8
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+
+[Sources]
+ PrePi.h
+ PrePi.c
+ MainUniCore.c
+
+[Sources.ARM]
+ Arm/ArchPrePi.c
+ Arm/ModuleEntryPoint.S | GCC
+ Arm/ModuleEntryPoint.asm | RVCT
+
+[Sources.AArch64]
+ AArch64/ArchPrePi.c
+ AArch64/ModuleEntryPoint.S
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ CacheMaintenanceLib
+ DebugLib
+ DebugAgentLib
+ ArmLib
+ IoLib
+ TimerLib
+ SerialPortLib
+ ExtractGuidedSectionLib
+ LzmaDecompressLib
+ DebugAgentLib
+ PrePiLib
+ ArmPlatformLib
+ ArmPlatformStackLib
+ MemoryAllocationLib
+ HobLib
+ PrePiHobListPointerLib
+ PlatformPeiLib
+ MemoryInitPeiLib
+
+[Ppis]
+ gArmMpCoreInfoPpiGuid
+
+[Guids]
+ gArmMpCoreInfoGuid
+ gEfiFirmwarePerformanceGuid
+
+[FeaturePcd]
+ gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
+ gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdVFPEnabled
+
+ gArmTokenSpaceGuid.PcdFdBaseAddress
+ gArmTokenSpaceGuid.PcdFdSize
+
+ gArmTokenSpaceGuid.PcdFvBaseAddress
+ gArmTokenSpaceGuid.PcdFvSize
+
+ gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize
+ gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize
+
+ gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
+
+ gArmPlatformTokenSpaceGuid.PcdCoreCount
+
+ 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
diff --git a/roms/edk2/ArmPlatformPkg/PrePi/PrePi.c b/roms/edk2/ArmPlatformPkg/PrePi/PrePi.c
new file mode 100644
index 000000000..5129dd09a
--- /dev/null
+++ b/roms/edk2/ArmPlatformPkg/PrePi/PrePi.c
@@ -0,0 +1,214 @@
+/** @file
+*
+* Copyright (c) 2011-2017, ARM Limited. All rights reserved.
+*
+* SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include <PiPei.h>
+
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/DebugAgentLib.h>
+#include <Library/PrePiLib.h>
+#include <Library/PrintLib.h>
+#include <Library/PrePiHobListPointerLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PerformanceLib.h>
+
+#include <Ppi/GuidedSectionExtraction.h>
+#include <Ppi/ArmMpCoreInfo.h>
+#include <Ppi/SecPerformance.h>
+
+#include "PrePi.h"
+
+#define IS_XIP() (((UINT64)FixedPcdGet64 (PcdFdBaseAddress) > mSystemMemoryEnd) || \
+ ((FixedPcdGet64 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) <= FixedPcdGet64 (PcdSystemMemoryBase)))
+
+UINT64 mSystemMemoryEnd = FixedPcdGet64(PcdSystemMemoryBase) +
+ FixedPcdGet64(PcdSystemMemorySize) - 1;
+
+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 UINT64 StartTimeStamp
+ )
+{
+ EFI_HOB_HANDOFF_INFO_TABLE* HobList;
+ ARM_MP_CORE_INFO_PPI* ArmMpCoreInfoPpi;
+ UINTN ArmCoreCount;
+ ARM_CORE_INFO* ArmCoreInfoTable;
+ EFI_STATUS Status;
+ CHAR8 Buffer[100];
+ UINTN CharCount;
+ UINTN StacksSize;
+ FIRMWARE_SEC_PERFORMANCE Performance;
+
+ // If ensure the FD is either part of the System Memory or totally outside of the System Memory (XIP)
+ ASSERT (IS_XIP() ||
+ ((FixedPcdGet64 (PcdFdBaseAddress) >= FixedPcdGet64 (PcdSystemMemoryBase)) &&
+ ((UINT64)(FixedPcdGet64 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) <= (UINT64)mSystemMemoryEnd)));
+
+ // 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);
+
+ // Initialize the Debug Agent for Source Level Debugging
+ InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, NULL, NULL);
+ SaveAndSetDebugTimerInterrupt (TRUE);
+
+ // 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)
+ if (ArmIsMpCore ()) {
+ StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize) +
+ ((FixedPcdGet32 (PcdCoreCount) - 1) * FixedPcdGet32 (PcdCPUCoreSecondaryStackSize));
+ } else {
+ StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize);
+ }
+ BuildStackHob (StacksBase, StacksSize);
+
+ //TODO: Call CpuPei as a library
+ BuildCpuHob (ArmGetPhysicalAddressBits (), PcdGet8 (PcdPrePiCpuIoSize));
+
+ if (ArmIsMpCore ()) {
+ // Only MP Core platform need to produce gArmMpCoreInfoPpiGuid
+ Status = GetPlatformPpi (&gArmMpCoreInfoPpiGuid, (VOID**)&ArmMpCoreInfoPpi);
+
+ // On MP Core Platform we must implement the ARM MP Core Info PPI (gArmMpCoreInfoPpiGuid)
+ ASSERT_EFI_ERROR (Status);
+
+ // Build the MP Core Info Table
+ ArmCoreCount = 0;
+ Status = ArmMpCoreInfoPpi->GetMpCoreInfo (&ArmCoreCount, &ArmCoreInfoTable);
+ if (!EFI_ERROR(Status) && (ArmCoreCount > 0)) {
+ // Build MPCore Info HOB
+ BuildGuidDataHob (&gArmMpCoreInfoGuid, ArmCoreInfoTable, sizeof (ARM_CORE_INFO) * ArmCoreCount);
+ }
+ }
+
+ // Store timer value logged at the beginning of firmware image execution
+ Performance.ResetEnd = GetTimeInNanoSecond (StartTimeStamp);
+
+ // Build SEC Performance Data Hob
+ BuildGuidDataHob (&gEfiFirmwarePerformanceGuid, &Performance, sizeof (Performance));
+
+ // 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.
+ 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;
+
+ // Initialize the platform specific controllers
+ ArmPlatformInitialize (MpId);
+
+ if (ArmPlatformIsPrimaryCore (MpId) && 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 ();
+
+ // Define the Global Variable region when we are not running in XIP
+ if (!IS_XIP()) {
+ if (ArmPlatformIsPrimaryCore (MpId)) {
+ if (ArmIsMpCore()) {
+ // Signal the Global Variable Region is defined (event: ARM_CPU_EVENT_DEFAULT)
+ ArmCallSEV ();
+ }
+ } else {
+ // Wait the Primary core has defined the address of the Global Variable region (event: ARM_CPU_EVENT_DEFAULT)
+ ArmCallWFE ();
+ }
+ }
+
+ // If not primary Jump to Secondary Main
+ if (ArmPlatformIsPrimaryCore (MpId)) {
+
+ InvalidateDataCacheRange ((VOID *)UefiMemoryBase,
+ FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
+
+ // Goto primary Main.
+ PrimaryMain (UefiMemoryBase, StacksBase, StartTimeStamp);
+ } else {
+ SecondaryMain (MpId);
+ }
+
+ // DXE Core should always load and never return
+ ASSERT (FALSE);
+}
diff --git a/roms/edk2/ArmPlatformPkg/PrePi/PrePi.h b/roms/edk2/ArmPlatformPkg/PrePi/PrePi.h
new file mode 100644
index 000000000..b64dd764a
--- /dev/null
+++ b/roms/edk2/ArmPlatformPkg/PrePi/PrePi.h
@@ -0,0 +1,90 @@
+/** @file
+*
+* Copyright (c) 2011-2015, 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>
+#include <Library/ArmPlatformLib.h>
+
+#define SerialPrint(txt) SerialPortWrite (txt, AsciiStrLen(txt)+1);
+
+extern UINT64 mSystemMemoryEnd;
+
+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
+ );
+
+VOID
+PrimaryMain (
+ IN UINTN UefiMemoryBase,
+ IN UINTN StacksBase,
+ IN UINT64 StartTimeStamp
+ );
+
+VOID
+SecondaryMain (
+ IN UINTN MpId
+ );
+
+// 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
+ );
+
+VOID
+EFIAPI
+ProcessLibraryConstructorList (
+ VOID
+ );
+
+#endif /* _PREPI_H_ */