UefiCpuPkg: Add STM GUIDs, Protocols, and PCDs
authorMichael Kinney <michael.d.kinney@intel.com>
Mon, 28 Nov 2016 21:52:57 +0000 (13:52 -0800)
committerFeng Tian <feng.tian@intel.com>
Mon, 19 Dec 2016 01:32:34 +0000 (09:32 +0800)
* Add GUIDed HOB that described MSEG region in SMRAM
* Add SM Monitor Init Protocol
* Add PCD to configure size of SMM exception stack
* Add PCD to configure MSEG region size if it is not
  described by the gMsegSmramGuid GUIDed HOB.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jeff Fan <jeff.fan@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Michael Kinney <michael.d.kinney@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Jeff Fan <jeff.fan@intel.com>
UefiCpuPkg/Include/Guid/MsegSmram.h [new file with mode: 0644]
UefiCpuPkg/Include/Protocol/SmMonitorInit.h [new file with mode: 0644]
UefiCpuPkg/Include/Register/StmApi.h [new file with mode: 0644]
UefiCpuPkg/Include/Register/StmResourceDescriptor.h [new file with mode: 0644]
UefiCpuPkg/Include/Register/StmStatusCode.h [new file with mode: 0644]
UefiCpuPkg/UefiCpuPkg.dec

diff --git a/UefiCpuPkg/Include/Guid/MsegSmram.h b/UefiCpuPkg/Include/Guid/MsegSmram.h
new file mode 100644 (file)
index 0000000..ab337c4
--- /dev/null
@@ -0,0 +1,30 @@
+/** @file\r
+\r
+  Defines the HOB GUID used to describe the MSEG memory region allocated in PEI.\r
+\r
+  Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _MSEG_SMRAM_H_\r
+#define _MSEG_SMRAM_H_\r
+\r
+#define MSEG_SMRAM_GUID \\r
+  { \\r
+    0x5802bce4, 0xeeee, 0x4e33, { 0xa1, 0x30, 0xeb, 0xad, 0x27, 0xf0, 0xe4, 0x39 } \\r
+  }\r
+\r
+extern EFI_GUID gMsegSmramGuid;\r
+\r
+//\r
+// The data portion of this HOB is type EFI_SMRAM_DESCRIPTOR\r
+//\r
+\r
+#endif\r
diff --git a/UefiCpuPkg/Include/Protocol/SmMonitorInit.h b/UefiCpuPkg/Include/Protocol/SmMonitorInit.h
new file mode 100644 (file)
index 0000000..7b0aab0
--- /dev/null
@@ -0,0 +1,141 @@
+/** @file\r
+  STM service protocol definition\r
+\r
+  Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _SM_MONITOR_INIT_PROTOCOL_H_\r
+#define _SM_MONITOR_INIT_PROTOCOL_H_\r
+\r
+#include <PiSmm.h>\r
+#include <Register/StmApi.h>\r
+\r
+#define EFI_SM_MONITOR_INIT_PROTOCOL_GUID \\r
+    { 0x228f344d, 0xb3de, 0x43bb, 0xa4, 0xd7, 0xea, 0x20, 0xb, 0x1b, 0x14, 0x82}\r
+\r
+//\r
+// STM service\r
+//\r
+\r
+/**\r
+\r
+  Load STM image to MSEG.\r
+\r
+  @param StmImage      STM image\r
+  @param StmImageSize  STM image size\r
+\r
+  @retval EFI_SUCCESS            Load STM to MSEG successfully\r
+  @retval EFI_ALREADY_STARTED    STM image is already loaded to MSEG\r
+  @retval EFI_BUFFER_TOO_SMALL   MSEG is smaller than minimal requirement of STM image\r
+  @retval EFI_UNSUPPORTED        MSEG is not enabled\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EFI_SM_MONITOR_LOAD_MONITOR) (\r
+  IN EFI_PHYSICAL_ADDRESS StmImage,\r
+  IN UINTN                StmImageSize\r
+  );\r
+\r
+/**\r
+\r
+  Add resources in list to database.\r
+\r
+  @param ResourceList  A pointer to resource list to be added\r
+  @param NumEntries    Optional number of entries.\r
+                       If 0, list must be terminated by END_OF_RESOURCES.\r
+\r
+  @retval EFI_SUCCESS            If resources are added\r
+  @retval EFI_INVALID_PARAMETER  If nested procedure detected resource failer\r
+  @retval EFI_OUT_OF_RESOURCES   If nested procedure returned it and we cannot allocate more areas.\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EFI_SM_MONITOR_ADD_PI_RESOURCE) (\r
+  IN STM_RSC *ResourceList,\r
+  IN UINT32   NumEntries OPTIONAL\r
+  );\r
+\r
+/**\r
+\r
+  Delete resources in list to database.\r
+\r
+  @param ResourceList  A pointer to resource list to be deleted\r
+                       NULL means delete all resources.\r
+  @param NumEntries    Optional number of entries.\r
+                       If 0, list must be terminated by END_OF_RESOURCES.\r
+\r
+  @retval EFI_SUCCESS            If resources are deleted\r
+  @retval EFI_INVALID_PARAMETER  If nested procedure detected resource failer\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EFI_SM_MONITOR_DELETE_PI_RESOURCE) (\r
+  IN STM_RSC *ResourceList OPTIONAL,\r
+  IN UINT32   NumEntries OPTIONAL\r
+  );\r
+\r
+/**\r
+\r
+  Get BIOS resources.\r
+\r
+  @param ResourceList  A pointer to resource list to be filled\r
+  @param ResourceSize  On input it means size of resource list input.\r
+                       On output it means size of resource list filled,\r
+                       or the size of resource list to be filled if size of too small.\r
+\r
+  @retval EFI_SUCCESS            If resources are returned.\r
+  @retval EFI_BUFFER_TOO_SMALL   If resource list buffer is too small to hold the whole resources.\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EFI_SM_MONITOR_GET_PI_RESOURCE) (\r
+  OUT    STM_RSC *ResourceList,\r
+  IN OUT UINT32  *ResourceSize\r
+  );\r
+\r
+typedef UINT32 EFI_SM_MONITOR_STATE;\r
+#define EFI_SM_MONITOR_STATE_ENABLED     0x1\r
+#define EFI_SM_MONITOR_STATE_ACTIVATED   0x2\r
+\r
+/**\r
+\r
+  Get STM state\r
+\r
+  @return STM state\r
+\r
+**/\r
+typedef\r
+EFI_SM_MONITOR_STATE\r
+(EFIAPI *EFI_SM_MONITOR_GET_MONITOR_STATE) (\r
+  VOID\r
+  );\r
+\r
+typedef struct _EFI_SM_MONITOR_INIT_PROTOCOL {\r
+  //\r
+  // Valid at boot-time only\r
+  //\r
+  EFI_SM_MONITOR_LOAD_MONITOR                      LoadMonitor;\r
+  EFI_SM_MONITOR_ADD_PI_RESOURCE                   AddPiResource;\r
+  EFI_SM_MONITOR_DELETE_PI_RESOURCE                DeletePiResource;\r
+  EFI_SM_MONITOR_GET_PI_RESOURCE                   GetPiResource;\r
+  //\r
+  // Valid at runtime\r
+  //\r
+  EFI_SM_MONITOR_GET_MONITOR_STATE                 GetMonitorState;\r
+} EFI_SM_MONITOR_INIT_PROTOCOL;\r
+\r
+extern EFI_GUID gEfiSmMonitorInitProtocolGuid;\r
+\r
+#endif\r
diff --git a/UefiCpuPkg/Include/Register/StmApi.h b/UefiCpuPkg/Include/Register/StmApi.h
new file mode 100644 (file)
index 0000000..6fb5971
--- /dev/null
@@ -0,0 +1,954 @@
+/** @file\r
+  STM API definition\r
+\r
+  Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+  @par Specification Reference:\r
+  SMI Transfer Monitor (STM) User Guide Revision 1.00\r
+\r
+**/\r
+\r
+#ifndef _STM_API_H_\r
+#define _STM_API_H_\r
+\r
+#include <Register/StmStatusCode.h>\r
+#include <Register/StmResourceDescriptor.h>\r
+#include <Register/ArchitecturalMsr.h>\r
+\r
+#pragma pack (1)\r
+\r
+/**\r
+  STM Header Structures\r
+**/\r
+\r
+typedef struct {\r
+  UINT32  Intel64ModeSupported :1;  ///> bitfield\r
+  UINT32  EptSupported         :1;  ///> bitfield\r
+  UINT32  Reserved             :30; ///> must be 0\r
+} STM_FEAT;\r
+\r
+#define STM_SPEC_VERSION_MAJOR  1\r
+#define STM_SPEC_VERSION_MINOR  0\r
+\r
+typedef struct {\r
+  UINT8     StmSpecVerMajor;\r
+  UINT8     StmSpecVerMinor;\r
+  ///\r
+  /// Must be zero\r
+  ///\r
+  UINT16    Reserved;\r
+  UINT32    StaticImageSize;\r
+  UINT32    PerProcDynamicMemorySize;\r
+  UINT32    AdditionalDynamicMemorySize;\r
+  STM_FEAT  StmFeatures;\r
+  UINT32    NumberOfRevIDs;\r
+  UINT32    StmSmmRevID[1];\r
+  ///\r
+  /// The total STM_HEADER should be 4K.\r
+  ///\r
+} SOFTWARE_STM_HEADER;\r
+\r
+typedef struct {\r
+  MSEG_HEADER          HwStmHdr;\r
+  SOFTWARE_STM_HEADER  SwStmHdr;\r
+} STM_HEADER;\r
+\r
+\r
+/**\r
+  VMCALL API Numbers\r
+  API number convention: BIOS facing VMCALL interfaces have bit 16 clear\r
+**/\r
+\r
+/**\r
+  StmMapAddressRange enables a SMM guest to create a non-1:1 virtual to\r
+  physical mapping of an address range into the SMM guest's virtual\r
+  memory space.\r
+\r
+  @param  EAX  #STM_API_MAP_ADDRESS_RANGE (0x00000001)\r
+  @param  EBX  Low 32 bits of physical address of caller allocated\r
+               STM_MAP_ADDRESS_RANGE_DESCRIPTOR structure.\r
+  @param  ECX  High 32 bits of physical address of caller allocated\r
+               STM_MAP_ADDRESS_RANGE_DESCRIPTOR structure. If Intel64Mode is\r
+               clear (0), ECX must be 0.\r
+\r
+  @note  All fields of STM_MAP_ADDRESS_RANGE_DESCRIPTOR are inputs only. They\r
+         are not modified by StmMapAddressRange.\r
+\r
+  @retval  CF   0\r
+                No error, EAX set to STM_SUCCESS.\r
+                The memory range was mapped as requested.\r
+  @retval  CF   1\r
+                An error occurred, EAX holds relevant error value.\r
+  @retval  EAX  #ERROR_STM_SECURITY_VIOLATION\r
+                The requested mapping contains a protected resource.\r
+  @retval  EAX  #ERROR_STM_CACHE_TYPE_NOT_SUPPORTED\r
+                The requested cache type could not be satisfied.\r
+  @retval  EAX  #ERROR_STM_PAGE_NOT_FOUND\r
+                Page count must not be zero.\r
+  @retval  EAX  #ERROR_STM_FUNCTION_NOT_SUPPORTED\r
+                STM supports EPT and has not implemented StmMapAddressRange().\r
+  @retval  EAX  #ERROR_STM_UNSPECIFIED\r
+                An unspecified error occurred.\r
+\r
+  @note  All other registers unmodified.\r
+**/\r
+#define STM_API_MAP_ADDRESS_RANGE                  0x00000001\r
+\r
+/**\r
+  STM Map Address Range Descriptor for #STM_API_MAP_ADDRESS_RANGE VMCALL\r
+**/\r
+typedef struct {\r
+  UINT64  PhysicalAddress;\r
+  UINT64  VirtualAddress;\r
+  UINT32  PageCount;\r
+  UINT32  PatCacheType;\r
+} STM_MAP_ADDRESS_RANGE_DESCRIPTOR;\r
+\r
+/**\r
+  Define values for PatCacheType field of #STM_MAP_ADDRESS_RANGE_DESCRIPTOR\r
+  @{\r
+**/\r
+#define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_ST_UC        0x00\r
+#define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_WC           0x01\r
+#define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_WT           0x04\r
+#define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_WP           0x05\r
+#define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_WB           0x06\r
+#define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_UC           0x07\r
+#define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_FOLLOW_MTRR  0xFFFFFFFF\r
+/// @}\r
+\r
+/**\r
+  StmUnmapAddressRange enables a SMM guest to remove mappings from its page\r
+  table.\r
+\r
+  If TXT_PROCESSOR_SMM_DESCRIPTOR.EptEnabled bit is set by the STM, BIOS can\r
+  control its own page tables. In this case, the STM implementation may\r
+  optionally return ERROR_STM_FUNCTION_NOT_SUPPORTED.\r
+\r
+  @param  EAX  #STM_API_UNMAP_ADDRESS_RANGE (0x00000002)\r
+  @param  EBX  Low 32 bits of virtual address of caller allocated\r
+               STM_UNMAP_ADDRESS_RANGE_DESCRIPTOR structure.\r
+  @param  ECX  High 32 bits of virtual address of caller allocated\r
+               STM_UNMAP_ADDRESS_RANGE_DESCRIPTOR structure. If Intel64Mode is\r
+               clear (0), ECX must be zero.\r
+\r
+  @retval  CF   0\r
+                No error, EAX set to STM_SUCCESS. The memory range was unmapped\r
+                as requested.\r
+  @retval  CF   1\r
+                An error occurred, EAX holds relevant error value.\r
+  @retval  EAX  #ERROR_STM_FUNCTION_NOT_SUPPORTED\r
+                STM supports EPT and has not implemented StmUnmapAddressRange().\r
+  @retval  EAX  #ERROR_STM_UNSPECIFIED\r
+                An unspecified error occurred.\r
+\r
+  @note  All other registers unmodified.\r
+**/\r
+#define STM_API_UNMAP_ADDRESS_RANGE                0x00000002\r
+\r
+/**\r
+  STM Unmap Address Range Descriptor for #STM_API_UNMAP_ADDRESS_RANGE VMCALL\r
+**/\r
+typedef struct {\r
+  UINT64  VirtualAddress;\r
+  UINT32  Length;\r
+} STM_UNMAP_ADDRESS_RANGE_DESCRIPTOR;\r
+\r
+\r
+/**\r
+  Since the normal OS environment runs with a different set of page tables than\r
+  the SMM guest, virtual mappings will certainly be different. In order to do a\r
+  guest virtual to host physical translation of an address from the normal OS\r
+  code (EIP for example), it is necessary to walk the page tables governing the\r
+  OS page mappings. Since the SMM guest has no direct access to the page tables,\r
+  it must ask the STM to do this page table walk. This is supported via the\r
+  StmAddressLookup VMCALL. All OS page table formats need to be supported,\r
+  (e.g. PAE, PSE, Intel64, EPT, etc.)\r
+\r
+  StmAddressLookup takes a CR3 value and a virtual address from the interrupted\r
+  code as input and returns the corresponding physical address. It also\r
+  optionally maps the physical address into the SMM guest's virtual address\r
+  space. This new mapping persists ONLY for the duration of the SMI and if\r
+  needed in subsequent SMIs it must be remapped. PAT cache types follow the\r
+  interrupted environment's page table.\r
+\r
+  If EPT is enabled, OS CR3 only provides guest physical address information,\r
+  but the SMM guest might also need to know the host physical address. Since\r
+  SMM does not have direct access rights to EPT (it is protected by the STM),\r
+  SMM can input InterruptedEptp to let STM help to walk through it, and output\r
+  the host physical address.\r
+\r
+  @param  EAX  #STM_API_ADDRESS_LOOKUP (0x00000003)\r
+  @param  EBX  Low 32 bits of virtual address of caller allocated\r
+               STM_ADDRESS_LOOKUP_DESCRIPTOR structure.\r
+  @param  ECX  High 32 bits of virtual address of caller allocated\r
+               STM_ADDRESS_LOOKUP_DESCRIPTOR structure. If Intel64Mode is\r
+               clear (0), ECX must be zero.\r
+\r
+  @retval  CF   0\r
+                No error, EAX set to STM_SUCCESS.  PhysicalAddress contains the\r
+                host physical address determined by walking the interrupted SMM\r
+                guest's page tables.  SmmGuestVirtualAddress contains the SMM\r
+                guest's virtual mapping of the requested address.\r
+  @retval  CF   1\r
+                An error occurred, EAX holds relevant error value.\r
+  @retval  EAX  #ERROR_STM_SECURITY_VIOLATION\r
+                The requested page was a protected page.\r
+  @retval  EAX  #ERROR_STM_PAGE_NOT_FOUND\r
+                The requested virtual address did not exist in the page given\r
+                page table.\r
+  @retval  EAX  #ERROR_STM_BAD_CR3\r
+                The CR3 input was invalid. CR3 values must be from one of the\r
+                interrupted guest, or from the interrupted guest of another\r
+                processor.\r
+  @retval  EAX  #ERROR_STM_PHYSICAL_OVER_4G\r
+                The resulting physical address is greater than 4G and no virtual\r
+                address was supplied. The STM could not determine what address\r
+                within the SMM guest's virtual address space to do the mapping.\r
+                STM_ADDRESS_LOOKUP_DESCRIPTOR field PhysicalAddress contains the\r
+                physical address determined by walking the interrupted\r
+                environment's page tables.\r
+  @retval  EAX  #ERROR_STM_VIRTUAL_SPACE_TOO_SMALL\r
+                A specific virtual mapping was requested, but\r
+                SmmGuestVirtualAddress + Length exceeds 4G and the SMI handler\r
+                is running in 32 bit mode.\r
+  @retval  EAX  #ERROR_STM_UNSPECIFIED\r
+                An unspecified error occurred.\r
+\r
+  @note  All other registers unmodified.\r
+**/\r
+#define STM_API_ADDRESS_LOOKUP                     0x00000003\r
+\r
+/**\r
+  STM Lookup Address Range Descriptor for #STM_API_ADDRESS_LOOKUP VMCALL\r
+**/\r
+typedef struct {\r
+  UINT64  InterruptedGuestVirtualAddress;\r
+  UINT32  Length;\r
+  UINT64  InterruptedCr3;\r
+  UINT64  InterruptedEptp;\r
+  UINT32  MapToSmmGuest:2;\r
+  UINT32  InterruptedCr4Pae:1;\r
+  UINT32  InterruptedCr4Pse:1;\r
+  UINT32  InterruptedIa32eMode:1;\r
+  UINT32  Reserved1:27;\r
+  UINT32  Reserved2;\r
+  UINT64  PhysicalAddress;\r
+  UINT64  SmmGuestVirtualAddress;\r
+} STM_ADDRESS_LOOKUP_DESCRIPTOR;\r
+\r
+/**\r
+  Define values for the MapToSmmGuest field of #STM_ADDRESS_LOOKUP_DESCRIPTOR\r
+  @{\r
+**/\r
+#define STM_ADDRESS_LOOKUP_DESCRIPTOR_DO_NOT_MAP                 0\r
+#define STM_ADDRESS_LOOKUP_DESCRIPTOR_ONE_TO_ONE                 1\r
+#define STM_ADDRESS_LOOKUP_DESCRIPTOR_VIRTUAL_ADDRESS_SPECIFIED  3\r
+/// @}\r
+\r
+\r
+/**\r
+  When returning from a protection exception (see section 6.2), the SMM guest\r
+  can instruct the STM to take one of two paths. It can either request a value\r
+  be logged to the TXT.ERRORCODE register and subsequently reset the machine\r
+  (indicating it couldn't resolve the problem), or it can request that the STM\r
+  resume the SMM guest again with the specified register state.\r
+\r
+  Unlike other VMCALL interfaces, StmReturnFromProtectionException behaves more\r
+  like a jump or an IRET instruction than a "call". It does not return directly\r
+  to the caller, but indirectly to a different location specified on the\r
+  caller's stack (see section 6.2) or not at all.\r
+\r
+  If the SMM guest STM protection exception handler itself causes a protection\r
+  exception (e.g. a single nested exception), or more than 100 un-nested\r
+  exceptions occur within the scope of a single SMI event, the STM must write\r
+  STM_CRASH_PROTECTION_EXCEPTION_FAILURE to the TXT.ERRORCODE register and\r
+  assert TXT.CMD.SYS_RESET. The reason for these restrictions is to simplify\r
+  the code requirements while still enabling a reasonable debugging capability.\r
+\r
+  @param  EAX  #STM_API_RETURN_FROM_PROTECTION_EXCEPTION (0x00000004)\r
+  @param  EBX  If 0, resume SMM guest using register state found on exception\r
+               stack.  If in range 0x01..0x0F, EBX contains a BIOS error code\r
+               which the STM must record in the TXT.ERRORCODE register and\r
+               subsequently reset the system via TXT.CMD.SYS_RESET. The value\r
+               of the TXT.ERRORCODE register is calculated as follows:\r
+\r
+                 TXT.ERRORCODE = (EBX & 0x0F) | STM_CRASH_BIOS_PANIC\r
+\r
+               Values 0x10..0xFFFFFFFF are reserved, do not use.\r
+\r
+**/\r
+#define STM_API_RETURN_FROM_PROTECTION_EXCEPTION   0x00000004\r
+\r
+\r
+/**\r
+  VMCALL API Numbers\r
+  API number convention: MLE facing VMCALL interfaces have bit 16 set.\r
+\r
+  The STM configuration lifecycle is as follows:\r
+    1. SENTER->SINIT->MLE: MLE begins execution with SMI disabled (masked).\r
+    2. MLE invokes #STM_API_INITIALIZE_PROTECTION VMCALL to prepare STM for\r
+       setup of initial protection profile. This is done on a single CPU and\r
+       has global effect.\r
+    3. MLE invokes #STM_API_PROTECT_RESOURCE VMCALL to define the initial\r
+       protection profile. The protection profile is global across all CPUs.\r
+    4. MLE invokes #STM_API_START VMCALL to enable the STM to begin receiving\r
+       SMI events. This must be done on every logical CPU.\r
+    5. MLE may invoke #STM_API_PROTECT_RESOURCE VMCALL or\r
+       #STM_API_UNPROTECT_RESOURCE VMCALL during runtime as many times as\r
+       necessary.\r
+    6. MLE invokes #STM_API_STOP VMCALL to disable the STM. SMI is again masked\r
+       following #STM_API_STOP VMCALL.\r
+**/\r
+\r
+/**\r
+  StartStmVmcall() is used to configure an STM that is present in MSEG. SMIs\r
+  should remain disabled from the invocation of GETSEC[SENTER] until they are\r
+  re-enabled by StartStmVMCALL(). When StartStmVMCALL() returns, SMI is\r
+  enabled and the STM has been started and is active. Prior to invoking\r
+  StartStmVMCALL(), the MLE root should first invoke\r
+  InitializeProtectionVMCALL() followed by as many iterations of\r
+  ProtectResourceVMCALL() as necessary to establish the initial protection\r
+  profile.  StartStmVmcall() must be invoked on all processor threads.\r
+\r
+  @param  EAX  #STM_API_START (0x00010001)\r
+  @param  EDX  STM configuration options. These provide the MLE with the\r
+               ability to pass configuration parameters to the STM.\r
+\r
+  @retval  CF   0\r
+                No error, EAX set to STM_SUCCESS. The STM has been configured\r
+                and is now active and the guarding all requested resources.\r
+  @retval  CF   1\r
+                An error occurred, EAX holds relevant error value.\r
+  @retval  EAX  #ERROR_STM_ALREADY_STARTED\r
+                The STM is already configured and active. STM remains active and\r
+                guarding previously enabled resource list.\r
+  @retval  EAX  #ERROR_STM_WITHOUT_SMX_UNSUPPORTED\r
+                The StartStmVMCALL() was invoked from VMX root mode, but outside\r
+                of SMX. This error code indicates the STM or platform does not\r
+                support the STM outside of SMX. The SMI handler remains active\r
+                and operates in legacy mode. See Appendix C\r
+  @retval  EAX  #ERROR_STM_UNSUPPORTED_MSR_BIT\r
+                The CPU doesn't support the MSR bit. The STM is not active.\r
+  @retval  EAX  #ERROR_STM_UNSPECIFIED\r
+                An unspecified error occurred.\r
+\r
+  @note  All other registers unmodified.\r
+**/\r
+#define STM_API_START                              (BIT16 | 1)\r
+\r
+/**\r
+  Bit values for EDX input parameter to #STM_API_START VMCALL\r
+  @{\r
+**/\r
+#define STM_CONFIG_SMI_UNBLOCKING_BY_VMX_OFF  BIT0\r
+/// @}\r
+\r
+\r
+/**\r
+  The StopStmVMCALL() is invoked by the MLE to teardown an active STM. This is\r
+  normally done as part of a full teardown of the SMX environment when the\r
+  system is being shut down. At the time the call is invoked, SMI is enabled\r
+  and the STM is active.  When the call returns, the STM has been stopped and\r
+  all STM context is discarded and SMI is disabled.\r
+\r
+  @param  EAX  #STM_API_STOP (0x00010002)\r
+\r
+  @retval  CF   0\r
+                No error, EAX set to STM_SUCCESS. The STM has been stopped and\r
+                is no longer processing SMI events. SMI is blocked.\r
+  @retval  CF   1\r
+                An error occurred, EAX holds relevant error value.\r
+  @retval  EAX  #ERROR_STM_STOPPED\r
+                The STM was not active.\r
+  @retval  EAX  #ERROR_STM_UNSPECIFIED\r
+                An unspecified error occurred.\r
+\r
+  @note  All other registers unmodified.\r
+**/\r
+#define STM_API_STOP                               (BIT16 | 2)\r
+\r
+\r
+/**\r
+  The ProtectResourceVMCALL() is invoked by the MLE root to request protection\r
+  of specific resources. The request is defined by a STM_RESOURCE_LIST, which\r
+  may contain more than one resource descriptor. Each resource descriptor is\r
+  processed separately by the STM. Whether or not protection for any specific\r
+  resource is granted is returned by the STM via the ReturnStatus bit in the\r
+  associated STM_RSC_DESC_HEADER.\r
+\r
+  @param  EAX  #STM_API_PROTECT_RESOURCE (0x00010003)\r
+  @param  EBX  Low 32 bits of physical address of caller allocated\r
+               STM_RESOURCE_LIST. Bits 11:0 are ignored and assumed to be zero,\r
+               making the buffer 4K aligned.\r
+  @param  ECX  High 32 bits of physical address of caller allocated\r
+               STM_RESOURCE_LIST.\r
+\r
+  @note  All fields of STM_RESOURCE_LIST are inputs only, except for the\r
+         ReturnStatus bit. On input, the ReturnStatus bit must be clear. On\r
+         return, the ReturnStatus bit is set for each resource request granted,\r
+         and clear for each resource request denied. There are no other fields\r
+         modified by ProtectResourceVMCALL(). The STM_RESOURCE_LIST must be\r
+         contained entirely within a single 4K page.\r
+\r
+  @retval  CF   0\r
+                No error, EAX set to STM_SUCCESS. The STM has successfully\r
+                merged the entire protection request into the active protection\r
+                profile.  There is therefore no need to check the ReturnStatus\r
+                bits in the STM_RESOURCE_LIST.\r
+  @retval  CF   1\r
+                An error occurred, EAX holds relevant error value.\r
+  @retval  EAX  #ERROR_STM_UNPROTECTABLE_RESOURCE\r
+                At least one of the requested resource protections intersects a\r
+                BIOS required resource. Therefore, the caller must walk through\r
+                the STM_RESOURCE_LIST to determine which of the requested\r
+                resources was not granted protection. The entire list must be\r
+                traversed since there may be multiple failures.\r
+  @retval  EAX  #ERROR_STM_MALFORMED_RESOURCE_LIST\r
+                The resource list could not be parsed correctly, or did not\r
+                terminate before crossing a 4K page boundary. The caller must\r
+                walk through the STM_RESOURCE_LIST to determine which of the\r
+                requested resources was not granted protection. The entire list\r
+                must be traversed since there may be multiple failures.\r
+  @retval  EAX  #ERROR_STM_OUT_OF_RESOURCES\r
+                The STM has encountered an internal error and cannot complete\r
+                the request.\r
+  @retval  EAX  #ERROR_STM_UNSPECIFIED\r
+                An unspecified error occurred.\r
+\r
+  @note  All other registers unmodified.\r
+**/\r
+#define STM_API_PROTECT_RESOURCE                   (BIT16 | 3)\r
+\r
+\r
+/**\r
+  The UnProtectResourceVMCALL() is invoked by the MLE root to request that the\r
+  STM allow the SMI handler access to the specified resources.\r
+\r
+  @param  EAX  #STM_API_UNPROTECT_RESOURCE (0x00010004)\r
+  @param  EBX  Low 32 bits of physical address of caller allocated\r
+               STM_RESOURCE_LIST. Bits 11:0 are ignored and assumed to be zero,\r
+               making the buffer 4K aligned.\r
+  @param  ECX  High 32 bits of physical address of caller allocated\r
+               STM_RESOURCE_LIST.\r
+\r
+  @note  All fields of STM_RESOURCE_LIST are inputs only, except for the\r
+         ReturnStatus bit. On input, the ReturnStatus bit must be clear. On\r
+         return, the ReturnStatus bit is set for each resource processed. For\r
+         a properly formed STM_RESOURCE_LIST, this should be all resources\r
+         listed. There are no other fields modified by\r
+         UnProtectResourceVMCALL(). The STM_RESOURCE_LIST must be contained\r
+         entirely within a single 4K page.\r
+\r
+  @retval  CF   0\r
+                No error, EAX set to STM_SUCCESS. The requested resources are\r
+                not being guarded by the STM.\r
+  @retval  CF   1\r
+                An error occurred, EAX holds relevant error value.\r
+  @retval  EAX  #ERROR_STM_MALFORMED_RESOURCE_LIST\r
+                The resource list could not be parsed correctly, or did not\r
+                terminate before crossing a 4K page boundary. The caller must\r
+                walk through the STM_RESOURCE_LIST to determine which of the\r
+                requested resources were not able to be unprotected. The entire\r
+                list must be traversed since there may be multiple failures.\r
+  @retval  EAX  #ERROR_STM_UNSPECIFIED\r
+                An unspecified error occurred.\r
+\r
+  @note  All other registers unmodified.\r
+**/\r
+#define STM_API_UNPROTECT_RESOURCE                 (BIT16 | 4)\r
+\r
+\r
+/**\r
+  The GetBiosResourcesVMCALL() is invoked by the MLE root to request the list\r
+  of BIOS required resources from the STM.\r
+\r
+  @param  EAX  #STM_API_GET_BIOS_RESOURCES (0x00010005)\r
+  @param  EBX  Low 32 bits of physical address of caller allocated destination\r
+               buffer. Bits 11:0 are ignored and assumed to be zero, making the\r
+               buffer 4K aligned.\r
+  @param  ECX  High 32 bits of physical address of caller allocated destination\r
+               buffer.\r
+  @param  EDX  Indicates which page of the BIOS resource list to copy into the\r
+               destination buffer. The first page is indicated by 0, the second\r
+               page by 1, etc.\r
+\r
+  @retval  CF   0\r
+                No error, EAX set to STM_SUCCESS. The destination buffer\r
+                contains the BIOS required resources. If the page retrieved is\r
+                the last page, EDX will be cleared to 0. If there are more pages\r
+                to retrieve, EDX is incremented to the next page index. Calling\r
+                software should iterate on GetBiosResourcesVMCALL() until EDX is\r
+                returned cleared to 0.\r
+  @retval  CF   1\r
+                An error occurred, EAX holds relevant error value.\r
+  @retval  EAX  #ERROR_STM_PAGE_NOT_FOUND\r
+                The page index supplied in EDX input was out of range.\r
+  @retval  EAX  #ERROR_STM_UNSPECIFIED\r
+                An unspecified error occurred.\r
+  @retval  EDX  Page index of next page to read. A return of EDX=0 signifies\r
+                that the entire list has been read.\r
+                @note  EDX is both an input and an output register.\r
+\r
+  @note  All other registers unmodified.\r
+**/\r
+#define STM_API_GET_BIOS_RESOURCES                 (BIT16 | 5)\r
+\r
+\r
+/**\r
+  The ManageVmcsDatabaseVMCALL() is invoked by the MLE root to add or remove an\r
+  MLE guest (including the MLE root) from the list of protected domains.\r
+\r
+  @param  EAX  #STM_API_MANAGE_VMCS_DATABASE (0x00010006)\r
+  @param  EBX  Low 32 bits of physical address of caller allocated\r
+               STM_VMCS_DATABASE_REQUEST. Bits 11:0 are ignored and assumed to\r
+               be zero, making the buffer 4K aligned.\r
+  @param  ECX  High 32 bits of physical address of caller allocated\r
+               STM_VMCS_DATABASE_REQUEST.\r
+\r
+  @note  All fields of STM_VMCS_DATABASE_REQUEST are inputs only.  They are not\r
+         modified by ManageVmcsDatabaseVMCALL().\r
+\r
+  @retval  CF   0\r
+                No error, EAX set to STM_SUCCESS.\r
+  @retval  CF   1\r
+                An error occurred, EAX holds relevant error value.\r
+  @retval  EAX  #ERROR_STM_INVALID_VMCS\r
+                Indicates a request to remove a VMCS from the database was made,\r
+                but the referenced VMCS was not found in the database.\r
+  @retval  EAX  #ERROR_STM_VMCS_PRESENT\r
+                Indicates a request to add a VMCS to the database was made, but\r
+                the referenced VMCS was already present in the database.\r
+  @retval  EAX  #ERROR_INVALID_PARAMETER\r
+                Indicates non-zero reserved field.\r
+  @retval  EAX  #ERROR_STM_UNSPECIFIED\r
+                An unspecified error occurred\r
+\r
+  @note  All other registers unmodified.\r
+**/\r
+#define STM_API_MANAGE_VMCS_DATABASE               (BIT16 | 6)\r
+\r
+/**\r
+  STM VMCS Database Request for #STM_API_MANAGE_VMCS_DATABASE VMCALL\r
+**/\r
+typedef struct {\r
+  ///\r
+  /// bits 11:0 are reserved and must be 0\r
+  ///\r
+  UINT64  VmcsPhysPointer;\r
+  UINT32  DomainType :4;\r
+  UINT32  XStatePolicy :2;\r
+  UINT32  DegradationPolicy :4;\r
+  ///\r
+  /// Must be 0\r
+  ///\r
+  UINT32  Reserved1 :22;\r
+  UINT32  AddOrRemove;\r
+} STM_VMCS_DATABASE_REQUEST;\r
+\r
+/**\r
+  Values for the DomainType field of #STM_VMCS_DATABASE_REQUEST\r
+  @{\r
+**/\r
+#define DOMAIN_UNPROTECTED            0\r
+#define DOMAIN_DISALLOWED_IO_OUT      BIT0\r
+#define DOMAIN_DISALLOWED_IO_IN       BIT1\r
+#define DOMAIN_INTEGRITY              BIT2\r
+#define DOMAIN_CONFIDENTIALITY        BIT3\r
+#define DOMAIN_INTEGRITY_PROT_OUT_IN  (DOMAIN_INTEGRITY)\r
+#define DOMAIN_FULLY_PROT_OUT_IN      (DOMAIN_CONFIDENTIALITY | DOMAIN_INTEGRITY)\r
+#define DOMAIN_FULLY_PROT             (DOMAIN_FULLY_PROT_OUT_IN | DOMAIN_DISALLOWED_IO_IN | DOMAIN_DISALLOWED_IO_OUT)\r
+/// @}\r
+\r
+/**\r
+  Values for the XStatePolicy field of #STM_VMCS_DATABASE_REQUEST\r
+  @{\r
+**/\r
+#define XSTATE_READWRITE  0x00\r
+#define XSTATE_READONLY   0x01\r
+#define XSTATE_SCRUB      0x03\r
+/// @}\r
+\r
+/**\r
+  Values for the AddOrRemove field of #STM_VMCS_DATABASE_REQUEST\r
+  @{\r
+**/\r
+#define STM_VMCS_DATABASE_REQUEST_ADD     1\r
+#define STM_VMCS_DATABASE_REQUEST_REMOVE  0\r
+/// @}\r
+\r
+\r
+/**\r
+  InitializeProtectionVMCALL() prepares the STM for setup of the initial\r
+  protection profile which is subsequently communicated via one or more\r
+  invocations of ProtectResourceVMCALL(), prior to invoking StartStmVMCALL().\r
+  It is only necessary to invoke InitializeProtectionVMCALL() on one processor\r
+  thread.  InitializeProtectionVMCALL() does not alter whether SMIs are masked\r
+  or unmasked. The STM should return back to the MLE with "Blocking by SMI" set\r
+  to 1 in the GUEST_INTERRUPTIBILITY field for the VMCS the STM created for the\r
+  MLE guest.\r
+\r
+  @param  EAX  #STM_API_INITIALIZE_PROTECTION (0x00010007)\r
+\r
+  @retval  CF   0\r
+                No error, EAX set to STM_SUCCESS, EBX bits set to indicate STM\r
+                capabilities as defined below. The STM has set up an empty\r
+                protection profile, except for the resources that it sets up to\r
+                protect itself. The STM must not allow the SMI handler to map\r
+                any pages from the MSEG Base to the top of TSEG. The STM must\r
+                also not allow SMI handler access to those MSRs which the STM\r
+                requires for its own protection.\r
+  @retval  CF   1\r
+                An error occurred, EAX holds relevant error value.\r
+  @retval  EAX  #ERROR_STM_ALREADY_STARTED\r
+                The STM is already configured and active. The STM remains active\r
+                and guarding the previously enabled resource list.\r
+  @retval  EAX  #ERROR_STM_UNPROTECTABLE\r
+                The STM determines that based on the platform configuration, the\r
+                STM is unable to protect itself. For example, the BIOS required\r
+                resource list contains memory pages in MSEG.\r
+  @retval  EAX  #ERROR_STM_UNSPECIFIED\r
+                An unspecified error occurred.\r
+\r
+  @note  All other registers unmodified.\r
+**/\r
+#define STM_API_INITIALIZE_PROTECTION              (BIT16 | 7)\r
+\r
+/**\r
+  Byte granular support bits returned in EBX from #STM_API_INITIALIZE_PROTECTION\r
+  @{\r
+**/\r
+#define STM_RSC_BGI  BIT1\r
+#define STM_RSC_BGM  BIT2\r
+#define STM_RSC_MSR  BIT3\r
+/// @}\r
+\r
+\r
+/**\r
+  The ManageEventLogVMCALL() is invoked by the MLE root to control the logging\r
+  feature. It consists of several sub-functions to facilitate establishment of\r
+  the log itself, configuring what events will be logged, and functions to\r
+  start, stop, and clear the log.\r
+\r
+  @param  EAX  #STM_API_MANAGE_EVENT_LOG (0x00010008)\r
+  @param  EBX  Low 32 bits of physical address of caller allocated\r
+               STM_EVENT_LOG_MANAGEMENT_REQUEST. Bits 11:0 are ignored and\r
+               assumed to be zero, making the buffer 4K aligned.\r
+  @param  ECX  High 32 bits of physical address of caller allocated\r
+               STM_EVENT_LOG_MANAGEMENT_REQUEST.\r
+\r
+  @retval  CF=0\r
+           No error, EAX set to STM_SUCCESS.\r
+  @retval  CF=1\r
+           An error occurred, EAX holds relevant error value. See subfunction\r
+           descriptions below for details.\r
+\r
+  @note  All other registers unmodified.\r
+**/\r
+#define STM_API_MANAGE_EVENT_LOG                   (BIT16 | 8)\r
+\r
+///\r
+/// STM Event Log Management Request for #STM_API_MANAGE_EVENT_LOG VMCALL\r
+///\r
+typedef struct {\r
+  UINT32      SubFunctionIndex;\r
+  union {\r
+    struct {\r
+      UINT32  PageCount;\r
+      //\r
+      // number of elements is PageCount\r
+      //\r
+      UINT64  Pages[];\r
+    } LogBuffer;\r
+    //\r
+    // bitmap of EVENT_TYPE\r
+    //\r
+    UINT32    EventEnableBitmap;\r
+  } Data;\r
+} STM_EVENT_LOG_MANAGEMENT_REQUEST;\r
+\r
+/**\r
+  Defines values for the SubFunctionIndex field of\r
+  #STM_EVENT_LOG_MANAGEMENT_REQUEST\r
+  @{\r
+**/\r
+#define STM_EVENT_LOG_MANAGEMENT_REQUEST_NEW_LOG        1\r
+#define STM_EVENT_LOG_MANAGEMENT_REQUEST_CONFIGURE_LOG  2\r
+#define STM_EVENT_LOG_MANAGEMENT_REQUEST_START_LOG      3\r
+#define STM_EVENT_LOG_MANAGEMENT_REQUEST_STOP_LOG       4\r
+#define STM_EVENT_LOG_MANAGEMENT_REQUEST_CLEAR_LOG      5\r
+#define STM_EVENT_LOG_MANAGEMENT_REQUEST_DELETE_LOG     6\r
+/// @}\r
+\r
+/**\r
+  Log Entry Header\r
+**/\r
+typedef struct {\r
+  UINT32  EventSerialNumber;\r
+  UINT16  Type;\r
+  UINT16  Lock :1;\r
+  UINT16  Valid :1;\r
+  UINT16  ReadByMle :1;\r
+  UINT16  Wrapped :1;\r
+  UINT16  Reserved :12;\r
+} LOG_ENTRY_HEADER;\r
+\r
+/**\r
+  Enum values for the Type field of #LOG_ENTRY_HEADER\r
+**/\r
+typedef enum {\r
+  EvtLogStarted,\r
+  EvtLogStopped,\r
+  EvtLogInvalidParameterDetected,\r
+  EvtHandledProtectionException,\r
+  ///\r
+  /// unhandled protection exceptions result in reset & cannot be logged\r
+  ///\r
+  EvtBiosAccessToUnclaimedResource,\r
+  EvtMleResourceProtectionGranted,\r
+  EvtMleResourceProtectionDenied,\r
+  EvtMleResourceUnprotect,\r
+  EvtMleResourceUnprotectError,\r
+  EvtMleDomainTypeDegraded,\r
+  ///\r
+  /// add more here\r
+  ///\r
+  EvtMleMax,\r
+  ///\r
+  /// Not used\r
+  ///\r
+  EvtInvalid = 0xFFFFFFFF,\r
+} EVENT_TYPE;\r
+\r
+typedef struct {\r
+  UINT32  Reserved;\r
+} ENTRY_EVT_LOG_STARTED;\r
+\r
+typedef struct {\r
+  UINT32  Reserved;\r
+} ENTRY_EVT_LOG_STOPPED;\r
+\r
+typedef struct {\r
+  UINT32  VmcallApiNumber;\r
+} ENTRY_EVT_LOG_INVALID_PARAM;\r
+\r
+typedef struct {\r
+  STM_RSC  Resource;\r
+} ENTRY_EVT_LOG_HANDLED_PROTECTION_EXCEPTION;\r
+\r
+typedef struct {\r
+  STM_RSC  Resource;\r
+} ENTRY_EVT_BIOS_ACCESS_UNCLAIMED_RSC;\r
+\r
+typedef struct {\r
+  STM_RSC  Resource;\r
+} ENTRY_EVT_MLE_RSC_PROT_GRANTED;\r
+\r
+typedef struct {\r
+  STM_RSC  Resource;\r
+} ENTRY_EVT_MLE_RSC_PROT_DENIED;\r
+\r
+typedef struct {\r
+  STM_RSC  Resource;\r
+} ENTRY_EVT_MLE_RSC_UNPROT;\r
+\r
+typedef struct {\r
+  STM_RSC  Resource;\r
+} ENTRY_EVT_MLE_RSC_UNPROT_ERROR;\r
+\r
+typedef struct {\r
+  UINT64  VmcsPhysPointer;\r
+  UINT8   ExpectedDomainType;\r
+  UINT8   DegradedDomainType;\r
+} ENTRY_EVT_MLE_DOMAIN_TYPE_DEGRADED;\r
+\r
+typedef union {\r
+  ENTRY_EVT_LOG_STARTED                       Started;\r
+  ENTRY_EVT_LOG_STOPPED                       Stopped;\r
+  ENTRY_EVT_LOG_INVALID_PARAM                 InvalidParam;\r
+  ENTRY_EVT_LOG_HANDLED_PROTECTION_EXCEPTION  HandledProtectionException;\r
+  ENTRY_EVT_BIOS_ACCESS_UNCLAIMED_RSC         BiosUnclaimedRsc;\r
+  ENTRY_EVT_MLE_RSC_PROT_GRANTED              MleRscProtGranted;\r
+  ENTRY_EVT_MLE_RSC_PROT_DENIED               MleRscProtDenied;\r
+  ENTRY_EVT_MLE_RSC_UNPROT                    MleRscUnprot;\r
+  ENTRY_EVT_MLE_RSC_UNPROT_ERROR              MleRscUnprotError;\r
+  ENTRY_EVT_MLE_DOMAIN_TYPE_DEGRADED          MleDomainTypeDegraded;\r
+} LOG_ENTRY_DATA;\r
+\r
+typedef struct {\r
+  LOG_ENTRY_HEADER  Hdr;\r
+  LOG_ENTRY_DATA    Data;\r
+} STM_LOG_ENTRY;\r
+\r
+/**\r
+  Maximum STM Log Entry Size\r
+**/\r
+#define STM_LOG_ENTRY_SIZE  256\r
+\r
+\r
+/**\r
+  STM Protection Exception Stack Frame Structures\r
+**/\r
+\r
+typedef struct {\r
+  UINT32  Rdi;\r
+  UINT32  Rsi;\r
+  UINT32  Rbp;\r
+  UINT32  Rdx;\r
+  UINT32  Rcx;\r
+  UINT32  Rbx;\r
+  UINT32  Rax;\r
+  UINT32  Cr3;\r
+  UINT32  Cr2;\r
+  UINT32  Cr0;\r
+  UINT32  VmcsExitInstructionInfo;\r
+  UINT32  VmcsExitInstructionLength;\r
+  UINT64  VmcsExitQualification;\r
+  ///\r
+  /// An TXT_SMM_PROTECTION_EXCEPTION_TYPE num value\r
+  ///\r
+  UINT32  ErrorCode;\r
+  UINT32  Rip;\r
+  UINT32  Cs;\r
+  UINT32  Rflags;\r
+  UINT32  Rsp;\r
+  UINT32  Ss;\r
+} STM_PROTECTION_EXCEPTION_STACK_FRAME_IA32;\r
+\r
+typedef struct {\r
+  UINT64  R15;\r
+  UINT64  R14;\r
+  UINT64  R13;\r
+  UINT64  R12;\r
+  UINT64  R11;\r
+  UINT64  R10;\r
+  UINT64  R9;\r
+  UINT64  R8;\r
+  UINT64  Rdi;\r
+  UINT64  Rsi;\r
+  UINT64  Rbp;\r
+  UINT64  Rdx;\r
+  UINT64  Rcx;\r
+  UINT64  Rbx;\r
+  UINT64  Rax;\r
+  UINT64  Cr8;\r
+  UINT64  Cr3;\r
+  UINT64  Cr2;\r
+  UINT64  Cr0;\r
+  UINT64  VmcsExitInstructionInfo;\r
+  UINT64  VmcsExitInstructionLength;\r
+  UINT64  VmcsExitQualification;\r
+  ///\r
+  /// An TXT_SMM_PROTECTION_EXCEPTION_TYPE num value\r
+  ///\r
+  UINT64  ErrorCode;\r
+  UINT64  Rip;\r
+  UINT64  Cs;\r
+  UINT64  Rflags;\r
+  UINT64  Rsp;\r
+  UINT64  Ss;\r
+} STM_PROTECTION_EXCEPTION_STACK_FRAME_X64;\r
+\r
+typedef union {\r
+  STM_PROTECTION_EXCEPTION_STACK_FRAME_IA32  *Ia32StackFrame;\r
+  STM_PROTECTION_EXCEPTION_STACK_FRAME_X64   *X64StackFrame;\r
+} STM_PROTECTION_EXCEPTION_STACK_FRAME;\r
+\r
+/**\r
+  Enum values for the ErrorCode field in\r
+  #STM_PROTECTION_EXCEPTION_STACK_FRAME_IA32 and\r
+  #STM_PROTECTION_EXCEPTION_STACK_FRAME_X64\r
+**/\r
+typedef enum {\r
+  TxtSmmPageViolation = 1,\r
+  TxtSmmMsrViolation,\r
+  TxtSmmRegisterViolation,\r
+  TxtSmmIoViolation,\r
+  TxtSmmPciViolation\r
+} TXT_SMM_PROTECTION_EXCEPTION_TYPE;\r
+\r
+/**\r
+  TXT Pocessor SMM Descriptor (PSD) structures\r
+**/\r
+\r
+typedef struct {\r
+  UINT64  SpeRip;\r
+  UINT64  SpeRsp;\r
+  UINT16  SpeSs;\r
+  UINT16  PageViolationException:1;\r
+  UINT16  MsrViolationException:1;\r
+  UINT16  RegisterViolationException:1;\r
+  UINT16  IoViolationException:1;\r
+  UINT16  PciViolationException:1;\r
+  UINT16  Reserved1:11;\r
+  UINT32  Reserved2;\r
+} STM_PROTECTION_EXCEPTION_HANDLER;\r
+\r
+typedef struct {\r
+  UINT8  ExecutionDisableOutsideSmrr:1;\r
+  UINT8  Intel64Mode:1;\r
+  UINT8  Cr4Pae : 1;\r
+  UINT8  Cr4Pse : 1;\r
+  UINT8  Reserved1 : 4;\r
+} STM_SMM_ENTRY_STATE;\r
+\r
+typedef struct {\r
+  UINT8  SmramToVmcsRestoreRequired : 1; ///> BIOS restore hint\r
+  UINT8  ReinitializeVmcsRequired : 1;   ///> BIOS request\r
+  UINT8  Reserved2 : 6;\r
+} STM_SMM_RESUME_STATE;\r
+\r
+typedef struct {\r
+  UINT8  DomainType : 4;   ///> STM input to BIOS on each SMI\r
+  UINT8  XStatePolicy : 2; ///> STM input to BIOS on each SMI\r
+  UINT8  EptEnabled : 1;\r
+  UINT8  Reserved3 : 1;\r
+} STM_SMM_STATE;\r
+\r
+#define TXT_SMM_PSD_OFFSET                          0xfb00\r
+#define TXT_PROCESSOR_SMM_DESCRIPTOR_SIGNATURE      SIGNATURE_64('T', 'X', 'T', 'P', 'S', 'S', 'I', 'G')\r
+#define TXT_PROCESSOR_SMM_DESCRIPTOR_VERSION_MAJOR  1\r
+#define TXT_PROCESSOR_SMM_DESCRIPTOR_VERSION_MINOR  0\r
+\r
+typedef struct {\r
+  UINT64                            Signature;\r
+  UINT16                            Size;\r
+  UINT8                             SmmDescriptorVerMajor;\r
+  UINT8                             SmmDescriptorVerMinor;\r
+  UINT32                            LocalApicId;\r
+  STM_SMM_ENTRY_STATE               SmmEntryState;\r
+  STM_SMM_RESUME_STATE              SmmResumeState;\r
+  STM_SMM_STATE                     StmSmmState;\r
+  UINT8                             Reserved4;\r
+  UINT16                            SmmCs;\r
+  UINT16                            SmmDs;\r
+  UINT16                            SmmSs;\r
+  UINT16                            SmmOtherSegment;\r
+  UINT16                            SmmTr;\r
+  UINT16                            Reserved5;\r
+  UINT64                            SmmCr3;\r
+  UINT64                            SmmStmSetupRip;\r
+  UINT64                            SmmStmTeardownRip;\r
+  UINT64                            SmmSmiHandlerRip;\r
+  UINT64                            SmmSmiHandlerRsp;\r
+  UINT64                            SmmGdtPtr;\r
+  UINT32                            SmmGdtSize;\r
+  UINT32                            RequiredStmSmmRevId;\r
+  STM_PROTECTION_EXCEPTION_HANDLER  StmProtectionExceptionHandler;\r
+  UINT64                            Reserved6;\r
+  UINT64                            BiosHwResourceRequirementsPtr;\r
+  // extend area\r
+  UINT64                            AcpiRsdp;\r
+  UINT8                             PhysicalAddressBits;\r
+} TXT_PROCESSOR_SMM_DESCRIPTOR;\r
+\r
+#pragma pack ()\r
+\r
+#endif\r
diff --git a/UefiCpuPkg/Include/Register/StmResourceDescriptor.h b/UefiCpuPkg/Include/Register/StmResourceDescriptor.h
new file mode 100644 (file)
index 0000000..1518462
--- /dev/null
@@ -0,0 +1,228 @@
+/** @file\r
+  STM Resource Descriptor\r
+\r
+  Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+  @par Specification Reference:\r
+  SMI Transfer Monitor (STM) User Guide Revision 1.00\r
+\r
+**/\r
+\r
+#ifndef _STM_RESOURCE_DESCRIPTOR_H_\r
+#define _STM_RESOURCE_DESCRIPTOR_H_\r
+\r
+#pragma pack (1)\r
+\r
+/**\r
+  STM Resource Descriptor Header\r
+**/\r
+typedef struct {\r
+  UINT32  RscType;\r
+  UINT16  Length;\r
+  UINT16  ReturnStatus:1;\r
+  UINT16  Reserved:14;\r
+  UINT16  IgnoreResource:1;\r
+} STM_RSC_DESC_HEADER;\r
+\r
+/**\r
+  Define values for the RscType field of #STM_RSC_DESC_HEADER\r
+  @{\r
+**/\r
+#define END_OF_RESOURCES      0\r
+#define MEM_RANGE             1\r
+#define IO_RANGE              2\r
+#define MMIO_RANGE            3\r
+#define MACHINE_SPECIFIC_REG  4\r
+#define PCI_CFG_RANGE         5\r
+#define TRAPPED_IO_RANGE      6\r
+#define ALL_RESOURCES         7\r
+#define REGISTER_VIOLATION    8\r
+#define MAX_DESC_TYPE         8\r
+/// @}\r
+\r
+/**\r
+  STM Resource End Descriptor\r
+**/\r
+typedef struct {\r
+  STM_RSC_DESC_HEADER  Hdr;\r
+  UINT64               ResourceListContinuation;\r
+} STM_RSC_END;\r
+\r
+/**\r
+  STM Resource Memory Descriptor\r
+**/\r
+typedef struct {\r
+  STM_RSC_DESC_HEADER  Hdr;\r
+  UINT64               Base;\r
+  UINT64               Length;\r
+  UINT32               RWXAttributes:3;\r
+  UINT32               Reserved:29;\r
+  UINT32               Reserved_2;\r
+} STM_RSC_MEM_DESC;\r
+\r
+/**\r
+  Define values for the RWXAttributes field of #STM_RSC_MEM_DESC\r
+  @{\r
+**/\r
+#define STM_RSC_MEM_R  0x1\r
+#define STM_RSC_MEM_W  0x2\r
+#define STM_RSC_MEM_X  0x4\r
+/// @}\r
+\r
+/**\r
+  STM Resource I/O Descriptor\r
+**/\r
+typedef struct {\r
+  STM_RSC_DESC_HEADER  Hdr;\r
+  UINT16               Base;\r
+  UINT16               Length;\r
+  UINT32               Reserved;\r
+} STM_RSC_IO_DESC;\r
+\r
+/**\r
+  STM Resource MMIO Descriptor\r
+**/\r
+typedef struct {\r
+  STM_RSC_DESC_HEADER  Hdr;\r
+  UINT64               Base;\r
+  UINT64               Length;\r
+  UINT32               RWXAttributes:3;\r
+  UINT32               Reserved:29;\r
+  UINT32               Reserved_2;\r
+} STM_RSC_MMIO_DESC;\r
+\r
+/**\r
+  Define values for the RWXAttributes field of #STM_RSC_MMIO_DESC\r
+  @{\r
+**/\r
+#define STM_RSC_MMIO_R  0x1\r
+#define STM_RSC_MMIO_W  0x2\r
+#define STM_RSC_MMIO_X  0x4\r
+/// @}\r
+\r
+/**\r
+  STM Resource MSR Descriptor\r
+**/\r
+typedef struct {\r
+  STM_RSC_DESC_HEADER  Hdr;\r
+  UINT32               MsrIndex;\r
+  UINT32               KernelModeProcessing:1;\r
+  UINT32               Reserved:31;\r
+  UINT64               ReadMask;\r
+  UINT64               WriteMask;\r
+} STM_RSC_MSR_DESC;\r
+\r
+/**\r
+  STM PCI Device Path node used for the PciDevicePath field of\r
+  #STM_RSC_PCI_CFG_DESC\r
+**/\r
+typedef struct {\r
+  ///\r
+  /// Must be 1, indicating Hardware Device Path\r
+  ///\r
+  UINT8   Type;\r
+  ///\r
+  /// Must be 1, indicating PCI\r
+  ///\r
+  UINT8   Subtype;\r
+  ///\r
+  /// sizeof(STM_PCI_DEVICE_PATH_NODE) which is 6\r
+  ///\r
+  UINT16  Length;\r
+  UINT8   PciFunction;\r
+  UINT8   PciDevice;\r
+} STM_PCI_DEVICE_PATH_NODE;\r
+\r
+/**\r
+  STM Resource PCI Configuration Descriptor\r
+**/\r
+typedef struct {\r
+  STM_RSC_DESC_HEADER       Hdr;\r
+  UINT16                    RWAttributes:2;\r
+  UINT16                    Reserved:14;\r
+  UINT16                    Base;\r
+  UINT16                    Length;\r
+  UINT8                     OriginatingBusNumber;\r
+  UINT8                     LastNodeIndex;\r
+  STM_PCI_DEVICE_PATH_NODE  PciDevicePath[1];\r
+//STM_PCI_DEVICE_PATH_NODE  PciDevicePath[LastNodeIndex + 1];\r
+} STM_RSC_PCI_CFG_DESC;\r
+\r
+/**\r
+  Define values for the RWAttributes field of #STM_RSC_PCI_CFG_DESC\r
+  @{\r
+**/\r
+#define STM_RSC_PCI_CFG_R  0x1\r
+#define STM_RSC_PCI_CFG_W  0x2\r
+/// @}\r
+\r
+/**\r
+  STM Resource Trapped I/O Descriptor\r
+**/\r
+typedef struct {\r
+  STM_RSC_DESC_HEADER  Hdr;\r
+  UINT16               Base;\r
+  UINT16               Length;\r
+  UINT16               In:1;\r
+  UINT16               Out:1;\r
+  UINT16               Api:1;\r
+  UINT16               Reserved1:13;\r
+  UINT16               Reserved2;\r
+} STM_RSC_TRAPPED_IO_DESC;\r
+\r
+/**\r
+  STM Resource All Descriptor\r
+**/\r
+typedef struct {\r
+  STM_RSC_DESC_HEADER  Hdr;\r
+} STM_RSC_ALL_RESOURCES_DESC;\r
+\r
+/**\r
+  STM Register Volation Descriptor\r
+**/\r
+typedef struct {\r
+  STM_RSC_DESC_HEADER  Hdr;\r
+  UINT32               RegisterType;\r
+  UINT32               Reserved;\r
+  UINT64               ReadMask;\r
+  UINT64               WriteMask;\r
+} STM_REGISTER_VIOLATION_DESC;\r
+\r
+/**\r
+  Enum values for the RWAttributes field of #STM_REGISTER_VIOLATION_DESC\r
+**/\r
+typedef enum {\r
+  StmRegisterCr0,\r
+  StmRegisterCr2,\r
+  StmRegisterCr3,\r
+  StmRegisterCr4,\r
+  StmRegisterCr8,\r
+  StmRegisterMax,\r
+} STM_REGISTER_VIOLATION_TYPE;\r
+\r
+/**\r
+  Union of all STM resource types\r
+**/\r
+typedef union {\r
+  STM_RSC_DESC_HEADER          Header;\r
+  STM_RSC_END                  End;\r
+  STM_RSC_MEM_DESC             Mem;\r
+  STM_RSC_IO_DESC              Io;\r
+  STM_RSC_MMIO_DESC            Mmio;\r
+  STM_RSC_MSR_DESC             Msr;\r
+  STM_RSC_PCI_CFG_DESC         PciCfg;\r
+  STM_RSC_TRAPPED_IO_DESC      TrappedIo;\r
+  STM_RSC_ALL_RESOURCES_DESC   All;\r
+  STM_REGISTER_VIOLATION_DESC  RegisterViolation;\r
+} STM_RSC;\r
+\r
+#pragma pack ()\r
+\r
+#endif\r
diff --git a/UefiCpuPkg/Include/Register/StmStatusCode.h b/UefiCpuPkg/Include/Register/StmStatusCode.h
new file mode 100644 (file)
index 0000000..f1fcb8b
--- /dev/null
@@ -0,0 +1,78 @@
+/** @file\r
+  STM Status Codes\r
+\r
+  Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php.\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+  @par Specification Reference:\r
+  SMI Transfer Monitor (STM) User Guide Revision 1.00\r
+\r
+**/\r
+\r
+#ifndef _STM_STATUS_CODE_H_\r
+#define _STM_STATUS_CODE_H_\r
+\r
+/**\r
+  STM Status Codes\r
+**/\r
+typedef UINT32  STM_STATUS;\r
+\r
+/**\r
+  Success code have BIT31 clear.\r
+  All error codes have BIT31 set.\r
+  STM errors have BIT16 set.\r
+  SMM errors have BIT17 set\r
+  Errors that apply to both STM and SMM have bits BIT15, BT16, and BIT17 set.\r
+  STM TXT.ERRORCODE codes have BIT30 set.\r
+  @{\r
+**/\r
+#define STM_SUCCESS                             0x00000000\r
+#define SMM_SUCCESS                             0x00000000\r
+#define ERROR_STM_SECURITY_VIOLATION            (BIT31 | BIT16 | 0x0001)\r
+#define ERROR_STM_CACHE_TYPE_NOT_SUPPORTED      (BIT31 | BIT16 | 0x0002)\r
+#define ERROR_STM_PAGE_NOT_FOUND                (BIT31 | BIT16 | 0x0003)\r
+#define ERROR_STM_BAD_CR3                       (BIT31 | BIT16 | 0x0004)\r
+#define ERROR_STM_PHYSICAL_OVER_4G              (BIT31 | BIT16 | 0x0005)\r
+#define ERROR_STM_VIRTUAL_SPACE_TOO_SMALL       (BIT31 | BIT16 | 0x0006)\r
+#define ERROR_STM_UNPROTECTABLE_RESOURCE        (BIT31 | BIT16 | 0x0007)\r
+#define ERROR_STM_ALREADY_STARTED               (BIT31 | BIT16 | 0x0008)\r
+#define ERROR_STM_WITHOUT_SMX_UNSUPPORTED       (BIT31 | BIT16 | 0x0009)\r
+#define ERROR_STM_STOPPED                       (BIT31 | BIT16 | 0x000A)\r
+#define ERROR_STM_BUFFER_TOO_SMALL              (BIT31 | BIT16 | 0x000B)\r
+#define ERROR_STM_INVALID_VMCS_DATABASE         (BIT31 | BIT16 | 0x000C)\r
+#define ERROR_STM_MALFORMED_RESOURCE_LIST       (BIT31 | BIT16 | 0x000D)\r
+#define ERROR_STM_INVALID_PAGECOUNT             (BIT31 | BIT16 | 0x000E)\r
+#define ERROR_STM_LOG_ALLOCATED                 (BIT31 | BIT16 | 0x000F)\r
+#define ERROR_STM_LOG_NOT_ALLOCATED             (BIT31 | BIT16 | 0x0010)\r
+#define ERROR_STM_LOG_NOT_STOPPED               (BIT31 | BIT16 | 0x0011)\r
+#define ERROR_STM_LOG_NOT_STARTED               (BIT31 | BIT16 | 0x0012)\r
+#define ERROR_STM_RESERVED_BIT_SET              (BIT31 | BIT16 | 0x0013)\r
+#define ERROR_STM_NO_EVENTS_ENABLED             (BIT31 | BIT16 | 0x0014)\r
+#define ERROR_STM_OUT_OF_RESOURCES              (BIT31 | BIT16 | 0x0015)\r
+#define ERROR_STM_FUNCTION_NOT_SUPPORTED        (BIT31 | BIT16 | 0x0016)\r
+#define ERROR_STM_UNPROTECTABLE                 (BIT31 | BIT16 | 0x0017)\r
+#define ERROR_STM_UNSUPPORTED_MSR_BIT           (BIT31 | BIT16 | 0x0018)\r
+#define ERROR_STM_UNSPECIFIED                   (BIT31 | BIT16 | 0xFFFF)\r
+#define ERROR_SMM_BAD_BUFFER                    (BIT31 | BIT17 | 0x0001)\r
+#define ERROR_SMM_INVALID_RSC                   (BIT31 | BIT17 | 0x0004)\r
+#define ERROR_SMM_INVALID_BUFFER_SIZE           (BIT31 | BIT17 | 0x0005)\r
+#define ERROR_SMM_BUFFER_TOO_SHORT              (BIT31 | BIT17 | 0x0006)\r
+#define ERROR_SMM_INVALID_LIST                  (BIT31 | BIT17 | 0x0007)\r
+#define ERROR_SMM_OUT_OF_MEMORY                 (BIT31 | BIT17 | 0x0008)\r
+#define ERROR_SMM_AFTER_INIT                    (BIT31 | BIT17 | 0x0009)\r
+#define ERROR_SMM_UNSPECIFIED                   (BIT31 | BIT17 | 0xFFFF)\r
+#define ERROR_INVALID_API                       (BIT31 | BIT17 | BIT16 | BIT15 | 0x0001)\r
+#define ERROR_INVALID_PARAMETER                 (BIT31 | BIT17 | BIT16 | BIT15 | 0x0002)\r
+#define STM_CRASH_PROTECTION_EXCEPTION          (BIT31 | BIT30 | 0xF001)\r
+#define STM_CRASH_PROTECTION_EXCEPTION_FAILURE  (BIT31 | BIT30 | 0xF002)\r
+#define STM_CRASH_DOMAIN_DEGRADATION_FAILURE    (BIT31 | BIT30 | 0xF003)\r
+#define STM_CRASH_BIOS_PANIC                    (BIT31 | BIT30 | 0xE000)\r
+/// @}\r
+\r
+#endif\r
index ca56039..c37b4d5 100644 (file)
@@ -60,6 +60,7 @@
 \r
 [Guids]\r
   gUefiCpuPkgTokenSpaceGuid      = { 0xac05bf33, 0x995a, 0x4ed4, { 0xaa, 0xb8, 0xef, 0x7a, 0xe8, 0xf, 0x5c, 0xb0 }}\r
+  gMsegSmramGuid                 = { 0x5802bce4, 0xeeee, 0x4e33, { 0xa1, 0x30, 0xeb, 0xad, 0x27, 0xf0, 0xe4, 0x39 }}\r
 \r
   ## Include/Guid/MicrocodeFmp.h\r
   gMicrocodeFmpImageTypeIdGuid      = { 0x96d4fdcd, 0x1502, 0x424d, { 0x9d, 0x4c, 0x9b, 0x12, 0xd2, 0xdc, 0xae, 0x5c } }\r
@@ -68,6 +69,9 @@
   ## Include/Protocol/SmmCpuService.h\r
   gEfiSmmCpuServiceProtocolGuid  = { 0x1d202cab, 0xc8ab, 0x4d5c, { 0x94, 0xf7, 0x3c, 0xfc, 0xc0, 0xd3, 0xd3, 0x35 }}\r
 \r
+  ## Include/Protocol/SmMonitorInit.h\r
+  gEfiSmMonitorInitProtocolGuid  = { 0x228f344d, 0xb3de, 0x43bb, { 0xa4, 0xd7, 0xea, 0x20, 0xb, 0x1b, 0x14, 0x82 }}\r
+\r
 #\r
 # [Error.gUefiCpuPkgTokenSpaceGuid]\r
 #   0x80000001 | Invalid value provided.\r
   # @Prompt Number of reserved variable MTRRs.\r
   gUefiCpuPkgTokenSpaceGuid.PcdCpuNumberOfReservedVariableMtrrs|0x2|UINT32|0x00000015\r
 \r
+  ## Specifies buffer size in bytes for STM exception stack. The value should be a multiple of 4KB.\r
+  # @Prompt STM exception stack size.\r
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStmExceptionStackSize|0x1000|UINT32|0x32132111\r
+\r
+  ## Specifies buffer size in bytes of MSEG. The value should be a multiple of 4KB.\r
+  # @Prompt MSEG size.\r
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuMsegSize|0x200000|UINT32|0x32132112\r
+\r
 [PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]\r
   ## Specifies max supported number of Logical Processors.\r
   # @Prompt Configure max supported number of Logical Processors\r