4. MM Protocols

4.1. Introduction

There is a share-nothing model that is employed between the management-mode application and the boot service/runtime UEFI environment. As such, a minimum set of services needs to be available to the boot service agent. The services described in this section coexist with a foreground pre-boot or runtime environment. The latter can include both UEFI and non-UEFI aware operating systems. As such, the implementation of these services must save and restore any “shared” resources with the foreground environment or only use resources that are private to the MM code.

4.2. Status Codes Services

4.2.1. EFI_MM_STATUS_CODE_PROTOCOL

Summary

Provides status code services from MM.

GUID

#define EFI_MM_STATUS_CODE_PROTOCOL_GUID \
  { 0x6afd2b77, 0x98c1, 0x4acd, 0xa6, 0xf9, 0x8a, 0x94, \
  0x39, 0xde, 0xf, 0xb1 }

Protocol Interface Structure

typedef struct \_EFI_MM_STATUS_CODE_PROTOCOL {
  EFI_MM_REPORT_STATUS_CODE                     ReportStatusCode;
} EFI_MM_STATUS_CODE_PROTOCOL;

Parameters

ReportStatusCode

Allows for the MM agent to produce a status code output. See the ReportStatusCode() function description.

Description

The EFI_MM_STATUS_CODE_PROTOCOL provides the basic status code services while in MMRAM.

4.2.2. EFI_MM_STATUS_CODE_PROTOCOL.ReportStatusCode()

Summary

Service to emit the status code in MM.

Prototype

typedef
EFI_STATUS
(EFIAPI \*EFI_MM_REPORT_STATUS_CODE) (
  IN CONST EFI_MM_STATUS_CODE_PROTOCOL   *This,
  IN EFI_STATUS_CODE_TYPE                CodeType,
  IN EFI_STATUS_CODE_VALUE               Value,
  IN UINT32                              Instance,
  IN CONST EFI_GUID                      *CallerId,
  IN EFI_STATUS_CODE_DATA                *Data OPTIONAL
  );

Parameters

This

Points to this instance of the EFI_MM_STATUS_CODE_PROTOCOL.

CodeType

Indicates the type of status code being reported. Type EFI_STATUS_CODE_TYPE is defined in “Related Definitions” below.

Value

Describes the current status of a hardware or software entity. This status includes information about the class and subclass that is used to classify the entity, as well as an operation. For progress codes, the operation is the current activity. For error codes, it is the exception. For debug codes, it is not defined at this time. Type EFI_STATUS_CODE_VALUE is defined in “Related Definitions” below.

Instance

The enumeration of a hardware or software entity within the system. A system may contain multiple entities that match a class/subclass pairing. The instance differentiates between them. An instance of 0 indicates that instance information is unavailable, not meaningful, or not relevant. Valid instance numbers start with 1.

CallerId

This optional parameter may be used to identify the caller. This parameter allows the status code driver to apply different rules to different callers.

Data

This optional parameter may be used to pass additional data. Type EFI_STATUS_CODE_DATA is defined in “Related Definitions” below. The contents of this data type may have additional GUID-specific data.

Description

The EFI_MM_STATUS_CODE_PROTOCOL.ReportStatusCode() function enables a driver to emit a status code while in MM. The reason that there is a separate protocol definition from the DXE variant of this service is that the publisher of this protocol will provide a service that is capability of coexisting with a foreground operational environment, such as an operating system after the termination of boot services.

In case of an error, the caller can specify the severity. In most cases, the entity that reports the error may not have a platform-wide view and may not be able to accurately assess the impact of the error condition. The MM MM Driver that produces the Status Code MM Protocol is responsible for assessing the true severity level based on the reported severity and other information. This MM MM Driver may perform platform specific actions based on the type and severity of the status code being reported.

If Data is present, the driver treats it as read only data. The driver must copy Data to a local buffer in an atomic operation before performing any other actions. This is necessary to make this function re-entrant. The size of the local buffer may be limited. As a result, some of the Data can be lost. The size of the local buffer should at least be 256 bytes in size. Larger buffers will reduce the probability of losing part of the Data . If all of the local buffers are consumed, then this service may not be able to perform the platform specific action required by the status code being reported. As a result, if all the local buffers are consumed, the behavior of this service is undefined.

If the CallerId parameter is not NULL , then it is required to point to a constant GUID. In other words, the caller may not reuse or release the buffer pointed to by CallerId.

Status Codes Returned

EFI_SUCCESS

The function completed successfully

EFI_DEVICE_ERROR

The function should not be completed due to a device error

4.3. CPU Save State Access Services

4.3.1. EFI_MM_CPU_PROTOCOL

Summary

Provides access to CPU-related information while in MM.

GUID

#define EFI_MM_CPU_PROTOCOL_GUID \
  { 0xeb346b97, 0x975f, 0x4a9f, \
  0x8b, 0x22, 0xf8, 0xe9, 0x2b, 0xb3, 0xd5, 0x69 }

Prototype

typedef struct \_EFI_MM_CPU_PROTOCOL {
  EFI_MM_READ_SAVE_STATE                ReadSaveState;
  EFI_MM_WRITE_SAVE_STATE               WriteSaveState;
} EFI_MM_CPU_PROTOCOL;

Members

ReadSaveState

Read information from the CPU save state. See ReadSaveState() for more information.

WriteSaveState

Write information to the CPU save state. See WriteSaveState() for more information.

Description

This protocol allows MM Drivers to access architecture-standard registers from any of the CPU save state areas. In some cases, difference processors provide the same information in the save state, but not in the same format. These so-called pseudo-registers provide this information in a standard format.

4.3.2. EFI_MM_CPU_PROTOCOL.ReadSaveState()

Summary

Read data from the CPU save state.

Prototype

typedef
  EFI_STATUS
(EFIAPI *EFI_MM_READ_SAVE_STATE (
  IN CONST EFI_MM_CPU_PROTOCOL      *This,
  IN UINTN                          Width,
  IN UINTN                          CpuIndex,
  OUT VOID                          *Buffer
  );

Parameters

Width

The number of bytes to read from the CPU save state. If the register specified by Register does not support the size specified by Width , then EFI_INVALID_PARAMETER is returned.

Register

Specifies the CPU register to read form the save state. The type EFI_MM_SAVE_STATE_REGISTER is defined in “Related Definitions” below. If the specified register is not implemented in the CPU save state map then EFI_NOT_FOUND error will be returned.

CpuIndex

Specifies the zero-based index of the CPU save state

*Buffer

Upon return, this holds the CPU register value read from the save state.

Description

This function is used to read the specified number of bytes of the specified register from the CPU save state of the specified CPU and place the value into the buffer. If the CPU does not support the specified register Register , then EFI_NOT_FOUND should be returned. If the CPU does not support the specified register width Width , then EFI_INVALID_PARAMETER is returned.

Related Definitions

typedef enum {
  //
  // x86/X64 standard registers
  //
  EFI_MM_SAVE_STATE_REGISTER_GDTBASE = 4,
  EFI_MM_SAVE_STATE_REGISTER_IDTBASE = 5,
  EFI_MM_SAVE_STATE_REGISTER_LDTBASE = 6,
  EFI_MM_SAVE_STATE_REGISTER_GDTLIMIT = 7,
  EFI_MM_SAVE_STATE_REGISTER_IDTLIMIT = 8,
  EFI_MM_SAVE_STATE_REGISTER_LDTLIMIT = 9,
  EFI_MM_SAVE_STATE_REGISTER_LDTINFO = 10,
  EFI_MM_SAVE_STATE_REGISTER_ES = 20,
  EFI_MM_SAVE_STATE_REGISTER_CS = 21,
  EFI_MM_SAVE_STATE_REGISTER_SS = 22,
  EFI_MM_SAVE_STATE_REGISTER_DS = 23,
  EFI_MM_SAVE_STATE_REGISTER_FS = 24,
  EFI_MM_SAVE_STATE_REGISTER_GS = 25,
  EFI_MM_SAVE_STATE_REGISTER_LDTR_SEL = 26,
  EFI_MM_SAVE_STATE_REGISTER_TR_SEL = 27,
  EFI_MM_SAVE_STATE_REGISTER_DR7 = 28,
  EFI_MM_SAVE_STATE_REGISTER_DR6 = 29,
  EFI_MM_SAVE_STATE_REGISTER_R8 = 30,
  EFI_MM_SAVE_STATE_REGISTER_R9 = 31,
  EFI_MM_SAVE_STATE_REGISTER_R10 = 32,
  EFI_MM_SAVE_STATE_REGISTER_R11 = 33,
  EFI_MM_SAVE_STATE_REGISTER_R12 = 34,
  EFI_MM_SAVE_STATE_REGISTER_R13 = 35,
  EFI_MM_SAVE_STATE_REGISTER_R14 = 36,
  EFI_MM_SAVE_STATE_REGISTER_R15 = 37,
  EFI_MM_SAVE_STATE_REGISTER_RAX = 38,
  EFI_MM_SAVE_STATE_REGISTER_RBX = 39,
  EFI_MM_SAVE_STATE_REGISTER_RCX = 40,
  EFI_MM_SAVE_STATE_REGISTER_RDX = 41,
  EFI_MM_SAVE_STATE_REGISTER_RSP = 42,
  EFI_MM_SAVE_STATE_REGISTER_RBP = 43,
  EFI_MM_SAVE_STATE_REGISTER_RSI = 44,
  EFI_MM_SAVE_STATE_REGISTER_RDI = 45,
  EFI_MM_SAVE_STATE_REGISTER_RIP = 46,
  EFI_MM_SAVE_STATE_REGISTER_RFLAGS = 51,
  EFI_MM_SAVE_STATE_REGISTER_CR0 = 52,
  EFI_MM_SAVE_STATE_REGISTER_CR3 = 53,
  EFI_MM_SAVE_STATE_REGISTER_CR4 = 54,
  EFI_MM_SAVE_STATE_REGISTER_FCW = 256,
  EFI_MM_SAVE_STATE_REGISTER_FSW = 257,
  EFI_MM_SAVE_STATE_REGISTER_FTW = 258,
  EFI_MM_SAVE_STATE_REGISTER_OPCODE = 259,
  EFI_MM_SAVE_STATE_REGISTER_FP_EIP = 260,
  EFI_MM_SAVE_STATE_REGISTER_FP_CS = 261,
  EFI_MM_SAVE_STATE_REGISTER_DATAOFFSET = 262,
  EFI_MM_SAVE_STATE_REGISTER_FP_DS = 263,
  EFI_MM_SAVE_STATE_REGISTER_MM0 = 264,
  EFI_MM_SAVE_STATE_REGISTER_MM1 = 265,
  EFI_MM_SAVE_STATE_REGISTER_MM2 = 266,
  EFI_MM_SAVE_STATE_REGISTER_MM3 = 267,
  EFI_MM_SAVE_STATE_REGISTER_MM4 = 268,
  EFI_MM_SAVE_STATE_REGISTER_MM5 = 269,
  EFI_MM_SAVE_STATE_REGISTER_MM6 = 270,
  EFI_MM_SAVE_STATE_REGISTER_MM7 = 271,
  EFI_MM_SAVE_STATE_REGISTER_XMM0 = 272,
  EFI_MM_SAVE_STATE_REGISTER_XMM1 = 273,
  EFI_MM_SAVE_STATE_REGISTER_XMM2 = 274,
  EFI_MM_SAVE_STATE_REGISTER_XMM3 = 275,
  EFI_MM_SAVE_STATE_REGISTER_XMM4 = 276,
  EFI_MM_SAVE_STATE_REGISTER_XMM5 = 277,
  EFI_MM_SAVE_STATE_REGISTER_XMM6 = 278,
  EFI_MM_SAVE_STATE_REGISTER_XMM7 = 279,
  EFI_MM_SAVE_STATE_REGISTER_XMM8 = 280,
  EFI_MM_SAVE_STATE_REGISTER_XMM9 = 281,
  EFI_MM_SAVE_STATE_REGISTER_XMM10 = 282,
  EFI_MM_SAVE_STATE_REGISTER_XMM11 = 283,
  EFI_MM_SAVE_STATE_REGISTER_XMM12 = 284,
  EFI_MM_SAVE_STATE_REGISTER_XMM13 = 285,
  EFI_MM_SAVE_STATE_REGISTER_XMM14 = 286,
  EFI_MM_SAVE_STATE_REGISTER_XMM15 = 287,
  //
  // Pseudo-Registers
  //
  EFI_MM_SAVE_STATE_REGISTER_IO = 512,
  EFI_MM_SAVE_STATE_REGISTER_LMA = 513,
  EFI_MM_SAVE_STATE_REGISTER_PROCESSOR_ID = 514,

  //
  // ARM Registers. X0 corresponds to R0
  //

  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X0 = 1024,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X1 = 1025,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X2 = 1026,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X3 = 1027,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X4 = 1028,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X5 = 1029,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X6 = 1030,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X7 = 1031,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X8 = 1032,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X9 = 1033,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X10 = 1034,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X11 = 1035,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X12 = 1036,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X13 = 1037,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X14 = 1038,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X15 = 1039,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X16 = 1040,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X17 = 1041,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X18 = 1042,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X19 = 1043,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X20 = 1044,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X21 = 1045,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X22 = 1046,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X23 = 1047,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X24 = 1048,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X25 = 1049,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X26 = 1050,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X27 = 1051,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X28 = 1052,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X29 = 1053,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X30 = 1054,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_X31 = 1055,

  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_FP = 1053, // x29 -
  Frame Pointer
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_LR = 1054, // x30 - Link
  Register
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_SP = 1055, // x31 -
  Stack Pointer

  // AArch64 EL1 Context System Registers
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_ELR_EL1 = 1300,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_ESR_EL1 = 1301,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_FAR_EL1 = 1302,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_ISR_EL1 = 1303,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_MAIR_EL1 = 1304,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_MIDR_EL1 = 1305,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_MPIDR_EL1 = 1306,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_SCTLR_EL1 = 1307,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_SP_EL0 = 1308,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_SP_EL1 = 1309,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_SPSR_EL1 = 1310,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_TCR_EL1 = 1311,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_TPIDR_EL0 = 1312,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_TPIDR_EL1 = 1313,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_TPIDRRO_EL0 = 1314,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_TTBR0_EL1 = 1315,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_TTBR1_EL1 = 1316,

  // AArch64 EL2 Context System Registers
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_ELR_EL2 = 1320,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_ESR_EL2 = 1321,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_FAR_EL2 = 1322,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_HACR_EL2 = 1333,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_HCR_EL2 = 1334,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_HPFAR_EL2 = 1335,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_MAIR_EL2 = 1336,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_SCTLR_EL2 = 1337,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_SP_EL2 = 1338,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_SPSR_EL2 = 1339,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_TCR_EL2 = 1340,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_TPIDR_EL2 = 1341,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_TTBR0_EL2 = 1342,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_VTCR_EL2 = 1343,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_VTTBR_EL2 = 1344,

  // AArch64 EL3 Context System Registers
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_ELR_EL3 = 1350,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_ESR_EL3 = 1351,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_FAR_EL3 = 1352,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_MAIR_EL3 = 1353,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_SCTLR_EL3 = 1354,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_SP_EL3 = 1355,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_SPSR_EL3 = 1356,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_TCR_EL3 = 1357,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_TPIDR_EL3 = 1358,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_TTBR0_EL3 = 1359,


  // 32-bit aliases for Rx->Xx
  EFI_SMM_SAVE_STATE_REGISTER_ARM_R0 = 1024,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_R1 = 1025,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_R2 = 1026,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_R3 = 1027,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_R4 = 1028,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_R5 = 1029,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_R6 = 1030,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_R7 = 1031,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_R8 = 1032,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_R9 = 1033,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_R10 = 1034,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_R11 = 1035,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_R12 = 1036,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_R13 = 1037,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_R14 = 1038,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_R15 = 1039,
  // Unique AArch32 Registers
  EFI_SMM_SAVE_STATE_REGISTER_ARM_SP = 1037, // alias for R13
  EFI_SMM_SAVE_STATE_REGISTER_ARM_LR = 1038, // alias for R14
  EFI_SMM_SAVE_STATE_REGISTER_ARM_PC = 1040, // alias for R15

  // AArch32 EL1 Context System Registers
  EFI_SMM_SAVE_STATE_REGISTER_ARM_DFAR = 1222,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_DFSR = 1223,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_IFAR = 1224,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_ISR = 1225,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_MAIR0 = 1226,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_MAIR1 = 1227,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_MIDR = 1228,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_MPIDR = 1229,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_NMRR = 1230,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_PRRR = 1231,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_SCTLR_NS = 1231,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_SPSR = 1232,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_SPSR_abt = 1233,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_SPSR_fiq = 1234,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_SPSR_irq = 1235,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_SPSR_svc = 1236,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_SPSR_und = 1237,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_TPIDRPRW = 1238,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_TPIDRURO = 1239,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_TPIDRURW = 1240,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_TTBCR = 1241,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_TTBR0 = 1242,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_TTBR1 = 1243,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_DACR = 1244,

  // AArch32 EL1 Context System Registers
  EFI_SMM_SAVE_STATE_REGISTER_ARM_ELR_hyp = 1245,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_HAMAIR0 = 1246,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_HAMAIR1 = 1247,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_HCR = 1248,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_HCR2 = 1249,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_HDFAR = 1250,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_HIFAR = 1251,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_HPFAR = 1252,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_HSR = 1253,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_HTCR = 1254,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_HTPIDR = 1255,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_HTTBR = 1256,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_SPSR_hyp = 1257,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_VTCR = 1258,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_VTTBR = 1259,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_DACR32_EL2 = 1260,

  // AArch32 EL2 Secure Context System Registers
  EFI_SMM_SAVE_STATE_REGISTER_ARM_SCTLR_S = 1261,
  EFI_SMM_SAVE_STATE_REGISTER_ARM_SPSR_mon = 1262,

  // Context System Registers: 32768 - 65535
  EFI_SMM_SAVE_STATE_REGISTER_ARM_CSR = 32768,
  EFI_SMM_SAVE_STATE_REGISTER_AARCH64_CSR = 32768
  } EFI_SMM_SAVE_STATE_REGISTER;

  } EFI_MM_SAVE_STATE_REGISTER;

4.3.3. AARCH32/AARCH64 REGISTER AVAILABILITY

Depending on the platform policy, not all registers may be available in the MM Save State. These registers will return the status code EFI_NOT_FOUND when calling ReadSaveState() or WriteSaveState() . In some cases this may be done to protect sensitive information in the non-secure execution environment.

4.3.4. EFI_MM_SAVE_STATE_ARM_CSR, EFI_MM_SAVE_STATE_AARCH64_CSR

The Read/Write interface can be used to retrieve AARCH32/AARCH64 Context System Registers that were saved upon entry to MM. These registers have the CPU Register Index starting with EFI_MM_SAVE_STATE_ARM_CSR . The actual CPU register index for a specific CSR register is calculated by adding the encoding of the MRS instruction, bits 5:19, to EFI_MM_SAVE_STATE_REGISTER_ARM_CSR .

That is: (MRSIntruction[5:19] << 5 + EFI_MM_SAVE_STATE_ARM_CSR ). See the UEFI Specification , Table 275 in Appendix N for more information.

4.3.5. EFI_MM_SAVE_STATE_REGISTER_PROCESSOR_ID

The Read/Write interface for the pseudo-register EFI_MM_SAVE_STATE_REGISTER_PROCESSOR_ID follows the following rules.

For ReadSaveState():

  • The pseudo-register only supports the 64-bit size specified by Width .

  • If the processor is in SM at the time the MMI occurred, the pseudo register value EFI_MM_SAVE_STATE_REGISTER_PROCESSOR_ID is returned in Buffer. The value should match the ProcessorId value, as described in the EFI_PROCESSOR_INFORMATION record defined in Volume 2 of the Platform Initialization Specification .

For WriteSaveState():

  • Write operations to this pseudo-register are ignored.

4.3.6. EFI_MM_SAVE_STATE_REGISTER_LMA

The Read/Write interface for the pseudo-register EFI_MM_SAVE_STATE_REGISTER_LMA follows the following rules.

For ReadSaveState():

  • The pseudo-register only supports the single Byte size specified by Width . If the processor acts in 32-bit mode at the time the MMI occurred, the pseudo register value EFI_MM_SAVE_STATE_REGISTER_LMA_32BIT is returned in Buffer . Otherwise, EFI_MM_SAVE_STATE_REGISTER_LMA_64BIT is returned in Buffer.

#define EFI_MM_SAVE_STATE_REGISTER_LMA_32BIT = 32
#define EFI_MM_SAVE_STATE_REGISTER_LMA_64BIT = 64

For WriteSaveState():

  • Write operations to this pseudo-register are ignored.

Status Codes Returned

EFI_SUCCESS

The register was read or written from Save State

EFI_NOT_FOUND

The register is not defined for the Save State of Processor

EFI_NOT_FOUND

The processor is not in SM

EFI_INVALID_PARAMETER

Input parameters are not valid For ex Processor No or register width is not correct This or Buffer is NULL

4.3.7. EFI_MM_CPU_PROTOCOL.WriteSaveState()

Summary

Write data to the CPU save state.

Prototype

typedef
   EFI_STATUS
(EFIAPI \*EFI_MM_WRITE_SAVE_STATE (
  IN CONST EFI_MM_CPU_PROTOCOL       *This,
  IN UINTN                           Width,
  IN EFI_MM_SAVE_STATE_REGISTER      Register,
  IN UINTN                           CpuIndex,
  IN CONST VOID                      *Buffer
  );

Parameters

Width

The number of bytes to write to the CPU save state. If the register specified by Register does not support the size specified by Width , then EFI_INVALID_PARAMETER s returned.

Register

Specifies the CPU register to write to the save state. The type EFI_MM_SAVE_STATE_REGISTER is defined in ReadSaveState() above. If the specified register is not implemented in the CPU save state map then EFI_NOT_FOUND error will be returned.

CpuIndex

Specifies the zero-based index of the CPU save state.

Buffer

Upon entry, this holds the new CPU register value.

Description

This function is used to write the specified number of bytes of the specified register to the CPU save state of the specified CPU and place the value into the buffer. If the CPU does not support the specified register Register , then EFI_NOT_FOUND should be returned. If the CPU does not support the specified register width Width , then EFI_INVALID_PARAMETER is returned.

Status Codes Returned

EFI_SUCCESS

The register was read or written from Save State

EFI_NOT_FOUND

The register Register is not defined for the Save State of Processor

EFI_INVALID_PARAMETER

Input parameters are not valid For example ProcessorIndex or Width is not correct This or Buffer is NULL

4.4. MM Save State IO Info

4.4.1. EFI_MM_SAVE_STATE_IO_INFO

Summary

Describes the I/O operation which was in process when the MMI was generated.

Prototype

typedef struct _EFI_MM_SAVE_STATE_IO_INFO {
  UINT64                                     IoData;
  UINT16                                     IoPort;
  EFI_MM_SAVE_STATE_IO_WIDTH                 IoWidth;
  EFI_MM_SAVE_STATE_IO_TYPE                  IoType;
} EFI_MM_SAVE_STATE_IO_INFO

Parameters

IoData

For input instruction (IN, INS), this is data read before the MMI occurred. For output instructions (OUT, OUTS) this is data that was written before the MMI occurred. The width of the data is specified by IoWidth . The data buffer is allocated by the Called MMfunction, and it is the Caller’s responsibility to free this buffer.

IoPort

The I/O port that was being accessed when the MMI was triggered.

IoWidth

Defines the size width (UINT8, UINT16, UINT32, UINT64) for IoData . See Related Definitions.

IoType

Defines type of I/O instruction. See Related Definitions.

Description

This is the structure of the data which is returned when ReadSaveState() is called with EFI_MM_SAVE_STATE_REGISTER_IO . If there was no I/O then ReadSaveState() will return EFI_NOT_FOUND .

Related Definitions

typedef enum {
  EFI_MM_SAVE_STATE_IO_WIDTH_UINT8 = 0,
  EFI_MM_SAVE_STATE_IO_WIDTH_UINT16 = 1,
  EFI_MM_SAVE_STATE_IO_WIDTH_UINT32 = 2,
  EFI_MM_SAVE_STATE_IO_WIDTH_UINT64 = 3
} EFI_MM_SAVE_STATE_IO_WIDTH

typedef enum {
  EFI_MM_SAVE_STATE_IO_TYPE_INPUT = 1,
  EFI_MM_SAVE_STATE_IO_TYPE_OUTPUT = 2,
  EFI_MM_SAVE_STATE_IO_TYPE_STRING = 4,
  EFI_MM_SAVE_STATE_IO_TYPE_REP_PREFIX = 8
} EFI_MM_SAVE_STATE_IO_TYPE

4.5. MM CPU I/O Protocol

4.5.1. EFI_MM_CPU_IO_PROTOCOL

Summary

Provides CPU I/O and memory access within SM

GUID

#define EFI_MM_CPU_IO_PROTOCOL_GUID \
  { 0x3242a9d8, 0xce70, 0x4aa0, \
  0x95, 0x5d, 0x5e, 0x7b, 0x14, 0xd, 0xe4, 0xd2 }

Protocol Interface Structure

typedef struct \_EFI_MM_CPU_IO_PROTOCOL {
  EFI_MM_IO_ACCESS                         Mem;
  EFI_MM_IO_ACCESS                         Io;
} EFI_MM_CPU_IO_PROTOCOL;

Parameters

Mem

Allows reads and writes to memory-mapped I/O space. See the Mem() function description. Type EFI_MM_IO_ACCESS is defined in “Related Definitions” below.

Io

Allows reads and writes to I/O space. See the Io() function description. Type EFI_MM_IO_ACCESS is defined in “Related Definitions” below.

Description

The EFI_MM_CPU_IO_PROTOCOL service provides the basic memory, I/O, and PCI interfaces that are used to abstract accesses to devices.

The interfaces provided in EFI_MM_CPU_IO_PROTOCOL are for performing basic operations to memory and I/O. The EFI_MM_CPU_IO_PROTOCOL can be thought of as the bus driver for the system. The system provides abstracted access to basic system resources to allow a driver to have a programmatic method to access these basic system resources.

Related Definitions

//*******************************************************
// EFI_MM_IO_ACCESS
//*******************************************************
typedef struct {
  EFI_MM_CPU_IO      Read;
  EFI_MM_CPU_IO      Write;
} EFI_MM_IO_ACCESS;

Parameters

Read

This service provides the various modalities of memory and I/O read.

Write

This service provides the various modalities of memory and I/O write.

4.5.2. EFI_MM_CPU_IO_PROTOCOL.Mem()

Summary

Enables a driver to access device registers in the memory space.

Prototype

typedef
EFI_STATUS
(EFIAPI * EFI_MM_CPU_IO (
  IN CONST *EFI_MM_CPU_IO_PROTOCOL   *This,
  IN *EFI_MM_IO_WIDTH*               Width,
  IN UINT64                          Address,
  IN UINTN                           Count,
  IN OUT VOID                        *Buffer
  );

Parameters

This

The EFI_MM_CPU_IO_PROTOCOL instance.

Width

Signifies the width of the I/O operations. Type EFI_MM_IO_WIDTH is defined in “Related Definitions” below.

Address

The base address of the I/O operations. The caller is responsible for aligning the Address if required.

Count

The number of I/O operations to perform. Bytes moved is Width size * Count, starting at Address.

Buffer

For read operations, the destination buffer to store the results. For write operations, the source buffer from which to write data.

Description

The EFI_MM_CPU_IO.Mem() function enables a driver to access device registers in the memory.

The I/O operations are carried out exactly as requested. The caller is responsible for any alignment and I/O width issues that the bus, device, platform, or type of I/O might require. For example, on IA-32 platforms, width requests of MM_IO_UINT64 do not work.

The Address field is the bus relative address as seen by the device on the bus.

Related Definitions

//*******************************************************
// EFI_MM_IO_WIDTH
//*******************************************************

typedef enum {
  MM_IO_UINT8 = 0,
  MM_IO_UINT16 = 1,
  MM_IO_UINT32 = 2,
  MM_IO_UINT64 = 3
} EFI_MM_IO_WIDTH;

Status Codes Returned

EFI_SUCCESS

The data was read from or written to the device

EFI_UNSUPPORTED

The Address is not valid for this system

EFI_INVALID_PARAMETER

Width or Count or both were invalid

EFI_OUT_OF_RESOURCES

The request could not be completed due to a lack of resources

4.5.3. EFI_MM_CPU_IO_PROTOCOL.Io()

Summary

Enables a driver to access device registers in the I/O space.

Prototype

typedef
EFI_STATUS
(EFIAPI \* EFI_MM_CPU_IO) (
  IN CONST *EFI_MM_CPU_IO_PROTOCOL   *This,
  IN *EFI_MM_IO_WIDTH*               Width,
  IN UINT64                          Address,
  IN UINTN                           Count,
  IN OUT VOID                        *Buffer
  );

Parameters

This

The EFI_MM_CPU_IO_PROTOCOL instance.

Width

Signifies the width of the I/O operations. Type EFI_MM_IO_WIDTH is defined in Mem() .

Address

The base address of the I/O operations. The caller is responsible for aligning the Address if required.

Count

The number of I/O operations to perform. Bytes moved is Width size * Count, starting at Address.

Buffer

For read operations, the destination buffer to store the results. For write operations, the source buffer from which to write data.

Description

The EFI_MM_CPU_IO.Io() function enables a driver to access device registers in the I/O space. The I/O operations are carried out exactly as requested. The caller is responsible for any alignment and I/O width issues which the bus, device, platform, or type of I/O might require. For example, on IA-32 platforms, width requests of MM_IO_UINT64 do not work. The caller must align the starting address to be on a proper width boundary.

Status Codes Returned

EFI_SUCCESS

The data was read from or written to the device

EFI_UNSUPPORTED

The Address is not valid for this system

EFI_INVALID_PARAMETER

Width or Count or both were invalid

EFI_OUT_OF_RESOURCES

The request could not be completed due to a lack of resources

4.6. MM PCI I/O Protocol

4.6.1. EFI_MM_PCI_ROOT_BRIDGE_IO_PROTOCOL

Summary

Provides access to PCI I/O, memory and configuration space inside of SM.

GUID

#define EFI_MM_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID \
  {0x8bc1714d, 0xffcb, 0x41c3, \
  0x89, 0xdc, 0x6c, 0x74, 0xd0, 0x6d, 0x98, 0xea}

Prototype

typedef EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
EFI_MM_PCI_ROOT_BRIDGE_IO_PROTOCOL;

Description

This protocol provides the same functionality as the PCI Root Bridge I/O Protocol defined in the UEFI Specifcation, except that the functions for Map() , Unmap() , Flush() , AllocateBuffer() , FreeBuffer() , SetAttributes() , and Configuration() may return EFI_UNSUPPORTED .

4.7. MM Ready to Lock Protocol

4.7.1. EFI_MM_READY_TO_LOCK_PROTOCOL

Summary

Indicates that MM resources and services that should not be used by the third party code are about to be locked.

GUID

#define EFI_MM_READY_TO_LOCK_PROTOCOL_GUID \
  { 0x47b7fa8c, 0xf4bd, 0x4af6, {0x82, 0x0, 0x33, 0x30, 0x86, 0xf0, 0xd2, 0xc8 } }

Prototype

NULL

Description

This protocol is a mandatory protocol published by the MM Foundation code when the system is preparing to lock certain resources and interfaces in anticipation of the invocation of 3rd party extensible modules. This protocol is an SM counterpart of the DXE MM Ready to Lock Protocol . This protocol prorogates resource locking notification into SM environment. This protocol is installed after installation of the SM End of DXE Protocol.

4.8. MM MP protocol

4.8.1. EFI_MM_MP_PROTOCOL

Summary

The MM MP protocol provides a set of functions to allow execution of procedures on processors that have entered MM. This protocol has the following properties:

  • The caller can only invoke execution of a procedure on a processor, other than the caller, that has also entered MM.

  • It is possible to invoke a procedure on multiple processors.

  • Supports blocking and non-blocking modes of operation.

GUID

// {5D5450D7-990C-4180-A803-8E63F0608307}
#define EFI_MM_MP_PROTOCOL_GUID \
  { 0x5d5450d7, 0x990c, 0x4180,
  { 0xa8, 0x3, 0x8e, 0x63, 0xf0, 0x60, 0x83, 0x7 } };

Protocol

typedef struct \_EFI_MM_MP_PROTOCOL {
  UINT32                                Revision,
  UINT32 Attributes ,
  EFI_MM\_ GET_NUMBER_OF_PROCESSORS     GetNumberOfProcessors,
  EFI_MM_DISPATCH_PROCEDURE             DispatchProcedure,
  EFI_MM_BROADCAST_PROCEDURE            BroadcastProcedure,
  EFI_MM_SET_STARTUP_PROCEDURE          SetStartupProcedure,
  EFI_CHECK_FOR_PROCEDURE               CheckOnProcedure,
  EFI_WAIT_FOR_PROCEDURE                WaitForProcedure,
}EFI_MM_MP_PROTOCOL;

Members

Revision

Revision information for the interface

Attributes

Provides information about the capabilities of the implementation.

GetNumberOfProcessors

Return the number of processors in the system.

DispatchProcedure

Run a procedure on one AP.

BroadcastProcedure

Run a procedure on all processors except the caller.

SetStartupProcedure

Provide a procedure to be executed when an AP starts up from power state where core context and configuration is lost.

CheckOnProcedure

Check whether a procedure on one or all APs has completed.

WaitForProcedure

Wait until a procedure on one or all APs has completed execution.

4.8.2. EFI_MM_MP_PROTOCOL.Revision

Summary

For implementations compliant with this revision of the specification this value must be 0.

4.8.3. EFI_MM_MP_PROTOCOL.Attributes

Summary

This parameter takes the following format:

Field

Number of bits

Bit offset

Description

Timeout support flag

1

0

This bit describes whether timeouts are supported in DispatchProcedure and BroadcastProcedure functions.
This bit is set to one if timeouts are supported in DispatchProcedure and BroadcastProcedure.
This bit is set to zero if timeouts are not supported in DispatchProcedure and BroadcastProcedure.
In implementations where timeouts are not supported, timeout values are always treated as infinite.
See EFI_MM_MP_TIMEOUT_SUPPORTED in Related Definitions below.

Reserved

31

1

Reserved must be zero

4.8.4. EFI_MM_MP_PROTOCOL.GetNumberOfProcessors()

Summary

This service retrieves the number of logical processor in the platform.

Prototype

typedef
FI_STATUS
(EFIAPI *EFI_MM_GET_NUMBER_OF_PROCESSORS) (
  IN CONST EFI_MM_MP_PROTOCOL                 *This,
  OUT UINTN                                   *NumberOfProcessors
);

Parameters

This

The EFI_MM_MP_PROTOCOL instance.

NumberOfProcessors

Pointer to the total number of logical processors in the system, including the BSP and all APs.

Status Codes Returned

EFI_SUCCESS

The number of processors was retrieved successfully

EFI_INVALID_PARAMETER

NumberOfProcessors is NULL

4.8.5. EFI_MM_MP_PROTOCOL.DispatchProcedure()

Summary

This service allows the caller to invoke a procedure one of the application processors (AP). This function uses an optional token parameter to support blocking and non-blocking modes. If the token is passed into the call, the function will operate in a non-blocking fashion and the caller can check for completion with CheckOnProcedure or WaitForProcedure .

Prototype

typedef
EFI_STATUS
(EFIAPI *EFI_MM_DISPATCH_PROCEDURE) (
  IN CONST EFI_MM_MP_PROTOCOL          *This,
  IN EFI_AP_PROCEDURE2                 Procedure,
  IN UINTN                             CpuNumber,
  IN UINTN                             TimeoutInMicroseconds,
  IN OUT VOID                          *ProcedureArguments OPTIONAL,
  IN OUT MM_COMPLETION                 *Token,
  IN OUT EFI_STATUS                    *CPUStatus,
);

Parameters

This

The EFI_MM_MP_PROTOCOL instance.

Procedure

A pointer to the procedure to be run on the designated target AP of the system. Type EFI_AP_PROCEDURE2 is defined below in related definitions.

CpuNumber

The zero-based index of the processor number of the target AP, on which the code stream is supposed to run. If the number points to the calling processor then it will not run the supplied code.

TimeoutInMicroseconds

Indicates the time limit in microseconds for this AP to finish execution of Procedure , either for blocking or non-blocking mode. Zero means infinity. If the timeout expires before this AP returns from Procedure , then Procedure on the AP is terminated. If the timeout expires in blocking mode, the call returns EFI_TIMEOUT. If the timeout expires in non-blocking mode, the timeout determined can be through CheckOnProcedure or WaitForProcedure.

Note that timeout support is optional. Whether an implementation supports this feature, can be determined via the Attributes data member.

ProcedureArguments

Allows the caller to pass a list of parameters to the code that is run by the AP. It is an optional common mailbox between APs and the caller to share information.

Token

This is an optional parameter that allows the caller to execute the procedure in a blocking or non-blocking fashion. If it is NULL the call is blocking, and the call will not return until the AP has completed the procedure. If the token is not NULL , the call will return immediately. The caller can check whether the procedure has completed with CheckOnProcedure or WaitForProcedure .

CpuStatus

This optional pointer may be used to get the status code returned by Procedure when it completes execution on the target AP, or with EFI_TIMEOUT if the Procedure fails to complete within the optional timeout. The implementation will update this variable with EFI_NOT_READY prior to starting Procedure on the target AP.

Status Codes Returned

EFI_SUCCESS

In the blocking case this indicates that Procedure has completed execution on the target AP In the non blocking case this indicates that the procedure has been successfully scheduled for execution on the target AP

EFI_INVALID_PARAMETER

The input arguments are out of range Either the target AP is the caller of the function or the Procedure or Token is NULL

EFI_NOT_READY

If the target AP is busy executing another procedure

EFI_ALREADY_STARTED

Before the AP procedure associated with the Token is finished the same Token cannot be used to dispatch or broadcast another procedure

EFI_TIMEOUT

In blocking mode the timeout expired before the specified AP has finished

4.8.6. EFI_MM_MP_PROTOCOL.BroadcastProcedure()

Summary

This service allows the caller to invoke a procedure on all running application processors (AP) except the caller. This function uses an optional token parameter to support blocking and non-blocking modes. If the token is passed into the call, the function will operate in a non-blocking fashion and the caller can check for completion with CheckOnProcedure or WaitForProcedure .

It is not necessary for the implementation to run the procedure on every processor on the platform. Processors that are powered down in such a way that they cannot respond to interrupts, may be excluded from the broadcast.

Prototype

typedef
EFI_STATUS
(EFIAPI *EFI_MM_BROADCAST_PROCEDURE) (
  IN CONST EFI_MM_MP_PROTOCOL           *This,
  IN EFI_AP_PROCEDURE2                  Procedure,
  IN UINTN                              TimeoutInMicroseconds,
  IN OUT VOID                           *ProcedureArguments OPTIONAL,
  IN OUT MM_COMPLETION                  *Token,
  IN OUT EFI_STATUS                     *CPUStatus,
  );

Parameters

This

The EFI_MM_MP_PROTOCOL instance.

Procedure

A pointer to the code stream to be run on the APs that have entered MM. Type EFI_AP_PROCEDURE2 is defined below in related definitions.

TimeoutInMicroseconds

Indicates the time limit in microseconds for the APs to finish execution of Procedure, either for blocking or non-blocking mode. Zero means infinity. If the timeout expires before all APs return from Procedure , then Procedure on the failed APs is terminated. If the timeout expires in blocking mode, the call returns EFI_TIMEOUT . If the timeout expires in non-blocking mode, the timeout determined can be through CheckOnProcedure or WaitForProcedure.

Note that timeout support is optional. Whether an implementation supports this feature can be determined via the Attributes data member.

ProcedureArguments

Allows the caller to pass a list of parameters to the code that is run by the AP. It is an optional common mailbox between APs and the caller to share information.

Token

This is an optional parameter that allows the caller to execute the procedure in a blocking or non-blocking fashion. If it is NULL the call is blocking, and the call will not return until the AP has completed the procedure. If the token is not NULL, the call will return immediately. The caller can check whether the procedure has completed with CheckOnProcedure or WaitForProcedure .

CPUStatus

This optional pointer may be used to get the individual status returned by every AP that participated in the broadcast. This parameter if used provides the base address of an array to hold the EFI_STATUS value of each AP in the system. The size of the array can be ascertained by the GetNumberOfProcessors function.

As mentioned above, the broadcast may not include every processor in the system. Some implementations may exclude processors that have been powered down in such a way that they are not responsive to interrupts. Additionally the broadcast excludes the processor which is making the BroadcastProcedure call. For every excluded processor, the array entry must contain a value of EFI_NOT_STARTED .

Status Codes Returned

EFI_SUCCESS

In the blocking case this indicates that Procedure has completed execution on the APs In the non blocking case this indicates that the procedure has been successfully scheduled for execution on the APs

EFI_INVALID_PARAMETER

Procedure or Token is NULL

EFI_NOT_READY

If a target AP is busy executing another procedure

EFI_TIMEOUT

In blocking mode the timeout expired before all enabled APs have finished

EFI_ALREADY_STARTED

Before the AP procedure associated with the Token is finished the same Token cannot be used to dispatch or broadcast another procedure

4.8.7. EFI_MM_MP_PROTOCOL.SetStartupProcedure()

Summary

This service allows the caller to set a startup procedure that will be executed when an AP powers up from a state where core configuration and context is lost. The procedure is execution has the following properties:

  • The procedure executes before the processor is handed over to the operating system.

  • All processors execute the same startup procedure.

  • The procedure may run in parallel with other procedures invoked through the functions in this protocol, or with processors that are executing an MM handler or running in the operating system.

Prototype

typedef
EFI_STATUS
(EFIAPI *EFI_SET_STARTUP\_ PROCEDURE) (
  IN CONST EFI_MM_MP_PROTOCOL            *This,
  IN EFI_AP_PROCEDURE *                  Procedure,
  IN OUT VOID                            *ProcedureArguments OPTIONAL,
);

Parameters

This

The EFI_MM_MP_PROTOCOL instance.

Procedure

A pointer to the code stream to be run on the designated target AP of the system. Type EFI_AP_PROCEDURE is defined below in Volume 2 with the related definitions of EFI_MP_SERVICES_PROTOCOL.StartupAllAPs .

If caller may pass a value of NULL to deregister any existing startup procedure.

ProcedureArguments

Allows the caller to pass a list of parameters to the code that is run by the AP. It is an optional common mailbox between APs and the caller to share information.

Status Codes Returned

EFI_SUCCESS

The Procedure has been set successfully.

4.8.8. EFI_MM_MP_PROTOCOL.CheckOnProcedure()

Summary

When non-blocking execution of a procedure on an AP is invoked with DispatchProcedure , via the use of a token, this function can be used to check for completion of the procedure on the AP. The function takes the token that was passed into the DispatchProcedure call. If the procedure is complete, and therefore it is now possible to run another procedure on the same AP, this function returns EFI_SUCESS . In this case the status returned by the procedure that executed on the AP is returned in the token’s Status field. If the procedure has not yet completed, then this function returns EFI_NOT_READY .

When a non-blocking execution of a procedure is invoked with BroadcastProcedure , via the use of a token, this function can be used to check for completion of the procedure on all the broadcast APs. The function takes the token that was passed into the BroadcastProcedure call. If the procedure is complete on all broadcast APs this function returns EFI_SUCESS . If the procedure has not yet completed on the broadcast APs, the function returns EFI_NOT_READY .

Prototype

typedef
EFI_STATUS
(EFIAPI \*EFI_CHECK_ON_PROCEDURE)
  IN CONST EFI_MM_MP_PROTOCOL      *This,
  IN OUT MM_COMPLETION             Token
);

Parameters

This

The EFI_MM_MP_PROTOCOL instance.

Token

This parameter describes the token that was passed into DispatchProcedure or BroadcastProcedure. Type MM_COMPLETION is defined below in related definitions.

Status Codes Returned

EFI_SUCCESS

Procedure has completed

EFI_NOT_READY

The Procedure has not completed

EFI_INVALID_PARAMETER

Token is NULL

EFI_NOT_FOUND

Token is not currently in use for a non blocking call

4.8.9. EFI_MM_MP_PROTOCOL.WaitForProcedure()

Summary

When a non-blocking execution of a procedure on an AP is invoked via DispatchProcedure , this function will block the caller until the remote procedure has completed on the designated AP. The non-blocking procedure invocation is identified by the Token parameter, which must match the token that used when DispatchProcedure was called.

When a non-blocking execution of a procedure on an AP is invoked via BroadcastProcedure this function will block the caller until the remote procedure has completed on all of the APs that entered MM. The non-blocking procedure invocation is identified by the Token parameter, which must match the token that used when BroadcastProcedure was called.

Prototype

typedef
EFI_STATUS
(EFIAPI \*EFI_WAIT_FOR_PROCEDURE)
  IN CONST EFI_MM_MP_PROTOCOL      *This,
  IN OUT MM_COMPLETION             Token,
);

Parameters

This

The EFI_MM_MP_PROTOCOL instance.

Token

This parameter describes token that was passed into DispatchProcedure or BroadcastProcedure.

Status Codes Returned

EFI_SUCCESS

The procedure has completed

EFI_INVALID_PARAMETER

Token is NULL

EFI_NOT_FOUND

Token is not currently in use for a non blocking call

Related Definitions

EFI_AP_PROCEDURE is defined in Volume 2 of this specification, with EFI_MP_SERVICES_PROTOCOL.StartupAllAPs

// Attribute flags
#define EFI_MM_MP_TIMEOUT_SUPPORTED   0x1

// Procedure callback
typedef
EFI_STATUS
(EFIAPI                               *EFI_AP_PROCEDURE2)(
IN VOID                               *ProcedureArgument
);

// completion token
typedef VOID                          *MM_COMPLETION;

4.9. MM Configuration Protocol

4.9.1. EFI_MM_CONFIGURATION_PROTOCOL

Summary

Register MM Foundation entry point.*

GUID

#define EFI_MM_CONFIGURATION_PROTOCOL_GUID { \
  0x26eeb3de, 0xb689, 0x492e, \
  0x80, 0xf0, 0xbe, 0x8b, 0xd7, 0xda, 0x4b, 0xa7
}

Prototype

typedef struct \_EFI_MM_CONFIGURATION_PROTOCOL {
EFI_MM_REGISTER_MM_FOUNDATION_ENTRY               RegisterMmFoundationEntry;
} EFI_MM_CONFIGURATION_PROTOCOL;

Members

RegisterMmFoundationEntry

A function to register the MM Foundation entry point.

Description

This Protocol is an MM Protocol published by a standalone MM CPU driver to allow MM Foundation register MM Foundation entry point. If a platform chooses to let MM Foundation load standalone MM CPU driver for MM relocation, this protocol must be produced this standalone MM CPU driver. The RegisterMmFoundationEntry() function allows the MM Foundation to register the MM Foundation entry point with the MM entry vector code.

4.9.2. EFI_MM_CONFIGURATION_PROTOCOL.RegisterMmFoundationEntry()

Summary

Register the MM Foundation entry point in MM standalone mode.

Prototype

typedef
EFI_STATUS
(EFIAPI \*EFI_MM_REGISTER_MM_FOUNDATION_ENTRY) (
  IN CONST EFI_MM_CONFIGURATION_PROTOCOL \* *This* ,
  IN EFI_MM_ENTRY_POINT *MmEntryPoint*
  )

Parameters

This

The EFI_MM_CONFIGURATION_PROTOCOL instance.

MmEntryPoint

MM Foundation entry point.

Description

This function registers the MM Foundation entry point with the processor code. This entry point will be invoked by the MM Processor entry code as defined in section 2.5.

Status Codes Returned

Table 4.5 Status Codes Returned

EFI_SUCCESS

The entry-point was successfully registered.

4.10. MM End Of PEI Protocol

4.10.1. EFI_MM_END_OF_PEI_PROTOCOL

Summary

Indicate that the UEFI/PI firmware is about to exit PEI phase.

GUID

#define EFI_MM_END_OF_PEI_PROTOCOL_GUID { \\
  0xf33e1bf3, 0x980b, 0x4bfb, 0xa2, 0x9a, 0xb2, 0x9c, 0x86,
  0x45, 0x37, 0x32 \\
}

Prototype

NULL

Description

This protocol is a MM Protocol published by a standalone MM Foundation code if MM Foundation is loaded in PEI phase. This protocol should be installed immediately after DXE IPL installs EFI_PEI_END_OF_PEI_PHASE_PPI .

4.11. MM UEFI Ready Protocol

4.11.1. EFI_MM_UEFI_READY_PROTOCOL

Summary

Indicate that the UEFI/PI firmware is in UEFI phase and EFI_SYSTEM_TABLE is ready to use.

GUID

#define EFI_MM_UEFI_READY_PROTOCOL_GUID { \
  0xc63a953b, 0x73b0, 0x482f, 0x8d, 0xa6, 0x76, 0x65, 0x66, 0xf6, 0x5a, 0x82 \
}

Prototype

NULL

Description

This protocol is a MM Protocol published by a standalone MM Foundation code after DXE MM IPL communicates with MM Foundation to tell MM Foundation UEFI system table location. After that tradition MM driver can be dispatched.

4.12. MM Ready To Boot Protocol

4.12.1. EFI_MM_READY_TO_BOOT_PROTOCOL

Summary

Indicate that the UEFI/PI firmware is about to load and execute a boot option.

GUID

#define EFI_MM_READY_TO_BOOT_PROTOCOL_GUID { \\
  0x6e057ecf, 0xfa99, 0x4f39, 0x95, 0xbc, 0x59, 0xf9, 0x92,
  0x1d, 0x17, 0xe4 \\
}

Prototype

NULL

Description

This protocol is a MM Protocol published by a standalone MM Foundation code, when UEFI/PI firmware is about to load and execute a boot option. There is an associated event GUID that is signaled for the DXE drivers called EFI_EVENT_GROUP_READY_TO_BOOT .

4.13. MM Exit Boot Services Protocol

4.13.1. EFI_MM_EXIT_BOOT_SERVICES_PROTOCOL

Summary

Indicate that the UEFI/PI firmware is about to enter UEFI runtime phase.

GUID

#define EFI_MM_EXIT_BOOT_SERVICES_PROTOCOL_GUID { \\
  0x296eb418, 0xc4c8, 0x4e05, 0xab, 0x59, 0x39, 0xe8, 0xaf,
  0x56, 0xf0, 0xa \\
}

Prototype

NULL

Description

This protocol is a MM Protocol published by a standalone MM Foundation code, when UEFI/PI firmware is about to enter UEFI runtime phase. There is an associated event GUID that is signaled for the DXE drivers called EFI_EVENT_GROUP_EXIT_BOOT_SERVICES .

4.14. MM Security Architecture Protocol

EFI_MM_SECURITY_ARCHITECTURE_PROTOCOL

Summary

Abstracts security-specific functions from the MM Foundation for purposes of handling GUIDed section encapsulations in standalone mode. This protocol must be produced by a MM driver and may only be consumed by the MM Foundation and any other MM drivers that need to validate the authentication of files.

GUID

#define EFI_MM_SECURITY_ARCH_PROTOCOL_GUID { \\
  0xb48e70a3, 0x476f, 0x486d, 0xb9, 0xc0, 0xc2, 0xd0, 0xf8,
  0xb9, 0x44, 0xd9 \\
}

Prototype

Same as *EFI_SECURITY_ARCH_PROTOCOL*.

Description

The EFI_MM_SECURITY_ARCH_PROTOCOL is used to abstract platform-specific policy from the MM Foundation in standalone mode. This includes locking flash upon failure to authenticate, attestation logging, and other exception operations. The usage is same as DXE EFI_SECURITY_ARCH_PROTOCOL .

4.15. MM End of DXE Protocol

4.15.1. EFI_MM_END_OF_DXE_PROTOCOL

Summary

Indicates end of the execution phase when all of the components are under the authority of the platform manufacturer.

GUID

#define EFI_MM_END_OF_DXE_PROTOCOL_GUID \\
  { 0x24e70042, 0xd5c5, 0x4260, \\
  { 0x8c, 0x39, 0xa, 0xd3, 0xaa, 0x32, 0xe9, 0x3d } }

Prototype

NULL

Description

This protocol is a mandatory protocol published by MM Foundation code. This protocol is an MM counterpart of the End of DXE Event. This protocol prorogates End of DXE notification into MM environment. This protocol is installed prior to installation of the MM Ready to Lock Protocol.

4.16. MM Handler State Notification Protocol

4.16.1. EFI_MM_HANDLER_STATE_NOTIFICATION_PROTOCOL

Summary

Register or unregister a MM Handler State notification function.

GUID

// {30C8340F-4C30-41D9-BFAE-444ACB2C1F76}
#define EFI_MM_HANDLER_STATE_NOTIFICATION_PROTOCOL_GUID \
  {0x30c8340f, 0x4c30, 0x41d9, {0xbf, 0xae, 0x44, 0x4a, 0xcb, 0x2c, 0x1f, 0x76}}

Prototype

typedef
struct \_EFI_MM_HANDLER_STATE_NOTIFICATION_PROTOCOL {
  EFI_MM_HANDLER_STATE_NOTIFIER_REGISTER
HandlerStateNotifierRegister;
  EFI_MM_HANDLER_STATE_NOTIFIER_UNREGISTER
HandlerStateNotifierUnregister;
} EFI_MM_HANDLER_STATE_NOTIFICATION_PROTOCOL;

Members

HandlerStateNotifierRegister

Register notification function

HandlerStateNotifierUnRegister

Un-register previously registered notification function.

Description

This protocol is an MM Protocol published by Standalone MM Foundation code if MM Foundation is loaded in SEC Phase. This protocol must be installed before any MM Standalone or Traditional drivers are initialized in MMRAM.

The MM Handler State notification protocol provides a set of functions to allow registration and un-registration of a notification procedure that is invoked whenever a MM Handler is registered or un-registered through an invocation of MmiHandlerRegister() or MmiHandlerUnRegister() services in the MMST.

4.16.2. EFI_MM_HANDLER_STATE_NOTIFICATION_PROTOCOL.HandlerStateNotifierRegister

Summary

Register notification function

Prototype

typedef
EFI_STATUS
(EFIAPI *EFI_MM_HANDLER_STATE_NOTIFIER_REGISTER)(
  IN EFI_MM_HANDLER_STATE_NOTIFY_FN                 Notifier,
  OUT VOID                                          **Registration
);

Parameters

Notifier

Pointer to function to invoke whenever MmiHandlerRegister() or MmiHandlerUnRegister() in the MMST are called. Type EFI_MM_HANDLER_STATE_NOTIFY_FN is defined in “Related Definitions” below

Registration

Returns the registration record that has been successfully added

Description

This service registers a function ( Notifier ) which will be called whenever a MM Handler is registered or un-registered through invocations of MmiHandlerRegister() or MmiHandlerUnRegister() in the MMST. On a successful return, Registration contains a record that can be later used to unregister the Notifier function.

Related Definitions

//**********************************************\*
// EFI_MM_HANDLER_STATE_NOTIFY_FN
//**********************************************\*
typedef
EFI_STATUS
(EFIAPI \*EFI_MM_HANDLER_STATE_NOTIFY_FN)(
  IN EFI_MM_HANDLER_ENTRY_POINT Handler,
  IN CONST EFI_GUID \*HandlerType OPTIONAL,
  IN EFI_MM_HANDLER_STATE HandlerState
);
Handler

MM Handler function pointer. The Handler parameter is the same as the one passed to MmiHandlerRegister() .Type EFI_MM_HANDLER_ENTRY_POINT is defined in Volume 4 of the Platform Initialization Specification.

HandlerType

Points to an EFI_GUID which describes the type of invocation that this handler is for or NULL to indicate a root MMI handler. The HandlerType parameter is the same as the one passed to MmiHandlerRegister().

HandlerState

Handler state i.e. registered or unregistered. Type EFI_MM_HANDLER_STATE is defined below. This parameter indicates whether EFI_MM_HANDLER_STATE_NOTIFY_FN has been invoked in response to MmiHandlerRegister() or MmiHandlerUnRegister() .

//***********************************************
// EFI_MM_HANDLER_STATE
//***********************************************
typedef enum {
  HandlerRegistered,
  HandlerUnregistered,
} EFI_MM_HANDLER_STATE;

Status Codes Returned (EFI_MM_HANDLER_STATE_NOTIFY_FN)

EFI_SUCCESS

Notification function was successfully invoked

EFI_INVALID_PARAMETER

Handler is NULL or HandlerType is unrecognized

Status Codes Returned (HandlerStateNotifierRegister)

EFI_SUCCESS

Notification function registered successfully

EFI_INVALID_PARAMETER

Registration is NULL

EFI_OUT_OF_RESOURCES

Not enough memory resource to finish the request

4.16.3. EFI_MM_HANDLER_STATE_NOTIFICATION_PROTOCOL.HandlerStateNotifierUnregister

Summary

Un-register notification function.

Prototype

typedef
EFI_STATUS
(EFIAPI \*EFI_MM_HANDLER_STATE_NOTIFIER_UNREGISTER)(
  IN VOID \*Registration
);

Parameters

Registration

Registration record returned upon successfully registering the callback function

Description

This service un-registers a previously registered Notifier function. The function is identified by the Registration parameter. Subsequent invocations of MmiHandlerRegister() or MmiHandlerUnRegister() will not invoke the Notifier function.

Status Codes Returned (HandlerStateNotifierUnRegister)

EFI_SUCCESS

Notification function un-registered successfully

EFI_INVALID_PARAMETER

Registration is NULL

EFI_NOT_FOUND

Registration record not found