diff options
Diffstat (limited to 'ArmPkg/Include')
-rw-r--r-- | ArmPkg/Include/Library/ArmStandaloneMmCoreEntryPoint.h | 294 | ||||
-rw-r--r-- | ArmPkg/Include/Protocol/PiMmCpuDriverEp.h | 60 |
2 files changed, 354 insertions, 0 deletions
diff --git a/ArmPkg/Include/Library/ArmStandaloneMmCoreEntryPoint.h b/ArmPkg/Include/Library/ArmStandaloneMmCoreEntryPoint.h new file mode 100644 index 0000000000..1549211613 --- /dev/null +++ b/ArmPkg/Include/Library/ArmStandaloneMmCoreEntryPoint.h @@ -0,0 +1,294 @@ +/** @file
+ Entry point to the Standalone MM Foundation when initialized during the SEC
+ phase on ARM platforms
+
+ Copyright (c) 2017 - 2024, Arm Ltd. All rights reserved.<BR>
+ 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/latest]
+
+**/
+
+#ifndef __STANDALONEMMCORE_ENTRY_POINT_H__
+#define __STANDALONEMMCORE_ENTRY_POINT_H__
+
+#include <Library/ArmSvcLib.h>
+#include <Library/ArmFfaLib.h>
+#include <Library/PeCoffLib.h>
+#include <Library/FvLib.h>
+
+#define CPU_INFO_FLAG_PRIMARY_CPU 0x00000001
+
+/*
+ * Index information for mm range descriptors in
+ * gEfiMmPeiMmramMemoryReserveGuid Guid Hob.
+ */
+#define MMRAM_DESC_IDX_IMAGE 0
+#define MMRAM_DESC_IDX_SECURE_SHARED_BUFFER 1
+#define MMRAM_DESC_IDX_NORMAL_SHARED_BUFFER 2
+#define MMRAM_DESC_IDX_HEAP 3
+#define MMRAM_DESC_MIN_COUNT 4
+
+/*
+ * Communication ABI protocol to communicate between normal/secure partition.
+ */
+typedef enum {
+ /// Unknown Communication ABI protocol
+ CommProtocolUnknown,
+
+ /// Communicate via SPM_MM ABI protocol
+ CommProtocolSpmMm,
+
+ /// Communicate via FF-A ABI protocol
+ CommProtocolFfa,
+
+ CommProtocolMax,
+} 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 {
+ UINT8 Type; /* type of the structure */
+ UINT8 Version; /* version of this structure */
+ UINT16 Size; /* size of this structure in bytes */
+ UINT32 Attr; /* attributes: unused bits SBZ */
+} EFI_PARAM_HEADER;
+
+typedef RETURN_STATUS (*REGION_PERMISSION_UPDATE_FUNC) (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ );
+
+/**
+ Privileged firmware assigns RO & Executable attributes to all memory occupied
+ by the Boot Firmware Volume. This function sets the correct permissions of
+ sections in the Standalone MM Core module to be able to access RO and RW data
+ and make further progress in the boot process.
+
+ @param [in] ImageContext Pointer to PE/COFF image context
+ @param [in] ImageBase Base of image in memory
+ @param [in] SectionHeaderOffset Offset of PE/COFF image section header
+ @param [in] NumberOfSections Number of Sections
+ @param [in] TextUpdater Function to change code permissions
+ @param [in] ReadOnlyUpdater Function to change RO permissions
+ @param [in] ReadWriteUpdater Function to change RW permissions
+
+**/
+EFI_STATUS
+EFIAPI
+UpdateMmFoundationPeCoffPermissions (
+ IN CONST PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
+ IN EFI_PHYSICAL_ADDRESS ImageBase,
+ IN UINT32 SectionHeaderOffset,
+ IN CONST UINT16 NumberOfSections,
+ IN REGION_PERMISSION_UPDATE_FUNC TextUpdater,
+ IN REGION_PERMISSION_UPDATE_FUNC ReadOnlyUpdater,
+ IN REGION_PERMISSION_UPDATE_FUNC ReadWriteUpdater
+ );
+
+/**
+ Privileged firmware assigns RO & Executable attributes to all memory occupied
+ by the Boot Firmware Volume. This function locates the section information of
+ the Standalone MM Core module to be able to change permissions of the
+ individual sections later in the boot process.
+
+ @param [in] TeData Pointer to PE/COFF image data
+ @param [in, out] ImageContext Pointer to PE/COFF image context
+ @param [out] ImageBase Pointer to ImageBase variable
+ @param [in, out] SectionHeaderOffset Offset of PE/COFF image section header
+ @param [in, out] NumberOfSections Number of Sections
+
+**/
+EFI_STATUS
+EFIAPI
+GetStandaloneMmCorePeCoffSections (
+ IN VOID *TeData,
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
+ OUT EFI_PHYSICAL_ADDRESS *ImageBase,
+ IN OUT UINT32 *SectionHeaderOffset,
+ IN OUT UINT16 *NumberOfSections
+ );
+
+/**
+ Privileged firmware assigns RO & Executable attributes to all memory occupied
+ by the Boot Firmware Volume. This function locates the Standalone MM Core
+ module PE/COFF image in the BFV and returns this information.
+
+ @param [in] BfvAddress Base Address of Boot Firmware Volume
+ @param [in, out] TeData Pointer to address for allocating memory
+ for PE/COFF image data
+ @param [in, out] TeDataSize Pointer to size of PE/COFF image data
+
+**/
+EFI_STATUS
+EFIAPI
+LocateStandaloneMmCorePeCoffData (
+ IN EFI_FIRMWARE_VOLUME_HEADER *BfvAddress,
+ IN OUT VOID **TeData,
+ IN OUT UINTN *TeDataSize
+ );
+
+/**
+ 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 In case of FF-A, address of FF-A boot information
+ In case of SPM_MM, this parameter must be zero
+ @param [in] Arg1 In case of FF-A, this parameter must be zero
+ 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
+EFIAPI
+CEntryPoint (
+ IN UINTN Arg0,
+ IN UINTN Arg1,
+ IN UINTN Arg2,
+ IN UINTN Arg3
+ );
+
+/**
+ Auto generated function that calls the library constructors for all of the module's dependent libraries.
+
+ This function must be called by CEntryPoint().
+ This function calls the set of library constructors for the set of library instances
+ that a module depends on. This includes library instances that a module depends on
+ directly and library instances that a module depends on indirectly through other
+ libraries. This function is auto generated by build tools and those build tools are
+ responsible for collecting the set of library instances, determine which ones have
+ constructors, and calling the library constructors in the proper order based upon
+ each of the library instances own dependencies.
+
+ @param ImageHandle The image handle of the DXE Core.
+ @param SystemTable A pointer to the EFI System Table.
+
+**/
+VOID
+EFIAPI
+ProcessLibraryConstructorList (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_MM_SYSTEM_TABLE *MmSystemTable
+ );
+
+/**
+ Auto generated function that calls a set of module entry points.
+
+ This function must be called by CEntryPoint().
+ This function calls the set of module entry points.
+ This function is auto generated by build tools and those build tools are responsible
+ for collecting the module entry points and calling them in a specified order.
+
+ @param HobStart Pointer to the beginning of the HOB List passed in from the PEI Phase.
+
+**/
+VOID
+EFIAPI
+ProcessModuleEntryPointList (
+ IN VOID *HobStart
+ );
+
+#endif
diff --git a/ArmPkg/Include/Protocol/PiMmCpuDriverEp.h b/ArmPkg/Include/Protocol/PiMmCpuDriverEp.h new file mode 100644 index 0000000000..4b2f61fa06 --- /dev/null +++ b/ArmPkg/Include/Protocol/PiMmCpuDriverEp.h @@ -0,0 +1,60 @@ +/** @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 EDKII_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] 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 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
|