UefiCpuPkg: Add STM GUIDs, Protocols, and PCDs

* 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>
diff --git a/UefiCpuPkg/Include/Guid/MsegSmram.h b/UefiCpuPkg/Include/Guid/MsegSmram.h
new file mode 100644
index 0000000..ab337c4
--- /dev/null
+++ b/UefiCpuPkg/Include/Guid/MsegSmram.h
@@ -0,0 +1,30 @@
+/** @file

+

+  Defines the HOB GUID used to describe the MSEG memory region allocated in PEI.

+

+  Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php.

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#ifndef _MSEG_SMRAM_H_

+#define _MSEG_SMRAM_H_

+

+#define MSEG_SMRAM_GUID \

+  { \

+    0x5802bce4, 0xeeee, 0x4e33, { 0xa1, 0x30, 0xeb, 0xad, 0x27, 0xf0, 0xe4, 0x39 } \

+  }

+

+extern EFI_GUID gMsegSmramGuid;

+

+//

+// The data portion of this HOB is type EFI_SMRAM_DESCRIPTOR

+//

+

+#endif

diff --git a/UefiCpuPkg/Include/Protocol/SmMonitorInit.h b/UefiCpuPkg/Include/Protocol/SmMonitorInit.h
new file mode 100644
index 0000000..7b0aab0
--- /dev/null
+++ b/UefiCpuPkg/Include/Protocol/SmMonitorInit.h
@@ -0,0 +1,141 @@
+/** @file

+  STM service protocol definition

+

+  Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php.

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+**/

+

+#ifndef _SM_MONITOR_INIT_PROTOCOL_H_

+#define _SM_MONITOR_INIT_PROTOCOL_H_

+

+#include <PiSmm.h>

+#include <Register/StmApi.h>

+

+#define EFI_SM_MONITOR_INIT_PROTOCOL_GUID \

+    { 0x228f344d, 0xb3de, 0x43bb, 0xa4, 0xd7, 0xea, 0x20, 0xb, 0x1b, 0x14, 0x82}

+

+//

+// STM service

+//

+

+/**

+

+  Load STM image to MSEG.

+

+  @param StmImage      STM image

+  @param StmImageSize  STM image size

+

+  @retval EFI_SUCCESS            Load STM to MSEG successfully

+  @retval EFI_ALREADY_STARTED    STM image is already loaded to MSEG

+  @retval EFI_BUFFER_TOO_SMALL   MSEG is smaller than minimal requirement of STM image

+  @retval EFI_UNSUPPORTED        MSEG is not enabled

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SM_MONITOR_LOAD_MONITOR) (

+  IN EFI_PHYSICAL_ADDRESS StmImage,

+  IN UINTN                StmImageSize

+  );

+

+/**

+

+  Add resources in list to database.

+

+  @param ResourceList  A pointer to resource list to be added

+  @param NumEntries    Optional number of entries.

+                       If 0, list must be terminated by END_OF_RESOURCES.

+

+  @retval EFI_SUCCESS            If resources are added

+  @retval EFI_INVALID_PARAMETER  If nested procedure detected resource failer

+  @retval EFI_OUT_OF_RESOURCES   If nested procedure returned it and we cannot allocate more areas.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SM_MONITOR_ADD_PI_RESOURCE) (

+  IN STM_RSC *ResourceList,

+  IN UINT32   NumEntries OPTIONAL

+  );

+

+/**

+

+  Delete resources in list to database.

+

+  @param ResourceList  A pointer to resource list to be deleted

+                       NULL means delete all resources.

+  @param NumEntries    Optional number of entries.

+                       If 0, list must be terminated by END_OF_RESOURCES.

+

+  @retval EFI_SUCCESS            If resources are deleted

+  @retval EFI_INVALID_PARAMETER  If nested procedure detected resource failer

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SM_MONITOR_DELETE_PI_RESOURCE) (

+  IN STM_RSC *ResourceList OPTIONAL,

+  IN UINT32   NumEntries OPTIONAL

+  );

+

+/**

+

+  Get BIOS resources.

+

+  @param ResourceList  A pointer to resource list to be filled

+  @param ResourceSize  On input it means size of resource list input.

+                       On output it means size of resource list filled,

+                       or the size of resource list to be filled if size of too small.

+

+  @retval EFI_SUCCESS            If resources are returned.

+  @retval EFI_BUFFER_TOO_SMALL   If resource list buffer is too small to hold the whole resources.

+

+**/

+typedef

+EFI_STATUS

+(EFIAPI *EFI_SM_MONITOR_GET_PI_RESOURCE) (

+  OUT    STM_RSC *ResourceList,

+  IN OUT UINT32  *ResourceSize

+  );

+

+typedef UINT32 EFI_SM_MONITOR_STATE;

+#define EFI_SM_MONITOR_STATE_ENABLED     0x1

+#define EFI_SM_MONITOR_STATE_ACTIVATED   0x2

+

+/**

+

+  Get STM state

+

+  @return STM state

+

+**/

+typedef

+EFI_SM_MONITOR_STATE

+(EFIAPI *EFI_SM_MONITOR_GET_MONITOR_STATE) (

+  VOID

+  );

+

+typedef struct _EFI_SM_MONITOR_INIT_PROTOCOL {

+  //

+  // Valid at boot-time only

+  //

+  EFI_SM_MONITOR_LOAD_MONITOR                      LoadMonitor;

+  EFI_SM_MONITOR_ADD_PI_RESOURCE                   AddPiResource;

+  EFI_SM_MONITOR_DELETE_PI_RESOURCE                DeletePiResource;

+  EFI_SM_MONITOR_GET_PI_RESOURCE                   GetPiResource;

+  //

+  // Valid at runtime

+  //

+  EFI_SM_MONITOR_GET_MONITOR_STATE                 GetMonitorState;

+} EFI_SM_MONITOR_INIT_PROTOCOL;

+

+extern EFI_GUID gEfiSmMonitorInitProtocolGuid;

+

+#endif

diff --git a/UefiCpuPkg/Include/Register/StmApi.h b/UefiCpuPkg/Include/Register/StmApi.h
new file mode 100644
index 0000000..6fb5971
--- /dev/null
+++ b/UefiCpuPkg/Include/Register/StmApi.h
@@ -0,0 +1,954 @@
+/** @file

+  STM API definition

+

+  Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php.

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+  @par Specification Reference:

+  SMI Transfer Monitor (STM) User Guide Revision 1.00

+

+**/

+

+#ifndef _STM_API_H_

+#define _STM_API_H_

+

+#include <Register/StmStatusCode.h>

+#include <Register/StmResourceDescriptor.h>

+#include <Register/ArchitecturalMsr.h>

+

+#pragma pack (1)

+

+/**

+  STM Header Structures

+**/

+

+typedef struct {

+  UINT32  Intel64ModeSupported :1;  ///> bitfield

+  UINT32  EptSupported         :1;  ///> bitfield

+  UINT32  Reserved             :30; ///> must be 0

+} STM_FEAT;

+

+#define STM_SPEC_VERSION_MAJOR  1

+#define STM_SPEC_VERSION_MINOR  0

+

+typedef struct {

+  UINT8     StmSpecVerMajor;

+  UINT8     StmSpecVerMinor;

+  ///

+  /// Must be zero

+  ///

+  UINT16    Reserved;

+  UINT32    StaticImageSize;

+  UINT32    PerProcDynamicMemorySize;

+  UINT32    AdditionalDynamicMemorySize;

+  STM_FEAT  StmFeatures;

+  UINT32    NumberOfRevIDs;

+  UINT32    StmSmmRevID[1];

+  ///

+  /// The total STM_HEADER should be 4K.

+  ///

+} SOFTWARE_STM_HEADER;

+

+typedef struct {

+  MSEG_HEADER          HwStmHdr;

+  SOFTWARE_STM_HEADER  SwStmHdr;

+} STM_HEADER;

+

+

+/**

+  VMCALL API Numbers

+  API number convention: BIOS facing VMCALL interfaces have bit 16 clear

+**/

+

+/**

+  StmMapAddressRange enables a SMM guest to create a non-1:1 virtual to

+  physical mapping of an address range into the SMM guest's virtual

+  memory space.

+

+  @param  EAX  #STM_API_MAP_ADDRESS_RANGE (0x00000001)

+  @param  EBX  Low 32 bits of physical address of caller allocated

+               STM_MAP_ADDRESS_RANGE_DESCRIPTOR structure.

+  @param  ECX  High 32 bits of physical address of caller allocated

+               STM_MAP_ADDRESS_RANGE_DESCRIPTOR structure. If Intel64Mode is

+               clear (0), ECX must be 0.

+

+  @note  All fields of STM_MAP_ADDRESS_RANGE_DESCRIPTOR are inputs only. They

+         are not modified by StmMapAddressRange.

+

+  @retval  CF   0

+                No error, EAX set to STM_SUCCESS.

+                The memory range was mapped as requested.

+  @retval  CF   1

+                An error occurred, EAX holds relevant error value.

+  @retval  EAX  #ERROR_STM_SECURITY_VIOLATION

+                The requested mapping contains a protected resource.

+  @retval  EAX  #ERROR_STM_CACHE_TYPE_NOT_SUPPORTED

+                The requested cache type could not be satisfied.

+  @retval  EAX  #ERROR_STM_PAGE_NOT_FOUND

+                Page count must not be zero.

+  @retval  EAX  #ERROR_STM_FUNCTION_NOT_SUPPORTED

+                STM supports EPT and has not implemented StmMapAddressRange().

+  @retval  EAX  #ERROR_STM_UNSPECIFIED

+                An unspecified error occurred.

+

+  @note  All other registers unmodified.

+**/

+#define STM_API_MAP_ADDRESS_RANGE                  0x00000001

+

+/**

+  STM Map Address Range Descriptor for #STM_API_MAP_ADDRESS_RANGE VMCALL

+**/

+typedef struct {

+  UINT64  PhysicalAddress;

+  UINT64  VirtualAddress;

+  UINT32  PageCount;

+  UINT32  PatCacheType;

+} STM_MAP_ADDRESS_RANGE_DESCRIPTOR;

+

+/**

+  Define values for PatCacheType field of #STM_MAP_ADDRESS_RANGE_DESCRIPTOR

+  @{

+**/

+#define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_ST_UC        0x00

+#define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_WC           0x01

+#define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_WT           0x04

+#define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_WP           0x05

+#define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_WB           0x06

+#define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_UC           0x07

+#define STM_MAP_ADDRESS_RANGE_PAT_CACHE_TYPE_FOLLOW_MTRR  0xFFFFFFFF

+/// @}

+

+/**

+  StmUnmapAddressRange enables a SMM guest to remove mappings from its page

+  table.

+

+  If TXT_PROCESSOR_SMM_DESCRIPTOR.EptEnabled bit is set by the STM, BIOS can

+  control its own page tables. In this case, the STM implementation may

+  optionally return ERROR_STM_FUNCTION_NOT_SUPPORTED.

+

+  @param  EAX  #STM_API_UNMAP_ADDRESS_RANGE (0x00000002)

+  @param  EBX  Low 32 bits of virtual address of caller allocated

+               STM_UNMAP_ADDRESS_RANGE_DESCRIPTOR structure.

+  @param  ECX  High 32 bits of virtual address of caller allocated

+               STM_UNMAP_ADDRESS_RANGE_DESCRIPTOR structure. If Intel64Mode is

+               clear (0), ECX must be zero.

+

+  @retval  CF   0

+                No error, EAX set to STM_SUCCESS. The memory range was unmapped

+                as requested.

+  @retval  CF   1

+                An error occurred, EAX holds relevant error value.

+  @retval  EAX  #ERROR_STM_FUNCTION_NOT_SUPPORTED

+                STM supports EPT and has not implemented StmUnmapAddressRange().

+  @retval  EAX  #ERROR_STM_UNSPECIFIED

+                An unspecified error occurred.

+

+  @note  All other registers unmodified.

+**/

+#define STM_API_UNMAP_ADDRESS_RANGE                0x00000002

+

+/**

+  STM Unmap Address Range Descriptor for #STM_API_UNMAP_ADDRESS_RANGE VMCALL

+**/

+typedef struct {

+  UINT64  VirtualAddress;

+  UINT32  Length;

+} STM_UNMAP_ADDRESS_RANGE_DESCRIPTOR;

+

+

+/**

+  Since the normal OS environment runs with a different set of page tables than

+  the SMM guest, virtual mappings will certainly be different. In order to do a

+  guest virtual to host physical translation of an address from the normal OS

+  code (EIP for example), it is necessary to walk the page tables governing the

+  OS page mappings. Since the SMM guest has no direct access to the page tables,

+  it must ask the STM to do this page table walk. This is supported via the

+  StmAddressLookup VMCALL. All OS page table formats need to be supported,

+  (e.g. PAE, PSE, Intel64, EPT, etc.)

+

+  StmAddressLookup takes a CR3 value and a virtual address from the interrupted

+  code as input and returns the corresponding physical address. It also

+  optionally maps the physical address into the SMM guest's virtual address

+  space. This new mapping persists ONLY for the duration of the SMI and if

+  needed in subsequent SMIs it must be remapped. PAT cache types follow the

+  interrupted environment's page table.

+

+  If EPT is enabled, OS CR3 only provides guest physical address information,

+  but the SMM guest might also need to know the host physical address. Since

+  SMM does not have direct access rights to EPT (it is protected by the STM),

+  SMM can input InterruptedEptp to let STM help to walk through it, and output

+  the host physical address.

+

+  @param  EAX  #STM_API_ADDRESS_LOOKUP (0x00000003)

+  @param  EBX  Low 32 bits of virtual address of caller allocated

+               STM_ADDRESS_LOOKUP_DESCRIPTOR structure.

+  @param  ECX  High 32 bits of virtual address of caller allocated

+               STM_ADDRESS_LOOKUP_DESCRIPTOR structure. If Intel64Mode is

+               clear (0), ECX must be zero.

+

+  @retval  CF   0

+                No error, EAX set to STM_SUCCESS.  PhysicalAddress contains the

+                host physical address determined by walking the interrupted SMM

+                guest's page tables.  SmmGuestVirtualAddress contains the SMM

+                guest's virtual mapping of the requested address.

+  @retval  CF   1

+                An error occurred, EAX holds relevant error value.

+  @retval  EAX  #ERROR_STM_SECURITY_VIOLATION

+                The requested page was a protected page.

+  @retval  EAX  #ERROR_STM_PAGE_NOT_FOUND

+                The requested virtual address did not exist in the page given

+                page table.

+  @retval  EAX  #ERROR_STM_BAD_CR3

+                The CR3 input was invalid. CR3 values must be from one of the

+                interrupted guest, or from the interrupted guest of another

+                processor.

+  @retval  EAX  #ERROR_STM_PHYSICAL_OVER_4G

+                The resulting physical address is greater than 4G and no virtual

+                address was supplied. The STM could not determine what address

+                within the SMM guest's virtual address space to do the mapping.

+                STM_ADDRESS_LOOKUP_DESCRIPTOR field PhysicalAddress contains the

+                physical address determined by walking the interrupted

+                environment's page tables.

+  @retval  EAX  #ERROR_STM_VIRTUAL_SPACE_TOO_SMALL

+                A specific virtual mapping was requested, but

+                SmmGuestVirtualAddress + Length exceeds 4G and the SMI handler

+                is running in 32 bit mode.

+  @retval  EAX  #ERROR_STM_UNSPECIFIED

+                An unspecified error occurred.

+

+  @note  All other registers unmodified.

+**/

+#define STM_API_ADDRESS_LOOKUP                     0x00000003

+

+/**

+  STM Lookup Address Range Descriptor for #STM_API_ADDRESS_LOOKUP VMCALL

+**/

+typedef struct {

+  UINT64  InterruptedGuestVirtualAddress;

+  UINT32  Length;

+  UINT64  InterruptedCr3;

+  UINT64  InterruptedEptp;

+  UINT32  MapToSmmGuest:2;

+  UINT32  InterruptedCr4Pae:1;

+  UINT32  InterruptedCr4Pse:1;

+  UINT32  InterruptedIa32eMode:1;

+  UINT32  Reserved1:27;

+  UINT32  Reserved2;

+  UINT64  PhysicalAddress;

+  UINT64  SmmGuestVirtualAddress;

+} STM_ADDRESS_LOOKUP_DESCRIPTOR;

+

+/**

+  Define values for the MapToSmmGuest field of #STM_ADDRESS_LOOKUP_DESCRIPTOR

+  @{

+**/

+#define STM_ADDRESS_LOOKUP_DESCRIPTOR_DO_NOT_MAP                 0

+#define STM_ADDRESS_LOOKUP_DESCRIPTOR_ONE_TO_ONE                 1

+#define STM_ADDRESS_LOOKUP_DESCRIPTOR_VIRTUAL_ADDRESS_SPECIFIED  3

+/// @}

+

+

+/**

+  When returning from a protection exception (see section 6.2), the SMM guest

+  can instruct the STM to take one of two paths. It can either request a value

+  be logged to the TXT.ERRORCODE register and subsequently reset the machine

+  (indicating it couldn't resolve the problem), or it can request that the STM

+  resume the SMM guest again with the specified register state.

+

+  Unlike other VMCALL interfaces, StmReturnFromProtectionException behaves more

+  like a jump or an IRET instruction than a "call". It does not return directly

+  to the caller, but indirectly to a different location specified on the

+  caller's stack (see section 6.2) or not at all.

+

+  If the SMM guest STM protection exception handler itself causes a protection

+  exception (e.g. a single nested exception), or more than 100 un-nested

+  exceptions occur within the scope of a single SMI event, the STM must write

+  STM_CRASH_PROTECTION_EXCEPTION_FAILURE to the TXT.ERRORCODE register and

+  assert TXT.CMD.SYS_RESET. The reason for these restrictions is to simplify

+  the code requirements while still enabling a reasonable debugging capability.

+

+  @param  EAX  #STM_API_RETURN_FROM_PROTECTION_EXCEPTION (0x00000004)

+  @param  EBX  If 0, resume SMM guest using register state found on exception

+               stack.  If in range 0x01..0x0F, EBX contains a BIOS error code

+               which the STM must record in the TXT.ERRORCODE register and

+               subsequently reset the system via TXT.CMD.SYS_RESET. The value

+               of the TXT.ERRORCODE register is calculated as follows:

+

+                 TXT.ERRORCODE = (EBX & 0x0F) | STM_CRASH_BIOS_PANIC

+

+               Values 0x10..0xFFFFFFFF are reserved, do not use.

+

+**/

+#define STM_API_RETURN_FROM_PROTECTION_EXCEPTION   0x00000004

+

+

+/**

+  VMCALL API Numbers

+  API number convention: MLE facing VMCALL interfaces have bit 16 set.

+

+  The STM configuration lifecycle is as follows:

+    1. SENTER->SINIT->MLE: MLE begins execution with SMI disabled (masked).

+    2. MLE invokes #STM_API_INITIALIZE_PROTECTION VMCALL to prepare STM for

+       setup of initial protection profile. This is done on a single CPU and

+       has global effect.

+    3. MLE invokes #STM_API_PROTECT_RESOURCE VMCALL to define the initial

+       protection profile. The protection profile is global across all CPUs.

+    4. MLE invokes #STM_API_START VMCALL to enable the STM to begin receiving

+       SMI events. This must be done on every logical CPU.

+    5. MLE may invoke #STM_API_PROTECT_RESOURCE VMCALL or

+       #STM_API_UNPROTECT_RESOURCE VMCALL during runtime as many times as

+       necessary.

+    6. MLE invokes #STM_API_STOP VMCALL to disable the STM. SMI is again masked

+       following #STM_API_STOP VMCALL.

+**/

+

+/**

+  StartStmVmcall() is used to configure an STM that is present in MSEG. SMIs

+  should remain disabled from the invocation of GETSEC[SENTER] until they are

+  re-enabled by StartStmVMCALL(). When StartStmVMCALL() returns, SMI is

+  enabled and the STM has been started and is active. Prior to invoking

+  StartStmVMCALL(), the MLE root should first invoke

+  InitializeProtectionVMCALL() followed by as many iterations of

+  ProtectResourceVMCALL() as necessary to establish the initial protection

+  profile.  StartStmVmcall() must be invoked on all processor threads.

+

+  @param  EAX  #STM_API_START (0x00010001)

+  @param  EDX  STM configuration options. These provide the MLE with the

+               ability to pass configuration parameters to the STM.

+

+  @retval  CF   0

+                No error, EAX set to STM_SUCCESS. The STM has been configured

+                and is now active and the guarding all requested resources.

+  @retval  CF   1

+                An error occurred, EAX holds relevant error value.

+  @retval  EAX  #ERROR_STM_ALREADY_STARTED

+                The STM is already configured and active. STM remains active and

+                guarding previously enabled resource list.

+  @retval  EAX  #ERROR_STM_WITHOUT_SMX_UNSUPPORTED

+                The StartStmVMCALL() was invoked from VMX root mode, but outside

+                of SMX. This error code indicates the STM or platform does not

+                support the STM outside of SMX. The SMI handler remains active

+                and operates in legacy mode. See Appendix C

+  @retval  EAX  #ERROR_STM_UNSUPPORTED_MSR_BIT

+                The CPU doesn't support the MSR bit. The STM is not active.

+  @retval  EAX  #ERROR_STM_UNSPECIFIED

+                An unspecified error occurred.

+

+  @note  All other registers unmodified.

+**/

+#define STM_API_START                              (BIT16 | 1)

+

+/**

+  Bit values for EDX input parameter to #STM_API_START VMCALL

+  @{

+**/

+#define STM_CONFIG_SMI_UNBLOCKING_BY_VMX_OFF  BIT0

+/// @}

+

+

+/**

+  The StopStmVMCALL() is invoked by the MLE to teardown an active STM. This is

+  normally done as part of a full teardown of the SMX environment when the

+  system is being shut down. At the time the call is invoked, SMI is enabled

+  and the STM is active.  When the call returns, the STM has been stopped and

+  all STM context is discarded and SMI is disabled.

+

+  @param  EAX  #STM_API_STOP (0x00010002)

+

+  @retval  CF   0

+                No error, EAX set to STM_SUCCESS. The STM has been stopped and

+                is no longer processing SMI events. SMI is blocked.

+  @retval  CF   1

+                An error occurred, EAX holds relevant error value.

+  @retval  EAX  #ERROR_STM_STOPPED

+                The STM was not active.

+  @retval  EAX  #ERROR_STM_UNSPECIFIED

+                An unspecified error occurred.

+

+  @note  All other registers unmodified.

+**/

+#define STM_API_STOP                               (BIT16 | 2)

+

+

+/**

+  The ProtectResourceVMCALL() is invoked by the MLE root to request protection

+  of specific resources. The request is defined by a STM_RESOURCE_LIST, which

+  may contain more than one resource descriptor. Each resource descriptor is

+  processed separately by the STM. Whether or not protection for any specific

+  resource is granted is returned by the STM via the ReturnStatus bit in the

+  associated STM_RSC_DESC_HEADER.

+

+  @param  EAX  #STM_API_PROTECT_RESOURCE (0x00010003)

+  @param  EBX  Low 32 bits of physical address of caller allocated

+               STM_RESOURCE_LIST. Bits 11:0 are ignored and assumed to be zero,

+               making the buffer 4K aligned.

+  @param  ECX  High 32 bits of physical address of caller allocated

+               STM_RESOURCE_LIST.

+

+  @note  All fields of STM_RESOURCE_LIST are inputs only, except for the

+         ReturnStatus bit. On input, the ReturnStatus bit must be clear. On

+         return, the ReturnStatus bit is set for each resource request granted,

+         and clear for each resource request denied. There are no other fields

+         modified by ProtectResourceVMCALL(). The STM_RESOURCE_LIST must be

+         contained entirely within a single 4K page.

+

+  @retval  CF   0

+                No error, EAX set to STM_SUCCESS. The STM has successfully

+                merged the entire protection request into the active protection

+                profile.  There is therefore no need to check the ReturnStatus

+                bits in the STM_RESOURCE_LIST.

+  @retval  CF   1

+                An error occurred, EAX holds relevant error value.

+  @retval  EAX  #ERROR_STM_UNPROTECTABLE_RESOURCE

+                At least one of the requested resource protections intersects a

+                BIOS required resource. Therefore, the caller must walk through

+                the STM_RESOURCE_LIST to determine which of the requested

+                resources was not granted protection. The entire list must be

+                traversed since there may be multiple failures.

+  @retval  EAX  #ERROR_STM_MALFORMED_RESOURCE_LIST

+                The resource list could not be parsed correctly, or did not

+                terminate before crossing a 4K page boundary. The caller must

+                walk through the STM_RESOURCE_LIST to determine which of the

+                requested resources was not granted protection. The entire list

+                must be traversed since there may be multiple failures.

+  @retval  EAX  #ERROR_STM_OUT_OF_RESOURCES

+                The STM has encountered an internal error and cannot complete

+                the request.

+  @retval  EAX  #ERROR_STM_UNSPECIFIED

+                An unspecified error occurred.

+

+  @note  All other registers unmodified.

+**/

+#define STM_API_PROTECT_RESOURCE                   (BIT16 | 3)

+

+

+/**

+  The UnProtectResourceVMCALL() is invoked by the MLE root to request that the

+  STM allow the SMI handler access to the specified resources.

+

+  @param  EAX  #STM_API_UNPROTECT_RESOURCE (0x00010004)

+  @param  EBX  Low 32 bits of physical address of caller allocated

+               STM_RESOURCE_LIST. Bits 11:0 are ignored and assumed to be zero,

+               making the buffer 4K aligned.

+  @param  ECX  High 32 bits of physical address of caller allocated

+               STM_RESOURCE_LIST.

+

+  @note  All fields of STM_RESOURCE_LIST are inputs only, except for the

+         ReturnStatus bit. On input, the ReturnStatus bit must be clear. On

+         return, the ReturnStatus bit is set for each resource processed. For

+         a properly formed STM_RESOURCE_LIST, this should be all resources

+         listed. There are no other fields modified by

+         UnProtectResourceVMCALL(). The STM_RESOURCE_LIST must be contained

+         entirely within a single 4K page.

+

+  @retval  CF   0

+                No error, EAX set to STM_SUCCESS. The requested resources are

+                not being guarded by the STM.

+  @retval  CF   1

+                An error occurred, EAX holds relevant error value.

+  @retval  EAX  #ERROR_STM_MALFORMED_RESOURCE_LIST

+                The resource list could not be parsed correctly, or did not

+                terminate before crossing a 4K page boundary. The caller must

+                walk through the STM_RESOURCE_LIST to determine which of the

+                requested resources were not able to be unprotected. The entire

+                list must be traversed since there may be multiple failures.

+  @retval  EAX  #ERROR_STM_UNSPECIFIED

+                An unspecified error occurred.

+

+  @note  All other registers unmodified.

+**/

+#define STM_API_UNPROTECT_RESOURCE                 (BIT16 | 4)

+

+

+/**

+  The GetBiosResourcesVMCALL() is invoked by the MLE root to request the list

+  of BIOS required resources from the STM.

+

+  @param  EAX  #STM_API_GET_BIOS_RESOURCES (0x00010005)

+  @param  EBX  Low 32 bits of physical address of caller allocated destination

+               buffer. Bits 11:0 are ignored and assumed to be zero, making the

+               buffer 4K aligned.

+  @param  ECX  High 32 bits of physical address of caller allocated destination

+               buffer.

+  @param  EDX  Indicates which page of the BIOS resource list to copy into the

+               destination buffer. The first page is indicated by 0, the second

+               page by 1, etc.

+

+  @retval  CF   0

+                No error, EAX set to STM_SUCCESS. The destination buffer

+                contains the BIOS required resources. If the page retrieved is

+                the last page, EDX will be cleared to 0. If there are more pages

+                to retrieve, EDX is incremented to the next page index. Calling

+                software should iterate on GetBiosResourcesVMCALL() until EDX is

+                returned cleared to 0.

+  @retval  CF   1

+                An error occurred, EAX holds relevant error value.

+  @retval  EAX  #ERROR_STM_PAGE_NOT_FOUND

+                The page index supplied in EDX input was out of range.

+  @retval  EAX  #ERROR_STM_UNSPECIFIED

+                An unspecified error occurred.

+  @retval  EDX  Page index of next page to read. A return of EDX=0 signifies

+                that the entire list has been read.

+                @note  EDX is both an input and an output register.

+

+  @note  All other registers unmodified.

+**/

+#define STM_API_GET_BIOS_RESOURCES                 (BIT16 | 5)

+

+

+/**

+  The ManageVmcsDatabaseVMCALL() is invoked by the MLE root to add or remove an

+  MLE guest (including the MLE root) from the list of protected domains.

+

+  @param  EAX  #STM_API_MANAGE_VMCS_DATABASE (0x00010006)

+  @param  EBX  Low 32 bits of physical address of caller allocated

+               STM_VMCS_DATABASE_REQUEST. Bits 11:0 are ignored and assumed to

+               be zero, making the buffer 4K aligned.

+  @param  ECX  High 32 bits of physical address of caller allocated

+               STM_VMCS_DATABASE_REQUEST.

+

+  @note  All fields of STM_VMCS_DATABASE_REQUEST are inputs only.  They are not

+         modified by ManageVmcsDatabaseVMCALL().

+

+  @retval  CF   0

+                No error, EAX set to STM_SUCCESS.

+  @retval  CF   1

+                An error occurred, EAX holds relevant error value.

+  @retval  EAX  #ERROR_STM_INVALID_VMCS

+                Indicates a request to remove a VMCS from the database was made,

+                but the referenced VMCS was not found in the database.

+  @retval  EAX  #ERROR_STM_VMCS_PRESENT

+                Indicates a request to add a VMCS to the database was made, but

+                the referenced VMCS was already present in the database.

+  @retval  EAX  #ERROR_INVALID_PARAMETER

+                Indicates non-zero reserved field.

+  @retval  EAX  #ERROR_STM_UNSPECIFIED

+                An unspecified error occurred

+

+  @note  All other registers unmodified.

+**/

+#define STM_API_MANAGE_VMCS_DATABASE               (BIT16 | 6)

+

+/**

+  STM VMCS Database Request for #STM_API_MANAGE_VMCS_DATABASE VMCALL

+**/

+typedef struct {

+  ///

+  /// bits 11:0 are reserved and must be 0

+  ///

+  UINT64  VmcsPhysPointer;

+  UINT32  DomainType :4;

+  UINT32  XStatePolicy :2;

+  UINT32  DegradationPolicy :4;

+  ///

+  /// Must be 0

+  ///

+  UINT32  Reserved1 :22;

+  UINT32  AddOrRemove;

+} STM_VMCS_DATABASE_REQUEST;

+

+/**

+  Values for the DomainType field of #STM_VMCS_DATABASE_REQUEST

+  @{

+**/

+#define DOMAIN_UNPROTECTED            0

+#define DOMAIN_DISALLOWED_IO_OUT      BIT0

+#define DOMAIN_DISALLOWED_IO_IN       BIT1

+#define DOMAIN_INTEGRITY              BIT2

+#define DOMAIN_CONFIDENTIALITY        BIT3

+#define DOMAIN_INTEGRITY_PROT_OUT_IN  (DOMAIN_INTEGRITY)

+#define DOMAIN_FULLY_PROT_OUT_IN      (DOMAIN_CONFIDENTIALITY | DOMAIN_INTEGRITY)

+#define DOMAIN_FULLY_PROT             (DOMAIN_FULLY_PROT_OUT_IN | DOMAIN_DISALLOWED_IO_IN | DOMAIN_DISALLOWED_IO_OUT)

+/// @}

+

+/**

+  Values for the XStatePolicy field of #STM_VMCS_DATABASE_REQUEST

+  @{

+**/

+#define XSTATE_READWRITE  0x00

+#define XSTATE_READONLY   0x01

+#define XSTATE_SCRUB      0x03

+/// @}

+

+/**

+  Values for the AddOrRemove field of #STM_VMCS_DATABASE_REQUEST

+  @{

+**/

+#define STM_VMCS_DATABASE_REQUEST_ADD     1

+#define STM_VMCS_DATABASE_REQUEST_REMOVE  0

+/// @}

+

+

+/**

+  InitializeProtectionVMCALL() prepares the STM for setup of the initial

+  protection profile which is subsequently communicated via one or more

+  invocations of ProtectResourceVMCALL(), prior to invoking StartStmVMCALL().

+  It is only necessary to invoke InitializeProtectionVMCALL() on one processor

+  thread.  InitializeProtectionVMCALL() does not alter whether SMIs are masked

+  or unmasked. The STM should return back to the MLE with "Blocking by SMI" set

+  to 1 in the GUEST_INTERRUPTIBILITY field for the VMCS the STM created for the

+  MLE guest.

+

+  @param  EAX  #STM_API_INITIALIZE_PROTECTION (0x00010007)

+

+  @retval  CF   0

+                No error, EAX set to STM_SUCCESS, EBX bits set to indicate STM

+                capabilities as defined below. The STM has set up an empty

+                protection profile, except for the resources that it sets up to

+                protect itself. The STM must not allow the SMI handler to map

+                any pages from the MSEG Base to the top of TSEG. The STM must

+                also not allow SMI handler access to those MSRs which the STM

+                requires for its own protection.

+  @retval  CF   1

+                An error occurred, EAX holds relevant error value.

+  @retval  EAX  #ERROR_STM_ALREADY_STARTED

+                The STM is already configured and active. The STM remains active

+                and guarding the previously enabled resource list.

+  @retval  EAX  #ERROR_STM_UNPROTECTABLE

+                The STM determines that based on the platform configuration, the

+                STM is unable to protect itself. For example, the BIOS required

+                resource list contains memory pages in MSEG.

+  @retval  EAX  #ERROR_STM_UNSPECIFIED

+                An unspecified error occurred.

+

+  @note  All other registers unmodified.

+**/

+#define STM_API_INITIALIZE_PROTECTION              (BIT16 | 7)

+

+/**

+  Byte granular support bits returned in EBX from #STM_API_INITIALIZE_PROTECTION

+  @{

+**/

+#define STM_RSC_BGI  BIT1

+#define STM_RSC_BGM  BIT2

+#define STM_RSC_MSR  BIT3

+/// @}

+

+

+/**

+  The ManageEventLogVMCALL() is invoked by the MLE root to control the logging

+  feature. It consists of several sub-functions to facilitate establishment of

+  the log itself, configuring what events will be logged, and functions to

+  start, stop, and clear the log.

+

+  @param  EAX  #STM_API_MANAGE_EVENT_LOG (0x00010008)

+  @param  EBX  Low 32 bits of physical address of caller allocated

+               STM_EVENT_LOG_MANAGEMENT_REQUEST. Bits 11:0 are ignored and

+               assumed to be zero, making the buffer 4K aligned.

+  @param  ECX  High 32 bits of physical address of caller allocated

+               STM_EVENT_LOG_MANAGEMENT_REQUEST.

+

+  @retval  CF=0

+           No error, EAX set to STM_SUCCESS.

+  @retval  CF=1

+           An error occurred, EAX holds relevant error value. See subfunction

+           descriptions below for details.

+

+  @note  All other registers unmodified.

+**/

+#define STM_API_MANAGE_EVENT_LOG                   (BIT16 | 8)

+

+///

+/// STM Event Log Management Request for #STM_API_MANAGE_EVENT_LOG VMCALL

+///

+typedef struct {

+  UINT32      SubFunctionIndex;

+  union {

+    struct {

+      UINT32  PageCount;

+      //

+      // number of elements is PageCount

+      //

+      UINT64  Pages[];

+    } LogBuffer;

+    //

+    // bitmap of EVENT_TYPE

+    //

+    UINT32    EventEnableBitmap;

+  } Data;

+} STM_EVENT_LOG_MANAGEMENT_REQUEST;

+

+/**

+  Defines values for the SubFunctionIndex field of

+  #STM_EVENT_LOG_MANAGEMENT_REQUEST

+  @{

+**/

+#define STM_EVENT_LOG_MANAGEMENT_REQUEST_NEW_LOG        1

+#define STM_EVENT_LOG_MANAGEMENT_REQUEST_CONFIGURE_LOG  2

+#define STM_EVENT_LOG_MANAGEMENT_REQUEST_START_LOG      3

+#define STM_EVENT_LOG_MANAGEMENT_REQUEST_STOP_LOG       4

+#define STM_EVENT_LOG_MANAGEMENT_REQUEST_CLEAR_LOG      5

+#define STM_EVENT_LOG_MANAGEMENT_REQUEST_DELETE_LOG     6

+/// @}

+

+/**

+  Log Entry Header

+**/

+typedef struct {

+  UINT32  EventSerialNumber;

+  UINT16  Type;

+  UINT16  Lock :1;

+  UINT16  Valid :1;

+  UINT16  ReadByMle :1;

+  UINT16  Wrapped :1;

+  UINT16  Reserved :12;

+} LOG_ENTRY_HEADER;

+

+/**

+  Enum values for the Type field of #LOG_ENTRY_HEADER

+**/

+typedef enum {

+  EvtLogStarted,

+  EvtLogStopped,

+  EvtLogInvalidParameterDetected,

+  EvtHandledProtectionException,

+  ///

+  /// unhandled protection exceptions result in reset & cannot be logged

+  ///

+  EvtBiosAccessToUnclaimedResource,

+  EvtMleResourceProtectionGranted,

+  EvtMleResourceProtectionDenied,

+  EvtMleResourceUnprotect,

+  EvtMleResourceUnprotectError,

+  EvtMleDomainTypeDegraded,

+  ///

+  /// add more here

+  ///

+  EvtMleMax,

+  ///

+  /// Not used

+  ///

+  EvtInvalid = 0xFFFFFFFF,

+} EVENT_TYPE;

+

+typedef struct {

+  UINT32  Reserved;

+} ENTRY_EVT_LOG_STARTED;

+

+typedef struct {

+  UINT32  Reserved;

+} ENTRY_EVT_LOG_STOPPED;

+

+typedef struct {

+  UINT32  VmcallApiNumber;

+} ENTRY_EVT_LOG_INVALID_PARAM;

+

+typedef struct {

+  STM_RSC  Resource;

+} ENTRY_EVT_LOG_HANDLED_PROTECTION_EXCEPTION;

+

+typedef struct {

+  STM_RSC  Resource;

+} ENTRY_EVT_BIOS_ACCESS_UNCLAIMED_RSC;

+

+typedef struct {

+  STM_RSC  Resource;

+} ENTRY_EVT_MLE_RSC_PROT_GRANTED;

+

+typedef struct {

+  STM_RSC  Resource;

+} ENTRY_EVT_MLE_RSC_PROT_DENIED;

+

+typedef struct {

+  STM_RSC  Resource;

+} ENTRY_EVT_MLE_RSC_UNPROT;

+

+typedef struct {

+  STM_RSC  Resource;

+} ENTRY_EVT_MLE_RSC_UNPROT_ERROR;

+

+typedef struct {

+  UINT64  VmcsPhysPointer;

+  UINT8   ExpectedDomainType;

+  UINT8   DegradedDomainType;

+} ENTRY_EVT_MLE_DOMAIN_TYPE_DEGRADED;

+

+typedef union {

+  ENTRY_EVT_LOG_STARTED                       Started;

+  ENTRY_EVT_LOG_STOPPED                       Stopped;

+  ENTRY_EVT_LOG_INVALID_PARAM                 InvalidParam;

+  ENTRY_EVT_LOG_HANDLED_PROTECTION_EXCEPTION  HandledProtectionException;

+  ENTRY_EVT_BIOS_ACCESS_UNCLAIMED_RSC         BiosUnclaimedRsc;

+  ENTRY_EVT_MLE_RSC_PROT_GRANTED              MleRscProtGranted;

+  ENTRY_EVT_MLE_RSC_PROT_DENIED               MleRscProtDenied;

+  ENTRY_EVT_MLE_RSC_UNPROT                    MleRscUnprot;

+  ENTRY_EVT_MLE_RSC_UNPROT_ERROR              MleRscUnprotError;

+  ENTRY_EVT_MLE_DOMAIN_TYPE_DEGRADED          MleDomainTypeDegraded;

+} LOG_ENTRY_DATA;

+

+typedef struct {

+  LOG_ENTRY_HEADER  Hdr;

+  LOG_ENTRY_DATA    Data;

+} STM_LOG_ENTRY;

+

+/**

+  Maximum STM Log Entry Size

+**/

+#define STM_LOG_ENTRY_SIZE  256

+

+

+/**

+  STM Protection Exception Stack Frame Structures

+**/

+

+typedef struct {

+  UINT32  Rdi;

+  UINT32  Rsi;

+  UINT32  Rbp;

+  UINT32  Rdx;

+  UINT32  Rcx;

+  UINT32  Rbx;

+  UINT32  Rax;

+  UINT32  Cr3;

+  UINT32  Cr2;

+  UINT32  Cr0;

+  UINT32  VmcsExitInstructionInfo;

+  UINT32  VmcsExitInstructionLength;

+  UINT64  VmcsExitQualification;

+  ///

+  /// An TXT_SMM_PROTECTION_EXCEPTION_TYPE num value

+  ///

+  UINT32  ErrorCode;

+  UINT32  Rip;

+  UINT32  Cs;

+  UINT32  Rflags;

+  UINT32  Rsp;

+  UINT32  Ss;

+} STM_PROTECTION_EXCEPTION_STACK_FRAME_IA32;

+

+typedef struct {

+  UINT64  R15;

+  UINT64  R14;

+  UINT64  R13;

+  UINT64  R12;

+  UINT64  R11;

+  UINT64  R10;

+  UINT64  R9;

+  UINT64  R8;

+  UINT64  Rdi;

+  UINT64  Rsi;

+  UINT64  Rbp;

+  UINT64  Rdx;

+  UINT64  Rcx;

+  UINT64  Rbx;

+  UINT64  Rax;

+  UINT64  Cr8;

+  UINT64  Cr3;

+  UINT64  Cr2;

+  UINT64  Cr0;

+  UINT64  VmcsExitInstructionInfo;

+  UINT64  VmcsExitInstructionLength;

+  UINT64  VmcsExitQualification;

+  ///

+  /// An TXT_SMM_PROTECTION_EXCEPTION_TYPE num value

+  ///

+  UINT64  ErrorCode;

+  UINT64  Rip;

+  UINT64  Cs;

+  UINT64  Rflags;

+  UINT64  Rsp;

+  UINT64  Ss;

+} STM_PROTECTION_EXCEPTION_STACK_FRAME_X64;

+

+typedef union {

+  STM_PROTECTION_EXCEPTION_STACK_FRAME_IA32  *Ia32StackFrame;

+  STM_PROTECTION_EXCEPTION_STACK_FRAME_X64   *X64StackFrame;

+} STM_PROTECTION_EXCEPTION_STACK_FRAME;

+

+/**

+  Enum values for the ErrorCode field in

+  #STM_PROTECTION_EXCEPTION_STACK_FRAME_IA32 and

+  #STM_PROTECTION_EXCEPTION_STACK_FRAME_X64

+**/

+typedef enum {

+  TxtSmmPageViolation = 1,

+  TxtSmmMsrViolation,

+  TxtSmmRegisterViolation,

+  TxtSmmIoViolation,

+  TxtSmmPciViolation

+} TXT_SMM_PROTECTION_EXCEPTION_TYPE;

+

+/**

+  TXT Pocessor SMM Descriptor (PSD) structures

+**/

+

+typedef struct {

+  UINT64  SpeRip;

+  UINT64  SpeRsp;

+  UINT16  SpeSs;

+  UINT16  PageViolationException:1;

+  UINT16  MsrViolationException:1;

+  UINT16  RegisterViolationException:1;

+  UINT16  IoViolationException:1;

+  UINT16  PciViolationException:1;

+  UINT16  Reserved1:11;

+  UINT32  Reserved2;

+} STM_PROTECTION_EXCEPTION_HANDLER;

+

+typedef struct {

+  UINT8  ExecutionDisableOutsideSmrr:1;

+  UINT8  Intel64Mode:1;

+  UINT8  Cr4Pae : 1;

+  UINT8  Cr4Pse : 1;

+  UINT8  Reserved1 : 4;

+} STM_SMM_ENTRY_STATE;

+

+typedef struct {

+  UINT8  SmramToVmcsRestoreRequired : 1; ///> BIOS restore hint

+  UINT8  ReinitializeVmcsRequired : 1;   ///> BIOS request

+  UINT8  Reserved2 : 6;

+} STM_SMM_RESUME_STATE;

+

+typedef struct {

+  UINT8  DomainType : 4;   ///> STM input to BIOS on each SMI

+  UINT8  XStatePolicy : 2; ///> STM input to BIOS on each SMI

+  UINT8  EptEnabled : 1;

+  UINT8  Reserved3 : 1;

+} STM_SMM_STATE;

+

+#define TXT_SMM_PSD_OFFSET                          0xfb00

+#define TXT_PROCESSOR_SMM_DESCRIPTOR_SIGNATURE      SIGNATURE_64('T', 'X', 'T', 'P', 'S', 'S', 'I', 'G')

+#define TXT_PROCESSOR_SMM_DESCRIPTOR_VERSION_MAJOR  1

+#define TXT_PROCESSOR_SMM_DESCRIPTOR_VERSION_MINOR  0

+

+typedef struct {

+  UINT64                            Signature;

+  UINT16                            Size;

+  UINT8                             SmmDescriptorVerMajor;

+  UINT8                             SmmDescriptorVerMinor;

+  UINT32                            LocalApicId;

+  STM_SMM_ENTRY_STATE               SmmEntryState;

+  STM_SMM_RESUME_STATE              SmmResumeState;

+  STM_SMM_STATE                     StmSmmState;

+  UINT8                             Reserved4;

+  UINT16                            SmmCs;

+  UINT16                            SmmDs;

+  UINT16                            SmmSs;

+  UINT16                            SmmOtherSegment;

+  UINT16                            SmmTr;

+  UINT16                            Reserved5;

+  UINT64                            SmmCr3;

+  UINT64                            SmmStmSetupRip;

+  UINT64                            SmmStmTeardownRip;

+  UINT64                            SmmSmiHandlerRip;

+  UINT64                            SmmSmiHandlerRsp;

+  UINT64                            SmmGdtPtr;

+  UINT32                            SmmGdtSize;

+  UINT32                            RequiredStmSmmRevId;

+  STM_PROTECTION_EXCEPTION_HANDLER  StmProtectionExceptionHandler;

+  UINT64                            Reserved6;

+  UINT64                            BiosHwResourceRequirementsPtr;

+  // extend area

+  UINT64                            AcpiRsdp;

+  UINT8                             PhysicalAddressBits;

+} TXT_PROCESSOR_SMM_DESCRIPTOR;

+

+#pragma pack ()

+

+#endif

diff --git a/UefiCpuPkg/Include/Register/StmResourceDescriptor.h b/UefiCpuPkg/Include/Register/StmResourceDescriptor.h
new file mode 100644
index 0000000..1518462
--- /dev/null
+++ b/UefiCpuPkg/Include/Register/StmResourceDescriptor.h
@@ -0,0 +1,228 @@
+/** @file

+  STM Resource Descriptor

+

+  Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php.

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+  @par Specification Reference:

+  SMI Transfer Monitor (STM) User Guide Revision 1.00

+

+**/

+

+#ifndef _STM_RESOURCE_DESCRIPTOR_H_

+#define _STM_RESOURCE_DESCRIPTOR_H_

+

+#pragma pack (1)

+

+/**

+  STM Resource Descriptor Header

+**/

+typedef struct {

+  UINT32  RscType;

+  UINT16  Length;

+  UINT16  ReturnStatus:1;

+  UINT16  Reserved:14;

+  UINT16  IgnoreResource:1;

+} STM_RSC_DESC_HEADER;

+

+/**

+  Define values for the RscType field of #STM_RSC_DESC_HEADER

+  @{

+**/

+#define END_OF_RESOURCES      0

+#define MEM_RANGE             1

+#define IO_RANGE              2

+#define MMIO_RANGE            3

+#define MACHINE_SPECIFIC_REG  4

+#define PCI_CFG_RANGE         5

+#define TRAPPED_IO_RANGE      6

+#define ALL_RESOURCES         7

+#define REGISTER_VIOLATION    8

+#define MAX_DESC_TYPE         8

+/// @}

+

+/**

+  STM Resource End Descriptor

+**/

+typedef struct {

+  STM_RSC_DESC_HEADER  Hdr;

+  UINT64               ResourceListContinuation;

+} STM_RSC_END;

+

+/**

+  STM Resource Memory Descriptor

+**/

+typedef struct {

+  STM_RSC_DESC_HEADER  Hdr;

+  UINT64               Base;

+  UINT64               Length;

+  UINT32               RWXAttributes:3;

+  UINT32               Reserved:29;

+  UINT32               Reserved_2;

+} STM_RSC_MEM_DESC;

+

+/**

+  Define values for the RWXAttributes field of #STM_RSC_MEM_DESC

+  @{

+**/

+#define STM_RSC_MEM_R  0x1

+#define STM_RSC_MEM_W  0x2

+#define STM_RSC_MEM_X  0x4

+/// @}

+

+/**

+  STM Resource I/O Descriptor

+**/

+typedef struct {

+  STM_RSC_DESC_HEADER  Hdr;

+  UINT16               Base;

+  UINT16               Length;

+  UINT32               Reserved;

+} STM_RSC_IO_DESC;

+

+/**

+  STM Resource MMIO Descriptor

+**/

+typedef struct {

+  STM_RSC_DESC_HEADER  Hdr;

+  UINT64               Base;

+  UINT64               Length;

+  UINT32               RWXAttributes:3;

+  UINT32               Reserved:29;

+  UINT32               Reserved_2;

+} STM_RSC_MMIO_DESC;

+

+/**

+  Define values for the RWXAttributes field of #STM_RSC_MMIO_DESC

+  @{

+**/

+#define STM_RSC_MMIO_R  0x1

+#define STM_RSC_MMIO_W  0x2

+#define STM_RSC_MMIO_X  0x4

+/// @}

+

+/**

+  STM Resource MSR Descriptor

+**/

+typedef struct {

+  STM_RSC_DESC_HEADER  Hdr;

+  UINT32               MsrIndex;

+  UINT32               KernelModeProcessing:1;

+  UINT32               Reserved:31;

+  UINT64               ReadMask;

+  UINT64               WriteMask;

+} STM_RSC_MSR_DESC;

+

+/**

+  STM PCI Device Path node used for the PciDevicePath field of

+  #STM_RSC_PCI_CFG_DESC

+**/

+typedef struct {

+  ///

+  /// Must be 1, indicating Hardware Device Path

+  ///

+  UINT8   Type;

+  ///

+  /// Must be 1, indicating PCI

+  ///

+  UINT8   Subtype;

+  ///

+  /// sizeof(STM_PCI_DEVICE_PATH_NODE) which is 6

+  ///

+  UINT16  Length;

+  UINT8   PciFunction;

+  UINT8   PciDevice;

+} STM_PCI_DEVICE_PATH_NODE;

+

+/**

+  STM Resource PCI Configuration Descriptor

+**/

+typedef struct {

+  STM_RSC_DESC_HEADER       Hdr;

+  UINT16                    RWAttributes:2;

+  UINT16                    Reserved:14;

+  UINT16                    Base;

+  UINT16                    Length;

+  UINT8                     OriginatingBusNumber;

+  UINT8                     LastNodeIndex;

+  STM_PCI_DEVICE_PATH_NODE  PciDevicePath[1];

+//STM_PCI_DEVICE_PATH_NODE  PciDevicePath[LastNodeIndex + 1];

+} STM_RSC_PCI_CFG_DESC;

+

+/**

+  Define values for the RWAttributes field of #STM_RSC_PCI_CFG_DESC

+  @{

+**/

+#define STM_RSC_PCI_CFG_R  0x1

+#define STM_RSC_PCI_CFG_W  0x2

+/// @}

+

+/**

+  STM Resource Trapped I/O Descriptor

+**/

+typedef struct {

+  STM_RSC_DESC_HEADER  Hdr;

+  UINT16               Base;

+  UINT16               Length;

+  UINT16               In:1;

+  UINT16               Out:1;

+  UINT16               Api:1;

+  UINT16               Reserved1:13;

+  UINT16               Reserved2;

+} STM_RSC_TRAPPED_IO_DESC;

+

+/**

+  STM Resource All Descriptor

+**/

+typedef struct {

+  STM_RSC_DESC_HEADER  Hdr;

+} STM_RSC_ALL_RESOURCES_DESC;

+

+/**

+  STM Register Volation Descriptor

+**/

+typedef struct {

+  STM_RSC_DESC_HEADER  Hdr;

+  UINT32               RegisterType;

+  UINT32               Reserved;

+  UINT64               ReadMask;

+  UINT64               WriteMask;

+} STM_REGISTER_VIOLATION_DESC;

+

+/**

+  Enum values for the RWAttributes field of #STM_REGISTER_VIOLATION_DESC

+**/

+typedef enum {

+  StmRegisterCr0,

+  StmRegisterCr2,

+  StmRegisterCr3,

+  StmRegisterCr4,

+  StmRegisterCr8,

+  StmRegisterMax,

+} STM_REGISTER_VIOLATION_TYPE;

+

+/**

+  Union of all STM resource types

+**/

+typedef union {

+  STM_RSC_DESC_HEADER          Header;

+  STM_RSC_END                  End;

+  STM_RSC_MEM_DESC             Mem;

+  STM_RSC_IO_DESC              Io;

+  STM_RSC_MMIO_DESC            Mmio;

+  STM_RSC_MSR_DESC             Msr;

+  STM_RSC_PCI_CFG_DESC         PciCfg;

+  STM_RSC_TRAPPED_IO_DESC      TrappedIo;

+  STM_RSC_ALL_RESOURCES_DESC   All;

+  STM_REGISTER_VIOLATION_DESC  RegisterViolation;

+} STM_RSC;

+

+#pragma pack ()

+

+#endif

diff --git a/UefiCpuPkg/Include/Register/StmStatusCode.h b/UefiCpuPkg/Include/Register/StmStatusCode.h
new file mode 100644
index 0000000..f1fcb8b6
--- /dev/null
+++ b/UefiCpuPkg/Include/Register/StmStatusCode.h
@@ -0,0 +1,78 @@
+/** @file

+  STM Status Codes

+

+  Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>

+  This program and the accompanying materials

+  are licensed and made available under the terms and conditions of the BSD License

+  which accompanies this distribution.  The full text of the license may be found at

+  http://opensource.org/licenses/bsd-license.php.

+

+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

+

+  @par Specification Reference:

+  SMI Transfer Monitor (STM) User Guide Revision 1.00

+

+**/

+

+#ifndef _STM_STATUS_CODE_H_

+#define _STM_STATUS_CODE_H_

+

+/**

+  STM Status Codes

+**/

+typedef UINT32  STM_STATUS;

+

+/**

+  Success code have BIT31 clear.

+  All error codes have BIT31 set.

+  STM errors have BIT16 set.

+  SMM errors have BIT17 set

+  Errors that apply to both STM and SMM have bits BIT15, BT16, and BIT17 set.

+  STM TXT.ERRORCODE codes have BIT30 set.

+  @{

+**/

+#define STM_SUCCESS                             0x00000000

+#define SMM_SUCCESS                             0x00000000

+#define ERROR_STM_SECURITY_VIOLATION            (BIT31 | BIT16 | 0x0001)

+#define ERROR_STM_CACHE_TYPE_NOT_SUPPORTED      (BIT31 | BIT16 | 0x0002)

+#define ERROR_STM_PAGE_NOT_FOUND                (BIT31 | BIT16 | 0x0003)

+#define ERROR_STM_BAD_CR3                       (BIT31 | BIT16 | 0x0004)

+#define ERROR_STM_PHYSICAL_OVER_4G              (BIT31 | BIT16 | 0x0005)

+#define ERROR_STM_VIRTUAL_SPACE_TOO_SMALL       (BIT31 | BIT16 | 0x0006)

+#define ERROR_STM_UNPROTECTABLE_RESOURCE        (BIT31 | BIT16 | 0x0007)

+#define ERROR_STM_ALREADY_STARTED               (BIT31 | BIT16 | 0x0008)

+#define ERROR_STM_WITHOUT_SMX_UNSUPPORTED       (BIT31 | BIT16 | 0x0009)

+#define ERROR_STM_STOPPED                       (BIT31 | BIT16 | 0x000A)

+#define ERROR_STM_BUFFER_TOO_SMALL              (BIT31 | BIT16 | 0x000B)

+#define ERROR_STM_INVALID_VMCS_DATABASE         (BIT31 | BIT16 | 0x000C)

+#define ERROR_STM_MALFORMED_RESOURCE_LIST       (BIT31 | BIT16 | 0x000D)

+#define ERROR_STM_INVALID_PAGECOUNT             (BIT31 | BIT16 | 0x000E)

+#define ERROR_STM_LOG_ALLOCATED                 (BIT31 | BIT16 | 0x000F)

+#define ERROR_STM_LOG_NOT_ALLOCATED             (BIT31 | BIT16 | 0x0010)

+#define ERROR_STM_LOG_NOT_STOPPED               (BIT31 | BIT16 | 0x0011)

+#define ERROR_STM_LOG_NOT_STARTED               (BIT31 | BIT16 | 0x0012)

+#define ERROR_STM_RESERVED_BIT_SET              (BIT31 | BIT16 | 0x0013)

+#define ERROR_STM_NO_EVENTS_ENABLED             (BIT31 | BIT16 | 0x0014)

+#define ERROR_STM_OUT_OF_RESOURCES              (BIT31 | BIT16 | 0x0015)

+#define ERROR_STM_FUNCTION_NOT_SUPPORTED        (BIT31 | BIT16 | 0x0016)

+#define ERROR_STM_UNPROTECTABLE                 (BIT31 | BIT16 | 0x0017)

+#define ERROR_STM_UNSUPPORTED_MSR_BIT           (BIT31 | BIT16 | 0x0018)

+#define ERROR_STM_UNSPECIFIED                   (BIT31 | BIT16 | 0xFFFF)

+#define ERROR_SMM_BAD_BUFFER                    (BIT31 | BIT17 | 0x0001)

+#define ERROR_SMM_INVALID_RSC                   (BIT31 | BIT17 | 0x0004)

+#define ERROR_SMM_INVALID_BUFFER_SIZE           (BIT31 | BIT17 | 0x0005)

+#define ERROR_SMM_BUFFER_TOO_SHORT              (BIT31 | BIT17 | 0x0006)

+#define ERROR_SMM_INVALID_LIST                  (BIT31 | BIT17 | 0x0007)

+#define ERROR_SMM_OUT_OF_MEMORY                 (BIT31 | BIT17 | 0x0008)

+#define ERROR_SMM_AFTER_INIT                    (BIT31 | BIT17 | 0x0009)

+#define ERROR_SMM_UNSPECIFIED                   (BIT31 | BIT17 | 0xFFFF)

+#define ERROR_INVALID_API                       (BIT31 | BIT17 | BIT16 | BIT15 | 0x0001)

+#define ERROR_INVALID_PARAMETER                 (BIT31 | BIT17 | BIT16 | BIT15 | 0x0002)

+#define STM_CRASH_PROTECTION_EXCEPTION          (BIT31 | BIT30 | 0xF001)

+#define STM_CRASH_PROTECTION_EXCEPTION_FAILURE  (BIT31 | BIT30 | 0xF002)

+#define STM_CRASH_DOMAIN_DEGRADATION_FAILURE    (BIT31 | BIT30 | 0xF003)

+#define STM_CRASH_BIOS_PANIC                    (BIT31 | BIT30 | 0xE000)

+/// @}

+

+#endif

diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
index ca56039..c37b4d5 100644
--- a/UefiCpuPkg/UefiCpuPkg.dec
+++ b/UefiCpuPkg/UefiCpuPkg.dec
@@ -60,6 +60,7 @@
 

 [Guids]

   gUefiCpuPkgTokenSpaceGuid      = { 0xac05bf33, 0x995a, 0x4ed4, { 0xaa, 0xb8, 0xef, 0x7a, 0xe8, 0xf, 0x5c, 0xb0 }}

+  gMsegSmramGuid                 = { 0x5802bce4, 0xeeee, 0x4e33, { 0xa1, 0x30, 0xeb, 0xad, 0x27, 0xf0, 0xe4, 0x39 }}

 

   ## Include/Guid/MicrocodeFmp.h

   gMicrocodeFmpImageTypeIdGuid      = { 0x96d4fdcd, 0x1502, 0x424d, { 0x9d, 0x4c, 0x9b, 0x12, 0xd2, 0xdc, 0xae, 0x5c } }

@@ -68,6 +69,9 @@
   ## Include/Protocol/SmmCpuService.h

   gEfiSmmCpuServiceProtocolGuid  = { 0x1d202cab, 0xc8ab, 0x4d5c, { 0x94, 0xf7, 0x3c, 0xfc, 0xc0, 0xd3, 0xd3, 0x35 }}

 

+  ## Include/Protocol/SmMonitorInit.h

+  gEfiSmMonitorInitProtocolGuid  = { 0x228f344d, 0xb3de, 0x43bb, { 0xa4, 0xd7, 0xea, 0x20, 0xb, 0x1b, 0x14, 0x82 }}

+

 #

 # [Error.gUefiCpuPkgTokenSpaceGuid]

 #   0x80000001 | Invalid value provided.

@@ -169,6 +173,14 @@
   # @Prompt Number of reserved variable MTRRs.

   gUefiCpuPkgTokenSpaceGuid.PcdCpuNumberOfReservedVariableMtrrs|0x2|UINT32|0x00000015

 

+  ## Specifies buffer size in bytes for STM exception stack. The value should be a multiple of 4KB.

+  # @Prompt STM exception stack size.

+  gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStmExceptionStackSize|0x1000|UINT32|0x32132111

+

+  ## Specifies buffer size in bytes of MSEG. The value should be a multiple of 4KB.

+  # @Prompt MSEG size.

+  gUefiCpuPkgTokenSpaceGuid.PcdCpuMsegSize|0x200000|UINT32|0x32132112

+

 [PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]

   ## Specifies max supported number of Logical Processors.

   # @Prompt Configure max supported number of Logical Processors