]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/CpuCommonFeaturesLib/FeatureControl.c
UefiCpuPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / UefiCpuPkg / Library / CpuCommonFeaturesLib / FeatureControl.c
index e627a65dfdfc1addfa229bcb529a61999120d52c..3712ef1e5cc9c5417491c08b3f0204a50a35a631 100644 (file)
-/** @file
-  Features in MSR_IA32_FEATURE_CONTROL register.
-
-  Copyright (c) 2017, 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.
-
-**/
-
-#include "CpuCommonFeatures.h"
-
-/**
-  Prepares for the data used by CPU feature detection and initialization.
-
-  @param[in]  NumberOfProcessors  The number of CPUs in the platform.
-
-  @return  Pointer to a buffer of CPU related configuration data.
-
-  @note This service could be called by BSP only.
-**/
-VOID *
-EFIAPI
-FeatureControlGetConfigData (
-  IN UINTN               NumberOfProcessors
-  )
-{
-  VOID          *ConfigData;
-
-  ConfigData = AllocateZeroPool (sizeof (MSR_IA32_FEATURE_CONTROL_REGISTER) * NumberOfProcessors);
-  ASSERT (ConfigData != NULL);
-  return ConfigData;
-}
-
-/**
-  Detects if VMX feature supported on current processor.
-
-  @param[in]  ProcessorNumber  The index of the CPU executing this function.
-  @param[in]  CpuInfo          A pointer to the REGISTER_CPU_FEATURE_INFORMATION
-                               structure for the CPU executing this function.
-  @param[in]  ConfigData       A pointer to the configuration buffer returned
-                               by CPU_FEATURE_GET_CONFIG_DATA.  NULL if
-                               CPU_FEATURE_GET_CONFIG_DATA was not provided in
-                               RegisterCpuFeature().
-
-  @retval TRUE     VMX feature is supported.
-  @retval FALSE    VMX feature is not supported.
-
-  @note This service could be called by BSP/APs.
-**/
-BOOLEAN
-EFIAPI
-VmxSupport (
-  IN UINTN                             ProcessorNumber,
-  IN REGISTER_CPU_FEATURE_INFORMATION  *CpuInfo,
-  IN VOID                              *ConfigData  OPTIONAL
-  )
-{
-  MSR_IA32_FEATURE_CONTROL_REGISTER    *MsrRegister;
-
-  ASSERT (ConfigData != NULL);
-  MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;
-  MsrRegister[ProcessorNumber].Uint64 = AsmReadMsr64 (MSR_IA32_FEATURE_CONTROL);
-  return (CpuInfo->CpuIdVersionInfoEcx.Bits.VMX == 1);
-}
-
-/**
-  Initializes VMX inside SMX feature to specific state.
-
-  @param[in]  ProcessorNumber  The index of the CPU executing this function.
-  @param[in]  CpuInfo          A pointer to the REGISTER_CPU_FEATURE_INFORMATION
-                               structure for the CPU executing this function.
-  @param[in]  ConfigData       A pointer to the configuration buffer returned
-                               by CPU_FEATURE_GET_CONFIG_DATA.  NULL if
-                               CPU_FEATURE_GET_CONFIG_DATA was not provided in
-                               RegisterCpuFeature().
-  @param[in]  State            If TRUE, then the VMX inside SMX feature must be enabled.
-                               If FALSE, then the VMX inside SMX feature must be disabled.
-
-  @retval RETURN_SUCCESS       VMX inside SMX feature is initialized.
-
-  @note This service could be called by BSP only.
-**/
-RETURN_STATUS
-EFIAPI
-VmxInsideSmxInitialize (
-  IN UINTN                             ProcessorNumber,
-  IN REGISTER_CPU_FEATURE_INFORMATION  *CpuInfo,
-  IN VOID                              *ConfigData,  OPTIONAL
-  IN BOOLEAN                           State
-  )
-{
-  MSR_IA32_FEATURE_CONTROL_REGISTER    *MsrRegister;
-
-  ASSERT (ConfigData != NULL);
-  MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;
-  if (MsrRegister[ProcessorNumber].Bits.Lock == 0) {
-    CPU_REGISTER_TABLE_WRITE_FIELD (
-      ProcessorNumber,
-      Msr,
-      MSR_IA32_FEATURE_CONTROL,
-      MSR_IA32_FEATURE_CONTROL_REGISTER,
-      Bits.EnableVmxInsideSmx,
-      (State) ? 1 : 0
-      );
-  }
-  return RETURN_SUCCESS;
-}
-
-/**
-  Initializes SENTER feature to specific state.
-
-  @param[in]  ProcessorNumber  The index of the CPU executing this function.
-  @param[in]  CpuInfo          A pointer to the REGISTER_CPU_FEATURE_INFORMATION
-                               structure for the CPU executing this function.
-  @param[in]  ConfigData       A pointer to the configuration buffer returned
-                               by CPU_FEATURE_GET_CONFIG_DATA.  NULL if
-                               CPU_FEATURE_GET_CONFIG_DATA was not provided in
-                               RegisterCpuFeature().
-  @param[in]  State            If TRUE, then the SENTER feature must be enabled.
-                               If FALSE, then the SENTER feature must be disabled.
-
-  @retval RETURN_SUCCESS       SENTER feature is initialized.
-
-  @note This service could be called by BSP only.
-**/
-RETURN_STATUS
-EFIAPI
-SenterInitialize (
-  IN UINTN                             ProcessorNumber,
-  IN REGISTER_CPU_FEATURE_INFORMATION  *CpuInfo,
-  IN VOID                              *ConfigData,  OPTIONAL
-  IN BOOLEAN                           State
-  )
-{
-  MSR_IA32_FEATURE_CONTROL_REGISTER    *MsrRegister;
-
-  ASSERT (ConfigData != NULL);
-  MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;
-  if (MsrRegister[ProcessorNumber].Bits.Lock == 0) {
-    CPU_REGISTER_TABLE_WRITE_FIELD (
-      ProcessorNumber,
-      Msr,
-      MSR_IA32_FEATURE_CONTROL,
-      MSR_IA32_FEATURE_CONTROL_REGISTER,
-      Bits.SenterLocalFunctionEnables,
-      (State) ? 0x7F : 0
-      );
-
-    CPU_REGISTER_TABLE_WRITE_FIELD (
-      ProcessorNumber,
-      Msr,
-      MSR_IA32_FEATURE_CONTROL,
-      MSR_IA32_FEATURE_CONTROL_REGISTER,
-      Bits.SenterGlobalEnable,
-      (State) ? 1 : 0
-      );
-  }
-  return RETURN_SUCCESS;
-}
-
-/**
-  Detects if Lock Feature Control Register feature supported on current processor.
-
-  @param[in]  ProcessorNumber  The index of the CPU executing this function.
-  @param[in]  CpuInfo          A pointer to the REGISTER_CPU_FEATURE_INFORMATION
-                               structure for the CPU executing this function.
-  @param[in]  ConfigData       A pointer to the configuration buffer returned
-                               by CPU_FEATURE_GET_CONFIG_DATA.  NULL if
-                               CPU_FEATURE_GET_CONFIG_DATA was not provided in
-                               RegisterCpuFeature().
-
-  @retval TRUE     Lock Feature Control Register feature is supported.
-  @retval FALSE    Lock Feature Control Register feature is not supported.
-
-  @note This service could be called by BSP/APs.
-**/
-BOOLEAN
-EFIAPI
-LockFeatureControlRegisterSupport (
-  IN UINTN                             ProcessorNumber,
-  IN REGISTER_CPU_FEATURE_INFORMATION  *CpuInfo,
-  IN VOID                              *ConfigData  OPTIONAL
-  )
-{
-  MSR_IA32_FEATURE_CONTROL_REGISTER    *MsrRegister;
-
-  ASSERT (ConfigData != NULL);
-  MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;
-  MsrRegister[ProcessorNumber].Uint64 = AsmReadMsr64 (MSR_IA32_FEATURE_CONTROL);
-  return TRUE;
-}
-
-/**
-  Initializes Lock Feature Control Register feature to specific state.
-
-  @param[in]  ProcessorNumber  The index of the CPU executing this function.
-  @param[in]  CpuInfo          A pointer to the REGISTER_CPU_FEATURE_INFORMATION
-                               structure for the CPU executing this function.
-  @param[in]  ConfigData       A pointer to the configuration buffer returned
-                               by CPU_FEATURE_GET_CONFIG_DATA.  NULL if
-                               CPU_FEATURE_GET_CONFIG_DATA was not provided in
-                               RegisterCpuFeature().
-  @param[in]  State            If TRUE, then the Lock Feature Control Register feature must be enabled.
-                               If FALSE, then the Lock Feature Control Register feature must be disabled.
-
-  @retval RETURN_SUCCESS       Lock Feature Control Register feature is initialized.
-
-  @note This service could be called by BSP only.
-**/
-RETURN_STATUS
-EFIAPI
-LockFeatureControlRegisterInitialize (
-  IN UINTN                             ProcessorNumber,
-  IN REGISTER_CPU_FEATURE_INFORMATION  *CpuInfo,
-  IN VOID                              *ConfigData,  OPTIONAL
-  IN BOOLEAN                           State
-  )
-{
-  MSR_IA32_FEATURE_CONTROL_REGISTER    *MsrRegister;
-
-  ASSERT (ConfigData != NULL);
-  MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;
-  if (MsrRegister[ProcessorNumber].Bits.Lock == 0) {
-    CPU_REGISTER_TABLE_WRITE_FIELD (
-      ProcessorNumber,
-      Msr,
-      MSR_IA32_FEATURE_CONTROL,
-      MSR_IA32_FEATURE_CONTROL_REGISTER,
-      Bits.Lock,
-      1
-      );
-  }
-  return RETURN_SUCCESS;
-}
-
-/**
-  Detects if SMX feature supported on current processor.
-
-  @param[in]  ProcessorNumber  The index of the CPU executing this function.
-  @param[in]  CpuInfo          A pointer to the REGISTER_CPU_FEATURE_INFORMATION
-                               structure for the CPU executing this function.
-  @param[in]  ConfigData       A pointer to the configuration buffer returned
-                               by CPU_FEATURE_GET_CONFIG_DATA.  NULL if
-                               CPU_FEATURE_GET_CONFIG_DATA was not provided in
-                               RegisterCpuFeature().
-
-  @retval TRUE     SMX feature is supported.
-  @retval FALSE    SMX feature is not supported.
-
-  @note This service could be called by BSP/APs.
-**/
-BOOLEAN
-EFIAPI
-SmxSupport (
-  IN UINTN                             ProcessorNumber,
-  IN REGISTER_CPU_FEATURE_INFORMATION  *CpuInfo,
-  IN VOID                              *ConfigData  OPTIONAL
-  )
-{
-  MSR_IA32_FEATURE_CONTROL_REGISTER    *MsrRegister;
-
-  ASSERT (ConfigData != NULL);
-  MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;
-  MsrRegister[ProcessorNumber].Uint64 = AsmReadMsr64 (MSR_IA32_FEATURE_CONTROL);
-  return (CpuInfo->CpuIdVersionInfoEcx.Bits.SMX == 1);
-}
-
-/**
-  Initializes VMX outside SMX feature to specific state.
-
-  @param[in]  ProcessorNumber  The index of the CPU executing this function.
-  @param[in]  CpuInfo          A pointer to the REGISTER_CPU_FEATURE_INFORMATION
-                               structure for the CPU executing this function.
-  @param[in]  ConfigData       A pointer to the configuration buffer returned
-                               by CPU_FEATURE_GET_CONFIG_DATA.  NULL if
-                               CPU_FEATURE_GET_CONFIG_DATA was not provided in
-                               RegisterCpuFeature().
-  @param[in]  State            If TRUE, then the VMX outside SMX feature must be enabled.
-                               If FALSE, then the VMX outside SMX feature must be disabled.
-
-  @retval RETURN_SUCCESS       VMX outside SMX feature is initialized.
-
-  @note This service could be called by BSP only.
-**/
-RETURN_STATUS
-EFIAPI
-VmxOutsideSmxInitialize (
-  IN UINTN                             ProcessorNumber,
-  IN REGISTER_CPU_FEATURE_INFORMATION  *CpuInfo,
-  IN VOID                              *ConfigData,  OPTIONAL
-  IN BOOLEAN                           State
-  )
-{
-  MSR_IA32_FEATURE_CONTROL_REGISTER    *MsrRegister;
-
-  ASSERT (ConfigData != NULL);
-  MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;
-  if (MsrRegister[ProcessorNumber].Bits.Lock == 0) {
-    CPU_REGISTER_TABLE_WRITE_FIELD (
-      ProcessorNumber,
-      Msr,
-      MSR_IA32_FEATURE_CONTROL,
-      MSR_IA32_FEATURE_CONTROL_REGISTER,
-      Bits.EnableVmxOutsideSmx,
-      (State) ? 1 : 0
-      );
-  }
-  return RETURN_SUCCESS;
-}
+/** @file\r
+  Features in MSR_IA32_FEATURE_CONTROL register.\r
+\r
+  Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include "CpuCommonFeatures.h"\r
+\r
+/**\r
+  Prepares for the data used by CPU feature detection and initialization.\r
+\r
+  @param[in]  NumberOfProcessors  The number of CPUs in the platform.\r
+\r
+  @return  Pointer to a buffer of CPU related configuration data.\r
+\r
+  @note This service could be called by BSP only.\r
+**/\r
+VOID *\r
+EFIAPI\r
+FeatureControlGetConfigData (\r
+  IN UINTN               NumberOfProcessors\r
+  )\r
+{\r
+  VOID          *ConfigData;\r
+\r
+  ConfigData = AllocateZeroPool (sizeof (MSR_IA32_FEATURE_CONTROL_REGISTER) * NumberOfProcessors);\r
+  ASSERT (ConfigData != NULL);\r
+  return ConfigData;\r
+}\r
+\r
+/**\r
+  Detects if VMX feature supported on current processor.\r
+\r
+  @param[in]  ProcessorNumber  The index of the CPU executing this function.\r
+  @param[in]  CpuInfo          A pointer to the REGISTER_CPU_FEATURE_INFORMATION\r
+                               structure for the CPU executing this function.\r
+  @param[in]  ConfigData       A pointer to the configuration buffer returned\r
+                               by CPU_FEATURE_GET_CONFIG_DATA.  NULL if\r
+                               CPU_FEATURE_GET_CONFIG_DATA was not provided in\r
+                               RegisterCpuFeature().\r
+\r
+  @retval TRUE     VMX feature is supported.\r
+  @retval FALSE    VMX feature is not supported.\r
+\r
+  @note This service could be called by BSP/APs.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+VmxSupport (\r
+  IN UINTN                             ProcessorNumber,\r
+  IN REGISTER_CPU_FEATURE_INFORMATION  *CpuInfo,\r
+  IN VOID                              *ConfigData  OPTIONAL\r
+  )\r
+{\r
+  MSR_IA32_FEATURE_CONTROL_REGISTER    *MsrRegister;\r
+\r
+  ASSERT (ConfigData != NULL);\r
+  MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;\r
+  MsrRegister[ProcessorNumber].Uint64 = AsmReadMsr64 (MSR_IA32_FEATURE_CONTROL);\r
+  return (CpuInfo->CpuIdVersionInfoEcx.Bits.VMX == 1);\r
+}\r
+\r
+/**\r
+  Initializes VMX feature to specific state.\r
+\r
+  @param[in]  ProcessorNumber  The index of the CPU executing this function.\r
+  @param[in]  CpuInfo          A pointer to the REGISTER_CPU_FEATURE_INFORMATION\r
+                               structure for the CPU executing this function.\r
+  @param[in]  ConfigData       A pointer to the configuration buffer returned\r
+                               by CPU_FEATURE_GET_CONFIG_DATA.  NULL if\r
+                               CPU_FEATURE_GET_CONFIG_DATA was not provided in\r
+                               RegisterCpuFeature().\r
+  @param[in]  State            If TRUE, then the VMX feature must be enabled.\r
+                               If FALSE, then the VMX feature must be disabled.\r
+\r
+  @retval RETURN_SUCCESS       VMX feature is initialized.\r
+\r
+  @note This service could be called by BSP only.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+VmxInitialize (\r
+  IN UINTN                             ProcessorNumber,\r
+  IN REGISTER_CPU_FEATURE_INFORMATION  *CpuInfo,\r
+  IN VOID                              *ConfigData,  OPTIONAL\r
+  IN BOOLEAN                           State\r
+  )\r
+{\r
+  MSR_IA32_FEATURE_CONTROL_REGISTER    *MsrRegister;\r
+\r
+  //\r
+  // The scope of EnableVmxOutsideSmx bit in the MSR_IA32_FEATURE_CONTROL is core for\r
+  // below processor type, only program MSR_IA32_FEATURE_CONTROL for thread 0 in each\r
+  // core.\r
+  //\r
+  if (IS_SILVERMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) ||\r
+      IS_GOLDMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) ||\r
+      IS_GOLDMONT_PLUS_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) {\r
+    if (CpuInfo->ProcessorInfo.Location.Thread != 0) {\r
+      return RETURN_SUCCESS;\r
+    }\r
+  }\r
+\r
+  ASSERT (ConfigData != NULL);\r
+  MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;\r
+  if (MsrRegister[ProcessorNumber].Bits.Lock == 0) {\r
+    CPU_REGISTER_TABLE_WRITE_FIELD (\r
+      ProcessorNumber,\r
+      Msr,\r
+      MSR_IA32_FEATURE_CONTROL,\r
+      MSR_IA32_FEATURE_CONTROL_REGISTER,\r
+      Bits.EnableVmxOutsideSmx,\r
+      (State) ? 1 : 0\r
+      );\r
+  }\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Detects if Lock Feature Control Register feature supported on current processor.\r
+\r
+  @param[in]  ProcessorNumber  The index of the CPU executing this function.\r
+  @param[in]  CpuInfo          A pointer to the REGISTER_CPU_FEATURE_INFORMATION\r
+                               structure for the CPU executing this function.\r
+  @param[in]  ConfigData       A pointer to the configuration buffer returned\r
+                               by CPU_FEATURE_GET_CONFIG_DATA.  NULL if\r
+                               CPU_FEATURE_GET_CONFIG_DATA was not provided in\r
+                               RegisterCpuFeature().\r
+\r
+  @retval TRUE     Lock Feature Control Register feature is supported.\r
+  @retval FALSE    Lock Feature Control Register feature is not supported.\r
+\r
+  @note This service could be called by BSP/APs.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+LockFeatureControlRegisterSupport (\r
+  IN UINTN                             ProcessorNumber,\r
+  IN REGISTER_CPU_FEATURE_INFORMATION  *CpuInfo,\r
+  IN VOID                              *ConfigData  OPTIONAL\r
+  )\r
+{\r
+  MSR_IA32_FEATURE_CONTROL_REGISTER    *MsrRegister;\r
+\r
+  ASSERT (ConfigData != NULL);\r
+  MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;\r
+  MsrRegister[ProcessorNumber].Uint64 = AsmReadMsr64 (MSR_IA32_FEATURE_CONTROL);\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Initializes Lock Feature Control Register feature to specific state.\r
+\r
+  @param[in]  ProcessorNumber  The index of the CPU executing this function.\r
+  @param[in]  CpuInfo          A pointer to the REGISTER_CPU_FEATURE_INFORMATION\r
+                               structure for the CPU executing this function.\r
+  @param[in]  ConfigData       A pointer to the configuration buffer returned\r
+                               by CPU_FEATURE_GET_CONFIG_DATA.  NULL if\r
+                               CPU_FEATURE_GET_CONFIG_DATA was not provided in\r
+                               RegisterCpuFeature().\r
+  @param[in]  State            If TRUE, then the Lock Feature Control Register feature must be enabled.\r
+                               If FALSE, then the Lock Feature Control Register feature must be disabled.\r
+\r
+  @retval RETURN_SUCCESS       Lock Feature Control Register feature is initialized.\r
+\r
+  @note This service could be called by BSP only.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+LockFeatureControlRegisterInitialize (\r
+  IN UINTN                             ProcessorNumber,\r
+  IN REGISTER_CPU_FEATURE_INFORMATION  *CpuInfo,\r
+  IN VOID                              *ConfigData,  OPTIONAL\r
+  IN BOOLEAN                           State\r
+  )\r
+{\r
+  MSR_IA32_FEATURE_CONTROL_REGISTER    *MsrRegister;\r
+\r
+  //\r
+  // The scope of Lock bit in the MSR_IA32_FEATURE_CONTROL is core for\r
+  // below processor type, only program MSR_IA32_FEATURE_CONTROL for thread 0 in each\r
+  // core.\r
+  //\r
+  if (IS_SILVERMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) ||\r
+      IS_GOLDMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) ||\r
+      IS_GOLDMONT_PLUS_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) {\r
+    if (CpuInfo->ProcessorInfo.Location.Thread != 0) {\r
+      return RETURN_SUCCESS;\r
+    }\r
+  }\r
+\r
+  ASSERT (ConfigData != NULL);\r
+  MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;\r
+  if (MsrRegister[ProcessorNumber].Bits.Lock == 0) {\r
+    CPU_REGISTER_TABLE_WRITE_FIELD (\r
+      ProcessorNumber,\r
+      Msr,\r
+      MSR_IA32_FEATURE_CONTROL,\r
+      MSR_IA32_FEATURE_CONTROL_REGISTER,\r
+      Bits.Lock,\r
+      1\r
+      );\r
+  }\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Detects if SMX feature supported on current processor.\r
+\r
+  @param[in]  ProcessorNumber  The index of the CPU executing this function.\r
+  @param[in]  CpuInfo          A pointer to the REGISTER_CPU_FEATURE_INFORMATION\r
+                               structure for the CPU executing this function.\r
+  @param[in]  ConfigData       A pointer to the configuration buffer returned\r
+                               by CPU_FEATURE_GET_CONFIG_DATA.  NULL if\r
+                               CPU_FEATURE_GET_CONFIG_DATA was not provided in\r
+                               RegisterCpuFeature().\r
+\r
+  @retval TRUE     SMX feature is supported.\r
+  @retval FALSE    SMX feature is not supported.\r
+\r
+  @note This service could be called by BSP/APs.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+SmxSupport (\r
+  IN UINTN                             ProcessorNumber,\r
+  IN REGISTER_CPU_FEATURE_INFORMATION  *CpuInfo,\r
+  IN VOID                              *ConfigData  OPTIONAL\r
+  )\r
+{\r
+  MSR_IA32_FEATURE_CONTROL_REGISTER    *MsrRegister;\r
+\r
+  ASSERT (ConfigData != NULL);\r
+  MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;\r
+  MsrRegister[ProcessorNumber].Uint64 = AsmReadMsr64 (MSR_IA32_FEATURE_CONTROL);\r
+  return (CpuInfo->CpuIdVersionInfoEcx.Bits.SMX == 1);\r
+}\r
+\r
+/**\r
+  Initializes SMX feature to specific state.\r
+\r
+  @param[in]  ProcessorNumber  The index of the CPU executing this function.\r
+  @param[in]  CpuInfo          A pointer to the REGISTER_CPU_FEATURE_INFORMATION\r
+                               structure for the CPU executing this function.\r
+  @param[in]  ConfigData       A pointer to the configuration buffer returned\r
+                               by CPU_FEATURE_GET_CONFIG_DATA.  NULL if\r
+                               CPU_FEATURE_GET_CONFIG_DATA was not provided in\r
+                               RegisterCpuFeature().\r
+  @param[in]  State            If TRUE, then SMX feature must be enabled.\r
+                               If FALSE, then SMX feature must be disabled.\r
+\r
+  @retval RETURN_SUCCESS       SMX feature is initialized.\r
+  @retval RETURN_UNSUPPORTED   VMX not initialized.\r
+\r
+  @note This service could be called by BSP only.\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+SmxInitialize (\r
+  IN UINTN                             ProcessorNumber,\r
+  IN REGISTER_CPU_FEATURE_INFORMATION  *CpuInfo,\r
+  IN VOID                              *ConfigData,  OPTIONAL\r
+  IN BOOLEAN                           State\r
+  )\r
+{\r
+  MSR_IA32_FEATURE_CONTROL_REGISTER    *MsrRegister;\r
+  RETURN_STATUS                        Status;\r
+\r
+  //\r
+  // The scope of Lock bit in the MSR_IA32_FEATURE_CONTROL is core for\r
+  // below processor type, only program MSR_IA32_FEATURE_CONTROL for thread 0 in each\r
+  // core.\r
+  //\r
+  if (IS_GOLDMONT_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel) ||\r
+      IS_GOLDMONT_PLUS_PROCESSOR (CpuInfo->DisplayFamily, CpuInfo->DisplayModel)) {\r
+    if (CpuInfo->ProcessorInfo.Location.Thread != 0) {\r
+      return RETURN_SUCCESS;\r
+    }\r
+  }\r
+\r
+  Status = RETURN_SUCCESS;\r
+\r
+  if (State && (!IsCpuFeatureInSetting (CPU_FEATURE_VMX))) {\r
+    DEBUG ((DEBUG_WARN, "Warning :: Can't enable SMX feature when VMX feature not enabled, disable it.\n"));\r
+    State = FALSE;\r
+    Status = RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  ASSERT (ConfigData != NULL);\r
+  MsrRegister = (MSR_IA32_FEATURE_CONTROL_REGISTER *) ConfigData;\r
+  if (MsrRegister[ProcessorNumber].Bits.Lock == 0) {\r
+    CPU_REGISTER_TABLE_WRITE_FIELD (\r
+      ProcessorNumber,\r
+      Msr,\r
+      MSR_IA32_FEATURE_CONTROL,\r
+      MSR_IA32_FEATURE_CONTROL_REGISTER,\r
+      Bits.SenterLocalFunctionEnables,\r
+      (State) ? 0x7F : 0\r
+      );\r
+\r
+    CPU_REGISTER_TABLE_WRITE_FIELD (\r
+      ProcessorNumber,\r
+      Msr,\r
+      MSR_IA32_FEATURE_CONTROL,\r
+      MSR_IA32_FEATURE_CONTROL_REGISTER,\r
+      Bits.SenterGlobalEnable,\r
+      (State) ? 1 : 0\r
+      );\r
+\r
+    CPU_REGISTER_TABLE_WRITE_FIELD (\r
+      ProcessorNumber,\r
+      Msr,\r
+      MSR_IA32_FEATURE_CONTROL,\r
+      MSR_IA32_FEATURE_CONTROL_REGISTER,\r
+      Bits.EnableVmxInsideSmx,\r
+      (State) ? 1 : 0\r
+      );\r
+  }\r
+  return Status;\r
+}\r