StandaloneMm/Library: Apply transfer list boot protocol in StandaloneMm

To remove hob creation in StandaloneMm entrypoint,
TF-A should pass PHIT hob information to StandaloneMm.
When it passes PHIT hob, it passes according to
firmware handoff specification[0].

This patch applies boot protocol using transfer list with firmware
handoff specification and remove hob creation in StandaloneMm
entrypoint.

Link: https://github.com/FirmwareHandoff/firmware_handoff [0]

Signed-off-by: Levi Yun <yeoreum.yun@arm.com>
This commit is contained in:
Levi Yun 2024-08-21 16:08:54 +01:00 committed by mergify[bot]
parent 54e394b4a2
commit a5212d3db7
5 changed files with 561 additions and 451 deletions

View File

@ -2,20 +2,66 @@
Entry point to the Standalone MM Foundation when initialized during the SEC Entry point to the Standalone MM Foundation when initialized during the SEC
phase on ARM platforms phase on ARM platforms
Copyright (c) 2017 - 2021, Arm Ltd. All rights reserved.<BR> Copyright (c) 2017 - 2024, Arm Ltd. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent SPDX-License-Identifier: BSD-2-Clause-Patent
@par Glossary:
- SPM_MM - An implementation where the Secure Partition Manager resides at EL3
with management services running from an isolated Secure Partitions
at S-EL0, and the communication protocol is the Management Mode(MM)
interface.
- FF-A - Firmware Framework for Arm A-profile
- TL - Transfer List
@par Reference(s):
- Transfer List [https://github.com/FirmwareHandoff/firmware_handoff]
- Secure Partition Manager [https://trustedfirmware-a.readthedocs.io/en/latest/components/secure-partition-manager-mm.html].
- Arm Firmware Framework for Arm A-Profile [https://developer.arm.com/documentation/den0077/j/?lang=en]
**/ **/
#ifndef __STANDALONEMMCORE_ENTRY_POINT_H__ #ifndef __STANDALONEMMCORE_ENTRY_POINT_H__
#define __STANDALONEMMCORE_ENTRY_POINT_H__ #define __STANDALONEMMCORE_ENTRY_POINT_H__
#include <StandaloneMmCpu.h>
#include <Library/PeCoffLib.h> #include <Library/PeCoffLib.h>
#include <Library/FvLib.h> #include <Library/FvLib.h>
#define CPU_INFO_FLAG_PRIMARY_CPU 0x00000001 #define CPU_INFO_FLAG_PRIMARY_CPU 0x00000001
/*
* BOOT protocol used to boot StandaloneMm
*/
typedef enum {
/// Unknown Boot protocol.
BootProtocolUnknown,
/// Boot information delivered via Transfer List
/// with 32 bits register convention
BootProtocolTl32,
/// Boot information delivered via Transfer List
/// with 64 bits register convention
BootProtocolTl64,
BootProtocolMax,
} BOOT_PROTOCOL;
/*
* Communication ABI protocol to communicate between normal/secure partition.
*/
typedef enum {
/// Unknown Communication ABI protocol
AbiProtocolUnknown,
/// Communicate via SPM_MM ABI protocol
AbiProtocolSpmMm,
/// Communicate via FF-A ABI protocol
AbiProtocolFfa,
AbiProtocolMax,
} ABI_PROTOCOL;
typedef struct { typedef struct {
UINT8 Type; /* type of the structure */ UINT8 Type; /* type of the structure */
UINT8 Version; /* version of this structure */ UINT8 Version; /* version of this structure */
@ -23,31 +69,6 @@ typedef struct {
UINT32 Attr; /* attributes: unused bits SBZ */ UINT32 Attr; /* attributes: unused bits SBZ */
} EFI_PARAM_HEADER; } EFI_PARAM_HEADER;
typedef struct {
UINT64 Mpidr;
UINT32 LinearId;
UINT32 Flags;
} EFI_SECURE_PARTITION_CPU_INFO;
typedef struct {
EFI_PARAM_HEADER Header;
UINT64 SpMemBase;
UINT64 SpMemLimit;
UINT64 SpImageBase;
UINT64 SpStackBase;
UINT64 SpHeapBase;
UINT64 SpNsCommBufBase;
UINT64 SpSharedBufBase;
UINT64 SpImageSize;
UINT64 SpPcpuStackSize;
UINT64 SpHeapSize;
UINT64 SpNsCommBufSize;
UINT64 SpSharedBufSize;
UINT32 NumSpMemRegions;
UINT32 NumCpus;
EFI_SECURE_PARTITION_CPU_INFO *CpuInfo;
} EFI_SECURE_PARTITION_BOOT_INFO;
typedef RETURN_STATUS (*REGION_PERMISSION_UPDATE_FUNC) ( typedef RETURN_STATUS (*REGION_PERMISSION_UPDATE_FUNC) (
IN EFI_PHYSICAL_ADDRESS BaseAddress, IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length IN UINT64 Length
@ -122,36 +143,22 @@ LocateStandaloneMmCorePeCoffData (
IN OUT UINTN *TeDataSize IN OUT UINTN *TeDataSize
); );
/**
Use the boot information passed by privileged firmware to populate a HOB list
suitable for consumption by the MM Core and drivers.
@param [in] PayloadBootInfo Boot information passed by privileged
firmware
**/
VOID *
EFIAPI
CreateHobListFromBootInfo (
IN EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo
);
/** /**
The entry point of Standalone MM Foundation. The entry point of Standalone MM Foundation.
@param [in] SharedBufAddress Pointer to the Buffer between SPM and SP. @param [in] Arg0 Boot information passed according to boot protocol.
@param [in] SharedBufSize Size of the shared buffer. @param [in] Arg1 Boot information passed according to boot protocol.
@param [in] cookie1 Cookie 1 @param [in] Arg2 Boot information passed according to boot protocol.
@param [in] cookie2 Cookie 2 @param [in] Arg3 Boot information passed according to boot protocol.
**/ **/
VOID VOID
EFIAPI EFIAPI
_ModuleEntryPoint ( _ModuleEntryPoint (
IN VOID *SharedBufAddress, IN UINTN Arg0,
IN UINT64 SharedBufSize, IN UINTN Arg1,
IN UINT64 cookie1, IN UINTN Arg2,
IN UINT64 cookie2 IN UINTN Arg3
); );
/** /**

View File

@ -1,194 +0,0 @@
/** @file
Creates HOB during Standalone MM Foundation entry point
on ARM platforms.
Copyright (c) 2017 - 2021, Arm Ltd. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <PiMm.h>
#include <PiPei.h>
#include <Guid/MmramMemoryReserve.h>
#include <Guid/MpInformation.h>
#include <StandaloneMmCpu.h>
#include <Library/Arm/StandaloneMmCoreEntryPoint.h>
#include <Library/ArmMmuLib.h>
#include <Library/ArmSvcLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/SerialPortLib.h>
#include <IndustryStandard/ArmStdSmc.h>
extern EFI_HOB_HANDOFF_INFO_TABLE *
HobConstructor (
IN VOID *EfiMemoryBegin,
IN UINTN EfiMemoryLength,
IN VOID *EfiFreeMemoryBottom,
IN VOID *EfiFreeMemoryTop
);
// GUID to identify HOB with whereabouts of communication buffer with Normal
// World
extern EFI_GUID gEfiStandaloneMmNonSecureBufferGuid;
// GUID to identify HOB where the entry point of the CPU driver will be
// populated to allow this entry point driver to invoke it upon receipt of an
// event
extern EFI_GUID gEfiMmCpuDriverEpDescriptorGuid;
/**
Use the boot information passed by privileged firmware to populate a HOB list
suitable for consumption by the MM Core and drivers.
@param [in, out] CpuDriverEntryPoint Address of MM CPU driver entrypoint
@param [in] PayloadBootInfo Boot information passed by privileged
firmware
**/
VOID *
CreateHobListFromBootInfo (
IN EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo
)
{
EFI_HOB_HANDOFF_INFO_TABLE *HobStart;
EFI_RESOURCE_ATTRIBUTE_TYPE Attributes;
UINT32 Index;
UINT32 BufferSize;
UINT32 Flags;
EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *MmramRangesHob;
EFI_MMRAM_DESCRIPTOR *MmramRanges;
EFI_MMRAM_DESCRIPTOR *NsCommBufMmramRange;
MP_INFORMATION_HOB_DATA *MpInformationHobData;
EFI_PROCESSOR_INFORMATION *ProcInfoBuffer;
EFI_SECURE_PARTITION_CPU_INFO *CpuInfo;
// Create a hoblist with a PHIT and EOH
HobStart = HobConstructor (
(VOID *)(UINTN)PayloadBootInfo->SpMemBase,
(UINTN)PayloadBootInfo->SpMemLimit - PayloadBootInfo->SpMemBase,
(VOID *)(UINTN)PayloadBootInfo->SpHeapBase,
(VOID *)(UINTN)(PayloadBootInfo->SpHeapBase + PayloadBootInfo->SpHeapSize)
);
// Check that the Hoblist starts at the bottom of the Heap
ASSERT (HobStart == (VOID *)(UINTN)PayloadBootInfo->SpHeapBase);
// Build a Boot Firmware Volume HOB
BuildFvHob (PayloadBootInfo->SpImageBase, PayloadBootInfo->SpImageSize);
// Build a resource descriptor Hob that describes the available physical
// memory range
Attributes = (
EFI_RESOURCE_ATTRIBUTE_PRESENT |
EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
EFI_RESOURCE_ATTRIBUTE_TESTED |
EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
);
BuildResourceDescriptorHob (
EFI_RESOURCE_SYSTEM_MEMORY,
Attributes,
(UINTN)PayloadBootInfo->SpMemBase,
PayloadBootInfo->SpMemLimit - PayloadBootInfo->SpMemBase
);
// Find the size of the GUIDed HOB with MP information
BufferSize = sizeof (MP_INFORMATION_HOB_DATA);
BufferSize += sizeof (EFI_PROCESSOR_INFORMATION) * PayloadBootInfo->NumCpus;
// Create a Guided MP information HOB to enable the ARM TF CPU driver to
// perform per-cpu allocations.
MpInformationHobData = BuildGuidHob (&gMpInformationHobGuid, BufferSize);
// Populate the MP information HOB with the topology information passed by
// privileged firmware
MpInformationHobData->NumberOfProcessors = PayloadBootInfo->NumCpus;
MpInformationHobData->NumberOfEnabledProcessors = PayloadBootInfo->NumCpus;
ProcInfoBuffer = MpInformationHobData->ProcessorInfoBuffer;
CpuInfo = PayloadBootInfo->CpuInfo;
for (Index = 0; Index < PayloadBootInfo->NumCpus; Index++) {
ProcInfoBuffer[Index].ProcessorId = CpuInfo[Index].Mpidr;
ProcInfoBuffer[Index].Location.Package = GET_CLUSTER_ID (CpuInfo[Index].Mpidr);
ProcInfoBuffer[Index].Location.Core = GET_CORE_ID (CpuInfo[Index].Mpidr);
ProcInfoBuffer[Index].Location.Thread = GET_CORE_ID (CpuInfo[Index].Mpidr);
Flags = PROCESSOR_ENABLED_BIT | PROCESSOR_HEALTH_STATUS_BIT;
if (CpuInfo[Index].Flags & CPU_INFO_FLAG_PRIMARY_CPU) {
Flags |= PROCESSOR_AS_BSP_BIT;
}
ProcInfoBuffer[Index].StatusFlag = Flags;
}
// Create a Guided HOB to tell the ARM TF CPU driver the location and length
// of the communication buffer shared with the Normal world.
NsCommBufMmramRange = (EFI_MMRAM_DESCRIPTOR *)BuildGuidHob (
&gEfiStandaloneMmNonSecureBufferGuid,
sizeof (EFI_MMRAM_DESCRIPTOR)
);
NsCommBufMmramRange->PhysicalStart = PayloadBootInfo->SpNsCommBufBase;
NsCommBufMmramRange->CpuStart = PayloadBootInfo->SpNsCommBufBase;
NsCommBufMmramRange->PhysicalSize = PayloadBootInfo->SpNsCommBufSize;
NsCommBufMmramRange->RegionState = EFI_CACHEABLE | EFI_ALLOCATED;
// Find the size of the GUIDed HOB with SRAM ranges
BufferSize = sizeof (EFI_MMRAM_HOB_DESCRIPTOR_BLOCK);
BufferSize += PayloadBootInfo->NumSpMemRegions * sizeof (EFI_MMRAM_DESCRIPTOR);
// Create a GUIDed HOB with SRAM ranges
MmramRangesHob = BuildGuidHob (&gEfiMmPeiMmramMemoryReserveGuid, BufferSize);
// Fill up the number of MMRAM memory regions
MmramRangesHob->NumberOfMmReservedRegions = PayloadBootInfo->NumSpMemRegions;
// Fill up the MMRAM ranges
MmramRanges = &MmramRangesHob->Descriptor[0];
// Base and size of memory occupied by the Standalone MM image
MmramRanges[0].PhysicalStart = PayloadBootInfo->SpImageBase;
MmramRanges[0].CpuStart = PayloadBootInfo->SpImageBase;
MmramRanges[0].PhysicalSize = PayloadBootInfo->SpImageSize;
MmramRanges[0].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;
// Base and size of buffer shared with privileged Secure world software
MmramRanges[1].PhysicalStart = PayloadBootInfo->SpSharedBufBase;
MmramRanges[1].CpuStart = PayloadBootInfo->SpSharedBufBase;
MmramRanges[1].PhysicalSize = PayloadBootInfo->SpSharedBufSize;
MmramRanges[1].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;
// Base and size of buffer used for synchronous communication with Normal
// world software
MmramRanges[2].PhysicalStart = PayloadBootInfo->SpNsCommBufBase;
MmramRanges[2].CpuStart = PayloadBootInfo->SpNsCommBufBase;
MmramRanges[2].PhysicalSize = PayloadBootInfo->SpNsCommBufSize;
MmramRanges[2].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;
// Base and size of memory allocated for stacks for all cpus
MmramRanges[3].PhysicalStart = PayloadBootInfo->SpStackBase;
MmramRanges[3].CpuStart = PayloadBootInfo->SpStackBase;
MmramRanges[3].PhysicalSize = PayloadBootInfo->SpPcpuStackSize * PayloadBootInfo->NumCpus;
MmramRanges[3].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;
// Base and size of heap memory shared by all cpus
MmramRanges[4].PhysicalStart = (EFI_PHYSICAL_ADDRESS)(UINTN)HobStart;
MmramRanges[4].CpuStart = (EFI_PHYSICAL_ADDRESS)(UINTN)HobStart;
MmramRanges[4].PhysicalSize = HobStart->EfiFreeMemoryBottom - (EFI_PHYSICAL_ADDRESS)(UINTN)HobStart;
MmramRanges[4].RegionState = EFI_CACHEABLE | EFI_ALLOCATED;
// Base and size of heap memory shared by all cpus
MmramRanges[5].PhysicalStart = HobStart->EfiFreeMemoryBottom;
MmramRanges[5].CpuStart = HobStart->EfiFreeMemoryBottom;
MmramRanges[5].PhysicalSize = HobStart->EfiFreeMemoryTop - HobStart->EfiFreeMemoryBottom;
MmramRanges[5].RegionState = EFI_CACHEABLE;
return HobStart;
}

View File

@ -22,10 +22,12 @@
#include <PiPei.h> #include <PiPei.h>
#include <Guid/MmramMemoryReserve.h> #include <Guid/MmramMemoryReserve.h>
#include <Guid/MmCoreData.h>
#include <Guid/MpInformation.h> #include <Guid/MpInformation.h>
#include <StandaloneMmCpu.h> #include <Library/ArmLib.h>
#include <Library/ArmSvcLib.h> #include <Library/ArmSvcLib.h>
#include <Library/ArmTransferListLib.h>
#include <Library/DebugLib.h> #include <Library/DebugLib.h>
#include <Library/HobLib.h> #include <Library/HobLib.h>
#include <Library/BaseLib.h> #include <Library/BaseLib.h>
@ -40,87 +42,389 @@
#include <Protocol/PiMmCpuDriverEp.h> #include <Protocol/PiMmCpuDriverEp.h>
#define SPM_MAJOR_VER_MASK 0xFFFF0000
#define SPM_MINOR_VER_MASK 0x0000FFFF
#define SPM_MAJOR_VER_SHIFT 16
#define FFA_NOT_SUPPORTED -1
#define BOOT_PAYLOAD_VERSION 1
extern EFI_MM_SYSTEM_TABLE gMmCoreMmst; extern EFI_MM_SYSTEM_TABLE gMmCoreMmst;
STATIC CONST UINT32 mSpmMajorVer = SPM_MAJOR_VERSION; VOID *gHobList = NULL;
STATIC CONST UINT32 mSpmMinorVer = SPM_MINOR_VERSION;
STATIC CONST UINT32 mSpmMajorVerFfa = SPM_MAJOR_VERSION_FFA; STATIC MP_INFORMATION_HOB_DATA *mMpInfo = NULL;
STATIC CONST UINT32 mSpmMinorVerFfa = SPM_MINOR_VERSION_FFA;
/** /**
Retrieve a pointer to and print the boot information passed by privileged Get ABI protocol.
secure firmware.
@param [in] SharedBufAddress The pointer memory shared with privileged @retval AbiProtocolSpmMm SPM_MM ABI
firmware. @retval AbiProtocolFfa FF-A ABI
@retval AbiProtocolUnknown Invalid ABI.
**/ **/
EFI_SECURE_PARTITION_BOOT_INFO * STATIC
GetAndPrintBootinformation ( ABI_PROTOCOL
IN VOID *SharedBufAddress EFIAPI
GetAbiProtocol (
IN VOID
) )
{ {
EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo; UINT16 RequestMajorVersion;
EFI_SECURE_PARTITION_CPU_INFO *PayloadCpuInfo; UINT16 RequestMinorVersion;
UINTN Index; UINT16 CurrentMajorVersion;
UINT16 CurrentMinorVersion;
ARM_SVC_ARGS SvcArgs;
ABI_PROTOCOL AbiProtocol;
PayloadBootInfo = (EFI_SECURE_PARTITION_BOOT_INFO *)SharedBufAddress; ZeroMem (&SvcArgs, sizeof (ARM_SVC_ARGS));
SvcArgs.Arg0 = ARM_SVC_ID_FFA_VERSION_AARCH32;
SvcArgs.Arg1 = ((SPM_MAJOR_VERSION_FFA << 16) | (SPM_MINOR_VERSION_FFA));
if (PayloadBootInfo == NULL) { ArmCallSvc (&SvcArgs);
DEBUG ((DEBUG_ERROR, "PayloadBootInfo NULL\n"));
return NULL; if (SvcArgs.Arg0 != ARM_FFA_SPM_RET_NOT_SUPPORTED) {
AbiProtocol = AbiProtocolFfa;
RequestMajorVersion = SPM_MAJOR_VERSION_FFA;
RequestMinorVersion = SPM_MINOR_VERSION_FFA;
CurrentMajorVersion = ((SvcArgs.Arg0 >> 16) & 0xffff);
CurrentMinorVersion = (SvcArgs.Arg0 & 0xffff);
} else {
ZeroMem (&SvcArgs, sizeof (ARM_SVC_ARGS));
SvcArgs.Arg0 = ARM_FID_SPM_MM_VERSION_AARCH32;
ArmCallSvc (&SvcArgs);
if (SvcArgs.Arg0 == ARM_SPM_MM_RET_NOT_SUPPORTED) {
return AbiProtocolUnknown;
}
AbiProtocol = AbiProtocolSpmMm;
RequestMajorVersion = ARM_SPM_MM_SUPPORT_MAJOR_VERSION;
RequestMinorVersion = ARM_SPM_MM_SUPPORT_MINOR_VERSION;
CurrentMajorVersion =
((SvcArgs.Arg0 >> ARM_SPM_MM_MAJOR_VERSION_SHIFT) & ARM_SPM_MM_VERSION_MASK);
CurrentMinorVersion =
((SvcArgs.Arg0 >> ARM_SPM_MM_MINOR_VERSION_SHIFT) & ARM_SPM_MM_VERSION_MASK);
} }
if (PayloadBootInfo->Header.Version != BOOT_PAYLOAD_VERSION) { // Different major revision values indicate possibly incompatible functions.
// For two revisions, A and B, for which the major revision values are
// identical, if the minor revision value of revision B is greater than
// the minor revision value of revision A, then every function in
// revision A must work in a compatible way with revision B.
// However, it is possible for revision B to have a higher
// function count than revision A
if ((RequestMajorVersion != CurrentMajorVersion) ||
(RequestMinorVersion > CurrentMinorVersion))
{
DEBUG (( DEBUG ((
DEBUG_ERROR, DEBUG_INFO,
"Boot Information Version Mismatch. Current=0x%x, Expected=0x%x.\n", "Incompatible %s Versions.\n" \
PayloadBootInfo->Header.Version, "Request Version: Major=0x%x, Minor>=0x%x.\n" \
BOOT_PAYLOAD_VERSION "Current Version: Major=0x%x, Minor=0x%x.\n",
(AbiProtocol == AbiProtocolFfa) ? L"FF-A" : L"SPM_MM",
RequestMajorVersion,
RequestMinorVersion,
CurrentMajorVersion,
CurrentMinorVersion
)); ));
AbiProtocol = AbiProtocolUnknown;
} else {
DEBUG ((
DEBUG_INFO,
"%s Version: Major=0x%x, Minor=0x%x\n",
(AbiProtocol == AbiProtocolFfa) ? L"FF-A" : L"SPM_MM",
CurrentMajorVersion,
CurrentMinorVersion
));
}
return AbiProtocol;
}
/**
Get Boot protocol.
@param[in] Arg0 Arg0 passed from firmware
@param[in] Arg1 Arg1 passed from firmware
@param[in] Arg2 Arg2 passed from firmware
@param[in] Arg3 Arg3 passed from firmware
@retval BootProtocolTl64 64 bits register convention transfer list
@retval BootProtocolTl32 32 bits register convention transfer list
@retval BootProtocolUnknown Invalid Boot protocol
**/
STATIC
BOOT_PROTOCOL
EFIAPI
GetBootProtocol (
IN UINTN Arg0,
IN UINTN Arg1,
IN UINTN Arg2,
IN UINTN Arg3
)
{
UINTN RegVersion;
UINT64 Fields;
Fields = Arg1;
/*
* The signature value in x1's [23:0] bits is the same regardless of
* architecture when using Transfer list.
* That's why it need to check signature value in x1 again with [31:0] bits
* to discern 32 or 64 bits architecture after checking x1 value in [23:0].
* Please see:
* https://github.com/FirmwareHandoff/firmware_handoff/blob/main/source/register_conventions.rst
*/
if ((Fields & TRANSFER_LIST_SIGNATURE_MASK_32) == TRANSFER_LIST_SIGNATURE_32) {
if ((Fields & TRANSFER_LIST_SIGNATURE_MASK_64) == TRANSFER_LIST_SIGNATURE_64) {
RegVersion = (Fields >> REGISTER_CONVENTION_VERSION_SHIFT_64) &
REGISTER_CONVENTION_VERSION_MASK;
if ((RegVersion != 1) || (Arg2 != 0x00) || (Arg3 == 0x00)) {
goto err_out;
}
return BootProtocolTl64;
} else {
RegVersion = (Fields >> REGISTER_CONVENTION_VERSION_SHIFT_32) &
REGISTER_CONVENTION_VERSION_MASK;
if ((RegVersion != 1) || (Arg0 != 0x00) || (Arg3 == 0x00)) {
goto err_out;
}
return BootProtocolTl32;
}
}
err_out:
DEBUG ((DEBUG_ERROR, "Error: Failed to get boot protocol!\n"));
return BootProtocolUnknown;
}
/**
Get PHIT hob information from firmware handoff transfer list protocol.
@param[in] TlhAddr Transfer list header address
@retval NULL Failed to get PHIT hob
@retval Address PHIT hob address
**/
STATIC
VOID *
EFIAPI
GetPhitHobFromTransferList (
IN UINTN TlhAddr
)
{
TRANSFER_LIST_HEADER *Tlh;
TRANSFER_ENTRY_HEADER *Te;
VOID *HobStart;
Tlh = (TRANSFER_LIST_HEADER *)TlhAddr;
Te = TlFindFirstEntry (Tlh, TRANSFER_ENTRY_TAG_ID_HOB_LIST);
if (Te == NULL) {
DEBUG ((DEBUG_ERROR, "Error: No Phit hob is present in transfer list...\n"));
return NULL; return NULL;
} }
DEBUG ((DEBUG_INFO, "NumSpMemRegions - 0x%x\n", PayloadBootInfo->NumSpMemRegions)); HobStart = TlGetEntryData (Te);
DEBUG ((DEBUG_INFO, "SpMemBase - 0x%lx\n", PayloadBootInfo->SpMemBase));
DEBUG ((DEBUG_INFO, "SpMemLimit - 0x%lx\n", PayloadBootInfo->SpMemLimit));
DEBUG ((DEBUG_INFO, "SpImageBase - 0x%lx\n", PayloadBootInfo->SpImageBase));
DEBUG ((DEBUG_INFO, "SpStackBase - 0x%lx\n", PayloadBootInfo->SpStackBase));
DEBUG ((DEBUG_INFO, "SpHeapBase - 0x%lx\n", PayloadBootInfo->SpHeapBase));
DEBUG ((DEBUG_INFO, "SpNsCommBufBase - 0x%lx\n", PayloadBootInfo->SpNsCommBufBase));
DEBUG ((DEBUG_INFO, "SpSharedBufBase - 0x%lx\n", PayloadBootInfo->SpSharedBufBase));
DEBUG ((DEBUG_INFO, "SpImageSize - 0x%x\n", PayloadBootInfo->SpImageSize)); return HobStart;
DEBUG ((DEBUG_INFO, "SpPcpuStackSize - 0x%x\n", PayloadBootInfo->SpPcpuStackSize)); }
DEBUG ((DEBUG_INFO, "SpHeapSize - 0x%x\n", PayloadBootInfo->SpHeapSize));
DEBUG ((DEBUG_INFO, "SpNsCommBufSize - 0x%x\n", PayloadBootInfo->SpNsCommBufSize));
DEBUG ((DEBUG_INFO, "SpSharedBufSize - 0x%x\n", PayloadBootInfo->SpSharedBufSize));
DEBUG ((DEBUG_INFO, "NumCpus - 0x%x\n", PayloadBootInfo->NumCpus)); /**
DEBUG ((DEBUG_INFO, "CpuInfo - 0x%p\n", PayloadBootInfo->CpuInfo)); Get logical Cpu Number.
PayloadCpuInfo = (EFI_SECURE_PARTITION_CPU_INFO *)PayloadBootInfo->CpuInfo; @param [in] AbiProtocol Abi Protocol.
@param [in] EventCompleteSvcArgs Pointer to the event completion arguments.
if (PayloadCpuInfo == NULL) { @retval CpuNumber Cpu Number
DEBUG ((DEBUG_ERROR, "PayloadCpuInfo NULL\n")); **/
return NULL; STATIC
UINTN
EFIAPI
GetCpuNumber (
IN ABI_PROTOCOL AbiProtocol,
IN ARM_SVC_ARGS *EventCompleteSvcArgs
)
{
UINTN Idx;
if (AbiProtocol == AbiProtocolSpmMm) {
Idx = EventCompleteSvcArgs->Arg3;
} else {
Idx = EventCompleteSvcArgs->Arg6;
} }
for (Index = 0; Index < PayloadBootInfo->NumCpus; Index++) { ASSERT (Idx < mMpInfo->NumberOfProcessors);
DEBUG ((DEBUG_INFO, "Mpidr - 0x%lx\n", PayloadCpuInfo[Index].Mpidr));
DEBUG ((DEBUG_INFO, "LinearId - 0x%x\n", PayloadCpuInfo[Index].LinearId)); return Idx;
DEBUG ((DEBUG_INFO, "Flags - 0x%x\n", PayloadCpuInfo[Index].Flags)); }
/**
Dump mp information descriptor.
@param[in] ProcessorInfo Mp information
@param[in] Idx Cpu index
**/
STATIC
VOID
EFIAPI
DumpMpInfoDescriptor (
EFI_PROCESSOR_INFORMATION *ProcessorInfo,
UINTN Idx
)
{
if (ProcessorInfo == NULL) {
return;
} }
return PayloadBootInfo; DEBUG ((
DEBUG_INFO,
"CPU[%d]: MpIdr - 0x%lx\n",
Idx,
ProcessorInfo->ProcessorId
));
DEBUG ((
DEBUG_INFO,
"CPU[%d]: StatusFlag - 0x%lx\n",
Idx,
ProcessorInfo->StatusFlag
));
DEBUG ((
DEBUG_INFO,
"CPU[%d]: Location[P:C:T] - :%d:%d:%d\n",
Idx,
ProcessorInfo->Location.Package,
ProcessorInfo->Location.Core,
ProcessorInfo->Location.Thread
));
}
/**
Dump mmram descriptor.
@param[in] Name Name
@param[in] MmramDesc Mmram descriptor
**/
STATIC
VOID
EFIAPI
DumpMmramDescriptor (
IN CHAR16 *Name,
IN EFI_MMRAM_DESCRIPTOR *MmramDesc
)
{
if (MmramDesc == NULL) {
return;
}
if (Name == NULL) {
Name = L"Unknown";
}
DEBUG ((
DEBUG_INFO,
"MmramDescriptor[%s]: PhysicalStart - 0x%lx\n",
Name,
MmramDesc->PhysicalStart
));
DEBUG ((
DEBUG_INFO,
"MmramDescriptors[%s]: CpuStart - 0x%lx\n",
Name,
MmramDesc->CpuStart
));
DEBUG ((
DEBUG_INFO,
"MmramDescriptors[%s]: PhysicalSize - %ld\n",
Name,
MmramDesc->PhysicalSize
));
DEBUG ((
DEBUG_INFO,
"MmramDescriptors[%s]: RegionState - 0x%lx\n",
Name,
MmramDesc->RegionState
));
}
/**
Dump PHIT hob information.
@param[in] HobStart PHIT hob start address.
**/
STATIC
VOID
EFIAPI
DumpPhitHob (
IN VOID *HobStart
)
{
EFI_HOB_FIRMWARE_VOLUME *FvHob;
EFI_HOB_GUID_TYPE *GuidHob;
MP_INFORMATION_HOB_DATA *MpInfo;
EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *MmramRangesHobData;
EFI_MMRAM_DESCRIPTOR *MmramDesc;
UINTN Idx;
FvHob = GetNextHob (EFI_HOB_TYPE_FV, HobStart);
if (FvHob == NULL) {
DEBUG ((DEBUG_ERROR, "Error: No Firmware Volume Hob is present.\n"));
return;
}
DEBUG ((DEBUG_INFO, "FvHob: BaseAddress - 0x%lx\n", FvHob->BaseAddress));
DEBUG ((DEBUG_INFO, "FvHob: Length - %ld\n", FvHob->Length));
GuidHob = GetNextGuidHob (&gMpInformationHobGuid, HobStart);
if (GuidHob == NULL) {
DEBUG ((DEBUG_ERROR, "Error: No MpInformation Guid Hob is present.\n"));
return;
}
MpInfo = GET_GUID_HOB_DATA (GuidHob);
DEBUG ((DEBUG_INFO, "Number of Cpus - %d\n", MpInfo->NumberOfProcessors));
DEBUG ((
DEBUG_INFO,
"Number of Enabled Cpus - %d\n",
MpInfo->NumberOfEnabledProcessors
));
for (Idx = 0; Idx < MpInfo->NumberOfProcessors; Idx++) {
DumpMpInfoDescriptor (&MpInfo->ProcessorInfoBuffer[Idx], Idx);
}
GuidHob = GetNextGuidHob (&gEfiStandaloneMmNonSecureBufferGuid, HobStart);
if (GuidHob == NULL) {
DEBUG ((DEBUG_ERROR, "Error: No Ns Buffer Guid Hob is present.\n"));
return;
}
DumpMmramDescriptor (L"NsBuffer", GET_GUID_HOB_DATA (GuidHob));
GuidHob = GetNextGuidHob (&gEfiMmPeiMmramMemoryReserveGuid, HobStart);
if (GuidHob == NULL) {
DEBUG ((DEBUG_ERROR, "Error: No Pei Mmram Memory Reserved Guid Hob is present.\n"));
return;
}
MmramRangesHobData = GET_GUID_HOB_DATA (GuidHob);
if ((MmramRangesHobData == NULL) ||
(MmramRangesHobData->NumberOfMmReservedRegions == 0))
{
DEBUG ((DEBUG_ERROR, "Error: No Pei Mmram Memory Reserved information is present.\n"));
return;
}
for (Idx = 0; Idx < MmramRangesHobData->NumberOfMmReservedRegions; Idx++) {
MmramDesc = &MmramRangesHobData->Descriptor[Idx];
DumpMmramDescriptor (L"PeiMemReserved", MmramDesc);
}
} }
/** /**
@ -188,25 +492,25 @@ EfiStatusToFfaStatus (
} }
/** /**
Initialise Event Complete arguments to be returned via SVC call. Set Event Complete arguments to be returned via SVC call.
@param[in] FfaEnabled Ffa enabled. @param[in] AbiProtocol ABI Protocol.
@param[in] Status Result of StMm. @param[in] Status Result of StandaloneMm service.
@param[out] EventCompleteSvcArgs Args structure. @param[out] EventCompleteSvcArgs Args structure.
**/ **/
STATIC STATIC
VOID VOID
SetEventCompleteSvcArgs ( SetEventCompleteSvcArgs (
IN BOOLEAN FfaEnabled, IN ABI_PROTOCOL AbiProtocol,
IN EFI_STATUS Status, IN EFI_STATUS Status,
OUT ARM_SVC_ARGS *EventCompleteSvcArgs OUT ARM_SVC_ARGS *EventCompleteSvcArgs
) )
{ {
if (FfaEnabled) { ZeroMem (EventCompleteSvcArgs, sizeof (ARM_SVC_ARGS));
if (AbiProtocol == AbiProtocolFfa) {
EventCompleteSvcArgs->Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP; EventCompleteSvcArgs->Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP;
EventCompleteSvcArgs->Arg1 = 0;
EventCompleteSvcArgs->Arg2 = 0;
EventCompleteSvcArgs->Arg3 = ARM_FID_SPM_MM_SP_EVENT_COMPLETE; EventCompleteSvcArgs->Arg3 = ARM_FID_SPM_MM_SP_EVENT_COMPLETE;
EventCompleteSvcArgs->Arg4 = EfiStatusToFfaStatus (Status); EventCompleteSvcArgs->Arg4 = EfiStatusToFfaStatus (Status);
} else { } else {
@ -218,21 +522,23 @@ SetEventCompleteSvcArgs (
/** /**
A loop to delegated events. A loop to delegated events.
@param [in] AbiProtocol Abi Protocol.
@param [in] CpuDriverEntryPoint Entry point to handle request. @param [in] CpuDriverEntryPoint Entry point to handle request.
@param [in] EventCompleteSvcArgs Pointer to the event completion arguments. @param [in] EventCompleteSvcArgs Pointer to the event completion arguments.
**/ **/
STATIC
VOID VOID
EFIAPI EFIAPI
DelegatedEventLoop ( DelegatedEventLoop (
IN ABI_PROTOCOL AbiProtocol,
IN EDKII_PI_MM_CPU_DRIVER_ENTRYPOINT CpuDriverEntryPoint, IN EDKII_PI_MM_CPU_DRIVER_ENTRYPOINT CpuDriverEntryPoint,
IN ARM_SVC_ARGS *EventCompleteSvcArgs IN ARM_SVC_ARGS *EventCompleteSvcArgs
) )
{ {
BOOLEAN FfaEnabled;
EFI_STATUS Status; EFI_STATUS Status;
UINTN CpuNumber;
FfaEnabled = FeaturePcdGet (PcdFfaEnable); UINTN CommBufferAddr;
while (TRUE) { while (TRUE) {
ArmCallSvc (EventCompleteSvcArgs); ArmCallSvc (EventCompleteSvcArgs);
@ -247,174 +553,137 @@ DelegatedEventLoop (
DEBUG ((DEBUG_INFO, "X6 : 0x%x\n", (UINT32)EventCompleteSvcArgs->Arg6)); DEBUG ((DEBUG_INFO, "X6 : 0x%x\n", (UINT32)EventCompleteSvcArgs->Arg6));
DEBUG ((DEBUG_INFO, "X7 : 0x%x\n", (UINT32)EventCompleteSvcArgs->Arg7)); DEBUG ((DEBUG_INFO, "X7 : 0x%x\n", (UINT32)EventCompleteSvcArgs->Arg7));
// CpuNumber = GetCpuNumber (AbiProtocol, EventCompleteSvcArgs);
// ARM TF passes SMC FID of the MM_COMMUNICATE interface as the Event ID upon DEBUG ((DEBUG_INFO, "CpuNumber: %d\n", CpuNumber));
// receipt of a synchronous MM request. Use the Event ID to distinguish
// between synchronous and asynchronous events. if (AbiProtocol == AbiProtocolFfa) {
// if (EventCompleteSvcArgs->Arg0 != ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ) {
if ((ARM_SMC_ID_MM_COMMUNICATE != (UINT32)EventCompleteSvcArgs->Arg0) && Status = EFI_INVALID_PARAMETER;
(ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ != (UINT32)EventCompleteSvcArgs->Arg0)) DEBUG ((
{ DEBUG_ERROR,
DEBUG ((DEBUG_ERROR, "UnRecognized Event - 0x%x\n", (UINT32)EventCompleteSvcArgs->Arg0)); "Error: Unrecognized FF-A Id: 0x%x\n",
Status = EFI_INVALID_PARAMETER; EventCompleteSvcArgs->Arg0
} else { ));
if (FfaEnabled) { goto event_complete;
Status = CpuDriverEntryPoint (
EventCompleteSvcArgs->Arg0,
EventCompleteSvcArgs->Arg6,
EventCompleteSvcArgs->Arg3
);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
"Failed delegated event 0x%x, Status 0x%x\n",
EventCompleteSvcArgs->Arg3,
Status
));
}
} else {
Status = CpuDriverEntryPoint (
EventCompleteSvcArgs->Arg0,
EventCompleteSvcArgs->Arg3,
EventCompleteSvcArgs->Arg1
);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
"Failed delegated event 0x%x, Status 0x%x\n",
EventCompleteSvcArgs->Arg0,
Status
));
}
} }
CommBufferAddr = EventCompleteSvcArgs->Arg3;
} else {
/*
* Register Convention for SPM_MM
* Arg0: ARM_SMC_ID_MM_COMMUNICATE
* Arg1: Communication Buffer
* Arg2: Size of Communication Buffer
* Arg3: Cpu number where StandaloneMm running on.
*
* See tf-a/services/std_svc/spm/spm_mm/spm_mm_main.c
*/
if (EventCompleteSvcArgs->Arg0 != ARM_SMC_ID_MM_COMMUNICATE) {
Status = EFI_INVALID_PARAMETER;
DEBUG ((
DEBUG_ERROR,
"Error: Unrecognized SPM_MM Id: 0x%x\n",
EventCompleteSvcArgs->Arg0
));
goto event_complete;
}
CommBufferAddr = EventCompleteSvcArgs->Arg1;
} }
SetEventCompleteSvcArgs (FfaEnabled, Status, EventCompleteSvcArgs); Status = CpuDriverEntryPoint (EventCompleteSvcArgs->Arg0, CpuNumber, CommBufferAddr);
if (EFI_ERROR (Status)) {
DEBUG ((
DEBUG_ERROR,
"Error: Failed delegated event 0x%x, Status 0x%x\n",
CommBufferAddr,
Status
));
}
event_complete:
SetEventCompleteSvcArgs (
AbiProtocol,
Status,
EventCompleteSvcArgs
);
} }
} }
/**
Query the SPM version, check compatibility and return success if compatible.
@retval EFI_SUCCESS SPM versions compatible.
@retval EFI_UNSUPPORTED SPM versions not compatible.
**/
STATIC
EFI_STATUS
GetSpmVersion (
VOID
)
{
EFI_STATUS Status;
UINT16 CalleeSpmMajorVer;
UINT16 CallerSpmMajorVer;
UINT16 CalleeSpmMinorVer;
UINT16 CallerSpmMinorVer;
UINT32 SpmVersion;
ARM_SVC_ARGS SpmVersionArgs;
if (FeaturePcdGet (PcdFfaEnable)) {
SpmVersionArgs.Arg0 = ARM_SVC_ID_FFA_VERSION_AARCH32;
SpmVersionArgs.Arg1 = mSpmMajorVerFfa << SPM_MAJOR_VER_SHIFT;
SpmVersionArgs.Arg1 |= mSpmMinorVerFfa;
CallerSpmMajorVer = mSpmMajorVerFfa;
CallerSpmMinorVer = mSpmMinorVerFfa;
} else {
SpmVersionArgs.Arg0 = ARM_FID_SPM_MM_VERSION_AARCH32;
CallerSpmMajorVer = mSpmMajorVer;
CallerSpmMinorVer = mSpmMinorVer;
}
ArmCallSvc (&SpmVersionArgs);
SpmVersion = SpmVersionArgs.Arg0;
if (SpmVersion == FFA_NOT_SUPPORTED) {
return EFI_UNSUPPORTED;
}
CalleeSpmMajorVer = ((SpmVersion & SPM_MAJOR_VER_MASK) >> SPM_MAJOR_VER_SHIFT);
CalleeSpmMinorVer = ((SpmVersion & SPM_MINOR_VER_MASK) >> 0);
// Different major revision values indicate possibly incompatible functions.
// For two revisions, A and B, for which the major revision values are
// identical, if the minor revision value of revision B is greater than
// the minor revision value of revision A, then every function in
// revision A must work in a compatible way with revision B.
// However, it is possible for revision B to have a higher
// function count than revision A.
if ((CalleeSpmMajorVer == CallerSpmMajorVer) &&
(CalleeSpmMinorVer >= CallerSpmMinorVer))
{
DEBUG ((
DEBUG_INFO,
"SPM Version: Major=0x%x, Minor=0x%x\n",
CalleeSpmMajorVer,
CalleeSpmMinorVer
));
Status = EFI_SUCCESS;
} else {
DEBUG ((
DEBUG_INFO,
"Incompatible SPM Versions.\n Callee Version: Major=0x%x, Minor=0x%x.\n Caller: Major=0x%x, Minor>=0x%x.\n",
CalleeSpmMajorVer,
CalleeSpmMinorVer,
CallerSpmMajorVer,
CallerSpmMinorVer
));
Status = EFI_UNSUPPORTED;
}
return Status;
}
/** /**
The entry point of Standalone MM Foundation. The entry point of Standalone MM Foundation.
@param [in] SharedBufAddress Pointer to the Buffer between SPM and SP. @param [in] Arg0 Boot information passed according to boot protocol.
@param [in] SharedBufSize Size of the shared buffer. @param [in] Arg1 Boot information passed according to boot protocol.
@param [in] cookie1 Cookie 1 @param [in] Arg2 Boot information passed according to boot protocol.
@param [in] cookie2 Cookie 2 @param [in] Arg3 Boot information passed according to boot protocol.
**/ **/
VOID VOID
EFIAPI EFIAPI
_ModuleEntryPoint ( _ModuleEntryPoint (
IN VOID *SharedBufAddress, IN UINTN Arg0,
IN UINT64 SharedBufSize, IN UINTN Arg1,
IN UINT64 cookie1, IN UINTN Arg2,
IN UINT64 cookie2 IN UINTN Arg3
) )
{ {
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo;
ARM_SVC_ARGS EventCompleteSvcArgs; ARM_SVC_ARGS EventCompleteSvcArgs;
EFI_STATUS Status; EFI_STATUS Status;
UINT32 SectionHeaderOffset; UINT32 SectionHeaderOffset;
UINT16 NumberOfSections; UINT16 NumberOfSections;
BOOT_PROTOCOL BootProtocol;
ABI_PROTOCOL AbiProtocol;
VOID *HobStart; VOID *HobStart;
VOID *TeData; VOID *TeData;
UINTN TeDataSize; UINTN TeDataSize;
EFI_PHYSICAL_ADDRESS ImageBase; EFI_PHYSICAL_ADDRESS ImageBase;
EDKII_PI_MM_CPU_DRIVER_EP_PROTOCOL *PiMmCpuDriverEpProtocol; EDKII_PI_MM_CPU_DRIVER_EP_PROTOCOL *PiMmCpuDriverEpProtocol;
EDKII_PI_MM_CPU_DRIVER_ENTRYPOINT CpuDriverEntryPoint; EDKII_PI_MM_CPU_DRIVER_ENTRYPOINT CpuDriverEntryPoint;
EFI_HOB_FIRMWARE_VOLUME *FvHob;
EFI_HOB_GUID_TYPE *GuidHob;
EFI_CONFIGURATION_TABLE *ConfigurationTable;
UINTN Idx;
CpuDriverEntryPoint = NULL; CpuDriverEntryPoint = NULL;
// Get Secure Partition Manager Version Information AbiProtocol = GetAbiProtocol ();
Status = GetSpmVersion (); if (AbiProtocol == AbiProtocolUnknown) {
if (EFI_ERROR (Status)) { Status = EFI_UNSUPPORTED;
goto finish; goto finish;
} }
PayloadBootInfo = GetAndPrintBootinformation (SharedBufAddress); /**
if (PayloadBootInfo == NULL) { * Check boot information
*/
BootProtocol = GetBootProtocol (Arg0, Arg1, Arg2, Arg3);
if (BootProtocol == BootProtocolUnknown) {
Status = EFI_UNSUPPORTED; Status = EFI_UNSUPPORTED;
goto finish; goto finish;
} }
HobStart = GetPhitHobFromTransferList (Arg3);
if (HobStart == NULL) {
Status = EFI_UNSUPPORTED;
goto finish;
}
DEBUG ((DEBUG_INFO, "Start Dump Hob: %lx\n", (unsigned long)HobStart));
DumpPhitHob (HobStart);
DEBUG ((DEBUG_INFO, "End Dump Hob: %lx\n", (unsigned long)HobStart));
FvHob = GetNextHob (EFI_HOB_TYPE_FV, HobStart);
if (FvHob == NULL) {
DEBUG ((DEBUG_ERROR, "Error: No Firmware Volume Hob is present.\n"));
Status = EFI_INVALID_PARAMETER;
goto finish;
}
// Locate PE/COFF File information for the Standalone MM core module // Locate PE/COFF File information for the Standalone MM core module
Status = LocateStandaloneMmCorePeCoffData ( Status = LocateStandaloneMmCorePeCoffData (
(EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PayloadBootInfo->SpImageBase, (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvHob->BaseAddress,
&TeData, &TeData,
&TeDataSize &TeDataSize
); );
@ -457,7 +726,6 @@ _ModuleEntryPoint (
ArmSetMemoryRegionReadOnly, ArmSetMemoryRegionReadOnly,
ArmClearMemoryRegionReadOnly ArmClearMemoryRegionReadOnly
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
goto finish; goto finish;
} }
@ -471,16 +739,46 @@ _ModuleEntryPoint (
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR (Status);
} }
// gHobList = HobStart;
// Create Hoblist based upon boot information passed by privileged software
//
HobStart = CreateHobListFromBootInfo (PayloadBootInfo);
// //
// Call the MM Core entry point // Call the MM Core entry point
// //
ProcessModuleEntryPointList (HobStart); ProcessModuleEntryPointList (HobStart);
//
// Find HobList to check gEfiHobList is installed.
//
Status = EFI_NOT_FOUND;
ConfigurationTable = gMmCoreMmst.MmConfigurationTable;
for (Idx = 0; Idx < gMmCoreMmst.NumberOfTableEntries; Idx++) {
if (CompareGuid (&gEfiHobListGuid, &ConfigurationTable[Idx].VendorGuid)) {
Status = EFI_SUCCESS;
break;
}
}
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Error: Hoblist not found in MmConfigurationTable\n"));
goto finish;
}
//
// Find MpInformation Hob in HobList.
// It couldn't save address of mp information in gHobList
// because that memory area will be reused after StandaloneMm finishing
// initialization.
//
HobStart = ConfigurationTable[Idx].VendorTable;
GuidHob = GetNextGuidHob (&gMpInformationHobGuid, HobStart);
if (GuidHob == NULL) {
Status = EFI_NOT_FOUND;
DEBUG ((DEBUG_ERROR, "Error: No MpInformation hob ...\n"));
goto finish;
}
mMpInfo = GET_GUID_HOB_DATA (GuidHob);
// //
// Find out cpu driver entry point used in DelegatedEventLoop // Find out cpu driver entry point used in DelegatedEventLoop
// to handle MMI request. // to handle MMI request.
@ -503,11 +801,6 @@ _ModuleEntryPoint (
)); ));
finish: finish:
ZeroMem (&EventCompleteSvcArgs, sizeof (EventCompleteSvcArgs)); SetEventCompleteSvcArgs (AbiProtocol, Status, &EventCompleteSvcArgs);
SetEventCompleteSvcArgs ( DelegatedEventLoop (AbiProtocol, CpuDriverEntryPoint, &EventCompleteSvcArgs);
FeaturePcdGet (PcdFfaEnable),
Status,
&EventCompleteSvcArgs
);
DelegatedEventLoop (CpuDriverEntryPoint, t&EventCompleteSvcArgs);
} }

View File

@ -24,7 +24,6 @@
[Sources.AARCH64, Sources.ARM] [Sources.AARCH64, Sources.ARM]
Arm/StandaloneMmCoreEntryPoint.c Arm/StandaloneMmCoreEntryPoint.c
Arm/SetPermissions.c Arm/SetPermissions.c
Arm/CreateHobList.c
[Sources.X64] [Sources.X64]
X64/StandaloneMmCoreEntryPoint.c X64/StandaloneMmCoreEntryPoint.c
@ -44,12 +43,16 @@
[LibraryClasses.ARM, LibraryClasses.AARCH64] [LibraryClasses.ARM, LibraryClasses.AARCH64]
StandaloneMmMmuLib StandaloneMmMmuLib
ArmSvcLib ArmSvcLib
ArmTransferListLib
[Guids] [Guids]
gMpInformationHobGuid gMpInformationHobGuid
gEfiMmPeiMmramMemoryReserveGuid gEfiMmPeiMmramMemoryReserveGuid
gEfiStandaloneMmNonSecureBufferGuid gEfiStandaloneMmNonSecureBufferGuid
[Guids.ARM, Guids.AARCH64]
gEfiHobListGuid
[Protocols.ARM, Protocols.AARCH64] [Protocols.ARM, Protocols.AARCH64]
gEdkiiPiMmCpuDriverEpProtocolGuid gEdkiiPiMmCpuDriverEpProtocolGuid

View File

@ -78,6 +78,7 @@
ArmSvcLib|ArmPkg/Library/ArmSvcLib/ArmSvcLib.inf ArmSvcLib|ArmPkg/Library/ArmSvcLib/ArmSvcLib.inf
CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
PeCoffExtraActionLib|StandaloneMmPkg/Library/StandaloneMmPeCoffExtraActionLib/StandaloneMmPeCoffExtraActionLib.inf PeCoffExtraActionLib|StandaloneMmPkg/Library/StandaloneMmPeCoffExtraActionLib/StandaloneMmPeCoffExtraActionLib.inf
ArmTransferListLib|ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.inf
[LibraryClasses.common.MM_CORE_STANDALONE] [LibraryClasses.common.MM_CORE_STANDALONE]
HobLib|StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf HobLib|StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf