mirror of https://github.com/acidanthera/audk.git
StandaloneMm/Library: Apply FF-A v1.2 in StandaloneMm
To support the service other than Mmcommunication service, StandaloneMm should use FF-A v1.2 or later [0]. For this, StandaloneMm needs to change: 1. apply FF-A boot protocol - FF-A uses its own boot protocol and it can deliver phit hob. So, StandaloneMm should understand FF-A boot protocol and get phit hob from it to initialize. 2. Use DIRECT_REQ2 / DIRECT_RESP2 - To support the other service via FF-A protocol than MmCommunication, StandaloneMm should use DIRECT_REQ2 / DIRECT_RESP2. In case of service provided with MmCommunication protocol, register x2/x3 value is set as gEfiMmCommunication2ProtocolGuid and register x4 value is set with MmCommunication Buffer (ServiceTypeMmCommunication). In case of service with each speicifiation via FF-A, register x2/x3 value is set as each service guid and StandaloneMmCoreEntryPoint genreates Mm communication header with passed arguments to dispatch this service provided by StandaloneMm. i.e) Tpm service, Firmware update service and etc. (ServiceTypeMisc) Link: https://developer.arm.com/documentation/den0077/latest/ [0] Signed-off-by: Levi Yun <yeoreum.yun@arm.com>
This commit is contained in:
parent
4ca452cf91
commit
1c963008e8
|
@ -16,51 +16,124 @@
|
||||||
@par Reference(s):
|
@par Reference(s):
|
||||||
- Transfer List [https://github.com/FirmwareHandoff/firmware_handoff]
|
- Transfer List [https://github.com/FirmwareHandoff/firmware_handoff]
|
||||||
- Secure Partition Manager [https://trustedfirmware-a.readthedocs.io/en/latest/components/secure-partition-manager-mm.html].
|
- 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]
|
- Arm Firmware Framework for Arm A-Profile [https://developer.arm.com/documentation/den0077/latest]
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#ifndef __STANDALONEMMCORE_ENTRY_POINT_H__
|
#ifndef __STANDALONEMMCORE_ENTRY_POINT_H__
|
||||||
#define __STANDALONEMMCORE_ENTRY_POINT_H__
|
#define __STANDALONEMMCORE_ENTRY_POINT_H__
|
||||||
|
|
||||||
|
#include <Library/ArmSvcLib.h>
|
||||||
|
#include <Library/ArmFfaLib.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.
|
* Communication ABI protocol to communicate between normal/secure partition.
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/// Unknown Communication ABI protocol
|
/// Unknown Communication ABI protocol
|
||||||
AbiProtocolUnknown,
|
CommProtocolUnknown,
|
||||||
|
|
||||||
/// Communicate via SPM_MM ABI protocol
|
/// Communicate via SPM_MM ABI protocol
|
||||||
AbiProtocolSpmMm,
|
CommProtocolSpmMm,
|
||||||
|
|
||||||
/// Communicate via FF-A ABI protocol
|
/// Communicate via FF-A ABI protocol
|
||||||
AbiProtocolFfa,
|
CommProtocolFfa,
|
||||||
|
|
||||||
AbiProtocolMax,
|
CommProtocolMax,
|
||||||
} ABI_PROTOCOL;
|
} COMM_PROTOCOL;
|
||||||
|
|
||||||
|
/** When using FF-A ABI, there're ways to request service to StandaloneMm
|
||||||
|
- FF-A with MmCommunication protocol.
|
||||||
|
- FF-A service with each specification.
|
||||||
|
MmCommunication Protocol can use FFA_MSG_SEND_DIRECT_REQ or REQ2,
|
||||||
|
Other FF-A services should use FFA_MSG_SEND_DIRECT_REQ2.
|
||||||
|
In case of FF-A with MmCommunication protocol via FFA_MSG_SEND_DIRECT_REQ,
|
||||||
|
register x3 saves Communication Buffer with gEfiMmCommunication2ProtocolGuid.
|
||||||
|
In case of FF-A with MmCommunication protocol via FFA_MSG_SEND_DIRECT_REQ2,
|
||||||
|
register x2/x3 save gEfiMmCommunication2ProtocolGuid and
|
||||||
|
register x4 saves Communication Buffer with Service Guid.
|
||||||
|
|
||||||
|
Other FF-A services (ServiceTypeMisc) delivers register values according to
|
||||||
|
there own service specification.
|
||||||
|
That means it doesn't use MmCommunication Buffer with MmCommunication Header
|
||||||
|
format.
|
||||||
|
(i.e) Tpm service via FF-A or Firmware Update service via FF-A.
|
||||||
|
To support latter services by StandaloneMm, it defines SERVICE_TYPE_MISC.
|
||||||
|
So that StandaloneMmEntryPointCore.c generates MmCommunication Header
|
||||||
|
with delivered register values to dispatch service provided StandaloneMmCore.
|
||||||
|
So that service handler can get proper information from delivered register.
|
||||||
|
|
||||||
|
In case of SPM_MM Abi, it only supports MmCommunication service.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
/// Unknown
|
||||||
|
ServiceTypeUnknown,
|
||||||
|
|
||||||
|
/// MmCommunication services
|
||||||
|
ServiceTypeMmCommunication,
|
||||||
|
|
||||||
|
/// Misc services
|
||||||
|
ServiceTypeMisc,
|
||||||
|
|
||||||
|
ServiceTypeMax,
|
||||||
|
} SERVICE_TYPE;
|
||||||
|
|
||||||
|
/** Direct message request/response version
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
/// Direct message version 1. Use FFA_DIRECT_MSG_REQ/RESP
|
||||||
|
DirectMsgV1,
|
||||||
|
|
||||||
|
/// Direct message version 2. Use FFA_DIRECT_MSG_REQ2/RESP2
|
||||||
|
DirectMsgV2,
|
||||||
|
|
||||||
|
DirectMsgMax,
|
||||||
|
} DIRECT_MSG_VERSION;
|
||||||
|
|
||||||
|
/** Service table entry to return service type matched with service guid
|
||||||
|
*/
|
||||||
|
typedef struct ServiceTableEntry {
|
||||||
|
/// Service Guid
|
||||||
|
EFI_GUID *ServiceGuid;
|
||||||
|
|
||||||
|
/// Service Type
|
||||||
|
SERVICE_TYPE ServiceType;
|
||||||
|
} SERVICE_TABLE_ENTRY;
|
||||||
|
|
||||||
|
/** Ffa Abi data used in FFA_MSG_SEND_DIRECT_RESP/RESP2.
|
||||||
|
*/
|
||||||
|
typedef struct FfaMsgInfo {
|
||||||
|
/// Source partition id
|
||||||
|
UINT16 SourcePartId;
|
||||||
|
|
||||||
|
/// Destination partition id
|
||||||
|
UINT16 DestPartId;
|
||||||
|
|
||||||
|
/// Direct Message version
|
||||||
|
DIRECT_MSG_VERSION DirectMsgVersion;
|
||||||
|
|
||||||
|
/// Service Type
|
||||||
|
SERVICE_TYPE ServiceType;
|
||||||
|
} FFA_MSG_INFO;
|
||||||
|
|
||||||
|
/** MmCommunication Header for Misc service.
|
||||||
|
Misc service doesn't use MmCommunication Buffer.
|
||||||
|
This structure is used to dispatch Misc services by StandaloneMm.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/// Service guid
|
||||||
|
EFI_GUID HeaderGuid;
|
||||||
|
|
||||||
|
/// Length of Message. In case of misc service, sizeof (EventSvcArgs)
|
||||||
|
UINTN MessageLength;
|
||||||
|
|
||||||
|
/// Delivered register values.
|
||||||
|
DIRECT_MSG_ARGS DirectMsgArgs;
|
||||||
|
} MISC_MM_COMMUNICATE_BUFFER;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UINT8 Type; /* type of the structure */
|
UINT8 Type; /* type of the structure */
|
||||||
|
@ -144,12 +217,19 @@ LocateStandaloneMmCorePeCoffData (
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The entry point of Standalone MM Foundation.
|
The handoff between the SPMC to StandaloneMM depends on the
|
||||||
|
communication interface between the SPMC and StandaloneMM.
|
||||||
|
When SpmMM is used, the handoff is implemented using the
|
||||||
|
Firmware Handoff protocol. When FF-A is used the FF-A boot
|
||||||
|
protocol is used.
|
||||||
|
|
||||||
@param [in] Arg0 Boot information passed according to boot protocol.
|
@param [in] Arg0 In case of FF-A, address of FF-A boot information
|
||||||
@param [in] Arg1 Boot information passed according to boot protocol.
|
In case of SPM_MM, this parameter must be zero
|
||||||
@param [in] Arg2 Boot information passed according to boot protocol.
|
@param [in] Arg1 In case of FF-A, this parameter must be zero
|
||||||
@param [in] Arg3 Boot information passed according to boot protocol.
|
In case of SPM_MM, Signature and register convention version
|
||||||
|
@param [in] Arg2 Must be zero
|
||||||
|
@param [in] Arg3 In case of FF-A, this parameter must be zero
|
||||||
|
In case of SPM_MM, address of transfer list
|
||||||
|
|
||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -10,9 +10,13 @@
|
||||||
with management services running from an isolated Secure Partitions
|
with management services running from an isolated Secure Partitions
|
||||||
at S-EL0, and the communication protocol is the Management Mode(MM)
|
at S-EL0, and the communication protocol is the Management Mode(MM)
|
||||||
interface.
|
interface.
|
||||||
|
- FF-A - Firmware Framework for Arm A-profile
|
||||||
|
|
||||||
@par Reference(s):
|
@par Reference(s):
|
||||||
- Secure Partition Manager [https://trustedfirmware-a.readthedocs.io/en/latest/components/secure-partition-manager-mm.html].
|
- 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/latest]
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
@ -22,11 +26,11 @@
|
||||||
|
|
||||||
#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 <Library/ArmLib.h>
|
#include <Library/ArmLib.h>
|
||||||
#include <Library/ArmSvcLib.h>
|
#include <Library/ArmSvcLib.h>
|
||||||
|
#include <Library/ArmFfaLib.h>
|
||||||
#include <Library/ArmTransferListLib.h>
|
#include <Library/ArmTransferListLib.h>
|
||||||
#include <Library/DebugLib.h>
|
#include <Library/DebugLib.h>
|
||||||
#include <Library/HobLib.h>
|
#include <Library/HobLib.h>
|
||||||
|
@ -39,6 +43,7 @@
|
||||||
#include <IndustryStandard/ArmStdSmc.h>
|
#include <IndustryStandard/ArmStdSmc.h>
|
||||||
#include <IndustryStandard/ArmMmSvc.h>
|
#include <IndustryStandard/ArmMmSvc.h>
|
||||||
#include <IndustryStandard/ArmFfaSvc.h>
|
#include <IndustryStandard/ArmFfaSvc.h>
|
||||||
|
#include <IndustryStandard/ArmFfaBootInfo.h>
|
||||||
|
|
||||||
#include <Protocol/PiMmCpuDriverEp.h>
|
#include <Protocol/PiMmCpuDriverEp.h>
|
||||||
|
|
||||||
|
@ -46,42 +51,43 @@ extern EFI_MM_SYSTEM_TABLE gMmCoreMmst;
|
||||||
|
|
||||||
VOID *gHobList = NULL;
|
VOID *gHobList = NULL;
|
||||||
|
|
||||||
STATIC MP_INFORMATION_HOB_DATA *mMpInfo = NULL;
|
STATIC MP_INFORMATION_HOB_DATA *mMpInfo = NULL;
|
||||||
|
STATIC MISC_MM_COMMUNICATE_BUFFER *mMiscMmCommunicateBuffer = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get ABI protocol.
|
Get communication ABI protocol.
|
||||||
|
|
||||||
@retval AbiProtocolSpmMm SPM_MM ABI
|
@param [out] CommProtocol Communication protocol.
|
||||||
@retval AbiProtocolFfa FF-A ABI
|
|
||||||
@retval AbiProtocolUnknown Invalid ABI.
|
@retval EFI_SUCCESS
|
||||||
|
@retval EFI_UNSUPPORTED Not supported
|
||||||
|
|
||||||
**/
|
**/
|
||||||
STATIC
|
STATIC
|
||||||
ABI_PROTOCOL
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
GetAbiProtocol (
|
GetCommProtocol (
|
||||||
IN VOID
|
OUT COMM_PROTOCOL *CommProtocol
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
UINT16 RequestMajorVersion;
|
UINT16 RequestMajorVersion;
|
||||||
UINT16 RequestMinorVersion;
|
UINT16 RequestMinorVersion;
|
||||||
UINT16 CurrentMajorVersion;
|
UINT16 CurrentMajorVersion;
|
||||||
UINT16 CurrentMinorVersion;
|
UINT16 CurrentMinorVersion;
|
||||||
ARM_SVC_ARGS SvcArgs;
|
ARM_SVC_ARGS SvcArgs;
|
||||||
ABI_PROTOCOL AbiProtocol;
|
|
||||||
|
|
||||||
ZeroMem (&SvcArgs, sizeof (ARM_SVC_ARGS));
|
RequestMajorVersion = ARM_FFA_MAJOR_VERSION;
|
||||||
SvcArgs.Arg0 = ARM_SVC_ID_FFA_VERSION_AARCH32;
|
RequestMinorVersion = ARM_FFA_MINOR_VERSION;
|
||||||
SvcArgs.Arg1 = ((SPM_MAJOR_VERSION_FFA << 16) | (SPM_MINOR_VERSION_FFA));
|
|
||||||
|
|
||||||
ArmCallSvc (&SvcArgs);
|
Status = ArmFfaLibGetVersion (
|
||||||
|
RequestMajorVersion,
|
||||||
if (SvcArgs.Arg0 != ARM_FFA_SPM_RET_NOT_SUPPORTED) {
|
RequestMinorVersion,
|
||||||
AbiProtocol = AbiProtocolFfa;
|
&CurrentMajorVersion,
|
||||||
RequestMajorVersion = SPM_MAJOR_VERSION_FFA;
|
&CurrentMinorVersion
|
||||||
RequestMinorVersion = SPM_MINOR_VERSION_FFA;
|
);
|
||||||
CurrentMajorVersion = ((SvcArgs.Arg0 >> 16) & 0xffff);
|
if (!EFI_ERROR (Status)) {
|
||||||
CurrentMinorVersion = (SvcArgs.Arg0 & 0xffff);
|
*CommProtocol = CommProtocolFfa;
|
||||||
} else {
|
} else {
|
||||||
ZeroMem (&SvcArgs, sizeof (ARM_SVC_ARGS));
|
ZeroMem (&SvcArgs, sizeof (ARM_SVC_ARGS));
|
||||||
SvcArgs.Arg0 = ARM_FID_SPM_MM_VERSION_AARCH32;
|
SvcArgs.Arg0 = ARM_FID_SPM_MM_VERSION_AARCH32;
|
||||||
|
@ -89,10 +95,11 @@ GetAbiProtocol (
|
||||||
ArmCallSvc (&SvcArgs);
|
ArmCallSvc (&SvcArgs);
|
||||||
|
|
||||||
if (SvcArgs.Arg0 == ARM_SPM_MM_RET_NOT_SUPPORTED) {
|
if (SvcArgs.Arg0 == ARM_SPM_MM_RET_NOT_SUPPORTED) {
|
||||||
return AbiProtocolUnknown;
|
*CommProtocol = CommProtocolUnknown;
|
||||||
|
return EFI_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbiProtocol = AbiProtocolSpmMm;
|
*CommProtocol = CommProtocolSpmMm;
|
||||||
RequestMajorVersion = ARM_SPM_MM_SUPPORT_MAJOR_VERSION;
|
RequestMajorVersion = ARM_SPM_MM_SUPPORT_MAJOR_VERSION;
|
||||||
RequestMinorVersion = ARM_SPM_MM_SUPPORT_MINOR_VERSION;
|
RequestMinorVersion = ARM_SPM_MM_SUPPORT_MINOR_VERSION;
|
||||||
CurrentMajorVersion =
|
CurrentMajorVersion =
|
||||||
|
@ -116,53 +123,51 @@ GetAbiProtocol (
|
||||||
"Incompatible %s Versions.\n" \
|
"Incompatible %s Versions.\n" \
|
||||||
"Request Version: Major=0x%x, Minor>=0x%x.\n" \
|
"Request Version: Major=0x%x, Minor>=0x%x.\n" \
|
||||||
"Current Version: Major=0x%x, Minor=0x%x.\n",
|
"Current Version: Major=0x%x, Minor=0x%x.\n",
|
||||||
(AbiProtocol == AbiProtocolFfa) ? L"FF-A" : L"SPM_MM",
|
(*CommProtocol == CommProtocolFfa) ? L"FF-A" : L"SPM_MM",
|
||||||
RequestMajorVersion,
|
RequestMajorVersion,
|
||||||
RequestMinorVersion,
|
RequestMinorVersion,
|
||||||
CurrentMajorVersion,
|
CurrentMajorVersion,
|
||||||
CurrentMinorVersion
|
CurrentMinorVersion
|
||||||
));
|
));
|
||||||
AbiProtocol = AbiProtocolUnknown;
|
|
||||||
} else {
|
return EFI_UNSUPPORTED;
|
||||||
DEBUG ((
|
|
||||||
DEBUG_INFO,
|
|
||||||
"%s Version: Major=0x%x, Minor=0x%x\n",
|
|
||||||
(AbiProtocol == AbiProtocolFfa) ? L"FF-A" : L"SPM_MM",
|
|
||||||
CurrentMajorVersion,
|
|
||||||
CurrentMinorVersion
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return AbiProtocol;
|
DEBUG ((
|
||||||
|
DEBUG_INFO,
|
||||||
|
"%s Version: Major=0x%x, Minor=0x%x\n",
|
||||||
|
(*CommProtocol == CommProtocolFfa) ? L"FF-A" : L"SPM_MM",
|
||||||
|
CurrentMajorVersion,
|
||||||
|
CurrentMinorVersion
|
||||||
|
));
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get Boot protocol.
|
Validate Boot information when using SpmMm.
|
||||||
|
It should use Transfer list according to firmware handoff specification.
|
||||||
|
|
||||||
@param[in] Arg0 Arg0 passed from firmware
|
@param [in] Arg0 Should be 0x00 because we don't use device tree
|
||||||
@param[in] Arg1 Arg1 passed from firmware
|
@param [in] Fields Signature and register convention version
|
||||||
@param[in] Arg2 Arg2 passed from firmware
|
@param [in] Arg2 Should be 0x00 because we don't use device tree
|
||||||
@param[in] Arg3 Arg3 passed from firmware
|
@param [in] TlhAddr Address of transfer list
|
||||||
|
|
||||||
@retval BootProtocolTl64 64 bits register convention transfer list
|
@retval EFI_SUCCESS Valid boot information
|
||||||
@retval BootProtocolTl32 32 bits register convention transfer list
|
@retval EFI_INVALID_PARAMETER Invalid boot information
|
||||||
@retval BootProtocolUnknown Invalid Boot protocol
|
|
||||||
|
|
||||||
**/
|
**/
|
||||||
STATIC
|
STATIC
|
||||||
BOOT_PROTOCOL
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
GetBootProtocol (
|
ValidateSpmMmBootInfo (
|
||||||
IN UINTN Arg0,
|
IN UINTN Arg0,
|
||||||
IN UINTN Arg1,
|
IN UINT64 Fields,
|
||||||
IN UINTN Arg2,
|
IN UINTN Arg2,
|
||||||
IN UINTN Arg3
|
IN UINTN TlhAddr
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINTN RegVersion;
|
UINT64 RegVersion;
|
||||||
UINT64 Fields;
|
|
||||||
|
|
||||||
Fields = Arg1;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The signature value in x1's [23:0] bits is the same regardless of
|
* The signature value in x1's [23:0] bits is the same regardless of
|
||||||
|
@ -172,32 +177,105 @@ GetBootProtocol (
|
||||||
* Please see:
|
* Please see:
|
||||||
* https://github.com/FirmwareHandoff/firmware_handoff/blob/main/source/register_conventions.rst
|
* 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) {
|
||||||
if ((Fields & TRANSFER_LIST_SIGNATURE_MASK_64) == TRANSFER_LIST_SIGNATURE_64) {
|
RegVersion = (Fields >> REGISTER_CONVENTION_VERSION_SHIFT_64) &
|
||||||
RegVersion = (Fields >> REGISTER_CONVENTION_VERSION_SHIFT_64) &
|
REGISTER_CONVENTION_VERSION_MASK;
|
||||||
REGISTER_CONVENTION_VERSION_MASK;
|
if ((RegVersion != 1) || (Arg2 != 0x00) || (TlhAddr == 0x00)) {
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
if ((RegVersion != 1) || (Arg2 != 0x00) || (Arg3 == 0x00)) {
|
}
|
||||||
goto err_out;
|
} else if ((Fields & TRANSFER_LIST_SIGNATURE_MASK_32) == TRANSFER_LIST_SIGNATURE_32) {
|
||||||
}
|
RegVersion = (Fields >> REGISTER_CONVENTION_VERSION_SHIFT_32) &
|
||||||
|
REGISTER_CONVENTION_VERSION_MASK;
|
||||||
return BootProtocolTl64;
|
if ((RegVersion != 1) || (Arg0 != 0x00) || (TlhAddr == 0x00)) {
|
||||||
} else {
|
return EFI_INVALID_PARAMETER;
|
||||||
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:
|
return EFI_SUCCESS;
|
||||||
DEBUG ((DEBUG_ERROR, "Error: Failed to get boot protocol!\n"));
|
}
|
||||||
|
|
||||||
return BootProtocolUnknown;
|
/**
|
||||||
|
Validate Boot information when using FF-A.
|
||||||
|
|
||||||
|
@param [in] FfaBootInfoHeaderAddr Address of FF-A boot information
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Valid boot information
|
||||||
|
@retval EFI_INVALID_PARAMETER Invalid boot information
|
||||||
|
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
ValidateFfaBootInfo (
|
||||||
|
IN UINTN FfaBootInfoHeaderAddr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_FFA_BOOT_INFO_HEADER *FfaBootInfoHeader;
|
||||||
|
|
||||||
|
FfaBootInfoHeader = (EFI_FFA_BOOT_INFO_HEADER *)FfaBootInfoHeaderAddr;
|
||||||
|
if (FfaBootInfoHeader == NULL) {
|
||||||
|
DEBUG ((DEBUG_ERROR, "Error: No FF-A boot information...\n"));
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((FfaBootInfoHeader->Magic != FFA_BOOT_INFO_SIGNATURE) ||
|
||||||
|
(ARM_FFA_MAJOR_VERSION_GET (FfaBootInfoHeader->Version) <
|
||||||
|
ARM_FFA_MAJOR_VERSION) ||
|
||||||
|
(ARM_FFA_MINOR_VERSION_GET (FfaBootInfoHeader->Version) <
|
||||||
|
ARM_FFA_MINOR_VERSION))
|
||||||
|
{
|
||||||
|
DEBUG ((DEBUG_ERROR, "Error: Invalid FF-A boot information...\n"));
|
||||||
|
return EFI_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Validate Boot information.
|
||||||
|
|
||||||
|
@param [in] CommProtocol Communication ABI protocol
|
||||||
|
@param [in] Arg0 In case of FF-A, address of FF-A boot information
|
||||||
|
In case of SPM_MM, 0x00
|
||||||
|
@param [in] Arg1 In case of FF-A, 0x00
|
||||||
|
In case of SPM_MM, Signature and register convention version
|
||||||
|
@param [in] Arg2 should be 0x00
|
||||||
|
@param [in] Arg3 In case of FF-A, it's 0x00
|
||||||
|
In case of SPM_MM, address of transfer list
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Valid boot information
|
||||||
|
@retval EFI_INVALID_PARAMETER Invalid boot information
|
||||||
|
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
EFI_STATUS
|
||||||
|
EFIAPI
|
||||||
|
ValidateBootInfo (
|
||||||
|
IN COMM_PROTOCOL CommProtocol,
|
||||||
|
IN UINTN Arg0,
|
||||||
|
IN UINTN Arg1,
|
||||||
|
IN UINTN Arg2,
|
||||||
|
IN UINTN Arg3
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
if (CommProtocol == CommProtocolSpmMm) {
|
||||||
|
Status = ValidateSpmMmBootInfo (Arg0, Arg1, Arg2, Arg3);
|
||||||
|
} else if (CommProtocol == CommProtocolFfa) {
|
||||||
|
/*
|
||||||
|
* In case of FF-A, Arg0 is set as FFA_BOOT_INFO address.
|
||||||
|
*/
|
||||||
|
Status = ValidateFfaBootInfo (Arg0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
DEBUG ((DEBUG_ERROR, "Error: Failed to validate boot information!\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -235,9 +313,147 @@ GetPhitHobFromTransferList (
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get logical Cpu Number.
|
Get PHIT hob information from FF-A boot information.
|
||||||
|
|
||||||
@param [in] AbiProtocol Abi Protocol.
|
@param[in] FfaBootInfoHeaderAddr FF-A boot information header address
|
||||||
|
|
||||||
|
@retval NULL Failed to get PHIT hob
|
||||||
|
@retval Address PHIT hob address
|
||||||
|
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
VOID *
|
||||||
|
EFIAPI
|
||||||
|
GetPhitHobFromFfaBootInfo (
|
||||||
|
IN UINTN FfaBootInfoHeaderAddr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_FFA_BOOT_INFO_HEADER *FfaBootInfoHeader;
|
||||||
|
EFI_FFA_BOOT_INFO_DESC *FfaBootInfoDesc;
|
||||||
|
UINT32 Idx;
|
||||||
|
|
||||||
|
FfaBootInfoHeader = (EFI_FFA_BOOT_INFO_HEADER *)FfaBootInfoHeaderAddr;
|
||||||
|
|
||||||
|
for (Idx = 0; Idx < FfaBootInfoHeader->CountBootInfoDesc; Idx++) {
|
||||||
|
FfaBootInfoDesc = (EFI_FFA_BOOT_INFO_DESC *)((FfaBootInfoHeaderAddr +
|
||||||
|
FfaBootInfoHeader->OffsetBootInfoDesc) +
|
||||||
|
(Idx * FfaBootInfoHeader->SizeBootInfoDesc));
|
||||||
|
|
||||||
|
if ((FFA_BOOT_INFO_TYPE (FfaBootInfoDesc->Type) != FFA_BOOT_INFO_TYPE_STD) ||
|
||||||
|
(FFA_BOOT_INFO_TYPE_ID (FfaBootInfoDesc->Type) != FFA_BOOT_INFO_TYPE_ID_HOB) ||
|
||||||
|
(FFA_BOOT_INFO_FLAG_CONTENT (FfaBootInfoDesc->Flags) != FFA_BOOT_INFO_FLAG_CONTENT_ADDR))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (VOID *)(UINTN)FfaBootInfoDesc->Content;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG ((DEBUG_ERROR, "Error: No Phit hob is present in FfaBootInfo...\n"));
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get PHIT Hob from Boot information.
|
||||||
|
|
||||||
|
@param [in] CommProtocol Communication ABI protocol
|
||||||
|
@param [in] Arg0 In case of FF-A, address of FF-A boot information
|
||||||
|
In case of SPM_MM, 0x00 because we don't use device tree.
|
||||||
|
@param [in] Arg1 In case of FF-A, 0x00
|
||||||
|
In case of SPM_MM, Signature and register convention version
|
||||||
|
@param [in] Arg2 Should be 0x00 because we don't use device tree.
|
||||||
|
@param [in] Arg3 In case of FF-A, it's 0x00
|
||||||
|
In case of SPM_MM, address of transfer list
|
||||||
|
|
||||||
|
@retval NULL Failed to get PHIT hob
|
||||||
|
@retval Address PHIT hob address
|
||||||
|
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
VOID *
|
||||||
|
EFIAPI
|
||||||
|
GetPhitHobFromBootInfo (
|
||||||
|
IN COMM_PROTOCOL CommProtocol,
|
||||||
|
IN UINTN Arg0,
|
||||||
|
IN UINTN Arg1,
|
||||||
|
IN UINTN Arg2,
|
||||||
|
IN UINTN Arg3
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
VOID *HobStart;
|
||||||
|
|
||||||
|
Status = ValidateBootInfo (CommProtocol, Arg0, Arg1, Arg2, Arg3);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CommProtocol == CommProtocolFfa) {
|
||||||
|
HobStart = GetPhitHobFromFfaBootInfo (Arg0);
|
||||||
|
} else {
|
||||||
|
HobStart = GetPhitHobFromTransferList (Arg3);
|
||||||
|
}
|
||||||
|
|
||||||
|
return HobStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get service type.
|
||||||
|
When using FF-A ABI, there're ways to request service to StandaloneMm
|
||||||
|
- FF-A with MmCommunication protocol.
|
||||||
|
- FF-A service with each specification.
|
||||||
|
MmCommunication Protocol can use FFA_MSG_SEND_DIRECT_REQ or REQ2,
|
||||||
|
Other FF-A services should use FFA_MSG_SEND_DIRECT_REQ2.
|
||||||
|
In case of FF-A with MmCommunication protocol via FFA_MSG_SEND_DIRECT_REQ,
|
||||||
|
register x3 saves Communication Buffer with gEfiMmCommunication2ProtocolGuid.
|
||||||
|
In case of FF-A with MmCommunication protocol via FFA_MSG_SEND_DIRECT_REQ2,
|
||||||
|
register x2/x3 save gEfiMmCommunication2ProtocolGuid and
|
||||||
|
register x4 saves Communication Buffer with Service Guid.
|
||||||
|
|
||||||
|
Other FF-A services (ServiceTypeMisc) delivers register values according to
|
||||||
|
there own service specification.
|
||||||
|
That means it doesn't use MmCommunication Buffer with MmCommunication Header
|
||||||
|
format.
|
||||||
|
(i.e) Tpm service via FF-A or Firmware Update service via FF-A.
|
||||||
|
To support latter services by StandaloneMm, it defines SERVICE_TYPE_MISC.
|
||||||
|
So that StandaloneMmEntryPointCore.c generates MmCommunication Header
|
||||||
|
with delivered register values to dispatch service provided StandaloneMmCore.
|
||||||
|
So that service handler can get proper information from delivered register.
|
||||||
|
|
||||||
|
In case of SPM_MM Abi, it only supports MmCommunication service.
|
||||||
|
|
||||||
|
|
||||||
|
@param[in] ServiceGuid Service Guid
|
||||||
|
|
||||||
|
@retval ServiceTypeMmCommunication Mm communication service
|
||||||
|
@retval ServiceTypeMisc Service via implemented defined
|
||||||
|
register ABI.
|
||||||
|
This will generate internal
|
||||||
|
MmCommunication Header
|
||||||
|
to dispatch service implemented
|
||||||
|
in standaloneMm
|
||||||
|
@retval ServiceTypeUnknown Not supported service.
|
||||||
|
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
SERVICE_TYPE
|
||||||
|
EFIAPI
|
||||||
|
GetServiceType (
|
||||||
|
IN EFI_GUID *ServiceGuid
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (CompareGuid (ServiceGuid, &gEfiMmCommunication2ProtocolGuid)) {
|
||||||
|
return ServiceTypeMmCommunication;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ServiceTypeMisc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get logical Cpu Number based on MpInformation hob data.
|
||||||
|
|
||||||
|
@param [in] CommProtocol Abi Protocol.
|
||||||
@param [in] EventCompleteSvcArgs Pointer to the event completion arguments.
|
@param [in] EventCompleteSvcArgs Pointer to the event completion arguments.
|
||||||
|
|
||||||
@retval CpuNumber Cpu Number
|
@retval CpuNumber Cpu Number
|
||||||
|
@ -246,16 +462,21 @@ STATIC
|
||||||
UINTN
|
UINTN
|
||||||
EFIAPI
|
EFIAPI
|
||||||
GetCpuNumber (
|
GetCpuNumber (
|
||||||
IN ABI_PROTOCOL AbiProtocol,
|
IN COMM_PROTOCOL CommProtocol,
|
||||||
IN ARM_SVC_ARGS *EventCompleteSvcArgs
|
IN ARM_SVC_ARGS *EventCompleteSvcArgs
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINTN Idx;
|
UINTN Idx;
|
||||||
|
|
||||||
if (AbiProtocol == AbiProtocolSpmMm) {
|
if (CommProtocol == CommProtocolSpmMm) {
|
||||||
Idx = EventCompleteSvcArgs->Arg3;
|
Idx = EventCompleteSvcArgs->Arg3;
|
||||||
} else {
|
} else {
|
||||||
Idx = EventCompleteSvcArgs->Arg6;
|
/*
|
||||||
|
* There's no way to find out CPU number in StandaloneMm via FF-A v1.2.
|
||||||
|
* Because StandaloneMm is S-EL0 partition, it couldn't read mpidr.
|
||||||
|
* Currently, StandaloneMm is UP migratable SP so, just return idx 0.
|
||||||
|
*/
|
||||||
|
Idx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT (Idx < mMpInfo->NumberOfProcessors);
|
ASSERT (Idx < mMpInfo->NumberOfProcessors);
|
||||||
|
@ -428,7 +649,7 @@ DumpPhitHob (
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Convert EFI_STATUS to SPM_MM return code.
|
Convert EFI_STATUS to MM SPM return code.
|
||||||
|
|
||||||
@param [in] Status edk2 status code.
|
@param [in] Status edk2 status code.
|
||||||
|
|
||||||
|
@ -457,44 +678,57 @@ EfiStatusToSpmMmStatus (
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Convert EFI_STATUS to FFA return code.
|
Set svc arguments to report initialization status of StandaloneMm.
|
||||||
|
|
||||||
@param [in] Status edk2 status code.
|
@param[in] CommProtocol ABI Protocol.
|
||||||
|
@param[in] Status Result of initializing StandaloneMm.
|
||||||
@retval ARM_FFA_SPM_RET_* return value correspond to EFI_STATUS.
|
@param[out] EventCompleteSvcArgs Args structure.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
STATIC
|
STATIC
|
||||||
UINTN
|
VOID
|
||||||
EFIAPI
|
ReturnInitStatusToSpmc (
|
||||||
EfiStatusToFfaStatus (
|
IN COMM_PROTOCOL CommProtocol,
|
||||||
IN EFI_STATUS Status
|
IN EFI_STATUS Status,
|
||||||
|
OUT ARM_SVC_ARGS *EventCompleteSvcArgs
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
switch (Status) {
|
ZeroMem (EventCompleteSvcArgs, sizeof (ARM_SVC_ARGS));
|
||||||
case EFI_SUCCESS:
|
|
||||||
return ARM_FFA_SPM_RET_SUCCESS;
|
if (CommProtocol == CommProtocolFfa) {
|
||||||
case EFI_INVALID_PARAMETER:
|
if (EFI_ERROR (Status)) {
|
||||||
return ARM_FFA_SPM_RET_INVALID_PARAMETERS;
|
EventCompleteSvcArgs->Arg0 = ARM_FID_FFA_ERROR;
|
||||||
case EFI_OUT_OF_RESOURCES:
|
|
||||||
return ARM_FFA_SPM_RET_NO_MEMORY;
|
/*
|
||||||
case EFI_ALREADY_STARTED:
|
* In case SvcConduit, this must be zero.
|
||||||
return ARM_FFA_SPM_RET_BUSY;
|
*/
|
||||||
case EFI_INTERRUPT_PENDING:
|
EventCompleteSvcArgs->Arg1 = 0x00;
|
||||||
return ARM_FFA_SPM_RET_INTERRUPTED;
|
EventCompleteSvcArgs->Arg2 = EfiStatusToFfaStatus (Status);
|
||||||
case EFI_ACCESS_DENIED:
|
} else {
|
||||||
return ARM_FFA_SPM_RET_DENIED;
|
/*
|
||||||
case EFI_ABORTED:
|
* For completion of initialization, It should use FFA_MSG_WAIT.
|
||||||
return ARM_FFA_SPM_RET_ABORTED;
|
* See FF-A specification 5.5 Protocol for completing execution context
|
||||||
default:
|
* initialization
|
||||||
return ARM_FFA_SPM_RET_NOT_SUPPORTED;
|
*/
|
||||||
|
EventCompleteSvcArgs->Arg0 = ARM_FID_FFA_WAIT;
|
||||||
|
}
|
||||||
|
} else if (CommProtocol == CommProtocolSpmMm) {
|
||||||
|
EventCompleteSvcArgs->Arg0 = ARM_FID_SPM_MM_SP_EVENT_COMPLETE;
|
||||||
|
EventCompleteSvcArgs->Arg1 = EfiStatusToSpmMmStatus (Status);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* We don't know what communication abi protocol is using.
|
||||||
|
* Set Arg0 as MAX_UINTN to make SPMC know it's error situation.
|
||||||
|
*/
|
||||||
|
EventCompleteSvcArgs->Arg0 = MAX_UINTN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set Event Complete arguments to be returned via SVC call.
|
Set Event Complete arguments to be returned via SVC call.
|
||||||
|
|
||||||
@param[in] AbiProtocol ABI Protocol.
|
@param[in] CommProtocol Communication Protocol.
|
||||||
|
@param[in] CommData Communication Abi specific data.
|
||||||
@param[in] Status Result of StandaloneMm service.
|
@param[in] Status Result of StandaloneMm service.
|
||||||
@param[out] EventCompleteSvcArgs Args structure.
|
@param[out] EventCompleteSvcArgs Args structure.
|
||||||
|
|
||||||
|
@ -502,17 +736,50 @@ EfiStatusToFfaStatus (
|
||||||
STATIC
|
STATIC
|
||||||
VOID
|
VOID
|
||||||
SetEventCompleteSvcArgs (
|
SetEventCompleteSvcArgs (
|
||||||
IN ABI_PROTOCOL AbiProtocol,
|
IN COMM_PROTOCOL CommProtocol,
|
||||||
|
IN VOID *CommData,
|
||||||
IN EFI_STATUS Status,
|
IN EFI_STATUS Status,
|
||||||
OUT ARM_SVC_ARGS *EventCompleteSvcArgs
|
OUT ARM_SVC_ARGS *EventCompleteSvcArgs
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
FFA_MSG_INFO *FfaMsgInfo;
|
||||||
|
|
||||||
ZeroMem (EventCompleteSvcArgs, sizeof (ARM_SVC_ARGS));
|
ZeroMem (EventCompleteSvcArgs, sizeof (ARM_SVC_ARGS));
|
||||||
|
|
||||||
if (AbiProtocol == AbiProtocolFfa) {
|
if (CommProtocol == CommProtocolFfa) {
|
||||||
EventCompleteSvcArgs->Arg0 = ARM_SVC_ID_FFA_MSG_SEND_DIRECT_RESP;
|
FfaMsgInfo = CommData;
|
||||||
EventCompleteSvcArgs->Arg3 = ARM_FID_SPM_MM_SP_EVENT_COMPLETE;
|
|
||||||
EventCompleteSvcArgs->Arg4 = EfiStatusToFfaStatus (Status);
|
if (EFI_ERROR (Status)) {
|
||||||
|
EventCompleteSvcArgs->Arg0 = ARM_FID_FFA_ERROR;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* StandaloneMm is secure instance. So set as 0x00.
|
||||||
|
*/
|
||||||
|
EventCompleteSvcArgs->Arg1 = 0x00;
|
||||||
|
EventCompleteSvcArgs->Arg2 = EfiStatusToFfaStatus (Status);
|
||||||
|
} else {
|
||||||
|
if (FfaMsgInfo->DirectMsgVersion == DirectMsgV1) {
|
||||||
|
EventCompleteSvcArgs->Arg0 = ARM_FID_FFA_MSG_SEND_DIRECT_RESP;
|
||||||
|
EventCompleteSvcArgs->Arg3 = ARM_FID_SPM_MM_SP_EVENT_COMPLETE;
|
||||||
|
} else {
|
||||||
|
EventCompleteSvcArgs->Arg0 = ARM_FID_FFA_MSG_SEND_DIRECT_RESP2;
|
||||||
|
|
||||||
|
if (FfaMsgInfo->ServiceType == ServiceTypeMisc) {
|
||||||
|
EventCompleteSvcArgs->Arg4 = mMiscMmCommunicateBuffer->DirectMsgArgs.Arg0;
|
||||||
|
EventCompleteSvcArgs->Arg5 = mMiscMmCommunicateBuffer->DirectMsgArgs.Arg1;
|
||||||
|
EventCompleteSvcArgs->Arg6 = mMiscMmCommunicateBuffer->DirectMsgArgs.Arg2;
|
||||||
|
EventCompleteSvcArgs->Arg7 = mMiscMmCommunicateBuffer->DirectMsgArgs.Arg3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Swap source & dest partition id.
|
||||||
|
*/
|
||||||
|
EventCompleteSvcArgs->Arg1 = PACK_PARTITION_ID_INFO (
|
||||||
|
FfaMsgInfo->DestPartId,
|
||||||
|
FfaMsgInfo->SourcePartId
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
EventCompleteSvcArgs->Arg0 = ARM_FID_SPM_MM_SP_EVENT_COMPLETE;
|
EventCompleteSvcArgs->Arg0 = ARM_FID_SPM_MM_SP_EVENT_COMPLETE;
|
||||||
EventCompleteSvcArgs->Arg1 = EfiStatusToSpmMmStatus (Status);
|
EventCompleteSvcArgs->Arg1 = EfiStatusToSpmMmStatus (Status);
|
||||||
|
@ -520,9 +787,86 @@ SetEventCompleteSvcArgs (
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A loop to delegated events.
|
Wrap Misc service buffer with MmCommunication Header to
|
||||||
|
patch event handler via MmCommunication protocol.
|
||||||
|
|
||||||
@param [in] AbiProtocol Abi Protocol.
|
@param[in] EventSvcArgs Passed arguments
|
||||||
|
@param[in] ServiceGuid Service Guid
|
||||||
|
@param[out] Buffer Misc service data
|
||||||
|
wrapped with MmCommunication Header.
|
||||||
|
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
InitializeMiscMmCommunicateBuffer (
|
||||||
|
IN ARM_SVC_ARGS *EventSvcArgs,
|
||||||
|
IN EFI_GUID *ServiceGuid,
|
||||||
|
OUT MISC_MM_COMMUNICATE_BUFFER *Buffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ZeroMem (Buffer, sizeof (MISC_MM_COMMUNICATE_BUFFER));
|
||||||
|
|
||||||
|
Buffer->MessageLength = sizeof (DIRECT_MSG_ARGS);
|
||||||
|
Buffer->DirectMsgArgs.Arg0 = EventSvcArgs->Arg4;
|
||||||
|
Buffer->DirectMsgArgs.Arg1 = EventSvcArgs->Arg5;
|
||||||
|
Buffer->DirectMsgArgs.Arg2 = EventSvcArgs->Arg6;
|
||||||
|
Buffer->DirectMsgArgs.Arg3 = EventSvcArgs->Arg7;
|
||||||
|
CopyGuid (&Buffer->HeaderGuid, ServiceGuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Convert UUID to EFI_GUID format.
|
||||||
|
for example, If there is EFI_GUID named
|
||||||
|
"378daedc-f06b-4446-8314-40ab933c87a3",
|
||||||
|
|
||||||
|
EFI_GUID is saved in memory like:
|
||||||
|
dc ae 8d 37
|
||||||
|
6b f0 46 44
|
||||||
|
83 14 40 ab
|
||||||
|
93 3c 87 a3
|
||||||
|
|
||||||
|
However, UUID should be saved like:
|
||||||
|
37 8d ae dc
|
||||||
|
f0 6b 44 46
|
||||||
|
83 14 40 ab
|
||||||
|
93 3c 87 a3
|
||||||
|
|
||||||
|
FF-A and other software components (i.e. linux-kernel)
|
||||||
|
uses below format.
|
||||||
|
|
||||||
|
To patch mm-service properly, the passed uuid should be converted to
|
||||||
|
EFI_GUID format.
|
||||||
|
|
||||||
|
@param [in] Uuid Uuid
|
||||||
|
@param [out] Guid EFI_GUID
|
||||||
|
|
||||||
|
**/
|
||||||
|
STATIC
|
||||||
|
VOID
|
||||||
|
EFIAPI
|
||||||
|
ConvertUuidToEfiGuid (
|
||||||
|
IN UINT64 *Uuid,
|
||||||
|
OUT EFI_GUID *Guid
|
||||||
|
)
|
||||||
|
{
|
||||||
|
UINT32 *Data32;
|
||||||
|
UINT16 *Data16;
|
||||||
|
|
||||||
|
Data32 = (UINT32 *)Uuid;
|
||||||
|
Data32[0] = SwapBytes32 (Data32[0]);
|
||||||
|
Data16 = (UINT16 *)&Data32[1];
|
||||||
|
Data16[0] = SwapBytes16 (Data16[0]);
|
||||||
|
Data16[1] = SwapBytes16 (Data16[1]);
|
||||||
|
CopyGuid (Guid, (EFI_GUID *)Uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
A loop to delegate events from SPMC.
|
||||||
|
DelegatedEventLoop() calls ArmCallSvc() to exit to SPMC.
|
||||||
|
When an event is delegated to StandaloneMm the SPMC returns control
|
||||||
|
to StandaloneMm by returning from the SVC call.
|
||||||
|
|
||||||
|
@param [in] CommProtocol 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.
|
||||||
|
|
||||||
|
@ -531,17 +875,26 @@ STATIC
|
||||||
VOID
|
VOID
|
||||||
EFIAPI
|
EFIAPI
|
||||||
DelegatedEventLoop (
|
DelegatedEventLoop (
|
||||||
IN ABI_PROTOCOL AbiProtocol,
|
IN COMM_PROTOCOL CommProtocol,
|
||||||
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
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINTN CpuNumber;
|
UINTN CpuNumber;
|
||||||
UINTN CommBufferAddr;
|
UINT64 Uuid[2];
|
||||||
|
VOID *CommData;
|
||||||
|
FFA_MSG_INFO FfaMsgInfo;
|
||||||
|
EFI_GUID ServiceGuid;
|
||||||
|
SERVICE_TYPE ServiceType;
|
||||||
|
UINTN CommBufferAddr;
|
||||||
|
|
||||||
|
CommData = NULL;
|
||||||
|
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
|
// Exit to SPMC.
|
||||||
ArmCallSvc (EventCompleteSvcArgs);
|
ArmCallSvc (EventCompleteSvcArgs);
|
||||||
|
// Enter from SPMC.
|
||||||
|
|
||||||
DEBUG ((DEBUG_INFO, "Received delegated event\n"));
|
DEBUG ((DEBUG_INFO, "Received delegated event\n"));
|
||||||
DEBUG ((DEBUG_INFO, "X0 : 0x%x\n", (UINT32)EventCompleteSvcArgs->Arg0));
|
DEBUG ((DEBUG_INFO, "X0 : 0x%x\n", (UINT32)EventCompleteSvcArgs->Arg0));
|
||||||
|
@ -553,22 +906,70 @@ 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);
|
CpuNumber = GetCpuNumber (CommProtocol, EventCompleteSvcArgs);
|
||||||
DEBUG ((DEBUG_INFO, "CpuNumber: %d\n", CpuNumber));
|
DEBUG ((DEBUG_INFO, "CpuNumber: %d\n", CpuNumber));
|
||||||
|
|
||||||
if (AbiProtocol == AbiProtocolFfa) {
|
if (CommProtocol == CommProtocolFfa) {
|
||||||
if (EventCompleteSvcArgs->Arg0 != ARM_SVC_ID_FFA_MSG_SEND_DIRECT_REQ) {
|
/*
|
||||||
|
* Register Convention for FF-A
|
||||||
|
* Arg0: ARM_FID_FFA_MSG_SEND_DIRECT_REQ/REQ2
|
||||||
|
* Arg1: Sender and Receiver endpoint IDs.
|
||||||
|
* Arg2: Message Flags for ARM_FID_FFA_MSG_SEND_DIRECT_REQ
|
||||||
|
* Low 8 bytes of UUID for ARM_FID_FFA_MSG_SEND_DIRECT_REQ2
|
||||||
|
* Arg3: Implementation Defined for ARM_FID_FFA_MSG_SEND_DIRECT_REQ
|
||||||
|
* High 8 bytes of UUID for ARM_FID_FFA_MSG_SEND_DIRECT_REQ2
|
||||||
|
* Others: Implementation Defined.
|
||||||
|
*
|
||||||
|
* See Arm Firmware Framework for Arm A-Profile for detail.
|
||||||
|
*/
|
||||||
|
FfaMsgInfo.SourcePartId = GET_SOURCE_PARTITION_ID (EventCompleteSvcArgs->Arg1);
|
||||||
|
FfaMsgInfo.DestPartId = GET_DEST_PARTITION_ID (EventCompleteSvcArgs->Arg1);
|
||||||
|
CommData = &FfaMsgInfo;
|
||||||
|
|
||||||
|
if (EventCompleteSvcArgs->Arg0 == ARM_FID_FFA_MSG_SEND_DIRECT_REQ) {
|
||||||
|
FfaMsgInfo.DirectMsgVersion = DirectMsgV1;
|
||||||
|
ServiceType = ServiceTypeMmCommunication;
|
||||||
|
} else if (EventCompleteSvcArgs->Arg0 == ARM_FID_FFA_MSG_SEND_DIRECT_REQ2) {
|
||||||
|
FfaMsgInfo.DirectMsgVersion = DirectMsgV2;
|
||||||
|
Uuid[0] = EventCompleteSvcArgs->Arg2;
|
||||||
|
Uuid[1] = EventCompleteSvcArgs->Arg3;
|
||||||
|
ConvertUuidToEfiGuid (Uuid, &ServiceGuid);
|
||||||
|
ServiceType = GetServiceType (&ServiceGuid);
|
||||||
|
} else {
|
||||||
Status = EFI_INVALID_PARAMETER;
|
Status = EFI_INVALID_PARAMETER;
|
||||||
DEBUG ((
|
DEBUG ((
|
||||||
DEBUG_ERROR,
|
DEBUG_ERROR,
|
||||||
"Error: Unrecognized FF-A Id: 0x%x\n",
|
"Error: Unrecognized FF-A Id: 0x%x\n",
|
||||||
EventCompleteSvcArgs->Arg0
|
EventCompleteSvcArgs->Arg0
|
||||||
));
|
));
|
||||||
goto event_complete;
|
goto ExitHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
CommBufferAddr = EventCompleteSvcArgs->Arg3;
|
FfaMsgInfo.ServiceType = ServiceType;
|
||||||
} else {
|
|
||||||
|
if (ServiceType == ServiceTypeMmCommunication) {
|
||||||
|
if (FfaMsgInfo.DirectMsgVersion == DirectMsgV1) {
|
||||||
|
CommBufferAddr = EventCompleteSvcArgs->Arg3;
|
||||||
|
} else {
|
||||||
|
CommBufferAddr = EventCompleteSvcArgs->Arg4;
|
||||||
|
}
|
||||||
|
} else if (ServiceType == ServiceTypeMisc) {
|
||||||
|
/*
|
||||||
|
* In case of Misc service, generate mm communication header
|
||||||
|
* to dispatch service via StandaloneMmCore.
|
||||||
|
*/
|
||||||
|
InitializeMiscMmCommunicateBuffer (
|
||||||
|
EventCompleteSvcArgs,
|
||||||
|
&ServiceGuid,
|
||||||
|
mMiscMmCommunicateBuffer
|
||||||
|
);
|
||||||
|
CommBufferAddr = (UINTN)mMiscMmCommunicateBuffer;
|
||||||
|
} else {
|
||||||
|
Status = EFI_INVALID_PARAMETER;
|
||||||
|
DEBUG ((DEBUG_ERROR, "Error: Invalid FF-A Service...\n"));
|
||||||
|
goto ExitHandler;
|
||||||
|
}
|
||||||
|
} else if (CommProtocol == CommProtocolSpmMm) {
|
||||||
/*
|
/*
|
||||||
* Register Convention for SPM_MM
|
* Register Convention for SPM_MM
|
||||||
* Arg0: ARM_SMC_ID_MM_COMMUNICATE
|
* Arg0: ARM_SMC_ID_MM_COMMUNICATE
|
||||||
|
@ -585,13 +986,14 @@ DelegatedEventLoop (
|
||||||
"Error: Unrecognized SPM_MM Id: 0x%x\n",
|
"Error: Unrecognized SPM_MM Id: 0x%x\n",
|
||||||
EventCompleteSvcArgs->Arg0
|
EventCompleteSvcArgs->Arg0
|
||||||
));
|
));
|
||||||
goto event_complete;
|
goto ExitHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
CommBufferAddr = EventCompleteSvcArgs->Arg1;
|
CommBufferAddr = EventCompleteSvcArgs->Arg1;
|
||||||
|
ServiceType = ServiceTypeMmCommunication;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = CpuDriverEntryPoint (EventCompleteSvcArgs->Arg0, CpuNumber, CommBufferAddr);
|
Status = CpuDriverEntryPoint ((UINTN)ServiceType, CpuNumber, CommBufferAddr);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
DEBUG ((
|
DEBUG ((
|
||||||
DEBUG_ERROR,
|
DEBUG_ERROR,
|
||||||
|
@ -601,22 +1003,30 @@ DelegatedEventLoop (
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
event_complete:
|
ExitHandler:
|
||||||
SetEventCompleteSvcArgs (
|
SetEventCompleteSvcArgs (
|
||||||
AbiProtocol,
|
CommProtocol,
|
||||||
|
CommData,
|
||||||
Status,
|
Status,
|
||||||
EventCompleteSvcArgs
|
EventCompleteSvcArgs
|
||||||
);
|
);
|
||||||
}
|
} // while
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The entry point of Standalone MM Foundation.
|
The handoff between the SPMC to StandaloneMM depends on the
|
||||||
|
communication interface between the SPMC and StandaloneMM.
|
||||||
|
When SpmMM is used, the handoff is implemented using the
|
||||||
|
Firmware Handoff protocol. When FF-A is used the FF-A boot
|
||||||
|
protocol is used.
|
||||||
|
|
||||||
@param [in] Arg0 Boot information passed according to boot protocol.
|
@param [in] Arg0 In case of FF-A, address of FF-A boot information
|
||||||
@param [in] Arg1 Boot information passed according to boot protocol.
|
In case of SPM_MM, this parameter must be zero
|
||||||
@param [in] Arg2 Boot information passed according to boot protocol.
|
@param [in] Arg1 In case of FF-A, this parameter must be zero
|
||||||
@param [in] Arg3 Boot information passed according to boot protocol.
|
In case of SPM_MM, Signature and register convention version
|
||||||
|
@param [in] Arg2 Must be zero
|
||||||
|
@param [in] Arg3 In case of FF-A, this parameter must be zero
|
||||||
|
In case of SPM_MM, address of transfer list
|
||||||
|
|
||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
|
@ -633,8 +1043,7 @@ _ModuleEntryPoint (
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINT32 SectionHeaderOffset;
|
UINT32 SectionHeaderOffset;
|
||||||
UINT16 NumberOfSections;
|
UINT16 NumberOfSections;
|
||||||
BOOT_PROTOCOL BootProtocol;
|
COMM_PROTOCOL CommProtocol;
|
||||||
ABI_PROTOCOL AbiProtocol;
|
|
||||||
VOID *HobStart;
|
VOID *HobStart;
|
||||||
VOID *TeData;
|
VOID *TeData;
|
||||||
UINTN TeDataSize;
|
UINTN TeDataSize;
|
||||||
|
@ -648,22 +1057,12 @@ _ModuleEntryPoint (
|
||||||
|
|
||||||
CpuDriverEntryPoint = NULL;
|
CpuDriverEntryPoint = NULL;
|
||||||
|
|
||||||
AbiProtocol = GetAbiProtocol ();
|
Status = GetCommProtocol (&CommProtocol);
|
||||||
if (AbiProtocol == AbiProtocolUnknown) {
|
if (EFI_ERROR (Status)) {
|
||||||
Status = EFI_UNSUPPORTED;
|
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
HobStart = GetPhitHobFromBootInfo (CommProtocol, Arg0, Arg1, Arg2, Arg3);
|
||||||
* Check boot information
|
|
||||||
*/
|
|
||||||
BootProtocol = GetBootProtocol (Arg0, Arg1, Arg2, Arg3);
|
|
||||||
if (BootProtocol == BootProtocolUnknown) {
|
|
||||||
Status = EFI_UNSUPPORTED;
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
HobStart = GetPhitHobFromTransferList (Arg3);
|
|
||||||
if (HobStart == NULL) {
|
if (HobStart == NULL) {
|
||||||
Status = EFI_UNSUPPORTED;
|
Status = EFI_UNSUPPORTED;
|
||||||
goto finish;
|
goto finish;
|
||||||
|
@ -739,6 +1138,8 @@ _ModuleEntryPoint (
|
||||||
ASSERT_EFI_ERROR (Status);
|
ASSERT_EFI_ERROR (Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the gHobList to point to the HOB list passed by TF-A.
|
||||||
|
// This will be used by StandaloneMmCoreHobLib in early stage.
|
||||||
gHobList = HobStart;
|
gHobList = HobStart;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -746,9 +1147,14 @@ _ModuleEntryPoint (
|
||||||
//
|
//
|
||||||
ProcessModuleEntryPointList (HobStart);
|
ProcessModuleEntryPointList (HobStart);
|
||||||
|
|
||||||
//
|
// ProcessModuleEntryPointList() copies the HOB List passed
|
||||||
// Find HobList to check gEfiHobList is installed.
|
// by TF-A, i.e. HobStart, in the ConfigurationTable[].
|
||||||
//
|
// Therefore, find the HobList in the ConfigurationTable[] by
|
||||||
|
// searching for the gEfiHobListGuid.
|
||||||
|
// Also update the gHobList to point to the HobList in the
|
||||||
|
// ConfigurationTable[] as the HobList passed by TF-A can
|
||||||
|
// be overwritten by StMM after StMM Core is initialised, i.e.
|
||||||
|
// after the MM Core entry point is called.
|
||||||
Status = EFI_NOT_FOUND;
|
Status = EFI_NOT_FOUND;
|
||||||
ConfigurationTable = gMmCoreMmst.MmConfigurationTable;
|
ConfigurationTable = gMmCoreMmst.MmConfigurationTable;
|
||||||
for (Idx = 0; Idx < gMmCoreMmst.NumberOfTableEntries; Idx++) {
|
for (Idx = 0; Idx < gMmCoreMmst.NumberOfTableEntries; Idx++) {
|
||||||
|
@ -763,14 +1169,16 @@ _ModuleEntryPoint (
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the gHobList to point to the HOB list saved in ConfigurationTable[].
|
||||||
|
gHobList = ConfigurationTable[Idx].VendorTable;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Find MpInformation Hob in HobList.
|
// Find MpInformation Hob in HobList.
|
||||||
// It couldn't save address of mp information in gHobList
|
// It couldn't save address of mp information in gHobList
|
||||||
// because that memory area will be reused after StandaloneMm finishing
|
// because that memory area will be reused after StandaloneMm finishing
|
||||||
// initialization.
|
// initialization.
|
||||||
//
|
//
|
||||||
HobStart = ConfigurationTable[Idx].VendorTable;
|
GuidHob = GetNextGuidHob (&gMpInformationHobGuid, gHobList);
|
||||||
GuidHob = GetNextGuidHob (&gMpInformationHobGuid, HobStart);
|
|
||||||
if (GuidHob == NULL) {
|
if (GuidHob == NULL) {
|
||||||
Status = EFI_NOT_FOUND;
|
Status = EFI_NOT_FOUND;
|
||||||
DEBUG ((DEBUG_ERROR, "Error: No MpInformation hob ...\n"));
|
DEBUG ((DEBUG_ERROR, "Error: No MpInformation hob ...\n"));
|
||||||
|
@ -800,7 +1208,24 @@ _ModuleEntryPoint (
|
||||||
CpuDriverEntryPoint
|
CpuDriverEntryPoint
|
||||||
));
|
));
|
||||||
|
|
||||||
|
if (CommProtocol == CommProtocolFfa) {
|
||||||
|
Status = gMmCoreMmst.MmAllocatePool (
|
||||||
|
EfiRuntimeServicesData,
|
||||||
|
sizeof (MISC_MM_COMMUNICATE_BUFFER),
|
||||||
|
(VOID **)&mMiscMmCommunicateBuffer
|
||||||
|
);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
DEBUG ((
|
||||||
|
DEBUG_ERROR,
|
||||||
|
"Error: Failed to allocate misc mm communication buffer...\n"
|
||||||
|
));
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
SetEventCompleteSvcArgs (AbiProtocol, Status, &EventCompleteSvcArgs);
|
ReturnInitStatusToSpmc (CommProtocol, Status, &EventCompleteSvcArgs);
|
||||||
DelegatedEventLoop (AbiProtocol, CpuDriverEntryPoint, &EventCompleteSvcArgs);
|
|
||||||
|
// Call DelegateEventLoop(), this function never returns.
|
||||||
|
DelegatedEventLoop (CommProtocol, CpuDriverEntryPoint, &EventCompleteSvcArgs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
StandaloneMmMmuLib
|
StandaloneMmMmuLib
|
||||||
ArmSvcLib
|
ArmSvcLib
|
||||||
ArmTransferListLib
|
ArmTransferListLib
|
||||||
|
ArmFfaLib
|
||||||
|
|
||||||
[Guids]
|
[Guids]
|
||||||
gMpInformationHobGuid
|
gMpInformationHobGuid
|
||||||
|
@ -55,6 +56,7 @@
|
||||||
|
|
||||||
[Protocols.ARM, Protocols.AARCH64]
|
[Protocols.ARM, Protocols.AARCH64]
|
||||||
gEdkiiPiMmCpuDriverEpProtocolGuid
|
gEdkiiPiMmCpuDriverEpProtocolGuid
|
||||||
|
gEfiMmCommunication2ProtocolGuid
|
||||||
|
|
||||||
#
|
#
|
||||||
# This configuration fails for CLANGPDB, which does not support PIE in the GCC
|
# This configuration fails for CLANGPDB, which does not support PIE in the GCC
|
||||||
|
|
|
@ -75,6 +75,7 @@
|
||||||
[LibraryClasses.AARCH64, LibraryClasses.ARM]
|
[LibraryClasses.AARCH64, LibraryClasses.ARM]
|
||||||
ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
|
ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
|
||||||
StandaloneMmMmuLib|ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf
|
StandaloneMmMmuLib|ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf
|
||||||
|
ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
|
||||||
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
|
||||||
|
@ -84,6 +85,9 @@
|
||||||
HobLib|StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf
|
HobLib|StandaloneMmPkg/Library/StandaloneMmCoreHobLib/StandaloneMmCoreHobLib.inf
|
||||||
ArmFfaLib|ArmPkg/Library/ArmFfaLib/ArmFfaStandaloneMmCoreLib.inf
|
ArmFfaLib|ArmPkg/Library/ArmFfaLib/ArmFfaStandaloneMmCoreLib.inf
|
||||||
|
|
||||||
|
[LibraryClasses.AARCH64.MM_CORE_STANDALONE, LibraryClasses.ARM.MM_CORE_STANDALONE]
|
||||||
|
ArmFfaLib|ArmPkg/Library/ArmFfaLib/ArmFfaStandaloneMmCoreLib.inf
|
||||||
|
|
||||||
[LibraryClasses.common.MM_STANDALONE]
|
[LibraryClasses.common.MM_STANDALONE]
|
||||||
MemoryAllocationLib|StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf
|
MemoryAllocationLib|StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue