public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [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