* [PATCH 1/2] UefiCpuPkg/SmmCpuFeaturesLib: Abstract arch dependent code
@ 2022-09-30 9:52 Chang, Abner
2022-10-28 9:26 ` [edk2-devel] " Ni, Ray
0 siblings, 1 reply; 3+ messages in thread
From: Chang, Abner @ 2022-09-30 9:52 UTC (permalink / raw)
To: devel
Cc: Abdul Lateef Attar, Garrett Kirkendall, Paul Grimes, Eric Dong,
Ray Ni, Rahul Kumar
From: Abner Chang <abner.chang@amd.com>
This change strips away Intel X86 implementation and put
it in the IntelSmmCpuFeatureLib
Signed-off-by: Abner Chang <abner.chang@amd.com>
Cc: Abdul Lateef Attar <abdattar@amd.com>
Cc: Garrett Kirkendall <garrett.kirkendall@amd.com>
Cc: Paul Grimes <paul.grimes@amd.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
---
.../SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf | 1 +
.../SmmCpuFeaturesLibStm.inf | 1 +
.../StandaloneMmCpuFeaturesLib.inf | 1 +
.../SmmCpuFeaturesLib/CpuFeaturesLib.h | 6 +
.../IntelSmmCpuFeaturesLib.c | 403 ++++++++++++++++++
.../SmmCpuFeaturesLibCommon.c | 391 +----------------
6 files changed, 413 insertions(+), 390 deletions(-)
create mode 100644 UefiCpuPkg/Library/SmmCpuFeaturesLib/IntelSmmCpuFeaturesLib.c
diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
index 7b5cef97008..9ac7dde78f8 100644
--- a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
+++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
@@ -18,6 +18,7 @@
[Sources]
CpuFeaturesLib.h
+ IntelSmmCpuFeaturesLib.c
SmmCpuFeaturesLib.c
SmmCpuFeaturesLibCommon.c
SmmCpuFeaturesLibNoStm.c
diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf
index 85214ee31cd..86d367e0a09 100644
--- a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf
+++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf
@@ -19,6 +19,7 @@
[Sources]
CpuFeaturesLib.h
+ IntelSmmCpuFeaturesLib.c
SmmCpuFeaturesLibCommon.c
SmmStm.c
SmmStm.h
diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.inf b/UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.inf
index 3eacab48db3..61890205e18 100644
--- a/UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.inf
+++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.inf
@@ -20,6 +20,7 @@
[Sources]
CpuFeaturesLib.h
+ IntelSmmCpuFeaturesLib.c
StandaloneMmCpuFeaturesLib.c
SmmCpuFeaturesLibCommon.c
SmmCpuFeaturesLibNoStm.c
diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/CpuFeaturesLib.h b/UefiCpuPkg/Library/SmmCpuFeaturesLib/CpuFeaturesLib.h
index 8a1c2adc5c4..fd3e902547c 100644
--- a/UefiCpuPkg/Library/SmmCpuFeaturesLib/CpuFeaturesLib.h
+++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/CpuFeaturesLib.h
@@ -9,6 +9,12 @@
#ifndef CPU_FEATURES_LIB_H_
#define CPU_FEATURES_LIB_H_
+#include <Library/SmmCpuFeaturesLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+
/**
Performs library initialization.
diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/IntelSmmCpuFeaturesLib.c b/UefiCpuPkg/Library/SmmCpuFeaturesLib/IntelSmmCpuFeaturesLib.c
new file mode 100644
index 00000000000..cb4897b21e3
--- /dev/null
+++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/IntelSmmCpuFeaturesLib.c
@@ -0,0 +1,403 @@
+/** @file
+Implementation shared across all library instances.
+
+Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>
+Copyright (c) Microsoft Corporation.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CpuFeaturesLib.h"
+
+#include <Library/MtrrLib.h>
+#include <Register/Intel/Cpuid.h>
+#include <Register/Intel/SmramSaveStateMap.h>
+
+//
+// Machine Specific Registers (MSRs)
+//
+#define SMM_FEATURES_LIB_IA32_MTRR_CAP 0x0FE
+#define SMM_FEATURES_LIB_IA32_FEATURE_CONTROL 0x03A
+#define SMM_FEATURES_LIB_IA32_SMRR_PHYSBASE 0x1F2
+#define SMM_FEATURES_LIB_IA32_SMRR_PHYSMASK 0x1F3
+#define SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE 0x0A0
+#define SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSMASK 0x0A1
+#define EFI_MSR_SMRR_MASK 0xFFFFF000
+#define EFI_MSR_SMRR_PHYS_MASK_VALID BIT11
+#define SMM_FEATURES_LIB_SMM_FEATURE_CONTROL 0x4E0
+
+//
+// MSRs required for configuration of SMM Code Access Check
+//
+#define SMM_FEATURES_LIB_IA32_MCA_CAP 0x17D
+#define SMM_CODE_ACCESS_CHK_BIT BIT58
+
+//
+// Set default value to assume IA-32 Architectural MSRs are used
+//
+UINT32 mSmrrPhysBaseMsr = SMM_FEATURES_LIB_IA32_SMRR_PHYSBASE;
+UINT32 mSmrrPhysMaskMsr = SMM_FEATURES_LIB_IA32_SMRR_PHYSMASK;
+
+//
+// Set default value to assume MTRRs need to be configured on each SMI
+//
+BOOLEAN mNeedConfigureMtrrs = TRUE;
+
+//
+// Array for state of SMRR enable on all CPUs
+//
+BOOLEAN *mSmrrEnabled;
+
+/**
+ Performs library initialization.
+
+ This initialization function contains common functionality shared betwen all
+ library instance constructors.
+
+**/
+VOID
+CpuFeaturesLibInitialization (
+ VOID
+ )
+{
+ UINT32 RegEax;
+ UINT32 RegEdx;
+ UINTN FamilyId;
+ UINTN ModelId;
+
+ //
+ // Retrieve CPU Family and Model
+ //
+ AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, &RegEdx);
+ FamilyId = (RegEax >> 8) & 0xf;
+ ModelId = (RegEax >> 4) & 0xf;
+ if ((FamilyId == 0x06) || (FamilyId == 0x0f)) {
+ ModelId = ModelId | ((RegEax >> 12) & 0xf0);
+ }
+
+ //
+ // Check CPUID(CPUID_VERSION_INFO).EDX[12] for MTRR capability
+ //
+ if ((RegEdx & BIT12) != 0) {
+ //
+ // Check MTRR_CAP MSR bit 11 for SMRR support
+ //
+ if ((AsmReadMsr64 (SMM_FEATURES_LIB_IA32_MTRR_CAP) & BIT11) != 0) {
+ ASSERT (FeaturePcdGet (PcdSmrrEnable));
+ }
+ }
+
+ //
+ // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
+ // Volume 3C, Section 35.3 MSRs in the Intel(R) Atom(TM) Processor Family
+ //
+ // If CPU Family/Model is 06_1CH, 06_26H, 06_27H, 06_35H or 06_36H, then
+ // SMRR Physical Base and SMM Physical Mask MSRs are not available.
+ //
+ if (FamilyId == 0x06) {
+ if ((ModelId == 0x1C) || (ModelId == 0x26) || (ModelId == 0x27) || (ModelId == 0x35) || (ModelId == 0x36)) {
+ ASSERT (!FeaturePcdGet (PcdSmrrEnable));
+ }
+ }
+
+ //
+ // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
+ // Volume 3C, Section 35.2 MSRs in the Intel(R) Core(TM) 2 Processor Family
+ //
+ // If CPU Family/Model is 06_0F or 06_17, then use Intel(R) Core(TM) 2
+ // Processor Family MSRs
+ //
+ if (FamilyId == 0x06) {
+ if ((ModelId == 0x17) || (ModelId == 0x0f)) {
+ mSmrrPhysBaseMsr = SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE;
+ mSmrrPhysMaskMsr = SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSMASK;
+ }
+ }
+
+ //
+ // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
+ // Volume 3C, Section 34.4.2 SMRAM Caching
+ // An IA-32 processor does not automatically write back and invalidate its
+ // caches before entering SMM or before exiting SMM. Because of this behavior,
+ // care must be taken in the placement of the SMRAM in system memory and in
+ // the caching of the SMRAM to prevent cache incoherence when switching back
+ // and forth between SMM and protected mode operation.
+ //
+ // An IA-32 processor is a processor that does not support the Intel 64
+ // Architecture. Support for the Intel 64 Architecture can be detected from
+ // CPUID(CPUID_EXTENDED_CPU_SIG).EDX[29]
+ //
+ // If an IA-32 processor is detected, then set mNeedConfigureMtrrs to TRUE,
+ // so caches are flushed on SMI entry and SMI exit, the interrupted code
+ // MTRRs are saved/restored, and MTRRs for SMM are loaded.
+ //
+ AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
+ if (RegEax >= CPUID_EXTENDED_CPU_SIG) {
+ AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx);
+ if ((RegEdx & BIT29) != 0) {
+ mNeedConfigureMtrrs = FALSE;
+ }
+ }
+
+ //
+ // Allocate array for state of SMRR enable on all CPUs
+ //
+ mSmrrEnabled = (BOOLEAN *)AllocatePool (sizeof (BOOLEAN) * GetCpuMaxLogicalProcessorNumber ());
+ ASSERT (mSmrrEnabled != NULL);
+}
+
+/**
+ Called during the very first SMI into System Management Mode to initialize
+ CPU features, including SMBASE, for the currently executing CPU. Since this
+ is the first SMI, the SMRAM Save State Map is at the default address of
+ SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET. The currently executing
+ CPU is specified by CpuIndex and CpuIndex can be used to access information
+ about the currently executing CPU in the ProcessorInfo array and the
+ HotPlugCpuData data structure.
+
+ @param[in] CpuIndex The index of the CPU to initialize. The value
+ must be between 0 and the NumberOfCpus field in
+ the System Management System Table (SMST).
+ @param[in] IsMonarch TRUE if the CpuIndex is the index of the CPU that
+ was elected as monarch during System Management
+ Mode initialization.
+ FALSE if the CpuIndex is not the index of the CPU
+ that was elected as monarch during System
+ Management Mode initialization.
+ @param[in] ProcessorInfo Pointer to an array of EFI_PROCESSOR_INFORMATION
+ structures. ProcessorInfo[CpuIndex] contains the
+ information for the currently executing CPU.
+ @param[in] CpuHotPlugData Pointer to the CPU_HOT_PLUG_DATA structure that
+ contains the ApidId and SmBase arrays.
+**/
+VOID
+EFIAPI
+SmmCpuFeaturesInitializeProcessor (
+ IN UINTN CpuIndex,
+ IN BOOLEAN IsMonarch,
+ IN EFI_PROCESSOR_INFORMATION *ProcessorInfo,
+ IN CPU_HOT_PLUG_DATA *CpuHotPlugData
+ )
+{
+ SMRAM_SAVE_STATE_MAP *CpuState;
+ UINT64 FeatureControl;
+ UINT32 RegEax;
+ UINT32 RegEdx;
+ UINTN FamilyId;
+ UINTN ModelId;
+
+ //
+ // Configure SMBASE.
+ //
+ CpuState = (SMRAM_SAVE_STATE_MAP *)(UINTN)(SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET);
+ CpuState->x86.SMBASE = (UINT32)CpuHotPlugData->SmBase[CpuIndex];
+
+ //
+ // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
+ // Volume 3C, Section 35.2 MSRs in the Intel(R) Core(TM) 2 Processor Family
+ //
+ // If Intel(R) Core(TM) Core(TM) 2 Processor Family MSRs are being used, then
+ // make sure SMRR Enable(BIT3) of MSR_FEATURE_CONTROL MSR(0x3A) is set before
+ // accessing SMRR base/mask MSRs. If Lock(BIT0) of MSR_FEATURE_CONTROL MSR(0x3A)
+ // is set, then the MSR is locked and can not be modified.
+ //
+ if ((FeaturePcdGet (PcdSmrrEnable)) && (mSmrrPhysBaseMsr == SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE)) {
+ FeatureControl = AsmReadMsr64 (SMM_FEATURES_LIB_IA32_FEATURE_CONTROL);
+ if ((FeatureControl & BIT3) == 0) {
+ ASSERT ((FeatureControl & BIT0) == 0);
+ if ((FeatureControl & BIT0) == 0) {
+ AsmWriteMsr64 (SMM_FEATURES_LIB_IA32_FEATURE_CONTROL, FeatureControl | BIT3);
+ }
+ }
+ }
+
+ //
+ // If SMRR is supported, then program SMRR base/mask MSRs.
+ // The EFI_MSR_SMRR_PHYS_MASK_VALID bit is not set until the first normal SMI.
+ // The code that initializes SMM environment is running in normal mode
+ // from SMRAM region. If SMRR is enabled here, then the SMRAM region
+ // is protected and the normal mode code execution will fail.
+ //
+ if (FeaturePcdGet (PcdSmrrEnable)) {
+ //
+ // SMRR size cannot be less than 4-KBytes
+ // SMRR size must be of length 2^n
+ // SMRR base alignment cannot be less than SMRR length
+ //
+ if ((CpuHotPlugData->SmrrSize < SIZE_4KB) ||
+ (CpuHotPlugData->SmrrSize != GetPowerOfTwo32 (CpuHotPlugData->SmrrSize)) ||
+ ((CpuHotPlugData->SmrrBase & ~(CpuHotPlugData->SmrrSize - 1)) != CpuHotPlugData->SmrrBase))
+ {
+ //
+ // Print message and halt if CPU is Monarch
+ //
+ if (IsMonarch) {
+ DEBUG ((DEBUG_ERROR, "SMM Base/Size does not meet alignment/size requirement!\n"));
+ CpuDeadLoop ();
+ }
+ } else {
+ AsmWriteMsr64 (mSmrrPhysBaseMsr, CpuHotPlugData->SmrrBase | MTRR_CACHE_WRITE_BACK);
+ AsmWriteMsr64 (mSmrrPhysMaskMsr, (~(CpuHotPlugData->SmrrSize - 1) & EFI_MSR_SMRR_MASK));
+ mSmrrEnabled[CpuIndex] = FALSE;
+ }
+ }
+
+ //
+ // Retrieve CPU Family and Model
+ //
+ AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, &RegEdx);
+ FamilyId = (RegEax >> 8) & 0xf;
+ ModelId = (RegEax >> 4) & 0xf;
+ if ((FamilyId == 0x06) || (FamilyId == 0x0f)) {
+ ModelId = ModelId | ((RegEax >> 12) & 0xf0);
+ }
+
+ //
+ // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
+ // Volume 3C, Section 35.10.1 MSRs in 4th Generation Intel(R) Core(TM)
+ // Processor Family.
+ //
+ // If CPU Family/Model is 06_3C, 06_45, or 06_46 then use 4th Generation
+ // Intel(R) Core(TM) Processor Family MSRs.
+ //
+ if (FamilyId == 0x06) {
+ if ((ModelId == 0x3C) || (ModelId == 0x45) || (ModelId == 0x46) ||
+ (ModelId == 0x3D) || (ModelId == 0x47) || (ModelId == 0x4E) || (ModelId == 0x4F) ||
+ (ModelId == 0x3F) || (ModelId == 0x56) || (ModelId == 0x57) || (ModelId == 0x5C) ||
+ (ModelId == 0x8C))
+ {
+ //
+ // Check to see if the CPU supports the SMM Code Access Check feature
+ // Do not access this MSR unless the CPU supports the SmmRegFeatureControl
+ //
+ if ((AsmReadMsr64 (SMM_FEATURES_LIB_IA32_MCA_CAP) & SMM_CODE_ACCESS_CHK_BIT) != 0) {
+ ASSERT (FeaturePcdGet (PcdSmmFeatureControlEnable));
+ }
+ }
+ }
+
+ //
+ // Call internal worker function that completes the CPU initialization
+ //
+ FinishSmmCpuFeaturesInitializeProcessor ();
+}
+
+/**
+ Determines if MTRR registers must be configured to set SMRAM cache-ability
+ when executing in System Management Mode.
+
+ @retval TRUE MTRR registers must be configured to set SMRAM cache-ability.
+ @retval FALSE MTRR registers do not need to be configured to set SMRAM
+ cache-ability.
+**/
+BOOLEAN
+EFIAPI
+SmmCpuFeaturesNeedConfigureMtrrs (
+ VOID
+ )
+{
+ return mNeedConfigureMtrrs;
+}
+
+/**
+ Disable SMRR register if SMRR is supported and SmmCpuFeaturesNeedConfigureMtrrs()
+ returns TRUE.
+**/
+VOID
+EFIAPI
+SmmCpuFeaturesDisableSmrr (
+ VOID
+ )
+{
+ if (FeaturePcdGet (PcdSmrrEnable) && mNeedConfigureMtrrs) {
+ AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64 (mSmrrPhysMaskMsr) & ~EFI_MSR_SMRR_PHYS_MASK_VALID);
+ }
+}
+
+/**
+ Enable SMRR register if SMRR is supported and SmmCpuFeaturesNeedConfigureMtrrs()
+ returns TRUE.
+**/
+VOID
+EFIAPI
+SmmCpuFeaturesReenableSmrr (
+ VOID
+ )
+{
+ if (FeaturePcdGet (PcdSmrrEnable) && mNeedConfigureMtrrs) {
+ AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64 (mSmrrPhysMaskMsr) | EFI_MSR_SMRR_PHYS_MASK_VALID);
+ }
+}
+
+/**
+ Processor specific hook point each time a CPU enters System Management Mode.
+
+ @param[in] CpuIndex The index of the CPU that has entered SMM. The value
+ must be between 0 and the NumberOfCpus field in the
+ System Management System Table (SMST).
+**/
+VOID
+EFIAPI
+SmmCpuFeaturesRendezvousEntry (
+ IN UINTN CpuIndex
+ )
+{
+ //
+ // If SMRR is supported and this is the first normal SMI, then enable SMRR
+ //
+ if (FeaturePcdGet (PcdSmrrEnable) && !mSmrrEnabled[CpuIndex]) {
+ AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64 (mSmrrPhysMaskMsr) | EFI_MSR_SMRR_PHYS_MASK_VALID);
+ mSmrrEnabled[CpuIndex] = TRUE;
+ }
+}
+
+/**
+ Returns the current value of the SMM register for the specified CPU.
+ If the SMM register is not supported, then 0 is returned.
+
+ @param[in] CpuIndex The index of the CPU to read the SMM register. The
+ value must be between 0 and the NumberOfCpus field in
+ the System Management System Table (SMST).
+ @param[in] RegName Identifies the SMM register to read.
+
+ @return The value of the SMM register specified by RegName from the CPU
+ specified by CpuIndex.
+**/
+UINT64
+EFIAPI
+SmmCpuFeaturesGetSmmRegister (
+ IN UINTN CpuIndex,
+ IN SMM_REG_NAME RegName
+ )
+{
+ if (FeaturePcdGet (PcdSmmFeatureControlEnable) && (RegName == SmmRegFeatureControl)) {
+ return AsmReadMsr64 (SMM_FEATURES_LIB_SMM_FEATURE_CONTROL);
+ }
+
+ return 0;
+}
+
+/**
+ Sets the value of an SMM register on a specified CPU.
+ If the SMM register is not supported, then no action is performed.
+
+ @param[in] CpuIndex The index of the CPU to write the SMM register. The
+ value must be between 0 and the NumberOfCpus field in
+ the System Management System Table (SMST).
+ @param[in] RegName Identifies the SMM register to write.
+ registers are read-only.
+ @param[in] Value The value to write to the SMM register.
+**/
+VOID
+EFIAPI
+SmmCpuFeaturesSetSmmRegister (
+ IN UINTN CpuIndex,
+ IN SMM_REG_NAME RegName,
+ IN UINT64 Value
+ )
+{
+ if (FeaturePcdGet (PcdSmmFeatureControlEnable) && (RegName == SmmRegFeatureControl)) {
+ AsmWriteMsr64 (SMM_FEATURES_LIB_SMM_FEATURE_CONTROL, Value);
+ }
+}
+
diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibCommon.c b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibCommon.c
index 75a0ec8e948..7777e52740e 100644
--- a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibCommon.c
+++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibCommon.c
@@ -14,278 +14,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/PcdLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h>
-#include <Register/Intel/Cpuid.h>
-#include <Register/Intel/SmramSaveStateMap.h>
-#include "CpuFeaturesLib.h"
-
-//
-// Machine Specific Registers (MSRs)
-//
-#define SMM_FEATURES_LIB_IA32_MTRR_CAP 0x0FE
-#define SMM_FEATURES_LIB_IA32_FEATURE_CONTROL 0x03A
-#define SMM_FEATURES_LIB_IA32_SMRR_PHYSBASE 0x1F2
-#define SMM_FEATURES_LIB_IA32_SMRR_PHYSMASK 0x1F3
-#define SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE 0x0A0
-#define SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSMASK 0x0A1
-#define EFI_MSR_SMRR_MASK 0xFFFFF000
-#define EFI_MSR_SMRR_PHYS_MASK_VALID BIT11
-#define SMM_FEATURES_LIB_SMM_FEATURE_CONTROL 0x4E0
-
-//
-// MSRs required for configuration of SMM Code Access Check
-//
-#define SMM_FEATURES_LIB_IA32_MCA_CAP 0x17D
-#define SMM_CODE_ACCESS_CHK_BIT BIT58
-
-//
-// Set default value to assume IA-32 Architectural MSRs are used
-//
-UINT32 mSmrrPhysBaseMsr = SMM_FEATURES_LIB_IA32_SMRR_PHYSBASE;
-UINT32 mSmrrPhysMaskMsr = SMM_FEATURES_LIB_IA32_SMRR_PHYSMASK;
-
-//
-// Set default value to assume MTRRs need to be configured on each SMI
-//
-BOOLEAN mNeedConfigureMtrrs = TRUE;
-
-//
-// Array for state of SMRR enable on all CPUs
-//
-BOOLEAN *mSmrrEnabled;
-
-/**
- Performs library initialization.
-
- This initialization function contains common functionality shared betwen all
- library instance constructors.
-
-**/
-VOID
-CpuFeaturesLibInitialization (
- VOID
- )
-{
- UINT32 RegEax;
- UINT32 RegEdx;
- UINTN FamilyId;
- UINTN ModelId;
-
- //
- // Retrieve CPU Family and Model
- //
- AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, &RegEdx);
- FamilyId = (RegEax >> 8) & 0xf;
- ModelId = (RegEax >> 4) & 0xf;
- if ((FamilyId == 0x06) || (FamilyId == 0x0f)) {
- ModelId = ModelId | ((RegEax >> 12) & 0xf0);
- }
-
- //
- // Check CPUID(CPUID_VERSION_INFO).EDX[12] for MTRR capability
- //
- if ((RegEdx & BIT12) != 0) {
- //
- // Check MTRR_CAP MSR bit 11 for SMRR support
- //
- if ((AsmReadMsr64 (SMM_FEATURES_LIB_IA32_MTRR_CAP) & BIT11) != 0) {
- ASSERT (FeaturePcdGet (PcdSmrrEnable));
- }
- }
-
- //
- // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
- // Volume 3C, Section 35.3 MSRs in the Intel(R) Atom(TM) Processor Family
- //
- // If CPU Family/Model is 06_1CH, 06_26H, 06_27H, 06_35H or 06_36H, then
- // SMRR Physical Base and SMM Physical Mask MSRs are not available.
- //
- if (FamilyId == 0x06) {
- if ((ModelId == 0x1C) || (ModelId == 0x26) || (ModelId == 0x27) || (ModelId == 0x35) || (ModelId == 0x36)) {
- ASSERT (!FeaturePcdGet (PcdSmrrEnable));
- }
- }
-
- //
- // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
- // Volume 3C, Section 35.2 MSRs in the Intel(R) Core(TM) 2 Processor Family
- //
- // If CPU Family/Model is 06_0F or 06_17, then use Intel(R) Core(TM) 2
- // Processor Family MSRs
- //
- if (FamilyId == 0x06) {
- if ((ModelId == 0x17) || (ModelId == 0x0f)) {
- mSmrrPhysBaseMsr = SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE;
- mSmrrPhysMaskMsr = SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSMASK;
- }
- }
-
- //
- // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
- // Volume 3C, Section 34.4.2 SMRAM Caching
- // An IA-32 processor does not automatically write back and invalidate its
- // caches before entering SMM or before exiting SMM. Because of this behavior,
- // care must be taken in the placement of the SMRAM in system memory and in
- // the caching of the SMRAM to prevent cache incoherence when switching back
- // and forth between SMM and protected mode operation.
- //
- // An IA-32 processor is a processor that does not support the Intel 64
- // Architecture. Support for the Intel 64 Architecture can be detected from
- // CPUID(CPUID_EXTENDED_CPU_SIG).EDX[29]
- //
- // If an IA-32 processor is detected, then set mNeedConfigureMtrrs to TRUE,
- // so caches are flushed on SMI entry and SMI exit, the interrupted code
- // MTRRs are saved/restored, and MTRRs for SMM are loaded.
- //
- AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
- if (RegEax >= CPUID_EXTENDED_CPU_SIG) {
- AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx);
- if ((RegEdx & BIT29) != 0) {
- mNeedConfigureMtrrs = FALSE;
- }
- }
-
- //
- // Allocate array for state of SMRR enable on all CPUs
- //
- mSmrrEnabled = (BOOLEAN *)AllocatePool (sizeof (BOOLEAN) * GetCpuMaxLogicalProcessorNumber ());
- ASSERT (mSmrrEnabled != NULL);
-}
-
-/**
- Called during the very first SMI into System Management Mode to initialize
- CPU features, including SMBASE, for the currently executing CPU. Since this
- is the first SMI, the SMRAM Save State Map is at the default address of
- SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET. The currently executing
- CPU is specified by CpuIndex and CpuIndex can be used to access information
- about the currently executing CPU in the ProcessorInfo array and the
- HotPlugCpuData data structure.
-
- @param[in] CpuIndex The index of the CPU to initialize. The value
- must be between 0 and the NumberOfCpus field in
- the System Management System Table (SMST).
- @param[in] IsMonarch TRUE if the CpuIndex is the index of the CPU that
- was elected as monarch during System Management
- Mode initialization.
- FALSE if the CpuIndex is not the index of the CPU
- that was elected as monarch during System
- Management Mode initialization.
- @param[in] ProcessorInfo Pointer to an array of EFI_PROCESSOR_INFORMATION
- structures. ProcessorInfo[CpuIndex] contains the
- information for the currently executing CPU.
- @param[in] CpuHotPlugData Pointer to the CPU_HOT_PLUG_DATA structure that
- contains the ApidId and SmBase arrays.
-**/
-VOID
-EFIAPI
-SmmCpuFeaturesInitializeProcessor (
- IN UINTN CpuIndex,
- IN BOOLEAN IsMonarch,
- IN EFI_PROCESSOR_INFORMATION *ProcessorInfo,
- IN CPU_HOT_PLUG_DATA *CpuHotPlugData
- )
-{
- SMRAM_SAVE_STATE_MAP *CpuState;
- UINT64 FeatureControl;
- UINT32 RegEax;
- UINT32 RegEdx;
- UINTN FamilyId;
- UINTN ModelId;
-
- //
- // Configure SMBASE.
- //
- CpuState = (SMRAM_SAVE_STATE_MAP *)(UINTN)(SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET);
- CpuState->x86.SMBASE = (UINT32)CpuHotPlugData->SmBase[CpuIndex];
-
- //
- // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
- // Volume 3C, Section 35.2 MSRs in the Intel(R) Core(TM) 2 Processor Family
- //
- // If Intel(R) Core(TM) Core(TM) 2 Processor Family MSRs are being used, then
- // make sure SMRR Enable(BIT3) of MSR_FEATURE_CONTROL MSR(0x3A) is set before
- // accessing SMRR base/mask MSRs. If Lock(BIT0) of MSR_FEATURE_CONTROL MSR(0x3A)
- // is set, then the MSR is locked and can not be modified.
- //
- if ((FeaturePcdGet (PcdSmrrEnable)) && (mSmrrPhysBaseMsr == SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE)) {
- FeatureControl = AsmReadMsr64 (SMM_FEATURES_LIB_IA32_FEATURE_CONTROL);
- if ((FeatureControl & BIT3) == 0) {
- ASSERT ((FeatureControl & BIT0) == 0);
- if ((FeatureControl & BIT0) == 0) {
- AsmWriteMsr64 (SMM_FEATURES_LIB_IA32_FEATURE_CONTROL, FeatureControl | BIT3);
- }
- }
- }
- //
- // If SMRR is supported, then program SMRR base/mask MSRs.
- // The EFI_MSR_SMRR_PHYS_MASK_VALID bit is not set until the first normal SMI.
- // The code that initializes SMM environment is running in normal mode
- // from SMRAM region. If SMRR is enabled here, then the SMRAM region
- // is protected and the normal mode code execution will fail.
- //
- if (FeaturePcdGet (PcdSmrrEnable)) {
- //
- // SMRR size cannot be less than 4-KBytes
- // SMRR size must be of length 2^n
- // SMRR base alignment cannot be less than SMRR length
- //
- if ((CpuHotPlugData->SmrrSize < SIZE_4KB) ||
- (CpuHotPlugData->SmrrSize != GetPowerOfTwo32 (CpuHotPlugData->SmrrSize)) ||
- ((CpuHotPlugData->SmrrBase & ~(CpuHotPlugData->SmrrSize - 1)) != CpuHotPlugData->SmrrBase))
- {
- //
- // Print message and halt if CPU is Monarch
- //
- if (IsMonarch) {
- DEBUG ((DEBUG_ERROR, "SMM Base/Size does not meet alignment/size requirement!\n"));
- CpuDeadLoop ();
- }
- } else {
- AsmWriteMsr64 (mSmrrPhysBaseMsr, CpuHotPlugData->SmrrBase | MTRR_CACHE_WRITE_BACK);
- AsmWriteMsr64 (mSmrrPhysMaskMsr, (~(CpuHotPlugData->SmrrSize - 1) & EFI_MSR_SMRR_MASK));
- mSmrrEnabled[CpuIndex] = FALSE;
- }
- }
-
- //
- // Retrieve CPU Family and Model
- //
- AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, &RegEdx);
- FamilyId = (RegEax >> 8) & 0xf;
- ModelId = (RegEax >> 4) & 0xf;
- if ((FamilyId == 0x06) || (FamilyId == 0x0f)) {
- ModelId = ModelId | ((RegEax >> 12) & 0xf0);
- }
-
- //
- // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
- // Volume 3C, Section 35.10.1 MSRs in 4th Generation Intel(R) Core(TM)
- // Processor Family.
- //
- // If CPU Family/Model is 06_3C, 06_45, or 06_46 then use 4th Generation
- // Intel(R) Core(TM) Processor Family MSRs.
- //
- if (FamilyId == 0x06) {
- if ((ModelId == 0x3C) || (ModelId == 0x45) || (ModelId == 0x46) ||
- (ModelId == 0x3D) || (ModelId == 0x47) || (ModelId == 0x4E) || (ModelId == 0x4F) ||
- (ModelId == 0x3F) || (ModelId == 0x56) || (ModelId == 0x57) || (ModelId == 0x5C) ||
- (ModelId == 0x8C))
- {
- //
- // Check to see if the CPU supports the SMM Code Access Check feature
- // Do not access this MSR unless the CPU supports the SmmRegFeatureControl
- //
- if ((AsmReadMsr64 (SMM_FEATURES_LIB_IA32_MCA_CAP) & SMM_CODE_ACCESS_CHK_BIT) != 0) {
- ASSERT (FeaturePcdGet (PcdSmmFeatureControlEnable));
- }
- }
- }
-
- //
- // Call internal worker function that completes the CPU initialization
- //
- FinishSmmCpuFeaturesInitializeProcessor ();
-}
+#include "CpuFeaturesLib.h"
/**
This function updates the SMRAM save state on the currently executing CPU
@@ -345,75 +75,6 @@ SmmCpuFeaturesSmmRelocationComplete (
{
}
-/**
- Determines if MTRR registers must be configured to set SMRAM cache-ability
- when executing in System Management Mode.
-
- @retval TRUE MTRR registers must be configured to set SMRAM cache-ability.
- @retval FALSE MTRR registers do not need to be configured to set SMRAM
- cache-ability.
-**/
-BOOLEAN
-EFIAPI
-SmmCpuFeaturesNeedConfigureMtrrs (
- VOID
- )
-{
- return mNeedConfigureMtrrs;
-}
-
-/**
- Disable SMRR register if SMRR is supported and SmmCpuFeaturesNeedConfigureMtrrs()
- returns TRUE.
-**/
-VOID
-EFIAPI
-SmmCpuFeaturesDisableSmrr (
- VOID
- )
-{
- if (FeaturePcdGet (PcdSmrrEnable) && mNeedConfigureMtrrs) {
- AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64 (mSmrrPhysMaskMsr) & ~EFI_MSR_SMRR_PHYS_MASK_VALID);
- }
-}
-
-/**
- Enable SMRR register if SMRR is supported and SmmCpuFeaturesNeedConfigureMtrrs()
- returns TRUE.
-**/
-VOID
-EFIAPI
-SmmCpuFeaturesReenableSmrr (
- VOID
- )
-{
- if (FeaturePcdGet (PcdSmrrEnable) && mNeedConfigureMtrrs) {
- AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64 (mSmrrPhysMaskMsr) | EFI_MSR_SMRR_PHYS_MASK_VALID);
- }
-}
-
-/**
- Processor specific hook point each time a CPU enters System Management Mode.
-
- @param[in] CpuIndex The index of the CPU that has entered SMM. The value
- must be between 0 and the NumberOfCpus field in the
- System Management System Table (SMST).
-**/
-VOID
-EFIAPI
-SmmCpuFeaturesRendezvousEntry (
- IN UINTN CpuIndex
- )
-{
- //
- // If SMRR is supported and this is the first normal SMI, then enable SMRR
- //
- if (FeaturePcdGet (PcdSmrrEnable) && !mSmrrEnabled[CpuIndex]) {
- AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64 (mSmrrPhysMaskMsr) | EFI_MSR_SMRR_PHYS_MASK_VALID);
- mSmrrEnabled[CpuIndex] = TRUE;
- }
-}
-
/**
Processor specific hook point each time a CPU exits System Management Mode.
@@ -456,56 +117,6 @@ SmmCpuFeaturesIsSmmRegisterSupported (
return FALSE;
}
-/**
- Returns the current value of the SMM register for the specified CPU.
- If the SMM register is not supported, then 0 is returned.
-
- @param[in] CpuIndex The index of the CPU to read the SMM register. The
- value must be between 0 and the NumberOfCpus field in
- the System Management System Table (SMST).
- @param[in] RegName Identifies the SMM register to read.
-
- @return The value of the SMM register specified by RegName from the CPU
- specified by CpuIndex.
-**/
-UINT64
-EFIAPI
-SmmCpuFeaturesGetSmmRegister (
- IN UINTN CpuIndex,
- IN SMM_REG_NAME RegName
- )
-{
- if (FeaturePcdGet (PcdSmmFeatureControlEnable) && (RegName == SmmRegFeatureControl)) {
- return AsmReadMsr64 (SMM_FEATURES_LIB_SMM_FEATURE_CONTROL);
- }
-
- return 0;
-}
-
-/**
- Sets the value of an SMM register on a specified CPU.
- If the SMM register is not supported, then no action is performed.
-
- @param[in] CpuIndex The index of the CPU to write the SMM register. The
- value must be between 0 and the NumberOfCpus field in
- the System Management System Table (SMST).
- @param[in] RegName Identifies the SMM register to write.
- registers are read-only.
- @param[in] Value The value to write to the SMM register.
-**/
-VOID
-EFIAPI
-SmmCpuFeaturesSetSmmRegister (
- IN UINTN CpuIndex,
- IN SMM_REG_NAME RegName,
- IN UINT64 Value
- )
-{
- if (FeaturePcdGet (PcdSmmFeatureControlEnable) && (RegName == SmmRegFeatureControl)) {
- AsmWriteMsr64 (SMM_FEATURES_LIB_SMM_FEATURE_CONTROL, Value);
- }
-}
-
/**
Read an SMM Save State register on the target processor. If this function
returns EFI_UNSUPPORTED, then the caller is responsible for reading the
--
2.37.1.windows.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [edk2-devel] [PATCH 1/2] UefiCpuPkg/SmmCpuFeaturesLib: Abstract arch dependent code
2022-09-30 9:52 [PATCH 1/2] UefiCpuPkg/SmmCpuFeaturesLib: Abstract arch dependent code Chang, Abner
@ 2022-10-28 9:26 ` Ni, Ray
2022-10-30 13:03 ` Chang, Abner
0 siblings, 1 reply; 3+ messages in thread
From: Ni, Ray @ 2022-10-28 9:26 UTC (permalink / raw)
To: devel@edk2.groups.io, abner.chang@amd.com
Cc: Abdul Lateef Attar, Garrett Kirkendall, Paul Grimes, Dong, Eric,
Kumar, Rahul R
Can you do rename SmmCpuFeaturesLibCommon.c to IntelSmmCpuFeaturesLib.c?
This helps to keep the change history because I see that almost all content from Common.c is moved to Intelxxx.c.
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Chang,
> Abner via groups.io
> Sent: Friday, September 30, 2022 5:52 PM
> To: devel@edk2.groups.io
> Cc: Abdul Lateef Attar <abdattar@amd.com>; Garrett Kirkendall
> <garrett.kirkendall@amd.com>; Paul Grimes <paul.grimes@amd.com>; Dong,
> Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Kumar, Rahul R
> <rahul.r.kumar@intel.com>
> Subject: [edk2-devel] [PATCH 1/2] UefiCpuPkg/SmmCpuFeaturesLib:
> Abstract arch dependent code
>
> From: Abner Chang <abner.chang@amd.com>
>
> This change strips away Intel X86 implementation and put
> it in the IntelSmmCpuFeatureLib
>
> Signed-off-by: Abner Chang <abner.chang@amd.com>
> Cc: Abdul Lateef Attar <abdattar@amd.com>
> Cc: Garrett Kirkendall <garrett.kirkendall@amd.com>
> Cc: Paul Grimes <paul.grimes@amd.com>
> Cc: Eric Dong <eric.dong@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rahul Kumar <rahul1.kumar@intel.com>
> ---
> .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf | 1 +
> .../SmmCpuFeaturesLibStm.inf | 1 +
> .../StandaloneMmCpuFeaturesLib.inf | 1 +
> .../SmmCpuFeaturesLib/CpuFeaturesLib.h | 6 +
> .../IntelSmmCpuFeaturesLib.c | 403 ++++++++++++++++++
> .../SmmCpuFeaturesLibCommon.c | 391 +----------------
> 6 files changed, 413 insertions(+), 390 deletions(-)
> create mode 100644
> UefiCpuPkg/Library/SmmCpuFeaturesLib/IntelSmmCpuFeaturesLib.c
>
> diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
> b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
> index 7b5cef97008..9ac7dde78f8 100644
> --- a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
> +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
> @@ -18,6 +18,7 @@
>
> [Sources]
> CpuFeaturesLib.h
> + IntelSmmCpuFeaturesLib.c
> SmmCpuFeaturesLib.c
> SmmCpuFeaturesLibCommon.c
> SmmCpuFeaturesLibNoStm.c
> diff --git
> a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf
> b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf
> index 85214ee31cd..86d367e0a09 100644
> --- a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf
> +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf
> @@ -19,6 +19,7 @@
>
> [Sources]
> CpuFeaturesLib.h
> + IntelSmmCpuFeaturesLib.c
> SmmCpuFeaturesLibCommon.c
> SmmStm.c
> SmmStm.h
> diff --git
> a/UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.i
> nf
> b/UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.i
> nf
> index 3eacab48db3..61890205e18 100644
> ---
> a/UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.i
> nf
> +++
> b/UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.i
> nf
> @@ -20,6 +20,7 @@
>
> [Sources]
> CpuFeaturesLib.h
> + IntelSmmCpuFeaturesLib.c
> StandaloneMmCpuFeaturesLib.c
> SmmCpuFeaturesLibCommon.c
> SmmCpuFeaturesLibNoStm.c
> diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/CpuFeaturesLib.h
> b/UefiCpuPkg/Library/SmmCpuFeaturesLib/CpuFeaturesLib.h
> index 8a1c2adc5c4..fd3e902547c 100644
> --- a/UefiCpuPkg/Library/SmmCpuFeaturesLib/CpuFeaturesLib.h
> +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/CpuFeaturesLib.h
> @@ -9,6 +9,12 @@
> #ifndef CPU_FEATURES_LIB_H_
> #define CPU_FEATURES_LIB_H_
>
> +#include <Library/SmmCpuFeaturesLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/DebugLib.h>
> +
> /**
> Performs library initialization.
>
> diff --git
> a/UefiCpuPkg/Library/SmmCpuFeaturesLib/IntelSmmCpuFeaturesLib.c
> b/UefiCpuPkg/Library/SmmCpuFeaturesLib/IntelSmmCpuFeaturesLib.c
> new file mode 100644
> index 00000000000..cb4897b21e3
> --- /dev/null
> +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/IntelSmmCpuFeaturesLib.c
> @@ -0,0 +1,403 @@
> +/** @file
> +Implementation shared across all library instances.
> +
> +Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) Microsoft Corporation.<BR>
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "CpuFeaturesLib.h"
> +
> +#include <Library/MtrrLib.h>
> +#include <Register/Intel/Cpuid.h>
> +#include <Register/Intel/SmramSaveStateMap.h>
> +
> +//
> +// Machine Specific Registers (MSRs)
> +//
> +#define SMM_FEATURES_LIB_IA32_MTRR_CAP 0x0FE
> +#define SMM_FEATURES_LIB_IA32_FEATURE_CONTROL 0x03A
> +#define SMM_FEATURES_LIB_IA32_SMRR_PHYSBASE 0x1F2
> +#define SMM_FEATURES_LIB_IA32_SMRR_PHYSMASK 0x1F3
> +#define SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE 0x0A0
> +#define SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSMASK 0x0A1
> +#define EFI_MSR_SMRR_MASK 0xFFFFF000
> +#define EFI_MSR_SMRR_PHYS_MASK_VALID BIT11
> +#define SMM_FEATURES_LIB_SMM_FEATURE_CONTROL 0x4E0
> +
> +//
> +// MSRs required for configuration of SMM Code Access Check
> +//
> +#define SMM_FEATURES_LIB_IA32_MCA_CAP 0x17D
> +#define SMM_CODE_ACCESS_CHK_BIT BIT58
> +
> +//
> +// Set default value to assume IA-32 Architectural MSRs are used
> +//
> +UINT32 mSmrrPhysBaseMsr =
> SMM_FEATURES_LIB_IA32_SMRR_PHYSBASE;
> +UINT32 mSmrrPhysMaskMsr =
> SMM_FEATURES_LIB_IA32_SMRR_PHYSMASK;
> +
> +//
> +// Set default value to assume MTRRs need to be configured on each SMI
> +//
> +BOOLEAN mNeedConfigureMtrrs = TRUE;
> +
> +//
> +// Array for state of SMRR enable on all CPUs
> +//
> +BOOLEAN *mSmrrEnabled;
> +
> +/**
> + Performs library initialization.
> +
> + This initialization function contains common functionality shared betwen all
> + library instance constructors.
> +
> +**/
> +VOID
> +CpuFeaturesLibInitialization (
> + VOID
> + )
> +{
> + UINT32 RegEax;
> + UINT32 RegEdx;
> + UINTN FamilyId;
> + UINTN ModelId;
> +
> + //
> + // Retrieve CPU Family and Model
> + //
> + AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, &RegEdx);
> + FamilyId = (RegEax >> 8) & 0xf;
> + ModelId = (RegEax >> 4) & 0xf;
> + if ((FamilyId == 0x06) || (FamilyId == 0x0f)) {
> + ModelId = ModelId | ((RegEax >> 12) & 0xf0);
> + }
> +
> + //
> + // Check CPUID(CPUID_VERSION_INFO).EDX[12] for MTRR capability
> + //
> + if ((RegEdx & BIT12) != 0) {
> + //
> + // Check MTRR_CAP MSR bit 11 for SMRR support
> + //
> + if ((AsmReadMsr64 (SMM_FEATURES_LIB_IA32_MTRR_CAP) & BIT11) !=
> 0) {
> + ASSERT (FeaturePcdGet (PcdSmrrEnable));
> + }
> + }
> +
> + //
> + // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
> + // Volume 3C, Section 35.3 MSRs in the Intel(R) Atom(TM) Processor
> Family
> + //
> + // If CPU Family/Model is 06_1CH, 06_26H, 06_27H, 06_35H or 06_36H,
> then
> + // SMRR Physical Base and SMM Physical Mask MSRs are not available.
> + //
> + if (FamilyId == 0x06) {
> + if ((ModelId == 0x1C) || (ModelId == 0x26) || (ModelId == 0x27) ||
> (ModelId == 0x35) || (ModelId == 0x36)) {
> + ASSERT (!FeaturePcdGet (PcdSmrrEnable));
> + }
> + }
> +
> + //
> + // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
> + // Volume 3C, Section 35.2 MSRs in the Intel(R) Core(TM) 2 Processor
> Family
> + //
> + // If CPU Family/Model is 06_0F or 06_17, then use Intel(R) Core(TM) 2
> + // Processor Family MSRs
> + //
> + if (FamilyId == 0x06) {
> + if ((ModelId == 0x17) || (ModelId == 0x0f)) {
> + mSmrrPhysBaseMsr =
> SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE;
> + mSmrrPhysMaskMsr =
> SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSMASK;
> + }
> + }
> +
> + //
> + // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
> + // Volume 3C, Section 34.4.2 SMRAM Caching
> + // An IA-32 processor does not automatically write back and invalidate its
> + // caches before entering SMM or before exiting SMM. Because of this
> behavior,
> + // care must be taken in the placement of the SMRAM in system memory
> and in
> + // the caching of the SMRAM to prevent cache incoherence when
> switching back
> + // and forth between SMM and protected mode operation.
> + //
> + // An IA-32 processor is a processor that does not support the Intel 64
> + // Architecture. Support for the Intel 64 Architecture can be detected
> from
> + // CPUID(CPUID_EXTENDED_CPU_SIG).EDX[29]
> + //
> + // If an IA-32 processor is detected, then set mNeedConfigureMtrrs to
> TRUE,
> + // so caches are flushed on SMI entry and SMI exit, the interrupted code
> + // MTRRs are saved/restored, and MTRRs for SMM are loaded.
> + //
> + AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
> + if (RegEax >= CPUID_EXTENDED_CPU_SIG) {
> + AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx);
> + if ((RegEdx & BIT29) != 0) {
> + mNeedConfigureMtrrs = FALSE;
> + }
> + }
> +
> + //
> + // Allocate array for state of SMRR enable on all CPUs
> + //
> + mSmrrEnabled = (BOOLEAN *)AllocatePool (sizeof (BOOLEAN) *
> GetCpuMaxLogicalProcessorNumber ());
> + ASSERT (mSmrrEnabled != NULL);
> +}
> +
> +/**
> + Called during the very first SMI into System Management Mode to initialize
> + CPU features, including SMBASE, for the currently executing CPU. Since
> this
> + is the first SMI, the SMRAM Save State Map is at the default address of
> + SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET. The
> currently executing
> + CPU is specified by CpuIndex and CpuIndex can be used to access
> information
> + about the currently executing CPU in the ProcessorInfo array and the
> + HotPlugCpuData data structure.
> +
> + @param[in] CpuIndex The index of the CPU to initialize. The value
> + must be between 0 and the NumberOfCpus field in
> + the System Management System Table (SMST).
> + @param[in] IsMonarch TRUE if the CpuIndex is the index of the CPU
> that
> + was elected as monarch during System Management
> + Mode initialization.
> + FALSE if the CpuIndex is not the index of the CPU
> + that was elected as monarch during System
> + Management Mode initialization.
> + @param[in] ProcessorInfo Pointer to an array of
> EFI_PROCESSOR_INFORMATION
> + structures. ProcessorInfo[CpuIndex] contains the
> + information for the currently executing CPU.
> + @param[in] CpuHotPlugData Pointer to the CPU_HOT_PLUG_DATA
> structure that
> + contains the ApidId and SmBase arrays.
> +**/
> +VOID
> +EFIAPI
> +SmmCpuFeaturesInitializeProcessor (
> + IN UINTN CpuIndex,
> + IN BOOLEAN IsMonarch,
> + IN EFI_PROCESSOR_INFORMATION *ProcessorInfo,
> + IN CPU_HOT_PLUG_DATA *CpuHotPlugData
> + )
> +{
> + SMRAM_SAVE_STATE_MAP *CpuState;
> + UINT64 FeatureControl;
> + UINT32 RegEax;
> + UINT32 RegEdx;
> + UINTN FamilyId;
> + UINTN ModelId;
> +
> + //
> + // Configure SMBASE.
> + //
> + CpuState = (SMRAM_SAVE_STATE_MAP
> *)(UINTN)(SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET);
> + CpuState->x86.SMBASE = (UINT32)CpuHotPlugData->SmBase[CpuIndex];
> +
> + //
> + // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
> + // Volume 3C, Section 35.2 MSRs in the Intel(R) Core(TM) 2 Processor
> Family
> + //
> + // If Intel(R) Core(TM) Core(TM) 2 Processor Family MSRs are being used,
> then
> + // make sure SMRR Enable(BIT3) of MSR_FEATURE_CONTROL MSR(0x3A)
> is set before
> + // accessing SMRR base/mask MSRs. If Lock(BIT0) of
> MSR_FEATURE_CONTROL MSR(0x3A)
> + // is set, then the MSR is locked and can not be modified.
> + //
> + if ((FeaturePcdGet (PcdSmrrEnable)) && (mSmrrPhysBaseMsr ==
> SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE)) {
> + FeatureControl = AsmReadMsr64
> (SMM_FEATURES_LIB_IA32_FEATURE_CONTROL);
> + if ((FeatureControl & BIT3) == 0) {
> + ASSERT ((FeatureControl & BIT0) == 0);
> + if ((FeatureControl & BIT0) == 0) {
> + AsmWriteMsr64 (SMM_FEATURES_LIB_IA32_FEATURE_CONTROL,
> FeatureControl | BIT3);
> + }
> + }
> + }
> +
> + //
> + // If SMRR is supported, then program SMRR base/mask MSRs.
> + // The EFI_MSR_SMRR_PHYS_MASK_VALID bit is not set until the first
> normal SMI.
> + // The code that initializes SMM environment is running in normal mode
> + // from SMRAM region. If SMRR is enabled here, then the SMRAM region
> + // is protected and the normal mode code execution will fail.
> + //
> + if (FeaturePcdGet (PcdSmrrEnable)) {
> + //
> + // SMRR size cannot be less than 4-KBytes
> + // SMRR size must be of length 2^n
> + // SMRR base alignment cannot be less than SMRR length
> + //
> + if ((CpuHotPlugData->SmrrSize < SIZE_4KB) ||
> + (CpuHotPlugData->SmrrSize != GetPowerOfTwo32 (CpuHotPlugData-
> >SmrrSize)) ||
> + ((CpuHotPlugData->SmrrBase & ~(CpuHotPlugData->SmrrSize - 1)) !=
> CpuHotPlugData->SmrrBase))
> + {
> + //
> + // Print message and halt if CPU is Monarch
> + //
> + if (IsMonarch) {
> + DEBUG ((DEBUG_ERROR, "SMM Base/Size does not meet
> alignment/size requirement!\n"));
> + CpuDeadLoop ();
> + }
> + } else {
> + AsmWriteMsr64 (mSmrrPhysBaseMsr, CpuHotPlugData->SmrrBase |
> MTRR_CACHE_WRITE_BACK);
> + AsmWriteMsr64 (mSmrrPhysMaskMsr, (~(CpuHotPlugData->SmrrSize - 1)
> & EFI_MSR_SMRR_MASK));
> + mSmrrEnabled[CpuIndex] = FALSE;
> + }
> + }
> +
> + //
> + // Retrieve CPU Family and Model
> + //
> + AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, &RegEdx);
> + FamilyId = (RegEax >> 8) & 0xf;
> + ModelId = (RegEax >> 4) & 0xf;
> + if ((FamilyId == 0x06) || (FamilyId == 0x0f)) {
> + ModelId = ModelId | ((RegEax >> 12) & 0xf0);
> + }
> +
> + //
> + // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
> + // Volume 3C, Section 35.10.1 MSRs in 4th Generation Intel(R) Core(TM)
> + // Processor Family.
> + //
> + // If CPU Family/Model is 06_3C, 06_45, or 06_46 then use 4th Generation
> + // Intel(R) Core(TM) Processor Family MSRs.
> + //
> + if (FamilyId == 0x06) {
> + if ((ModelId == 0x3C) || (ModelId == 0x45) || (ModelId == 0x46) ||
> + (ModelId == 0x3D) || (ModelId == 0x47) || (ModelId == 0x4E) ||
> (ModelId == 0x4F) ||
> + (ModelId == 0x3F) || (ModelId == 0x56) || (ModelId == 0x57) ||
> (ModelId == 0x5C) ||
> + (ModelId == 0x8C))
> + {
> + //
> + // Check to see if the CPU supports the SMM Code Access Check feature
> + // Do not access this MSR unless the CPU supports the
> SmmRegFeatureControl
> + //
> + if ((AsmReadMsr64 (SMM_FEATURES_LIB_IA32_MCA_CAP) &
> SMM_CODE_ACCESS_CHK_BIT) != 0) {
> + ASSERT (FeaturePcdGet (PcdSmmFeatureControlEnable));
> + }
> + }
> + }
> +
> + //
> + // Call internal worker function that completes the CPU initialization
> + //
> + FinishSmmCpuFeaturesInitializeProcessor ();
> +}
> +
> +/**
> + Determines if MTRR registers must be configured to set SMRAM cache-
> ability
> + when executing in System Management Mode.
> +
> + @retval TRUE MTRR registers must be configured to set SMRAM cache-
> ability.
> + @retval FALSE MTRR registers do not need to be configured to set
> SMRAM
> + cache-ability.
> +**/
> +BOOLEAN
> +EFIAPI
> +SmmCpuFeaturesNeedConfigureMtrrs (
> + VOID
> + )
> +{
> + return mNeedConfigureMtrrs;
> +}
> +
> +/**
> + Disable SMRR register if SMRR is supported and
> SmmCpuFeaturesNeedConfigureMtrrs()
> + returns TRUE.
> +**/
> +VOID
> +EFIAPI
> +SmmCpuFeaturesDisableSmrr (
> + VOID
> + )
> +{
> + if (FeaturePcdGet (PcdSmrrEnable) && mNeedConfigureMtrrs) {
> + AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64
> (mSmrrPhysMaskMsr) & ~EFI_MSR_SMRR_PHYS_MASK_VALID);
> + }
> +}
> +
> +/**
> + Enable SMRR register if SMRR is supported and
> SmmCpuFeaturesNeedConfigureMtrrs()
> + returns TRUE.
> +**/
> +VOID
> +EFIAPI
> +SmmCpuFeaturesReenableSmrr (
> + VOID
> + )
> +{
> + if (FeaturePcdGet (PcdSmrrEnable) && mNeedConfigureMtrrs) {
> + AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64
> (mSmrrPhysMaskMsr) | EFI_MSR_SMRR_PHYS_MASK_VALID);
> + }
> +}
> +
> +/**
> + Processor specific hook point each time a CPU enters System Management
> Mode.
> +
> + @param[in] CpuIndex The index of the CPU that has entered SMM. The
> value
> + must be between 0 and the NumberOfCpus field in the
> + System Management System Table (SMST).
> +**/
> +VOID
> +EFIAPI
> +SmmCpuFeaturesRendezvousEntry (
> + IN UINTN CpuIndex
> + )
> +{
> + //
> + // If SMRR is supported and this is the first normal SMI, then enable SMRR
> + //
> + if (FeaturePcdGet (PcdSmrrEnable) && !mSmrrEnabled[CpuIndex]) {
> + AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64
> (mSmrrPhysMaskMsr) | EFI_MSR_SMRR_PHYS_MASK_VALID);
> + mSmrrEnabled[CpuIndex] = TRUE;
> + }
> +}
> +
> +/**
> + Returns the current value of the SMM register for the specified CPU.
> + If the SMM register is not supported, then 0 is returned.
> +
> + @param[in] CpuIndex The index of the CPU to read the SMM register.
> The
> + value must be between 0 and the NumberOfCpus field in
> + the System Management System Table (SMST).
> + @param[in] RegName Identifies the SMM register to read.
> +
> + @return The value of the SMM register specified by RegName from the
> CPU
> + specified by CpuIndex.
> +**/
> +UINT64
> +EFIAPI
> +SmmCpuFeaturesGetSmmRegister (
> + IN UINTN CpuIndex,
> + IN SMM_REG_NAME RegName
> + )
> +{
> + if (FeaturePcdGet (PcdSmmFeatureControlEnable) && (RegName ==
> SmmRegFeatureControl)) {
> + return AsmReadMsr64
> (SMM_FEATURES_LIB_SMM_FEATURE_CONTROL);
> + }
> +
> + return 0;
> +}
> +
> +/**
> + Sets the value of an SMM register on a specified CPU.
> + If the SMM register is not supported, then no action is performed.
> +
> + @param[in] CpuIndex The index of the CPU to write the SMM register.
> The
> + value must be between 0 and the NumberOfCpus field in
> + the System Management System Table (SMST).
> + @param[in] RegName Identifies the SMM register to write.
> + registers are read-only.
> + @param[in] Value The value to write to the SMM register.
> +**/
> +VOID
> +EFIAPI
> +SmmCpuFeaturesSetSmmRegister (
> + IN UINTN CpuIndex,
> + IN SMM_REG_NAME RegName,
> + IN UINT64 Value
> + )
> +{
> + if (FeaturePcdGet (PcdSmmFeatureControlEnable) && (RegName ==
> SmmRegFeatureControl)) {
> + AsmWriteMsr64 (SMM_FEATURES_LIB_SMM_FEATURE_CONTROL,
> Value);
> + }
> +}
> +
> diff --git
> a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibCommon.c
> b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibCommon.c
> index 75a0ec8e948..7777e52740e 100644
> ---
> a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibCommon.c
> +++
> b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibCommon.c
> @@ -14,278 +14,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> #include <Library/PcdLib.h>
> #include <Library/MemoryAllocationLib.h>
> #include <Library/DebugLib.h>
> -#include <Register/Intel/Cpuid.h>
> -#include <Register/Intel/SmramSaveStateMap.h>
> -#include "CpuFeaturesLib.h"
> -
> -//
> -// Machine Specific Registers (MSRs)
> -//
> -#define SMM_FEATURES_LIB_IA32_MTRR_CAP 0x0FE
> -#define SMM_FEATURES_LIB_IA32_FEATURE_CONTROL 0x03A
> -#define SMM_FEATURES_LIB_IA32_SMRR_PHYSBASE 0x1F2
> -#define SMM_FEATURES_LIB_IA32_SMRR_PHYSMASK 0x1F3
> -#define SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE 0x0A0
> -#define SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSMASK 0x0A1
> -#define EFI_MSR_SMRR_MASK 0xFFFFF000
> -#define EFI_MSR_SMRR_PHYS_MASK_VALID BIT11
> -#define SMM_FEATURES_LIB_SMM_FEATURE_CONTROL 0x4E0
> -
> -//
> -// MSRs required for configuration of SMM Code Access Check
> -//
> -#define SMM_FEATURES_LIB_IA32_MCA_CAP 0x17D
> -#define SMM_CODE_ACCESS_CHK_BIT BIT58
> -
> -//
> -// Set default value to assume IA-32 Architectural MSRs are used
> -//
> -UINT32 mSmrrPhysBaseMsr =
> SMM_FEATURES_LIB_IA32_SMRR_PHYSBASE;
> -UINT32 mSmrrPhysMaskMsr =
> SMM_FEATURES_LIB_IA32_SMRR_PHYSMASK;
> -
> -//
> -// Set default value to assume MTRRs need to be configured on each SMI
> -//
> -BOOLEAN mNeedConfigureMtrrs = TRUE;
> -
> -//
> -// Array for state of SMRR enable on all CPUs
> -//
> -BOOLEAN *mSmrrEnabled;
> -
> -/**
> - Performs library initialization.
> -
> - This initialization function contains common functionality shared betwen all
> - library instance constructors.
> -
> -**/
> -VOID
> -CpuFeaturesLibInitialization (
> - VOID
> - )
> -{
> - UINT32 RegEax;
> - UINT32 RegEdx;
> - UINTN FamilyId;
> - UINTN ModelId;
> -
> - //
> - // Retrieve CPU Family and Model
> - //
> - AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, &RegEdx);
> - FamilyId = (RegEax >> 8) & 0xf;
> - ModelId = (RegEax >> 4) & 0xf;
> - if ((FamilyId == 0x06) || (FamilyId == 0x0f)) {
> - ModelId = ModelId | ((RegEax >> 12) & 0xf0);
> - }
> -
> - //
> - // Check CPUID(CPUID_VERSION_INFO).EDX[12] for MTRR capability
> - //
> - if ((RegEdx & BIT12) != 0) {
> - //
> - // Check MTRR_CAP MSR bit 11 for SMRR support
> - //
> - if ((AsmReadMsr64 (SMM_FEATURES_LIB_IA32_MTRR_CAP) & BIT11) != 0)
> {
> - ASSERT (FeaturePcdGet (PcdSmrrEnable));
> - }
> - }
> -
> - //
> - // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
> - // Volume 3C, Section 35.3 MSRs in the Intel(R) Atom(TM) Processor Family
> - //
> - // If CPU Family/Model is 06_1CH, 06_26H, 06_27H, 06_35H or 06_36H, then
> - // SMRR Physical Base and SMM Physical Mask MSRs are not available.
> - //
> - if (FamilyId == 0x06) {
> - if ((ModelId == 0x1C) || (ModelId == 0x26) || (ModelId == 0x27) ||
> (ModelId == 0x35) || (ModelId == 0x36)) {
> - ASSERT (!FeaturePcdGet (PcdSmrrEnable));
> - }
> - }
> -
> - //
> - // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
> - // Volume 3C, Section 35.2 MSRs in the Intel(R) Core(TM) 2 Processor
> Family
> - //
> - // If CPU Family/Model is 06_0F or 06_17, then use Intel(R) Core(TM) 2
> - // Processor Family MSRs
> - //
> - if (FamilyId == 0x06) {
> - if ((ModelId == 0x17) || (ModelId == 0x0f)) {
> - mSmrrPhysBaseMsr =
> SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE;
> - mSmrrPhysMaskMsr =
> SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSMASK;
> - }
> - }
> -
> - //
> - // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
> - // Volume 3C, Section 34.4.2 SMRAM Caching
> - // An IA-32 processor does not automatically write back and invalidate its
> - // caches before entering SMM or before exiting SMM. Because of this
> behavior,
> - // care must be taken in the placement of the SMRAM in system memory
> and in
> - // the caching of the SMRAM to prevent cache incoherence when
> switching back
> - // and forth between SMM and protected mode operation.
> - //
> - // An IA-32 processor is a processor that does not support the Intel 64
> - // Architecture. Support for the Intel 64 Architecture can be detected from
> - // CPUID(CPUID_EXTENDED_CPU_SIG).EDX[29]
> - //
> - // If an IA-32 processor is detected, then set mNeedConfigureMtrrs to
> TRUE,
> - // so caches are flushed on SMI entry and SMI exit, the interrupted code
> - // MTRRs are saved/restored, and MTRRs for SMM are loaded.
> - //
> - AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
> - if (RegEax >= CPUID_EXTENDED_CPU_SIG) {
> - AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx);
> - if ((RegEdx & BIT29) != 0) {
> - mNeedConfigureMtrrs = FALSE;
> - }
> - }
> -
> - //
> - // Allocate array for state of SMRR enable on all CPUs
> - //
> - mSmrrEnabled = (BOOLEAN *)AllocatePool (sizeof (BOOLEAN) *
> GetCpuMaxLogicalProcessorNumber ());
> - ASSERT (mSmrrEnabled != NULL);
> -}
> -
> -/**
> - Called during the very first SMI into System Management Mode to initialize
> - CPU features, including SMBASE, for the currently executing CPU. Since
> this
> - is the first SMI, the SMRAM Save State Map is at the default address of
> - SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET. The
> currently executing
> - CPU is specified by CpuIndex and CpuIndex can be used to access
> information
> - about the currently executing CPU in the ProcessorInfo array and the
> - HotPlugCpuData data structure.
> -
> - @param[in] CpuIndex The index of the CPU to initialize. The value
> - must be between 0 and the NumberOfCpus field in
> - the System Management System Table (SMST).
> - @param[in] IsMonarch TRUE if the CpuIndex is the index of the CPU
> that
> - was elected as monarch during System Management
> - Mode initialization.
> - FALSE if the CpuIndex is not the index of the CPU
> - that was elected as monarch during System
> - Management Mode initialization.
> - @param[in] ProcessorInfo Pointer to an array of
> EFI_PROCESSOR_INFORMATION
> - structures. ProcessorInfo[CpuIndex] contains the
> - information for the currently executing CPU.
> - @param[in] CpuHotPlugData Pointer to the CPU_HOT_PLUG_DATA
> structure that
> - contains the ApidId and SmBase arrays.
> -**/
> -VOID
> -EFIAPI
> -SmmCpuFeaturesInitializeProcessor (
> - IN UINTN CpuIndex,
> - IN BOOLEAN IsMonarch,
> - IN EFI_PROCESSOR_INFORMATION *ProcessorInfo,
> - IN CPU_HOT_PLUG_DATA *CpuHotPlugData
> - )
> -{
> - SMRAM_SAVE_STATE_MAP *CpuState;
> - UINT64 FeatureControl;
> - UINT32 RegEax;
> - UINT32 RegEdx;
> - UINTN FamilyId;
> - UINTN ModelId;
> -
> - //
> - // Configure SMBASE.
> - //
> - CpuState = (SMRAM_SAVE_STATE_MAP
> *)(UINTN)(SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET);
> - CpuState->x86.SMBASE = (UINT32)CpuHotPlugData->SmBase[CpuIndex];
> -
> - //
> - // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
> - // Volume 3C, Section 35.2 MSRs in the Intel(R) Core(TM) 2 Processor
> Family
> - //
> - // If Intel(R) Core(TM) Core(TM) 2 Processor Family MSRs are being used,
> then
> - // make sure SMRR Enable(BIT3) of MSR_FEATURE_CONTROL MSR(0x3A) is
> set before
> - // accessing SMRR base/mask MSRs. If Lock(BIT0) of
> MSR_FEATURE_CONTROL MSR(0x3A)
> - // is set, then the MSR is locked and can not be modified.
> - //
> - if ((FeaturePcdGet (PcdSmrrEnable)) && (mSmrrPhysBaseMsr ==
> SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE)) {
> - FeatureControl = AsmReadMsr64
> (SMM_FEATURES_LIB_IA32_FEATURE_CONTROL);
> - if ((FeatureControl & BIT3) == 0) {
> - ASSERT ((FeatureControl & BIT0) == 0);
> - if ((FeatureControl & BIT0) == 0) {
> - AsmWriteMsr64 (SMM_FEATURES_LIB_IA32_FEATURE_CONTROL,
> FeatureControl | BIT3);
> - }
> - }
> - }
>
> - //
> - // If SMRR is supported, then program SMRR base/mask MSRs.
> - // The EFI_MSR_SMRR_PHYS_MASK_VALID bit is not set until the first
> normal SMI.
> - // The code that initializes SMM environment is running in normal mode
> - // from SMRAM region. If SMRR is enabled here, then the SMRAM region
> - // is protected and the normal mode code execution will fail.
> - //
> - if (FeaturePcdGet (PcdSmrrEnable)) {
> - //
> - // SMRR size cannot be less than 4-KBytes
> - // SMRR size must be of length 2^n
> - // SMRR base alignment cannot be less than SMRR length
> - //
> - if ((CpuHotPlugData->SmrrSize < SIZE_4KB) ||
> - (CpuHotPlugData->SmrrSize != GetPowerOfTwo32 (CpuHotPlugData-
> >SmrrSize)) ||
> - ((CpuHotPlugData->SmrrBase & ~(CpuHotPlugData->SmrrSize - 1)) !=
> CpuHotPlugData->SmrrBase))
> - {
> - //
> - // Print message and halt if CPU is Monarch
> - //
> - if (IsMonarch) {
> - DEBUG ((DEBUG_ERROR, "SMM Base/Size does not meet
> alignment/size requirement!\n"));
> - CpuDeadLoop ();
> - }
> - } else {
> - AsmWriteMsr64 (mSmrrPhysBaseMsr, CpuHotPlugData->SmrrBase |
> MTRR_CACHE_WRITE_BACK);
> - AsmWriteMsr64 (mSmrrPhysMaskMsr, (~(CpuHotPlugData->SmrrSize - 1)
> & EFI_MSR_SMRR_MASK));
> - mSmrrEnabled[CpuIndex] = FALSE;
> - }
> - }
> -
> - //
> - // Retrieve CPU Family and Model
> - //
> - AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, &RegEdx);
> - FamilyId = (RegEax >> 8) & 0xf;
> - ModelId = (RegEax >> 4) & 0xf;
> - if ((FamilyId == 0x06) || (FamilyId == 0x0f)) {
> - ModelId = ModelId | ((RegEax >> 12) & 0xf0);
> - }
> -
> - //
> - // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
> - // Volume 3C, Section 35.10.1 MSRs in 4th Generation Intel(R) Core(TM)
> - // Processor Family.
> - //
> - // If CPU Family/Model is 06_3C, 06_45, or 06_46 then use 4th Generation
> - // Intel(R) Core(TM) Processor Family MSRs.
> - //
> - if (FamilyId == 0x06) {
> - if ((ModelId == 0x3C) || (ModelId == 0x45) || (ModelId == 0x46) ||
> - (ModelId == 0x3D) || (ModelId == 0x47) || (ModelId == 0x4E) ||
> (ModelId == 0x4F) ||
> - (ModelId == 0x3F) || (ModelId == 0x56) || (ModelId == 0x57) ||
> (ModelId == 0x5C) ||
> - (ModelId == 0x8C))
> - {
> - //
> - // Check to see if the CPU supports the SMM Code Access Check feature
> - // Do not access this MSR unless the CPU supports the
> SmmRegFeatureControl
> - //
> - if ((AsmReadMsr64 (SMM_FEATURES_LIB_IA32_MCA_CAP) &
> SMM_CODE_ACCESS_CHK_BIT) != 0) {
> - ASSERT (FeaturePcdGet (PcdSmmFeatureControlEnable));
> - }
> - }
> - }
> -
> - //
> - // Call internal worker function that completes the CPU initialization
> - //
> - FinishSmmCpuFeaturesInitializeProcessor ();
> -}
> +#include "CpuFeaturesLib.h"
>
> /**
> This function updates the SMRAM save state on the currently executing
> CPU
> @@ -345,75 +75,6 @@ SmmCpuFeaturesSmmRelocationComplete (
> {
> }
>
> -/**
> - Determines if MTRR registers must be configured to set SMRAM cache-
> ability
> - when executing in System Management Mode.
> -
> - @retval TRUE MTRR registers must be configured to set SMRAM cache-
> ability.
> - @retval FALSE MTRR registers do not need to be configured to set SMRAM
> - cache-ability.
> -**/
> -BOOLEAN
> -EFIAPI
> -SmmCpuFeaturesNeedConfigureMtrrs (
> - VOID
> - )
> -{
> - return mNeedConfigureMtrrs;
> -}
> -
> -/**
> - Disable SMRR register if SMRR is supported and
> SmmCpuFeaturesNeedConfigureMtrrs()
> - returns TRUE.
> -**/
> -VOID
> -EFIAPI
> -SmmCpuFeaturesDisableSmrr (
> - VOID
> - )
> -{
> - if (FeaturePcdGet (PcdSmrrEnable) && mNeedConfigureMtrrs) {
> - AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64
> (mSmrrPhysMaskMsr) & ~EFI_MSR_SMRR_PHYS_MASK_VALID);
> - }
> -}
> -
> -/**
> - Enable SMRR register if SMRR is supported and
> SmmCpuFeaturesNeedConfigureMtrrs()
> - returns TRUE.
> -**/
> -VOID
> -EFIAPI
> -SmmCpuFeaturesReenableSmrr (
> - VOID
> - )
> -{
> - if (FeaturePcdGet (PcdSmrrEnable) && mNeedConfigureMtrrs) {
> - AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64
> (mSmrrPhysMaskMsr) | EFI_MSR_SMRR_PHYS_MASK_VALID);
> - }
> -}
> -
> -/**
> - Processor specific hook point each time a CPU enters System Management
> Mode.
> -
> - @param[in] CpuIndex The index of the CPU that has entered SMM. The
> value
> - must be between 0 and the NumberOfCpus field in the
> - System Management System Table (SMST).
> -**/
> -VOID
> -EFIAPI
> -SmmCpuFeaturesRendezvousEntry (
> - IN UINTN CpuIndex
> - )
> -{
> - //
> - // If SMRR is supported and this is the first normal SMI, then enable SMRR
> - //
> - if (FeaturePcdGet (PcdSmrrEnable) && !mSmrrEnabled[CpuIndex]) {
> - AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64
> (mSmrrPhysMaskMsr) | EFI_MSR_SMRR_PHYS_MASK_VALID);
> - mSmrrEnabled[CpuIndex] = TRUE;
> - }
> -}
> -
> /**
> Processor specific hook point each time a CPU exits System Management
> Mode.
>
> @@ -456,56 +117,6 @@ SmmCpuFeaturesIsSmmRegisterSupported (
> return FALSE;
> }
>
> -/**
> - Returns the current value of the SMM register for the specified CPU.
> - If the SMM register is not supported, then 0 is returned.
> -
> - @param[in] CpuIndex The index of the CPU to read the SMM register.
> The
> - value must be between 0 and the NumberOfCpus field in
> - the System Management System Table (SMST).
> - @param[in] RegName Identifies the SMM register to read.
> -
> - @return The value of the SMM register specified by RegName from the
> CPU
> - specified by CpuIndex.
> -**/
> -UINT64
> -EFIAPI
> -SmmCpuFeaturesGetSmmRegister (
> - IN UINTN CpuIndex,
> - IN SMM_REG_NAME RegName
> - )
> -{
> - if (FeaturePcdGet (PcdSmmFeatureControlEnable) && (RegName ==
> SmmRegFeatureControl)) {
> - return AsmReadMsr64 (SMM_FEATURES_LIB_SMM_FEATURE_CONTROL);
> - }
> -
> - return 0;
> -}
> -
> -/**
> - Sets the value of an SMM register on a specified CPU.
> - If the SMM register is not supported, then no action is performed.
> -
> - @param[in] CpuIndex The index of the CPU to write the SMM register.
> The
> - value must be between 0 and the NumberOfCpus field in
> - the System Management System Table (SMST).
> - @param[in] RegName Identifies the SMM register to write.
> - registers are read-only.
> - @param[in] Value The value to write to the SMM register.
> -**/
> -VOID
> -EFIAPI
> -SmmCpuFeaturesSetSmmRegister (
> - IN UINTN CpuIndex,
> - IN SMM_REG_NAME RegName,
> - IN UINT64 Value
> - )
> -{
> - if (FeaturePcdGet (PcdSmmFeatureControlEnable) && (RegName ==
> SmmRegFeatureControl)) {
> - AsmWriteMsr64 (SMM_FEATURES_LIB_SMM_FEATURE_CONTROL,
> Value);
> - }
> -}
> -
> /**
> Read an SMM Save State register on the target processor. If this function
> returns EFI_UNSUPPORTED, then the caller is responsible for reading the
> --
> 2.37.1.windows.1
>
>
>
>
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [edk2-devel] [PATCH 1/2] UefiCpuPkg/SmmCpuFeaturesLib: Abstract arch dependent code
2022-10-28 9:26 ` [edk2-devel] " Ni, Ray
@ 2022-10-30 13:03 ` Chang, Abner
0 siblings, 0 replies; 3+ messages in thread
From: Chang, Abner @ 2022-10-30 13:03 UTC (permalink / raw)
To: devel@edk2.groups.io, ray.ni@intel.com
Cc: Attar, AbdulLateef (Abdul Lateef), Kirkendall, Garrett,
Grimes, Paul, Dong, Eric, Kumar, Rahul R
[AMD Official Use Only - General]
Hi Ray,
Ok, the V2 send. Which rename SmmCpuFeaturesLiCommon.c to IntelSmmCpuFeaturesLib.c in the 1/3 patch.
Thanks
Abner
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Ni, Ray via
> groups.io
> Sent: Friday, October 28, 2022 5:26 PM
> To: devel@edk2.groups.io; Chang, Abner <Abner.Chang@amd.com>
> Cc: Attar, AbdulLateef (Abdul Lateef) <AbdulLateef.Attar@amd.com>; Kirkendall,
> Garrett <Garrett.Kirkendall@amd.com>; Grimes, Paul <Paul.Grimes@amd.com>;
> Dong, Eric <eric.dong@intel.com>; Kumar, Rahul R <rahul.r.kumar@intel.com>
> Subject: Re: [edk2-devel] [PATCH 1/2] UefiCpuPkg/SmmCpuFeaturesLib:
> Abstract arch dependent code
>
> Caution: This message originated from an External Source. Use proper caution
> when opening attachments, clicking links, or responding.
>
>
> Can you do rename SmmCpuFeaturesLibCommon.c to
> IntelSmmCpuFeaturesLib.c?
> This helps to keep the change history because I see that almost all content from
> Common.c is moved to Intelxxx.c.
>
>
> > -----Original Message-----
> > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Chang,
> > Abner via groups.io
> > Sent: Friday, September 30, 2022 5:52 PM
> > To: devel@edk2.groups.io
> > Cc: Abdul Lateef Attar <abdattar@amd.com>; Garrett Kirkendall
> > <garrett.kirkendall@amd.com>; Paul Grimes <paul.grimes@amd.com>; Dong,
> > Eric <eric.dong@intel.com>; Ni, Ray <ray.ni@intel.com>; Kumar, Rahul R
> > <rahul.r.kumar@intel.com>
> > Subject: [edk2-devel] [PATCH 1/2] UefiCpuPkg/SmmCpuFeaturesLib:
> > Abstract arch dependent code
> >
> > From: Abner Chang <abner.chang@amd.com>
> >
> > This change strips away Intel X86 implementation and put it in the
> > IntelSmmCpuFeatureLib
> >
> > Signed-off-by: Abner Chang <abner.chang@amd.com>
> > Cc: Abdul Lateef Attar <abdattar@amd.com>
> > Cc: Garrett Kirkendall <garrett.kirkendall@amd.com>
> > Cc: Paul Grimes <paul.grimes@amd.com>
> > Cc: Eric Dong <eric.dong@intel.com>
> > Cc: Ray Ni <ray.ni@intel.com>
> > Cc: Rahul Kumar <rahul1.kumar@intel.com>
> > ---
> > .../SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf | 1 +
> > .../SmmCpuFeaturesLibStm.inf | 1 +
> > .../StandaloneMmCpuFeaturesLib.inf | 1 +
> > .../SmmCpuFeaturesLib/CpuFeaturesLib.h | 6 +
> > .../IntelSmmCpuFeaturesLib.c | 403 ++++++++++++++++++
> > .../SmmCpuFeaturesLibCommon.c | 391 +----------------
> > 6 files changed, 413 insertions(+), 390 deletions(-) create mode
> > 100644 UefiCpuPkg/Library/SmmCpuFeaturesLib/IntelSmmCpuFeaturesLib.c
> >
> > diff --git
> > a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
> > b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
> > index 7b5cef97008..9ac7dde78f8 100644
> > --- a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
> > +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf
> > @@ -18,6 +18,7 @@
> >
> > [Sources]
> > CpuFeaturesLib.h
> > + IntelSmmCpuFeaturesLib.c
> > SmmCpuFeaturesLib.c
> > SmmCpuFeaturesLibCommon.c
> > SmmCpuFeaturesLibNoStm.c
> > diff --git
> > a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf
> > b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf
> > index 85214ee31cd..86d367e0a09 100644
> > --- a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf
> > +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf
> > @@ -19,6 +19,7 @@
> >
> > [Sources]
> > CpuFeaturesLib.h
> > + IntelSmmCpuFeaturesLib.c
> > SmmCpuFeaturesLibCommon.c
> > SmmStm.c
> > SmmStm.h
> > diff --git
> > a/UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.i
> > nf
> > b/UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.i
> > nf
> > index 3eacab48db3..61890205e18 100644
> > ---
> > a/UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.i
> > nf
> > +++
> > b/UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.i
> > nf
> > @@ -20,6 +20,7 @@
> >
> > [Sources]
> > CpuFeaturesLib.h
> > + IntelSmmCpuFeaturesLib.c
> > StandaloneMmCpuFeaturesLib.c
> > SmmCpuFeaturesLibCommon.c
> > SmmCpuFeaturesLibNoStm.c
> > diff --git a/UefiCpuPkg/Library/SmmCpuFeaturesLib/CpuFeaturesLib.h
> > b/UefiCpuPkg/Library/SmmCpuFeaturesLib/CpuFeaturesLib.h
> > index 8a1c2adc5c4..fd3e902547c 100644
> > --- a/UefiCpuPkg/Library/SmmCpuFeaturesLib/CpuFeaturesLib.h
> > +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/CpuFeaturesLib.h
> > @@ -9,6 +9,12 @@
> > #ifndef CPU_FEATURES_LIB_H_
> > #define CPU_FEATURES_LIB_H_
> >
> > +#include <Library/SmmCpuFeaturesLib.h> #include <Library/BaseLib.h>
> > +#include <Library/PcdLib.h> #include <Library/MemoryAllocationLib.h>
> > +#include <Library/DebugLib.h>
> > +
> > /**
> > Performs library initialization.
> >
> > diff --git
> > a/UefiCpuPkg/Library/SmmCpuFeaturesLib/IntelSmmCpuFeaturesLib.c
> > b/UefiCpuPkg/Library/SmmCpuFeaturesLib/IntelSmmCpuFeaturesLib.c
> > new file mode 100644
> > index 00000000000..cb4897b21e3
> > --- /dev/null
> > +++ b/UefiCpuPkg/Library/SmmCpuFeaturesLib/IntelSmmCpuFeaturesLib.c
> > @@ -0,0 +1,403 @@
> > +/** @file
> > +Implementation shared across all library instances.
> > +
> > +Copyright (c) 2010 - 2019, Intel Corporation. All rights
> > +reserved.<BR> Copyright (c) Microsoft Corporation.<BR>
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include "CpuFeaturesLib.h"
> > +
> > +#include <Library/MtrrLib.h>
> > +#include <Register/Intel/Cpuid.h>
> > +#include <Register/Intel/SmramSaveStateMap.h>
> > +
> > +//
> > +// Machine Specific Registers (MSRs)
> > +//
> > +#define SMM_FEATURES_LIB_IA32_MTRR_CAP 0x0FE
> > +#define SMM_FEATURES_LIB_IA32_FEATURE_CONTROL 0x03A
> > +#define SMM_FEATURES_LIB_IA32_SMRR_PHYSBASE 0x1F2
> > +#define SMM_FEATURES_LIB_IA32_SMRR_PHYSMASK 0x1F3
> > +#define SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE 0x0A0 #define
> > +SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSMASK 0x0A1
> > +#define EFI_MSR_SMRR_MASK 0xFFFFF000
> > +#define EFI_MSR_SMRR_PHYS_MASK_VALID BIT11
> > +#define SMM_FEATURES_LIB_SMM_FEATURE_CONTROL 0x4E0
> > +
> > +//
> > +// MSRs required for configuration of SMM Code Access Check //
> > +#define SMM_FEATURES_LIB_IA32_MCA_CAP 0x17D
> > +#define SMM_CODE_ACCESS_CHK_BIT BIT58
> > +
> > +//
> > +// Set default value to assume IA-32 Architectural MSRs are used //
> > +UINT32 mSmrrPhysBaseMsr =
> > SMM_FEATURES_LIB_IA32_SMRR_PHYSBASE;
> > +UINT32 mSmrrPhysMaskMsr =
> > SMM_FEATURES_LIB_IA32_SMRR_PHYSMASK;
> > +
> > +//
> > +// Set default value to assume MTRRs need to be configured on each
> > +SMI // BOOLEAN mNeedConfigureMtrrs = TRUE;
> > +
> > +//
> > +// Array for state of SMRR enable on all CPUs // BOOLEAN
> > +*mSmrrEnabled;
> > +
> > +/**
> > + Performs library initialization.
> > +
> > + This initialization function contains common functionality shared
> > + betwen all library instance constructors.
> > +
> > +**/
> > +VOID
> > +CpuFeaturesLibInitialization (
> > + VOID
> > + )
> > +{
> > + UINT32 RegEax;
> > + UINT32 RegEdx;
> > + UINTN FamilyId;
> > + UINTN ModelId;
> > +
> > + //
> > + // Retrieve CPU Family and Model
> > + //
> > + AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, &RegEdx);
> > + FamilyId = (RegEax >> 8) & 0xf; ModelId = (RegEax >> 4) & 0xf; if
> > + ((FamilyId == 0x06) || (FamilyId == 0x0f)) {
> > + ModelId = ModelId | ((RegEax >> 12) & 0xf0); }
> > +
> > + //
> > + // Check CPUID(CPUID_VERSION_INFO).EDX[12] for MTRR capability //
> > + if ((RegEdx & BIT12) != 0) {
> > + //
> > + // Check MTRR_CAP MSR bit 11 for SMRR support
> > + //
> > + if ((AsmReadMsr64 (SMM_FEATURES_LIB_IA32_MTRR_CAP) & BIT11) !=
> > 0) {
> > + ASSERT (FeaturePcdGet (PcdSmrrEnable));
> > + }
> > + }
> > +
> > + //
> > + // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
> > + // Volume 3C, Section 35.3 MSRs in the Intel(R) Atom(TM) Processor
> > Family
> > + //
> > + // If CPU Family/Model is 06_1CH, 06_26H, 06_27H, 06_35H or 06_36H,
> > then
> > + // SMRR Physical Base and SMM Physical Mask MSRs are not available.
> > + //
> > + if (FamilyId == 0x06) {
> > + if ((ModelId == 0x1C) || (ModelId == 0x26) || (ModelId == 0x27)
> > + ||
> > (ModelId == 0x35) || (ModelId == 0x36)) {
> > + ASSERT (!FeaturePcdGet (PcdSmrrEnable));
> > + }
> > + }
> > +
> > + //
> > + // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
> > + // Volume 3C, Section 35.2 MSRs in the Intel(R) Core(TM) 2 Processor
> > Family
> > + //
> > + // If CPU Family/Model is 06_0F or 06_17, then use Intel(R)
> > + Core(TM) 2 // Processor Family MSRs // if (FamilyId == 0x06) {
> > + if ((ModelId == 0x17) || (ModelId == 0x0f)) {
> > + mSmrrPhysBaseMsr =
> > SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE;
> > + mSmrrPhysMaskMsr =
> > SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSMASK;
> > + }
> > + }
> > +
> > + //
> > + // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
> > + // Volume 3C, Section 34.4.2 SMRAM Caching
> > + // An IA-32 processor does not automatically write back and invalidate its
> > + // caches before entering SMM or before exiting SMM. Because of this
> > behavior,
> > + // care must be taken in the placement of the SMRAM in system memory
> > and in
> > + // the caching of the SMRAM to prevent cache incoherence when
> > switching back
> > + // and forth between SMM and protected mode operation.
> > + //
> > + // An IA-32 processor is a processor that does not support the
> > + Intel 64 // Architecture. Support for the Intel 64 Architecture
> > + can be detected
> > from
> > + // CPUID(CPUID_EXTENDED_CPU_SIG).EDX[29]
> > + //
> > + // If an IA-32 processor is detected, then set mNeedConfigureMtrrs
> > + to
> > TRUE,
> > + // so caches are flushed on SMI entry and SMI exit, the interrupted
> > + code // MTRRs are saved/restored, and MTRRs for SMM are loaded.
> > + //
> > + AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); if
> > + (RegEax >= CPUID_EXTENDED_CPU_SIG) {
> > + AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx);
> > + if ((RegEdx & BIT29) != 0) {
> > + mNeedConfigureMtrrs = FALSE;
> > + }
> > + }
> > +
> > + //
> > + // Allocate array for state of SMRR enable on all CPUs //
> > + mSmrrEnabled = (BOOLEAN *)AllocatePool (sizeof (BOOLEAN) *
> > GetCpuMaxLogicalProcessorNumber ());
> > + ASSERT (mSmrrEnabled != NULL);
> > +}
> > +
> > +/**
> > + Called during the very first SMI into System Management Mode to
> > +initialize
> > + CPU features, including SMBASE, for the currently executing CPU.
> > +Since
> > this
> > + is the first SMI, the SMRAM Save State Map is at the default
> > + address of SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET.
> The
> > currently executing
> > + CPU is specified by CpuIndex and CpuIndex can be used to access
> > information
> > + about the currently executing CPU in the ProcessorInfo array and
> > + the HotPlugCpuData data structure.
> > +
> > + @param[in] CpuIndex The index of the CPU to initialize. The value
> > + must be between 0 and the NumberOfCpus field in
> > + the System Management System Table (SMST).
> > + @param[in] IsMonarch TRUE if the CpuIndex is the index of the CPU
> > that
> > + was elected as monarch during System Management
> > + Mode initialization.
> > + FALSE if the CpuIndex is not the index of the CPU
> > + that was elected as monarch during System
> > + Management Mode initialization.
> > + @param[in] ProcessorInfo Pointer to an array of
> > EFI_PROCESSOR_INFORMATION
> > + structures. ProcessorInfo[CpuIndex] contains the
> > + information for the currently executing CPU.
> > + @param[in] CpuHotPlugData Pointer to the CPU_HOT_PLUG_DATA
> > structure that
> > + contains the ApidId and SmBase arrays.
> > +**/
> > +VOID
> > +EFIAPI
> > +SmmCpuFeaturesInitializeProcessor (
> > + IN UINTN CpuIndex,
> > + IN BOOLEAN IsMonarch,
> > + IN EFI_PROCESSOR_INFORMATION *ProcessorInfo,
> > + IN CPU_HOT_PLUG_DATA *CpuHotPlugData
> > + )
> > +{
> > + SMRAM_SAVE_STATE_MAP *CpuState;
> > + UINT64 FeatureControl;
> > + UINT32 RegEax;
> > + UINT32 RegEdx;
> > + UINTN FamilyId;
> > + UINTN ModelId;
> > +
> > + //
> > + // Configure SMBASE.
> > + //
> > + CpuState = (SMRAM_SAVE_STATE_MAP
> > *)(UINTN)(SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET);
> > + CpuState->x86.SMBASE = (UINT32)CpuHotPlugData->SmBase[CpuIndex];
> > +
> > + //
> > + // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
> > + // Volume 3C, Section 35.2 MSRs in the Intel(R) Core(TM) 2 Processor
> > Family
> > + //
> > + // If Intel(R) Core(TM) Core(TM) 2 Processor Family MSRs are being
> > + used,
> > then
> > + // make sure SMRR Enable(BIT3) of MSR_FEATURE_CONTROL MSR(0x3A)
> > is set before
> > + // accessing SMRR base/mask MSRs. If Lock(BIT0) of
> > MSR_FEATURE_CONTROL MSR(0x3A)
> > + // is set, then the MSR is locked and can not be modified.
> > + //
> > + if ((FeaturePcdGet (PcdSmrrEnable)) && (mSmrrPhysBaseMsr ==
> > SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE)) {
> > + FeatureControl = AsmReadMsr64
> > (SMM_FEATURES_LIB_IA32_FEATURE_CONTROL);
> > + if ((FeatureControl & BIT3) == 0) {
> > + ASSERT ((FeatureControl & BIT0) == 0);
> > + if ((FeatureControl & BIT0) == 0) {
> > + AsmWriteMsr64 (SMM_FEATURES_LIB_IA32_FEATURE_CONTROL,
> > FeatureControl | BIT3);
> > + }
> > + }
> > + }
> > +
> > + //
> > + // If SMRR is supported, then program SMRR base/mask MSRs.
> > + // The EFI_MSR_SMRR_PHYS_MASK_VALID bit is not set until the first
> > normal SMI.
> > + // The code that initializes SMM environment is running in normal
> > + mode // from SMRAM region. If SMRR is enabled here, then the SMRAM
> > + region // is protected and the normal mode code execution will fail.
> > + //
> > + if (FeaturePcdGet (PcdSmrrEnable)) {
> > + //
> > + // SMRR size cannot be less than 4-KBytes
> > + // SMRR size must be of length 2^n
> > + // SMRR base alignment cannot be less than SMRR length
> > + //
> > + if ((CpuHotPlugData->SmrrSize < SIZE_4KB) ||
> > + (CpuHotPlugData->SmrrSize != GetPowerOfTwo32 (CpuHotPlugData-
> > >SmrrSize)) ||
> > + ((CpuHotPlugData->SmrrBase & ~(CpuHotPlugData->SmrrSize - 1))
> > + !=
> > CpuHotPlugData->SmrrBase))
> > + {
> > + //
> > + // Print message and halt if CPU is Monarch
> > + //
> > + if (IsMonarch) {
> > + DEBUG ((DEBUG_ERROR, "SMM Base/Size does not meet
> > alignment/size requirement!\n"));
> > + CpuDeadLoop ();
> > + }
> > + } else {
> > + AsmWriteMsr64 (mSmrrPhysBaseMsr, CpuHotPlugData->SmrrBase |
> > MTRR_CACHE_WRITE_BACK);
> > + AsmWriteMsr64 (mSmrrPhysMaskMsr, (~(CpuHotPlugData->SmrrSize -
> > + 1)
> > & EFI_MSR_SMRR_MASK));
> > + mSmrrEnabled[CpuIndex] = FALSE;
> > + }
> > + }
> > +
> > + //
> > + // Retrieve CPU Family and Model
> > + //
> > + AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, &RegEdx);
> > + FamilyId = (RegEax >> 8) & 0xf; ModelId = (RegEax >> 4) & 0xf; if
> > + ((FamilyId == 0x06) || (FamilyId == 0x0f)) {
> > + ModelId = ModelId | ((RegEax >> 12) & 0xf0); }
> > +
> > + //
> > + // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
> > + // Volume 3C, Section 35.10.1 MSRs in 4th Generation Intel(R)
> > + Core(TM) // Processor Family.
> > + //
> > + // If CPU Family/Model is 06_3C, 06_45, or 06_46 then use 4th
> > + Generation // Intel(R) Core(TM) Processor Family MSRs.
> > + //
> > + if (FamilyId == 0x06) {
> > + if ((ModelId == 0x3C) || (ModelId == 0x45) || (ModelId == 0x46) ||
> > + (ModelId == 0x3D) || (ModelId == 0x47) || (ModelId == 0x4E)
> > + ||
> > (ModelId == 0x4F) ||
> > + (ModelId == 0x3F) || (ModelId == 0x56) || (ModelId == 0x57)
> > + ||
> > (ModelId == 0x5C) ||
> > + (ModelId == 0x8C))
> > + {
> > + //
> > + // Check to see if the CPU supports the SMM Code Access Check feature
> > + // Do not access this MSR unless the CPU supports the
> > SmmRegFeatureControl
> > + //
> > + if ((AsmReadMsr64 (SMM_FEATURES_LIB_IA32_MCA_CAP) &
> > SMM_CODE_ACCESS_CHK_BIT) != 0) {
> > + ASSERT (FeaturePcdGet (PcdSmmFeatureControlEnable));
> > + }
> > + }
> > + }
> > +
> > + //
> > + // Call internal worker function that completes the CPU
> > +initialization
> > + //
> > + FinishSmmCpuFeaturesInitializeProcessor (); }
> > +
> > +/**
> > + Determines if MTRR registers must be configured to set SMRAM cache-
> > ability
> > + when executing in System Management Mode.
> > +
> > + @retval TRUE MTRR registers must be configured to set SMRAM cache-
> > ability.
> > + @retval FALSE MTRR registers do not need to be configured to set
> > SMRAM
> > + cache-ability.
> > +**/
> > +BOOLEAN
> > +EFIAPI
> > +SmmCpuFeaturesNeedConfigureMtrrs (
> > + VOID
> > + )
> > +{
> > + return mNeedConfigureMtrrs;
> > +}
> > +
> > +/**
> > + Disable SMRR register if SMRR is supported and
> > SmmCpuFeaturesNeedConfigureMtrrs()
> > + returns TRUE.
> > +**/
> > +VOID
> > +EFIAPI
> > +SmmCpuFeaturesDisableSmrr (
> > + VOID
> > + )
> > +{
> > + if (FeaturePcdGet (PcdSmrrEnable) && mNeedConfigureMtrrs) {
> > + AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64
> > (mSmrrPhysMaskMsr) & ~EFI_MSR_SMRR_PHYS_MASK_VALID);
> > + }
> > +}
> > +
> > +/**
> > + Enable SMRR register if SMRR is supported and
> > SmmCpuFeaturesNeedConfigureMtrrs()
> > + returns TRUE.
> > +**/
> > +VOID
> > +EFIAPI
> > +SmmCpuFeaturesReenableSmrr (
> > + VOID
> > + )
> > +{
> > + if (FeaturePcdGet (PcdSmrrEnable) && mNeedConfigureMtrrs) {
> > + AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64
> > (mSmrrPhysMaskMsr) | EFI_MSR_SMRR_PHYS_MASK_VALID);
> > + }
> > +}
> > +
> > +/**
> > + Processor specific hook point each time a CPU enters System
> > +Management
> > Mode.
> > +
> > + @param[in] CpuIndex The index of the CPU that has entered SMM.
> > + The
> > value
> > + must be between 0 and the NumberOfCpus field in the
> > + System Management System Table (SMST).
> > +**/
> > +VOID
> > +EFIAPI
> > +SmmCpuFeaturesRendezvousEntry (
> > + IN UINTN CpuIndex
> > + )
> > +{
> > + //
> > + // If SMRR is supported and this is the first normal SMI, then
> > +enable SMRR
> > + //
> > + if (FeaturePcdGet (PcdSmrrEnable) && !mSmrrEnabled[CpuIndex]) {
> > + AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64
> > (mSmrrPhysMaskMsr) | EFI_MSR_SMRR_PHYS_MASK_VALID);
> > + mSmrrEnabled[CpuIndex] = TRUE;
> > + }
> > +}
> > +
> > +/**
> > + Returns the current value of the SMM register for the specified CPU.
> > + If the SMM register is not supported, then 0 is returned.
> > +
> > + @param[in] CpuIndex The index of the CPU to read the SMM register.
> > The
> > + value must be between 0 and the NumberOfCpus field in
> > + the System Management System Table (SMST).
> > + @param[in] RegName Identifies the SMM register to read.
> > +
> > + @return The value of the SMM register specified by RegName from
> > + the
> > CPU
> > + specified by CpuIndex.
> > +**/
> > +UINT64
> > +EFIAPI
> > +SmmCpuFeaturesGetSmmRegister (
> > + IN UINTN CpuIndex,
> > + IN SMM_REG_NAME RegName
> > + )
> > +{
> > + if (FeaturePcdGet (PcdSmmFeatureControlEnable) && (RegName ==
> > SmmRegFeatureControl)) {
> > + return AsmReadMsr64
> > (SMM_FEATURES_LIB_SMM_FEATURE_CONTROL);
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +/**
> > + Sets the value of an SMM register on a specified CPU.
> > + If the SMM register is not supported, then no action is performed.
> > +
> > + @param[in] CpuIndex The index of the CPU to write the SMM register.
> > The
> > + value must be between 0 and the NumberOfCpus field in
> > + the System Management System Table (SMST).
> > + @param[in] RegName Identifies the SMM register to write.
> > + registers are read-only.
> > + @param[in] Value The value to write to the SMM register.
> > +**/
> > +VOID
> > +EFIAPI
> > +SmmCpuFeaturesSetSmmRegister (
> > + IN UINTN CpuIndex,
> > + IN SMM_REG_NAME RegName,
> > + IN UINT64 Value
> > + )
> > +{
> > + if (FeaturePcdGet (PcdSmmFeatureControlEnable) && (RegName ==
> > SmmRegFeatureControl)) {
> > + AsmWriteMsr64 (SMM_FEATURES_LIB_SMM_FEATURE_CONTROL,
> > Value);
> > + }
> > +}
> > +
> > diff --git
> > a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibCommon.c
> > b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibCommon.c
> > index 75a0ec8e948..7777e52740e 100644
> > ---
> > a/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibCommon.c
> > +++
> > b/UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibCommon.c
> > @@ -14,278 +14,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
> > #include <Library/PcdLib.h> #include <Library/MemoryAllocationLib.h>
> > #include <Library/DebugLib.h> -#include <Register/Intel/Cpuid.h>
> > -#include <Register/Intel/SmramSaveStateMap.h>
> > -#include "CpuFeaturesLib.h"
> > -
> > -//
> > -// Machine Specific Registers (MSRs)
> > -//
> > -#define SMM_FEATURES_LIB_IA32_MTRR_CAP 0x0FE
> > -#define SMM_FEATURES_LIB_IA32_FEATURE_CONTROL 0x03A
> > -#define SMM_FEATURES_LIB_IA32_SMRR_PHYSBASE 0x1F2
> > -#define SMM_FEATURES_LIB_IA32_SMRR_PHYSMASK 0x1F3
> > -#define SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE 0x0A0 -#define
> > SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSMASK 0x0A1
> > -#define EFI_MSR_SMRR_MASK 0xFFFFF000
> > -#define EFI_MSR_SMRR_PHYS_MASK_VALID BIT11
> > -#define SMM_FEATURES_LIB_SMM_FEATURE_CONTROL 0x4E0
> > -
> > -//
> > -// MSRs required for configuration of SMM Code Access Check -//
> > -#define SMM_FEATURES_LIB_IA32_MCA_CAP 0x17D
> > -#define SMM_CODE_ACCESS_CHK_BIT BIT58
> > -
> > -//
> > -// Set default value to assume IA-32 Architectural MSRs are used -//
> > -UINT32 mSmrrPhysBaseMsr =
> > SMM_FEATURES_LIB_IA32_SMRR_PHYSBASE;
> > -UINT32 mSmrrPhysMaskMsr =
> > SMM_FEATURES_LIB_IA32_SMRR_PHYSMASK;
> > -
> > -//
> > -// Set default value to assume MTRRs need to be configured on each
> > SMI -// -BOOLEAN mNeedConfigureMtrrs = TRUE;
> > -
> > -//
> > -// Array for state of SMRR enable on all CPUs -// -BOOLEAN
> > *mSmrrEnabled;
> > -
> > -/**
> > - Performs library initialization.
> > -
> > - This initialization function contains common functionality shared
> > betwen all
> > - library instance constructors.
> > -
> > -**/
> > -VOID
> > -CpuFeaturesLibInitialization (
> > - VOID
> > - )
> > -{
> > - UINT32 RegEax;
> > - UINT32 RegEdx;
> > - UINTN FamilyId;
> > - UINTN ModelId;
> > -
> > - //
> > - // Retrieve CPU Family and Model
> > - //
> > - AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, &RegEdx);
> > - FamilyId = (RegEax >> 8) & 0xf;
> > - ModelId = (RegEax >> 4) & 0xf;
> > - if ((FamilyId == 0x06) || (FamilyId == 0x0f)) {
> > - ModelId = ModelId | ((RegEax >> 12) & 0xf0);
> > - }
> > -
> > - //
> > - // Check CPUID(CPUID_VERSION_INFO).EDX[12] for MTRR capability
> > - //
> > - if ((RegEdx & BIT12) != 0) {
> > - //
> > - // Check MTRR_CAP MSR bit 11 for SMRR support
> > - //
> > - if ((AsmReadMsr64 (SMM_FEATURES_LIB_IA32_MTRR_CAP) & BIT11) != 0)
> > {
> > - ASSERT (FeaturePcdGet (PcdSmrrEnable));
> > - }
> > - }
> > -
> > - //
> > - // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
> > - // Volume 3C, Section 35.3 MSRs in the Intel(R) Atom(TM) Processor
> > Family
> > - //
> > - // If CPU Family/Model is 06_1CH, 06_26H, 06_27H, 06_35H or 06_36H,
> > then
> > - // SMRR Physical Base and SMM Physical Mask MSRs are not available.
> > - //
> > - if (FamilyId == 0x06) {
> > - if ((ModelId == 0x1C) || (ModelId == 0x26) || (ModelId == 0x27) ||
> > (ModelId == 0x35) || (ModelId == 0x36)) {
> > - ASSERT (!FeaturePcdGet (PcdSmrrEnable));
> > - }
> > - }
> > -
> > - //
> > - // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
> > - // Volume 3C, Section 35.2 MSRs in the Intel(R) Core(TM) 2
> > Processor Family
> > - //
> > - // If CPU Family/Model is 06_0F or 06_17, then use Intel(R)
> > Core(TM) 2
> > - // Processor Family MSRs
> > - //
> > - if (FamilyId == 0x06) {
> > - if ((ModelId == 0x17) || (ModelId == 0x0f)) {
> > - mSmrrPhysBaseMsr =
> > SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE;
> > - mSmrrPhysMaskMsr =
> > SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSMASK;
> > - }
> > - }
> > -
> > - //
> > - // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
> > - // Volume 3C, Section 34.4.2 SMRAM Caching
> > - // An IA-32 processor does not automatically write back and invalidate its
> > - // caches before entering SMM or before exiting SMM. Because of this
> > behavior,
> > - // care must be taken in the placement of the SMRAM in system memory
> > and in
> > - // the caching of the SMRAM to prevent cache incoherence when
> > switching back
> > - // and forth between SMM and protected mode operation.
> > - //
> > - // An IA-32 processor is a processor that does not support the
> > Intel 64
> > - // Architecture. Support for the Intel 64 Architecture can be
> > detected from
> > - // CPUID(CPUID_EXTENDED_CPU_SIG).EDX[29]
> > - //
> > - // If an IA-32 processor is detected, then set mNeedConfigureMtrrs
> > to TRUE,
> > - // so caches are flushed on SMI entry and SMI exit, the interrupted
> > code
> > - // MTRRs are saved/restored, and MTRRs for SMM are loaded.
> > - //
> > - AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
> > - if (RegEax >= CPUID_EXTENDED_CPU_SIG) {
> > - AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx);
> > - if ((RegEdx & BIT29) != 0) {
> > - mNeedConfigureMtrrs = FALSE;
> > - }
> > - }
> > -
> > - //
> > - // Allocate array for state of SMRR enable on all CPUs
> > - //
> > - mSmrrEnabled = (BOOLEAN *)AllocatePool (sizeof (BOOLEAN) *
> > GetCpuMaxLogicalProcessorNumber ());
> > - ASSERT (mSmrrEnabled != NULL);
> > -}
> > -
> > -/**
> > - Called during the very first SMI into System Management Mode to
> > initialize
> > - CPU features, including SMBASE, for the currently executing CPU.
> > Since this
> > - is the first SMI, the SMRAM Save State Map is at the default
> > address of
> > - SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET. The
> currently
> > executing
> > - CPU is specified by CpuIndex and CpuIndex can be used to access
> > information
> > - about the currently executing CPU in the ProcessorInfo array and
> > the
> > - HotPlugCpuData data structure.
> > -
> > - @param[in] CpuIndex The index of the CPU to initialize. The value
> > - must be between 0 and the NumberOfCpus field in
> > - the System Management System Table (SMST).
> > - @param[in] IsMonarch TRUE if the CpuIndex is the index of the CPU
> > that
> > - was elected as monarch during System Management
> > - Mode initialization.
> > - FALSE if the CpuIndex is not the index of the CPU
> > - that was elected as monarch during System
> > - Management Mode initialization.
> > - @param[in] ProcessorInfo Pointer to an array of
> > EFI_PROCESSOR_INFORMATION
> > - structures. ProcessorInfo[CpuIndex] contains the
> > - information for the currently executing CPU.
> > - @param[in] CpuHotPlugData Pointer to the CPU_HOT_PLUG_DATA
> > structure that
> > - contains the ApidId and SmBase arrays.
> > -**/
> > -VOID
> > -EFIAPI
> > -SmmCpuFeaturesInitializeProcessor (
> > - IN UINTN CpuIndex,
> > - IN BOOLEAN IsMonarch,
> > - IN EFI_PROCESSOR_INFORMATION *ProcessorInfo,
> > - IN CPU_HOT_PLUG_DATA *CpuHotPlugData
> > - )
> > -{
> > - SMRAM_SAVE_STATE_MAP *CpuState;
> > - UINT64 FeatureControl;
> > - UINT32 RegEax;
> > - UINT32 RegEdx;
> > - UINTN FamilyId;
> > - UINTN ModelId;
> > -
> > - //
> > - // Configure SMBASE.
> > - //
> > - CpuState = (SMRAM_SAVE_STATE_MAP
> > *)(UINTN)(SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET);
> > - CpuState->x86.SMBASE = (UINT32)CpuHotPlugData->SmBase[CpuIndex];
> > -
> > - //
> > - // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
> > - // Volume 3C, Section 35.2 MSRs in the Intel(R) Core(TM) 2
> > Processor Family
> > - //
> > - // If Intel(R) Core(TM) Core(TM) 2 Processor Family MSRs are being
> > used, then
> > - // make sure SMRR Enable(BIT3) of MSR_FEATURE_CONTROL MSR(0x3A) is
> > set before
> > - // accessing SMRR base/mask MSRs. If Lock(BIT0) of
> > MSR_FEATURE_CONTROL MSR(0x3A)
> > - // is set, then the MSR is locked and can not be modified.
> > - //
> > - if ((FeaturePcdGet (PcdSmrrEnable)) && (mSmrrPhysBaseMsr ==
> > SMM_FEATURES_LIB_IA32_CORE_SMRR_PHYSBASE)) {
> > - FeatureControl = AsmReadMsr64
> > (SMM_FEATURES_LIB_IA32_FEATURE_CONTROL);
> > - if ((FeatureControl & BIT3) == 0) {
> > - ASSERT ((FeatureControl & BIT0) == 0);
> > - if ((FeatureControl & BIT0) == 0) {
> > - AsmWriteMsr64 (SMM_FEATURES_LIB_IA32_FEATURE_CONTROL,
> > FeatureControl | BIT3);
> > - }
> > - }
> > - }
> >
> > - //
> > - // If SMRR is supported, then program SMRR base/mask MSRs.
> > - // The EFI_MSR_SMRR_PHYS_MASK_VALID bit is not set until the first
> > normal SMI.
> > - // The code that initializes SMM environment is running in normal
> > mode
> > - // from SMRAM region. If SMRR is enabled here, then the SMRAM
> > region
> > - // is protected and the normal mode code execution will fail.
> > - //
> > - if (FeaturePcdGet (PcdSmrrEnable)) {
> > - //
> > - // SMRR size cannot be less than 4-KBytes
> > - // SMRR size must be of length 2^n
> > - // SMRR base alignment cannot be less than SMRR length
> > - //
> > - if ((CpuHotPlugData->SmrrSize < SIZE_4KB) ||
> > - (CpuHotPlugData->SmrrSize != GetPowerOfTwo32 (CpuHotPlugData-
> > >SmrrSize)) ||
> > - ((CpuHotPlugData->SmrrBase & ~(CpuHotPlugData->SmrrSize - 1)) !=
> > CpuHotPlugData->SmrrBase))
> > - {
> > - //
> > - // Print message and halt if CPU is Monarch
> > - //
> > - if (IsMonarch) {
> > - DEBUG ((DEBUG_ERROR, "SMM Base/Size does not meet
> > alignment/size requirement!\n"));
> > - CpuDeadLoop ();
> > - }
> > - } else {
> > - AsmWriteMsr64 (mSmrrPhysBaseMsr, CpuHotPlugData->SmrrBase |
> > MTRR_CACHE_WRITE_BACK);
> > - AsmWriteMsr64 (mSmrrPhysMaskMsr, (~(CpuHotPlugData->SmrrSize - 1)
> > & EFI_MSR_SMRR_MASK));
> > - mSmrrEnabled[CpuIndex] = FALSE;
> > - }
> > - }
> > -
> > - //
> > - // Retrieve CPU Family and Model
> > - //
> > - AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, &RegEdx);
> > - FamilyId = (RegEax >> 8) & 0xf;
> > - ModelId = (RegEax >> 4) & 0xf;
> > - if ((FamilyId == 0x06) || (FamilyId == 0x0f)) {
> > - ModelId = ModelId | ((RegEax >> 12) & 0xf0);
> > - }
> > -
> > - //
> > - // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
> > - // Volume 3C, Section 35.10.1 MSRs in 4th Generation Intel(R)
> > Core(TM)
> > - // Processor Family.
> > - //
> > - // If CPU Family/Model is 06_3C, 06_45, or 06_46 then use 4th
> > Generation
> > - // Intel(R) Core(TM) Processor Family MSRs.
> > - //
> > - if (FamilyId == 0x06) {
> > - if ((ModelId == 0x3C) || (ModelId == 0x45) || (ModelId == 0x46) ||
> > - (ModelId == 0x3D) || (ModelId == 0x47) || (ModelId == 0x4E) ||
> > (ModelId == 0x4F) ||
> > - (ModelId == 0x3F) || (ModelId == 0x56) || (ModelId == 0x57) ||
> > (ModelId == 0x5C) ||
> > - (ModelId == 0x8C))
> > - {
> > - //
> > - // Check to see if the CPU supports the SMM Code Access Check feature
> > - // Do not access this MSR unless the CPU supports the
> > SmmRegFeatureControl
> > - //
> > - if ((AsmReadMsr64 (SMM_FEATURES_LIB_IA32_MCA_CAP) &
> > SMM_CODE_ACCESS_CHK_BIT) != 0) {
> > - ASSERT (FeaturePcdGet (PcdSmmFeatureControlEnable));
> > - }
> > - }
> > - }
> > -
> > - //
> > - // Call internal worker function that completes the CPU
> > initialization
> > - //
> > - FinishSmmCpuFeaturesInitializeProcessor (); -}
> > +#include "CpuFeaturesLib.h"
> >
> > /**
> > This function updates the SMRAM save state on the currently
> > executing CPU @@ -345,75 +75,6 @@
> SmmCpuFeaturesSmmRelocationComplete
> > ( { }
> >
> > -/**
> > - Determines if MTRR registers must be configured to set SMRAM cache-
> > ability
> > - when executing in System Management Mode.
> > -
> > - @retval TRUE MTRR registers must be configured to set SMRAM cache-
> > ability.
> > - @retval FALSE MTRR registers do not need to be configured to set SMRAM
> > - cache-ability.
> > -**/
> > -BOOLEAN
> > -EFIAPI
> > -SmmCpuFeaturesNeedConfigureMtrrs (
> > - VOID
> > - )
> > -{
> > - return mNeedConfigureMtrrs;
> > -}
> > -
> > -/**
> > - Disable SMRR register if SMRR is supported and
> > SmmCpuFeaturesNeedConfigureMtrrs()
> > - returns TRUE.
> > -**/
> > -VOID
> > -EFIAPI
> > -SmmCpuFeaturesDisableSmrr (
> > - VOID
> > - )
> > -{
> > - if (FeaturePcdGet (PcdSmrrEnable) && mNeedConfigureMtrrs) {
> > - AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64
> > (mSmrrPhysMaskMsr) & ~EFI_MSR_SMRR_PHYS_MASK_VALID);
> > - }
> > -}
> > -
> > -/**
> > - Enable SMRR register if SMRR is supported and
> > SmmCpuFeaturesNeedConfigureMtrrs()
> > - returns TRUE.
> > -**/
> > -VOID
> > -EFIAPI
> > -SmmCpuFeaturesReenableSmrr (
> > - VOID
> > - )
> > -{
> > - if (FeaturePcdGet (PcdSmrrEnable) && mNeedConfigureMtrrs) {
> > - AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64
> > (mSmrrPhysMaskMsr) | EFI_MSR_SMRR_PHYS_MASK_VALID);
> > - }
> > -}
> > -
> > -/**
> > - Processor specific hook point each time a CPU enters System
> > Management Mode.
> > -
> > - @param[in] CpuIndex The index of the CPU that has entered SMM.
> > The value
> > - must be between 0 and the NumberOfCpus field in the
> > - System Management System Table (SMST).
> > -**/
> > -VOID
> > -EFIAPI
> > -SmmCpuFeaturesRendezvousEntry (
> > - IN UINTN CpuIndex
> > - )
> > -{
> > - //
> > - // If SMRR is supported and this is the first normal SMI, then
> > enable SMRR
> > - //
> > - if (FeaturePcdGet (PcdSmrrEnable) && !mSmrrEnabled[CpuIndex]) {
> > - AsmWriteMsr64 (mSmrrPhysMaskMsr, AsmReadMsr64
> > (mSmrrPhysMaskMsr) | EFI_MSR_SMRR_PHYS_MASK_VALID);
> > - mSmrrEnabled[CpuIndex] = TRUE;
> > - }
> > -}
> > -
> > /**
> > Processor specific hook point each time a CPU exits System
> > Management Mode.
> >
> > @@ -456,56 +117,6 @@ SmmCpuFeaturesIsSmmRegisterSupported (
> > return FALSE;
> > }
> >
> > -/**
> > - Returns the current value of the SMM register for the specified CPU.
> > - If the SMM register is not supported, then 0 is returned.
> > -
> > - @param[in] CpuIndex The index of the CPU to read the SMM register.
> > The
> > - value must be between 0 and the NumberOfCpus field in
> > - the System Management System Table (SMST).
> > - @param[in] RegName Identifies the SMM register to read.
> > -
> > - @return The value of the SMM register specified by RegName from
> > the CPU
> > - specified by CpuIndex.
> > -**/
> > -UINT64
> > -EFIAPI
> > -SmmCpuFeaturesGetSmmRegister (
> > - IN UINTN CpuIndex,
> > - IN SMM_REG_NAME RegName
> > - )
> > -{
> > - if (FeaturePcdGet (PcdSmmFeatureControlEnable) && (RegName ==
> > SmmRegFeatureControl)) {
> > - return AsmReadMsr64 (SMM_FEATURES_LIB_SMM_FEATURE_CONTROL);
> > - }
> > -
> > - return 0;
> > -}
> > -
> > -/**
> > - Sets the value of an SMM register on a specified CPU.
> > - If the SMM register is not supported, then no action is performed.
> > -
> > - @param[in] CpuIndex The index of the CPU to write the SMM register.
> > The
> > - value must be between 0 and the NumberOfCpus field in
> > - the System Management System Table (SMST).
> > - @param[in] RegName Identifies the SMM register to write.
> > - registers are read-only.
> > - @param[in] Value The value to write to the SMM register.
> > -**/
> > -VOID
> > -EFIAPI
> > -SmmCpuFeaturesSetSmmRegister (
> > - IN UINTN CpuIndex,
> > - IN SMM_REG_NAME RegName,
> > - IN UINT64 Value
> > - )
> > -{
> > - if (FeaturePcdGet (PcdSmmFeatureControlEnable) && (RegName ==
> > SmmRegFeatureControl)) {
> > - AsmWriteMsr64 (SMM_FEATURES_LIB_SMM_FEATURE_CONTROL,
> > Value);
> > - }
> > -}
> > -
> > /**
> > Read an SMM Save State register on the target processor. If this function
> > returns EFI_UNSUPPORTED, then the caller is responsible for reading
> > the
> > --
> > 2.37.1.windows.1
> >
> >
> >
> >
> >
>
>
>
>
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2022-10-30 13:03 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-09-30 9:52 [PATCH 1/2] UefiCpuPkg/SmmCpuFeaturesLib: Abstract arch dependent code Chang, Abner
2022-10-28 9:26 ` [edk2-devel] " Ni, Ray
2022-10-30 13:03 ` Chang, Abner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox