--- /dev/null
+/** @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