diff --git a/ArmPlatformPkg/ArmPlatformPkg.dsc b/ArmPlatformPkg/ArmPlatformPkg.dsc
index 062246d8f2..278d3cf1f2 100644
--- a/ArmPlatformPkg/ArmPlatformPkg.dsc
+++ b/ArmPlatformPkg/ArmPlatformPkg.dsc
@@ -70,6 +70,7 @@
UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+ ArmTransferListLib|ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.inf
[LibraryClasses.common.PEIM]
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
diff --git a/ArmPlatformPkg/PeilessSec/AArch64/ModuleEntryPoint.S b/ArmPlatformPkg/PeilessSec/AArch64/ModuleEntryPoint.S
index 5f285f3f13..94635ef8d3 100644
--- a/ArmPlatformPkg/PeilessSec/AArch64/ModuleEntryPoint.S
+++ b/ArmPlatformPkg/PeilessSec/AArch64/ModuleEntryPoint.S
@@ -1,13 +1,29 @@
//
-// Copyright (c) 2011 - 2020, Arm Limited. All rights reserved.
+// Copyright (c) 2011 - 2025, Arm Limited. All rights reserved.
//
// SPDX-License-Identifier: BSD-2-Clause-Patent
//
+// @Par Reference(s):
+// - Firmware Handoff specification [https://firmwarehandoff.github.io/firmware_handoff/main]
//
#include
ASM_FUNC(_ModuleEntryPoint)
+
+ // Check if register assignment at handoff matches spec
+ MOV64 (x4, 0x14a0fb10b)
+ cmp x1, x4
+ // Skip TransferList init if x1 is not equal to the TransferList signature
+ b.ne _SkipTransferList
+
+ // Skip TransferList init if x2 is not equal to 0
+ cbnz x2, _SkipTransferList
+
+ // Set the TransferList Base Address from register x3
+ mov x6, x3
+
+_SkipTransferList:
// Do early platform specific actions
bl ASM_PFX(ArmPlatformPeiBootAction)
@@ -76,6 +92,8 @@ _GetStackBase:
MOV32 (x2, FixedPcdGet32(PcdCPUCorePrimaryStackSize))
sub x1, x1, x2
+ // Pass Transfer List Base Address
+ mov x2, x6
// 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)
diff --git a/ArmPlatformPkg/PeilessSec/PeilessSec.c b/ArmPlatformPkg/PeilessSec/PeilessSec.c
index 639c3744c9..95b81485a1 100644
--- a/ArmPlatformPkg/PeilessSec/PeilessSec.c
+++ b/ArmPlatformPkg/PeilessSec/PeilessSec.c
@@ -53,13 +53,15 @@ GetPlatformPpi (
@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
+ @param[in] TransferListBaseAddr Base address of the Transfer List
**/
STATIC
VOID
SecMain (
IN UINTN UefiMemoryBase,
IN UINTN StackBase,
- IN UINT64 StartTimeStamp
+ IN UINT64 StartTimeStamp,
+ IN UINTN TransferListBaseAddr
)
{
EFI_HOB_HANDOFF_INFO_TABLE *HobList;
@@ -71,6 +73,7 @@ SecMain (
UINTN CharCount;
UINTN StacksSize;
FIRMWARE_SEC_PERFORMANCE Performance;
+ VOID *TransferListBase;
// If ensure the FD is either part of the System Memory or totally outside of the System Memory (XIP)
ASSERT (
@@ -134,6 +137,20 @@ SecMain (
}
}
+ // Dump the Transfer List
+ TransferListBase = (VOID *)TransferListBaseAddr;
+ if (TransferListBase != NULL) {
+ if (TransferListCheckHeader (TransferListBase) != TRANSFER_LIST_OPS_INVALID) {
+ DEBUG_CODE_BEGIN ();
+ TransferListDump (TransferListBase);
+ DEBUG_CODE_END ();
+ } else {
+ DEBUG ((DEBUG_ERROR, "%a: No valid operations possible on TransferList found @ 0x%p\n", __func__, TransferListBase));
+ }
+ } else {
+ DEBUG ((DEBUG_INFO, "%a: No TransferList found, continuing boot\n", __func__));
+ }
+
// Store timer value logged at the beginning of firmware image execution
Performance.ResetEnd = GetTimeInNanoSecond (StartTimeStamp);
@@ -167,11 +184,13 @@ SecMain (
@param[in] UefiMemoryBase Start of the PI/UEFI memory region
@param[in] StackBase Start of the stack
+ @param[in] TransferListBaseAddr Base address of the Transfer List
**/
VOID
CEntryPoint (
IN UINTN UefiMemoryBase,
- IN UINTN StackBase
+ IN UINTN StackBase,
+ IN UINTN TransferListBaseAddr
)
{
UINT64 StartTimeStamp;
@@ -198,7 +217,7 @@ CEntryPoint (
FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)
);
- SecMain (UefiMemoryBase, StackBase, StartTimeStamp);
+ SecMain (UefiMemoryBase, StackBase, StartTimeStamp, TransferListBaseAddr);
// DXE Core should always load and never return
ASSERT (FALSE);
diff --git a/ArmPlatformPkg/PeilessSec/PeilessSec.h b/ArmPlatformPkg/PeilessSec/PeilessSec.h
index 70d78cafb0..217bf49f42 100644
--- a/ArmPlatformPkg/PeilessSec/PeilessSec.h
+++ b/ArmPlatformPkg/PeilessSec/PeilessSec.h
@@ -24,6 +24,7 @@
#include
#include
#include
+#include
#include
#include
diff --git a/ArmPlatformPkg/PeilessSec/PeilessSec.inf b/ArmPlatformPkg/PeilessSec/PeilessSec.inf
index e210d016da..4200d1a0e5 100644
--- a/ArmPlatformPkg/PeilessSec/PeilessSec.inf
+++ b/ArmPlatformPkg/PeilessSec/PeilessSec.inf
@@ -52,6 +52,7 @@
SerialPortLib
TimerLib
StackCheckLib
+ ArmTransferListLib
[Ppis]
gArmMpCoreInfoPpiGuid