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