| /** @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.<BR> | |
| 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 |