From af1a266670d040d2f4083ff309d732d648afba2a Mon Sep 17 00:00:00 2001 From: Angelos Mouzakitis Date: Tue, 10 Oct 2023 14:33:42 +0000 Subject: Add submodule dependency files Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec --- roms/edk2/ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c | 34 ++++ .../PrePi/AArch64/ModuleEntryPoint.S | 116 +++++++++++ roms/edk2/ArmPlatformPkg/PrePi/Arm/ArchPrePi.c | 23 +++ .../ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.S | 124 ++++++++++++ .../ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.asm | 142 ++++++++++++++ roms/edk2/ArmPlatformPkg/PrePi/MainMPCore.c | 99 ++++++++++ roms/edk2/ArmPlatformPkg/PrePi/MainUniCore.c | 32 +++ roms/edk2/ArmPlatformPkg/PrePi/PeiMPCore.inf | 107 +++++++++++ roms/edk2/ArmPlatformPkg/PrePi/PeiUniCore.inf | 103 ++++++++++ roms/edk2/ArmPlatformPkg/PrePi/PrePi.c | 214 +++++++++++++++++++++ roms/edk2/ArmPlatformPkg/PrePi/PrePi.h | 90 +++++++++ 11 files changed, 1084 insertions(+) create mode 100644 roms/edk2/ArmPlatformPkg/PrePi/AArch64/ArchPrePi.c create mode 100644 roms/edk2/ArmPlatformPkg/PrePi/AArch64/ModuleEntryPoint.S create mode 100644 roms/edk2/ArmPlatformPkg/PrePi/Arm/ArchPrePi.c create mode 100644 roms/edk2/ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.S create mode 100644 roms/edk2/ArmPlatformPkg/PrePi/Arm/ModuleEntryPoint.asm create mode 100644 roms/edk2/ArmPlatformPkg/PrePi/MainMPCore.c create mode 100644 roms/edk2/ArmPlatformPkg/PrePi/MainUniCore.c create mode 100644 roms/edk2/ArmPlatformPkg/PrePi/PeiMPCore.inf create mode 100644 roms/edk2/ArmPlatformPkg/PrePi/PeiUniCore.inf create mode 100644 roms/edk2/ArmPlatformPkg/PrePi/PrePi.c create mode 100644 roms/edk2/ArmPlatformPkg/PrePi/PrePi.h (limited to 'roms/edk2/ArmPlatformPkg/PrePi') 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 + +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 + +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 + +#include + +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 +#include + + 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 + +#include + +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.
+# Copyright (c) 2011-2017, ARM Ltd. All rights reserved.
+# +# 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.
+# Copyright (c) 2011-2017, ARM Ltd. All rights reserved.
+# +# 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 + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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_ */ -- cgit 1.2.3-korg