StandaloneMmPkg: Introduce PI_MM_CPU_DRIVER_EP protocol.

This patch introduces a PI_MM_CPU_DRIVER_EP protocol to handle
Mmcommunication request based on the CPU driver.
Previously the CPU driver entry point was retrieved using the
gEfiArmTfCpuDriverEntryPoint HOB.
However, this practice is incorrect as StandaloneMM must be a HOB
consumer and not a HOB producer.

Therefore, remove the CPU entry HOB gEfiArmTfCpuDriverEntryPoint,
and replace it with the CPU driver entry protocol
EDKII_PI_MM_CPU_DRIVER_EP_PROTOCOL.
The EDKII_PI_MM_CPU_DRIVER_EP_PROTOCOL installed in
StandaloneMmCpuInitialize() will be used by the code in
Arm/StandaloneMmCoreEntryPoint.

This protocol is used like below:
 +=====+
 |StandaloneMmCore|
 +=====+
    |
    CEntryPoint()
    ===================
      |
      ProcessModuleEntryPointList()
        |
        +--> StandaloneMmMain()
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
               |   // Load StandaloneMmCpu driver which implements
               |   // CpuDriverEntryPoint used by DelegatedEventLoop().
               |   // and install the gEdkiiPiMmCpuDriverEpProtocolGuid.
       --------------
        |
        ... // Get CpuDriverEntryPoint implemented by
        // StandaloneMmCpu driver with gEdkiiPiMmCpuDriverEpProtocolGuid
        |
        DelegatedEventLoop() // Handle request by delegating it to
                             // CpuDriverEntryPoint.

Signed-off-by: Levi Yun <yeoreum.yun@arm.com>
This commit is contained in:
levi.yun 2024-01-25 16:48:05 +00:00 committed by mergify[bot]
parent 62127dfbc7
commit 6087382c62
10 changed files with 138 additions and 75 deletions

View File

@ -54,6 +54,10 @@ EFI_MM_CONFIGURATION_PROTOCOL mMmConfig = {
MmFoundationEntryRegister MmFoundationEntryRegister
}; };
EDKII_PI_MM_CPU_DRIVER_EP_PROTOCOL mPiMmCpuDriverEpProtocol = {
PiMmStandaloneMmCpuDriverEntry
};
STATIC EFI_MM_ENTRY_POINT mMmEntryPoint = NULL; STATIC EFI_MM_ENTRY_POINT mMmEntryPoint = NULL;
/** /**

View File

@ -2,7 +2,7 @@
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR> Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
Copyright (c) 2016 HP Development Company, L.P. Copyright (c) 2016 HP Development Company, L.P.
Copyright (c) 2016 - 2021, Arm Limited. All rights reserved. Copyright (c) 2016 - 2024, Arm Limited. All rights reserved.
Copyright (c) 2023, Ventana Micro System Inc. All rights reserved. Copyright (c) 2023, Ventana Micro System Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent SPDX-License-Identifier: BSD-2-Clause-Patent
@ -26,10 +26,11 @@
// World // World
extern EFI_GUID gEfiStandaloneMmNonSecureBufferGuid; extern EFI_GUID gEfiStandaloneMmNonSecureBufferGuid;
// GUID to identify HOB where the entry point of this CPU driver will be //
// populated to allow the entry point driver to invoke it upon receipt of an // mPiMmCpuDriverEpProtocol for Cpu driver entry point to handle
// event // mm communication event.
extern EFI_GUID gEfiMmCpuDriverEpDescriptorGuid; //
extern EDKII_PI_MM_CPU_DRIVER_EP_PROTOCOL mPiMmCpuDriverEpProtocol;
// //
// Private copy of the MM system table for future use // Private copy of the MM system table for future use
@ -94,7 +95,6 @@ StandaloneMmCpuInitialize (
IN EFI_MM_SYSTEM_TABLE *SystemTable // not actual systemtable IN EFI_MM_SYSTEM_TABLE *SystemTable // not actual systemtable
) )
{ {
MM_CPU_DRIVER_EP_DESCRIPTOR *CpuDriverEntryPointDesc;
EFI_CONFIGURATION_TABLE *ConfigurationTable; EFI_CONFIGURATION_TABLE *ConfigurationTable;
MP_INFORMATION_HOB_DATA *MpInformationHobData; MP_INFORMATION_HOB_DATA *MpInformationHobData;
EFI_MMRAM_DESCRIPTOR *NsCommBufMmramRange; EFI_MMRAM_DESCRIPTOR *NsCommBufMmramRange;
@ -120,6 +120,19 @@ StandaloneMmCpuInitialize (
return Status; return Status;
} }
// Install entry point of this CPU driver to allow
// the entry point driver to be invoked upon receipt of an event in
// DelegatedEventLoop.
Status = mMmst->MmInstallProtocolInterface (
&mMmCpuHandle,
&gEdkiiPiMmCpuDriverEpProtocolGuid,
EFI_NATIVE_INTERFACE,
&mPiMmCpuDriverEpProtocol
);
if (EFI_ERROR (Status)) {
return Status;
}
// register the root MMI handler // register the root MMI handler
Status = mMmst->MmiHandlerRegister ( Status = mMmst->MmiHandlerRegister (
PiMmCpuTpFwRootMmiHandler, PiMmCpuTpFwRootMmiHandler,
@ -147,28 +160,6 @@ StandaloneMmCpuInitialize (
HobStart = ConfigurationTable[Index].VendorTable; HobStart = ConfigurationTable[Index].VendorTable;
//
// Locate the HOB with the buffer to populate the entry point of this driver
//
Status = GetGuidedHobData (
HobStart,
&gEfiMmCpuDriverEpDescriptorGuid,
(VOID **)&CpuDriverEntryPointDesc
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "MmCpuDriverEpDesc HOB data extraction failed - 0x%x\n", Status));
return Status;
}
// Share the entry point of the CPU driver
DEBUG ((
DEBUG_INFO,
"Sharing Cpu Driver EP *0x%lx = 0x%lx\n",
(UINTN)CpuDriverEntryPointDesc->MmCpuDriverEpPtr,
(UINTN)PiMmStandaloneMmCpuDriverEntry
));
*(CpuDriverEntryPointDesc->MmCpuDriverEpPtr) = PiMmStandaloneMmCpuDriverEntry;
// Find the descriptor that contains the whereabouts of the buffer for // Find the descriptor that contains the whereabouts of the buffer for
// communication with the Normal world. // communication with the Normal world.
Status = GetGuidedHobData ( Status = GetGuidedHobData (

View File

@ -36,6 +36,7 @@
[Protocols] [Protocols]
gEfiMmConfigurationProtocolGuid # PROTOCOL ALWAYS_PRODUCED gEfiMmConfigurationProtocolGuid # PROTOCOL ALWAYS_PRODUCED
gEfiMmCpuProtocolGuid # PROTOCOL ALWAYS_PRODUCED gEfiMmCpuProtocolGuid # PROTOCOL ALWAYS_PRODUCED
gEdkiiPiMmCpuDriverEpProtocolGuid # PROTOCOL ALWAYS_PRODUCED
[Guids] [Guids]
gEfiHobListGuid gEfiHobListGuid
@ -43,7 +44,6 @@
gZeroGuid gZeroGuid
gMpInformationHobGuid gMpInformationHobGuid
gEfiStandaloneMmNonSecureBufferGuid gEfiStandaloneMmNonSecureBufferGuid
gEfiMmCpuDriverEpDescriptorGuid
[Depex] [Depex]
TRUE TRUE

View File

@ -126,7 +126,6 @@ LocateStandaloneMmCorePeCoffData (
Use the boot information passed by privileged firmware to populate a HOB list Use the boot information passed by privileged firmware to populate a HOB list
suitable for consumption by the MM Core and drivers. 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 @param [in] PayloadBootInfo Boot information passed by privileged
firmware firmware
@ -134,7 +133,6 @@ LocateStandaloneMmCorePeCoffData (
VOID * VOID *
EFIAPI EFIAPI
CreateHobListFromBootInfo ( CreateHobListFromBootInfo (
IN OUT PI_MM_CPU_DRIVER_ENTRYPOINT *CpuDriverEntryPoint,
IN EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo IN EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo
); );

View File

@ -0,0 +1,61 @@
/** @file
This file describes the PiMm Cpu Driver Entry Point Protocol.
the protocol is for defining handler for mm communication request event
according to cpu driver.
Copyright (c) 2024, Arm Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef PI_MM_CPU_DRIVER_EP_H_
#define PI_MM_CPU_DRIVER_EP_H_
#include <PiMm.h>
#define EDKII_PI_MM_CPU_DRIVER_EP_GUID { \
0x6ecbd5a1, 0xc0f8, 0x4702, { 0x83, 0x01, 0x4f, 0xc2, 0xc5, 0x47, 0x0a, 0x51 } \
}
/**
The PI Standalone MM entry point for handling mm communication request
Here is an example of how the PI_MM_CPU_DRIVER_EP_PROTOCOL is utilized in ARM:
1. StandaloneMmCoreEntryPoint loads StandaloneMmCore.
2. StandaloneMmCore dispatches all MM drivers,
including the StandaloneMmCpu driver.
3. The StandaloneMmCpu driver declares its MMI CPU entry point through
the PI_MM_CPU_DRIVER_EP_PROTOCOL.
4. After all drivers have been dispatched,
StandaloneMmCoreEntryPoint retrieves the MMI CPU entry point
by locating the protocol.
5. The DelegatedEventLoop then calls the MM CPU entry point.
See StandaloneMmPkg/StandaloneMmCoreEntryPoint/Arm/StandaloneMmCoreEntryPoint.c
@param [in] EventId The event Id based on firmware.
@param [in] CpuNumber The CPU number.
@param [in] CommBufferAddr Address of the communication buffer.
@retval EFI_SUCCESS Success.
@retval EFI_INVALID_PARAMETER A parameter was invalid.
@retval EFI_ACCESS_DENIED Access not permitted.
@retval EFI_OUT_OF_RESOURCES Out of resources.
@retval EFI_UNSUPPORTED Operation not supported.
**/
typedef
EFI_STATUS
(EFIAPI *EDKII_PI_MM_CPU_DRIVER_ENTRYPOINT)(
IN UINTN EventId,
IN UINTN CpuNumber,
IN UINTN CommBufferAddr
);
typedef struct _EDKII_PI_MM_CPU_DRIVER_EP_PROTOCOL EDKII_PI_MM_CPU_DRIVER_EP_PROTOCOL;
struct _EDKII_PI_MM_CPU_DRIVER_EP_PROTOCOL {
EDKII_PI_MM_CPU_DRIVER_ENTRYPOINT PiMmCpuDriverEntryPoint;
};
extern EFI_GUID gEdkiiPiMmCpuDriverEpProtocolGuid;
#endif

View File

@ -13,20 +13,10 @@
#include <Protocol/MmCommunication2.h> #include <Protocol/MmCommunication2.h>
#include <Protocol/MmConfiguration.h> #include <Protocol/MmConfiguration.h>
#include <Protocol/MmCpu.h> #include <Protocol/MmCpu.h>
#include <Protocol/PiMmCpuDriverEp.h>
#include <Guid/MpInformation.h> #include <Guid/MpInformation.h>
typedef
EFI_STATUS
(*PI_MM_CPU_DRIVER_ENTRYPOINT) (
IN UINTN EventId,
IN UINTN CpuNumber,
IN UINTN NsCommBufferAddr
);
typedef struct {
PI_MM_CPU_DRIVER_ENTRYPOINT *MmCpuDriverEpPtr;
} MM_CPU_DRIVER_EP_DESCRIPTOR;
// //
// CPU driver initialization specific declarations // CPU driver initialization specific declarations
// //

View File

@ -53,7 +53,6 @@ extern EFI_GUID gEfiMmCpuDriverEpDescriptorGuid;
**/ **/
VOID * VOID *
CreateHobListFromBootInfo ( CreateHobListFromBootInfo (
IN OUT PI_MM_CPU_DRIVER_ENTRYPOINT *CpuDriverEntryPoint,
IN EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo IN EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo
) )
{ {
@ -68,7 +67,6 @@ CreateHobListFromBootInfo (
MP_INFORMATION_HOB_DATA *MpInformationHobData; MP_INFORMATION_HOB_DATA *MpInformationHobData;
EFI_PROCESSOR_INFORMATION *ProcInfoBuffer; EFI_PROCESSOR_INFORMATION *ProcInfoBuffer;
EFI_SECURE_PARTITION_CPU_INFO *CpuInfo; EFI_SECURE_PARTITION_CPU_INFO *CpuInfo;
MM_CPU_DRIVER_EP_DESCRIPTOR *CpuDriverEntryPointDesc;
// Create a hoblist with a PHIT and EOH // Create a hoblist with a PHIT and EOH
HobStart = HobConstructor ( HobStart = HobConstructor (
@ -143,16 +141,6 @@ CreateHobListFromBootInfo (
NsCommBufMmramRange->PhysicalSize = PayloadBootInfo->SpNsCommBufSize; NsCommBufMmramRange->PhysicalSize = PayloadBootInfo->SpNsCommBufSize;
NsCommBufMmramRange->RegionState = EFI_CACHEABLE | EFI_ALLOCATED; NsCommBufMmramRange->RegionState = EFI_CACHEABLE | EFI_ALLOCATED;
// Create a Guided HOB to enable the ARM TF CPU driver to share its entry
// point and populate it with the address of the shared buffer
CpuDriverEntryPointDesc = (MM_CPU_DRIVER_EP_DESCRIPTOR *)BuildGuidHob (
&gEfiMmCpuDriverEpDescriptorGuid,
sizeof (MM_CPU_DRIVER_EP_DESCRIPTOR)
);
*CpuDriverEntryPoint = NULL;
CpuDriverEntryPointDesc->MmCpuDriverEpPtr = CpuDriverEntryPoint;
// Find the size of the GUIDed HOB with SRAM ranges // Find the size of the GUIDed HOB with SRAM ranges
BufferSize = sizeof (EFI_MMRAM_HOB_DESCRIPTOR_BLOCK); BufferSize = sizeof (EFI_MMRAM_HOB_DESCRIPTOR_BLOCK);
BufferSize += PayloadBootInfo->NumSpMemRegions * sizeof (EFI_MMRAM_DESCRIPTOR); BufferSize += PayloadBootInfo->NumSpMemRegions * sizeof (EFI_MMRAM_DESCRIPTOR);

View File

@ -38,21 +38,23 @@
#include <IndustryStandard/ArmMmSvc.h> #include <IndustryStandard/ArmMmSvc.h>
#include <IndustryStandard/ArmFfaSvc.h> #include <IndustryStandard/ArmFfaSvc.h>
#include <Protocol/PiMmCpuDriverEp.h>
#define SPM_MAJOR_VER_MASK 0xFFFF0000 #define SPM_MAJOR_VER_MASK 0xFFFF0000
#define SPM_MINOR_VER_MASK 0x0000FFFF #define SPM_MINOR_VER_MASK 0x0000FFFF
#define SPM_MAJOR_VER_SHIFT 16 #define SPM_MAJOR_VER_SHIFT 16
#define FFA_NOT_SUPPORTED -1 #define FFA_NOT_SUPPORTED -1
#define BOOT_PAYLOAD_VERSION 1
extern EFI_MM_SYSTEM_TABLE gMmCoreMmst;
STATIC CONST UINT32 mSpmMajorVer = SPM_MAJOR_VERSION; STATIC CONST UINT32 mSpmMajorVer = SPM_MAJOR_VERSION;
STATIC CONST UINT32 mSpmMinorVer = SPM_MINOR_VERSION; STATIC CONST UINT32 mSpmMinorVer = SPM_MINOR_VERSION;
STATIC CONST UINT32 mSpmMajorVerFfa = SPM_MAJOR_VERSION_FFA; STATIC CONST UINT32 mSpmMajorVerFfa = SPM_MAJOR_VERSION_FFA;
STATIC CONST UINT32 mSpmMinorVerFfa = SPM_MINOR_VERSION_FFA; STATIC CONST UINT32 mSpmMinorVerFfa = SPM_MINOR_VERSION_FFA;
#define BOOT_PAYLOAD_VERSION 1
PI_MM_CPU_DRIVER_ENTRYPOINT CpuDriverEntryPoint = NULL;
/** /**
Retrieve a pointer to and print the boot information passed by privileged Retrieve a pointer to and print the boot information passed by privileged
secure firmware. secure firmware.
@ -216,13 +218,15 @@ SetEventCompleteSvcArgs (
/** /**
A loop to delegated events. A loop to delegated events.
@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.
**/ **/
VOID VOID
EFIAPI EFIAPI
DelegatedEventLoop ( DelegatedEventLoop (
IN ARM_SVC_ARGS *EventCompleteSvcArgs IN EDKII_PI_MM_CPU_DRIVER_ENTRYPOINT CpuDriverEntryPoint,
IN ARM_SVC_ARGS *EventCompleteSvcArgs
) )
{ {
BOOLEAN FfaEnabled; BOOLEAN FfaEnabled;
@ -381,16 +385,20 @@ _ModuleEntryPoint (
IN UINT64 cookie2 IN UINT64 cookie2
) )
{ {
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
EFI_SECURE_PARTITION_BOOT_INFO *PayloadBootInfo; 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;
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_ENTRYPOINT CpuDriverEntryPoint;
CpuDriverEntryPoint = NULL;
// Get Secure Partition Manager Version Information // Get Secure Partition Manager Version Information
Status = GetSpmVersion (); Status = GetSpmVersion ();
@ -466,14 +474,33 @@ _ModuleEntryPoint (
// //
// Create Hoblist based upon boot information passed by privileged software // Create Hoblist based upon boot information passed by privileged software
// //
HobStart = CreateHobListFromBootInfo (&CpuDriverEntryPoint, PayloadBootInfo); HobStart = CreateHobListFromBootInfo (PayloadBootInfo);
// //
// Call the MM Core entry point // Call the MM Core entry point
// //
ProcessModuleEntryPointList (HobStart); ProcessModuleEntryPointList (HobStart);
DEBUG ((DEBUG_INFO, "Shared Cpu Driver EP %p\n", (VOID *)CpuDriverEntryPoint)); //
// Find out cpu driver entry point used in DelegatedEventLoop
// to handle MMI request.
//
Status = gMmCoreMmst.MmLocateProtocol (
&gEdkiiPiMmCpuDriverEpProtocolGuid,
NULL,
(VOID **)&PiMmCpuDriverEpProtocol
);
if (EFI_ERROR (Status)) {
goto finish;
}
CpuDriverEntryPoint = PiMmCpuDriverEpProtocol->PiMmCpuDriverEntryPoint;
DEBUG ((
DEBUG_INFO,
"Shared Cpu Driver EP %p\n",
CpuDriverEntryPoint
));
finish: finish:
ZeroMem (&EventCompleteSvcArgs, sizeof (EventCompleteSvcArgs)); ZeroMem (&EventCompleteSvcArgs, sizeof (EventCompleteSvcArgs));
@ -482,5 +509,5 @@ finish:
Status, Status,
&EventCompleteSvcArgs &EventCompleteSvcArgs
); );
DelegatedEventLoop (&EventCompleteSvcArgs); DelegatedEventLoop (CpuDriverEntryPoint, t&EventCompleteSvcArgs);
} }

View File

@ -49,7 +49,9 @@
gMpInformationHobGuid gMpInformationHobGuid
gEfiMmPeiMmramMemoryReserveGuid gEfiMmPeiMmramMemoryReserveGuid
gEfiStandaloneMmNonSecureBufferGuid gEfiStandaloneMmNonSecureBufferGuid
gEfiMmCpuDriverEpDescriptorGuid
[Protocols.ARM, Protocols.AARCH64]
gEdkiiPiMmCpuDriverEpProtocolGuid
[FeaturePcd.ARM, FeaturePcd.AARCH64] [FeaturePcd.ARM, FeaturePcd.AARCH64]
gArmTokenSpaceGuid.PcdFfaEnable gArmTokenSpaceGuid.PcdFfaEnable

View File

@ -47,13 +47,15 @@
gEfiMmPeiMmramMemoryReserveGuid = { 0x0703f912, 0xbf8d, 0x4e2a, { 0xbe, 0x07, 0xab, 0x27, 0x25, 0x25, 0xc5, 0x92 }} gEfiMmPeiMmramMemoryReserveGuid = { 0x0703f912, 0xbf8d, 0x4e2a, { 0xbe, 0x07, 0xab, 0x27, 0x25, 0x25, 0xc5, 0x92 }}
gEfiStandaloneMmNonSecureBufferGuid = { 0xf00497e3, 0xbfa2, 0x41a1, { 0x9d, 0x29, 0x54, 0xc2, 0xe9, 0x37, 0x21, 0xc5 }} gEfiStandaloneMmNonSecureBufferGuid = { 0xf00497e3, 0xbfa2, 0x41a1, { 0x9d, 0x29, 0x54, 0xc2, 0xe9, 0x37, 0x21, 0xc5 }}
gEfiMmCpuDriverEpDescriptorGuid = { 0x6ecbd5a1, 0xc0f8, 0x4702, { 0x83, 0x01, 0x4f, 0xc2, 0xc5, 0x47, 0x0a, 0x51 }}
gEventMmDispatchGuid = { 0x7e6efffa, 0x69b4, 0x4c1b, { 0xa4, 0xc7, 0xaf, 0xf9, 0xc9, 0x24, 0x4f, 0xee }} gEventMmDispatchGuid = { 0x7e6efffa, 0x69b4, 0x4c1b, { 0xa4, 0xc7, 0xaf, 0xf9, 0xc9, 0x24, 0x4f, 0xee }}
[Ppis] [Ppis]
gMmCoreFvLocationPpiGuid = { 0x47a00618, 0x237a, 0x4386, { 0x8f, 0xc5, 0x2a, 0x86, 0xd8, 0xac, 0x41, 0x05 }} gMmCoreFvLocationPpiGuid = { 0x47a00618, 0x237a, 0x4386, { 0x8f, 0xc5, 0x2a, 0x86, 0xd8, 0xac, 0x41, 0x05 }}
[Protocols]
gEdkiiPiMmCpuDriverEpProtocolGuid = { 0x6ecbd5a1, 0xc0f8, 0x4702, { 0x83, 0x01, 0x4f, 0xc2, 0xc5, 0x47, 0x0a, 0x51 }}
[PcdsFixedAtBuild, PcdsPatchableInModule] [PcdsFixedAtBuild, PcdsPatchableInModule]
## Maximum permitted encapsulation levels of sections in a firmware volume, ## Maximum permitted encapsulation levels of sections in a firmware volume,
# in the MM phase. Minimum value is 1. Sections nested more deeply are rejected. # in the MM phase. Minimum value is 1. Sections nested more deeply are rejected.