ArmPlatformPkg: Clone PrePiUniCore into PeilessSec

PrePiUniCore was already spectacularly mis-named but now that the
UniCore bit has become redundant too, let's rename it in a way that
conveys its purpose a bit better: PeilessSec.

A straight rename would break all out-of-tree users, so clone it into a
new module with a fresh GUID, giving users some time to update.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
This commit is contained in:
Ard Biesheuvel 2024-07-30 20:33:21 +02:00 committed by mergify[bot]
parent bbe26ca2cc
commit 91117d70d8
8 changed files with 607 additions and 0 deletions

View File

@ -123,5 +123,6 @@
ArmPlatformPkg/PrePeiCore/PrePeiCoreUniCore.inf
ArmPlatformPkg/PrePi/PeiUniCore.inf
ArmPlatformPkg/PeilessSec/PeilessSec.inf
ArmPlatformPkg/Library/ArmMaliDp/ArmMaliDp.inf

View File

@ -0,0 +1,37 @@
/** @file
Copyright (c) 2011-2017, ARM Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "PeilessSec.h"
#include <AArch64/AArch64.h>
/**
Architecture specific initialization routine.
**/
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);
}
}

View File

@ -0,0 +1,89 @@
//
// Copyright (c) 2011 - 2020, Arm Limited. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
//
#include <AsmMacroIoLibV8.h>
ASM_FUNC(_ModuleEntryPoint)
// Do early platform specific actions
bl ASM_PFX(ArmPlatformPeiBootAction)
_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 SEC 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 x0, x1, x4
_GetStackBase:
// r1 = The top of the stack
mov sp, x1
// Stack for the primary core = PrimaryCoreStack
MOV32 (x2, FixedPcdGet32(PcdCPUCorePrimaryStackSize))
sub x1, x1, x2
// 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 SEC C code
// x0 = UefiMemoryBase
// x1 = StacksBase
blr x4
_NeverReturn:
b _NeverReturn

View File

@ -0,0 +1,25 @@
/** @file
Copyright (c) 2011 - 2013, ARM Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "PeilessSec.h"
/**
Architecture specific initialization routine.
**/
VOID
ArchInitialize (
VOID
)
{
// Enable program flow prediction, if supported.
ArmEnableBranchPrediction ();
if (FixedPcdGet32 (PcdVFPEnabled)) {
ArmEnableVFP ();
}
}

View File

@ -0,0 +1,96 @@
//
// Copyright (c) 2011 - 2020, Arm Limited. All rights reserved.<BR>
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
//
#include <AsmMacroIoLib.h>
#include <Arm/AArch32.h>
ASM_FUNC(_ModuleEntryPoint)
// Do early platform specific actions
bl ASM_PFX(ArmPlatformPeiBootAction)
_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 SEC 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 r0, r1, r4
_GetStackBase:
// r1 = The top of the stack
mov sp, r1
// Stack for the primary core = PrimaryCoreStack
MOV32 (r2, FixedPcdGet32(PcdCPUCorePrimaryStackSize))
sub r1, r1, r2
// 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 SEC C code
// r0 = UefiMemoryBase
// r1 = StacksBase
blx r4
_NeverReturn:
b _NeverReturn

View File

@ -0,0 +1,205 @@
/** @file
Copyright (c) 2011-2017, ARM Limited. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "PeilessSec.h"
#define IS_XIP() (((UINT64)FixedPcdGet64 (PcdFdBaseAddress) > mSystemMemoryEnd) ||\
((FixedPcdGet64 (PcdFdBaseAddress) + FixedPcdGet32 (PcdFdSize)) <= FixedPcdGet64 (PcdSystemMemoryBase)))
UINT64 mSystemMemoryEnd = FixedPcdGet64 (PcdSystemMemoryBase) +
FixedPcdGet64 (PcdSystemMemorySize) - 1;
/**
Obtain a PPI from the list of PPIs provided by the platform code.
@param[in] PpiGuid GUID of the PPI to obtain
@param[out] Ppi Address of GUID pointer to return the PPI
@return Whether the PPI was obtained successfully
**/
STATIC
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;
}
/**
SEC main routine.
@param[in] UefiMemoryBase Start of the PI/UEFI memory region
@param[in] StackBase Start of the stack
@param[in] StartTimeStamp Timer value at start of execution
**/
STATIC
VOID
SecMain (
IN UINTN UefiMemoryBase,
IN UINTN StackBase,
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 *)StackBase // The top of the UEFI Memory is reserved for the stack
);
PrePeiSetHobList (HobList);
// Initialize MMU and Memory HOBs (Resource Descriptor HOBs)
Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
ASSERT_EFI_ERROR (Status);
// Create the Stacks HOB
StacksSize = PcdGet32 (PcdCPUCorePrimaryStackSize);
BuildStackHob (StackBase, 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);
}
/**
C entrypoint into the SEC driver.
@param[in] UefiMemoryBase Start of the PI/UEFI memory region
@param[in] StackBase Start of the stack
**/
VOID
CEntryPoint (
IN UINTN UefiMemoryBase,
IN UINTN StackBase
)
{
UINT64 StartTimeStamp;
// Initialize the platform specific controllers
ArmPlatformInitialize (ArmReadMpidr ());
if (PerformanceMeasurementEnabled ()) {
// 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 ();
InvalidateDataCacheRange (
(VOID *)UefiMemoryBase,
FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)
);
SecMain (UefiMemoryBase, StackBase, StartTimeStamp);
// DXE Core should always load and never return
ASSERT (FALSE);
}

View File

@ -0,0 +1,76 @@
/** @file
Copyright (c) 2011 - 2020, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef PEILESSSEC_H_
#define PEILESSSEC_H_
#include <PiPei.h>
#include <Library/ArmLib.h>
#include <Library/ArmPlatformLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/DebugAgentLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/PerformanceLib.h>
#include <Library/PrePiHobListPointerLib.h>
#include <Library/PrePiLib.h>
#include <Library/PrintLib.h>
#include <Library/SerialPortLib.h>
#include <Library/TimerLib.h>
#include <Ppi/ArmMpCoreInfo.h>
#include <Ppi/GuidedSectionExtraction.h>
#include <Ppi/SecPerformance.h>
extern UINT64 mSystemMemoryEnd;
/**
Entrypoint of the memory PEIM driver.
@param[in] UefiMemoryBase The base of the PI/UEFI memory region
@param[in[ UefiMemorySize The size of the PI/UEFI memory region
@return Whether the memory PEIM driver executed successfully
**/
EFI_STATUS
EFIAPI
MemoryPeim (
IN EFI_PHYSICAL_ADDRESS UefiMemoryBase,
IN UINT64 UefiMemorySize
);
/**
Entrypoint of platform PEIM driver.
@return Whether the platform PEIM driver executed successfully
**/
EFI_STATUS
EFIAPI
PlatformPeim (
VOID
);
/**
Populate and install the memory type information HOB.
**/
VOID
BuildMemoryTypeInformationHob (
VOID
);
/**
Architecture specific initialization routine.
**/
VOID
ArchInitialize (
VOID
);
#endif /* PEILESSSEC_H_ */

View File

@ -0,0 +1,78 @@
## @file
# SEC driver for PEI-less ARM platforms.
#
# Copyright (C) 2015 Hewlett-Packard Development Company, L.P.<BR>
# Copyright (c) 2011-2017, ARM Ltd. All rights reserved.<BR>
# Copyright (c) 2020, Arm Limited. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
[Defines]
INF_VERSION = 1.30
BASE_NAME = PeilessSec
FILE_GUID = d90b03a8-2df5-4174-9ec1-c6e5b12b334b
MODULE_TYPE = SEC
VERSION_STRING = 1.0
[Sources]
PeilessSec.h
PeilessSec.c
[Sources.ARM]
Arm/ArchPeilessSec.c
Arm/ModuleEntryPoint.S
[Sources.AArch64]
AArch64/ArchPeilessSec.c
AArch64/ModuleEntryPoint.S
[Packages]
ArmPlatformPkg/ArmPlatformPkg.dec
ArmPkg/ArmPkg.dec
EmbeddedPkg/EmbeddedPkg.dec
MdeModulePkg/MdeModulePkg.dec
MdePkg/MdePkg.dec
[LibraryClasses]
ArmLib
ArmPlatformLib
BaseMemoryLib
CacheMaintenanceLib
DebugAgentLib
DebugLib
HobLib
MemoryInitPeiLib
PerformanceLib
PlatformPeiLib
PrePiHobListPointerLib
PrePiLib
PrintLib
SerialPortLib
TimerLib
[Ppis]
gArmMpCoreInfoPpiGuid
[Guids]
gArmMpCoreInfoGuid
gEfiFirmwarePerformanceGuid
[FeaturePcd]
gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
[FixedPcd]
gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize
gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
gArmTokenSpaceGuid.PcdFdBaseAddress
gArmTokenSpaceGuid.PcdFdSize
gArmTokenSpaceGuid.PcdFvBaseAddress
gArmTokenSpaceGuid.PcdFvSize
gArmTokenSpaceGuid.PcdVFPEnabled
gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize
[Pcd]
gArmTokenSpaceGuid.PcdSystemMemoryBase
gArmTokenSpaceGuid.PcdSystemMemorySize
gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString