/** @file EFI MM CPU Protocol as defined in the PI 1.5 specification. 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. Copyright (c) 2017, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef _MM_CPU_H_ #define _MM_CPU_H_ #define EFI_MM_CPU_PROTOCOL_GUID \ { \ 0xeb346b97, 0x975f, 0x4a9f, { 0x8b, 0x22, 0xf8, 0xe9, 0x2b, 0xb3, 0xd5, 0x69 } \ } /// /// Save State register index /// 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 } EFI_MM_SAVE_STATE_REGISTER; /// /// The EFI_MM_SAVE_STATE_REGISTER_LMA pseudo-register values /// 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 /// /// Size width of I/O instruction /// 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; /// /// Types of I/O instruction /// 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; /// /// 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. /// /// This structure describes the I/O operation which was in process when the MMI was generated. /// typedef struct _EFI_MM_SAVE_STATE_IO_INFO { /// /// 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. /// UINT64 IoData; /// /// The I/O port that was being accessed when the MMI was triggered. /// UINT16 IoPort; /// /// Defines the size width (UINT8, UINT16, UINT32, UINT64) for IoData. /// EFI_MM_SAVE_STATE_IO_WIDTH IoWidth; /// /// Defines type of I/O instruction. /// EFI_MM_SAVE_STATE_IO_TYPE IoType; } EFI_MM_SAVE_STATE_IO_INFO; typedef struct _EFI_MM_CPU_PROTOCOL EFI_MM_CPU_PROTOCOL; /** Read data from the CPU save state. 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. @param[in] This The EFI_MM_CPU_PROTOCOL instance. @param[in] Width The number of bytes to read from the CPU save state. @param[in] Register Specifies the CPU register to read form the save state. @param[in] CpuIndex Specifies the zero-based index of the CPU save state. @param[out] Buffer Upon return, this holds the CPU register value read from the save state. @retval EFI_SUCCESS The register was read from Save State. @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor. @retval EFI_INVALID_PARAMETER Input parameters are not valid, for example, Processor No or register width is not correct.This or Buffer is NULL. **/ typedef EFI_STATUS (EFIAPI *EFI_MM_READ_SAVE_STATE)( IN CONST EFI_MM_CPU_PROTOCOL *This, IN UINTN Width, IN EFI_MM_SAVE_STATE_REGISTER Register, IN UINTN CpuIndex, OUT VOID *Buffer ); /** Write data to the CPU save state. 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_UNSUPPORTED should be returned. If the CPU does not support the specified register width Width, then EFI_INVALID_PARAMETER is returned. @param[in] This The EFI_MM_CPU_PROTOCOL instance. @param[in] Width The number of bytes to write to the CPU save state. @param[in] Register Specifies the CPU register to write to the save state. @param[in] CpuIndex Specifies the zero-based index of the CPU save state. @param[in] Buffer Upon entry, this holds the new CPU register value. @retval EFI_SUCCESS The register was written to Save State. @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor. @retval EFI_INVALID_PARAMETER Input parameters are not valid. For example: ProcessorIndex or Width is not correct. **/ 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 ); /// /// EFI MM CPU Protocol provides access to CPU-related information while in MM. /// /// 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. /// struct _EFI_MM_CPU_PROTOCOL { EFI_MM_READ_SAVE_STATE ReadSaveState; EFI_MM_WRITE_SAVE_STATE WriteSaveState; }; extern EFI_GUID gEfiMmCpuProtocolGuid; #endif