Only adjust functions order and there is no any real functionality impact.

Cc: Feng Tian <feng.t...@intel.com>
Cc: Michael Kinney <michael.d.kin...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <jeff....@intel.com>
---
 UefiCpuPkg/Library/MtrrLib/MtrrLib.c | 956 +++++++++++++++++------------------
 1 file changed, 477 insertions(+), 479 deletions(-)

diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c 
b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
index b1c12aa..ea2b211 100644
--- a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
+++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
@@ -311,6 +311,103 @@ PostMtrrChange (
   PostMtrrChangeEnableCache (MtrrContext);
 }
 
+/**
+  Worker function gets the content in fixed MTRRs
+
+  @param[out]  FixedSettings  A buffer to hold fixed MTRRs content.
+
+  @retval The pointer of FixedSettings
+
+**/
+MTRR_FIXED_SETTINGS*
+MtrrGetFixedMtrrWorker (
+  OUT MTRR_FIXED_SETTINGS         *FixedSettings
+  )
+{
+  UINT32  Index;
+
+  for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
+      FixedSettings->Mtrr[Index] =
+        AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr);
+  }
+
+  return FixedSettings;
+}
+
+
+/**
+  This function gets the content in fixed MTRRs
+
+  @param[out]  FixedSettings  A buffer to hold fixed MTRRs content.
+
+  @retval The pointer of FixedSettings
+
+**/
+MTRR_FIXED_SETTINGS*
+EFIAPI
+MtrrGetFixedMtrr (
+  OUT MTRR_FIXED_SETTINGS         *FixedSettings
+  )
+{
+  if (!IsMtrrSupported ()) {
+    return FixedSettings;
+  }
+
+  return MtrrGetFixedMtrrWorker (FixedSettings);
+}
+
+
+/**
+  Worker function will get the raw value in variable MTRRs
+
+  @param[out] VariableSettings   A buffer to hold variable MTRRs content.
+
+  @return The VariableSettings input pointer
+
+**/
+MTRR_VARIABLE_SETTINGS*
+MtrrGetVariableMtrrWorker (
+  OUT MTRR_VARIABLE_SETTINGS  *VariableSettings
+  )
+{
+  UINT32  Index;
+  UINT32  VariableMtrrCount;
+
+  VariableMtrrCount = GetVariableMtrrCount ();
+  ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);
+
+  for (Index = 0; Index < VariableMtrrCount; Index++) {
+    VariableSettings->Mtrr[Index].Base =
+      AsmReadMsr64 (MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1));
+    VariableSettings->Mtrr[Index].Mask =
+      AsmReadMsr64 (MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1) + 1);
+  }
+
+  return  VariableSettings;
+}
+
+/**
+  This function will get the raw value in variable MTRRs
+
+  @param[out]  VariableSettings   A buffer to hold variable MTRRs content.
+
+  @return The VariableSettings input pointer
+
+**/
+MTRR_VARIABLE_SETTINGS*
+EFIAPI
+MtrrGetVariableMtrr (
+  OUT MTRR_VARIABLE_SETTINGS         *VariableSettings
+  )
+{
+  if (!IsMtrrSupported ()) {
+    return VariableSettings;
+  }
+
+  return MtrrGetVariableMtrrWorker (
+           VariableSettings
+           );
+}
 
 /**
   Programs fixed MTRRs registers.
@@ -965,126 +1062,368 @@ MtrrPrecedence (
 }
 
 
+
 /**
-  This function attempts to set the attributes for a memory range.
+  This function will get the memory cache type of the specific address.
 
-  @param[in]       BaseAddress       The physical address that is the start
-                                     address of a memory region.
-  @param[in]       Length            The size in bytes of the memory region.
-  @param[in]       Attribute         The bit mask of attributes to set for the
-                                     memory region.
+  This function is mainly for debug purpose.
 
-  @retval RETURN_SUCCESS            The attributes were set for the memory
-                                    region.
-  @retval RETURN_INVALID_PARAMETER  Length is zero.
-  @retval RETURN_UNSUPPORTED        The processor does not support one or
-                                    more bytes of the memory resource range
-                                    specified by BaseAddress and Length.
-  @retval RETURN_UNSUPPORTED        The bit mask of attributes is not support
-                                    for the memory resource range specified
-                                    by BaseAddress and Length.
-  @retval RETURN_ACCESS_DENIED      The attributes for the memory resource
-                                    range specified by BaseAddress and Length
-                                    cannot be modified.
-  @retval RETURN_OUT_OF_RESOURCES   There are not enough system resources to
-                                    modify the attributes of the memory
-                                    resource range.
+  @param[in]  Address            The specific address
+
+  @return Memory cache type of the specific address
 
 **/
-RETURN_STATUS
+MTRR_MEMORY_CACHE_TYPE
 EFIAPI
-MtrrSetMemoryAttribute (
-  IN PHYSICAL_ADDRESS        BaseAddress,
-  IN UINT64                  Length,
-  IN MTRR_MEMORY_CACHE_TYPE  Attribute
+MtrrGetMemoryAttribute (
+  IN PHYSICAL_ADDRESS   Address
   )
 {
-  UINT64                    TempQword;
-  RETURN_STATUS             Status;
-  UINT64                    MemoryType;
-  UINT64                    Alignment;
-  BOOLEAN                   OverLap;
-  BOOLEAN                   Positive;
-  UINT32                    MsrNum;
-  UINTN                     MtrrNumber;
-  VARIABLE_MTRR             VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];
-  UINT32                    UsedMtrr;
-  UINT64                    MtrrValidBitsMask;
-  UINT64                    MtrrValidAddressMask;
-  BOOLEAN                   OverwriteExistingMtrr;
-  UINT32                    FirmwareVariableMtrrCount;
-  UINT32                    VariableMtrrEnd;
-  MTRR_CONTEXT              MtrrContext;
-
-  DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttribute() %a:%016lx-%016lx\n", 
mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length));
+  UINT64                  TempQword;
+  UINTN                   Index;
+  UINTN                   SubIndex;
+  UINT64                  MtrrType;
+  UINT64                  TempMtrrType;
+  MTRR_MEMORY_CACHE_TYPE  CacheType;
+  VARIABLE_MTRR           VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];
+  UINT64                  MtrrValidBitsMask;
+  UINT64                  MtrrValidAddressMask;
+  UINTN                   VariableMtrrCount;
 
   if (!IsMtrrSupported ()) {
-    Status = RETURN_UNSUPPORTED;
-    goto Done;
+    return CacheUncacheable;
   }
 
-  FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCount ();
-  VariableMtrrEnd = MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (2 * 
GetVariableMtrrCount ()) - 1;
-
-  MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask);
-
-  TempQword = 0;
-  MemoryType = (UINT64)Attribute;
-  OverwriteExistingMtrr = FALSE;
-
   //
-  // Check for an invalid parameter
+  // Check if MTRR is enabled, if not, return UC as attribute
   //
-  if (Length == 0) {
-    Status = RETURN_INVALID_PARAMETER;
-    goto Done;
-  }
+  TempQword = AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE);
+  MtrrType = MTRR_CACHE_INVALID_TYPE;
 
-  if (
-       (BaseAddress & ~MtrrValidAddressMask) != 0 ||
-       (Length & ~MtrrValidAddressMask) != 0
-     ) {
-    Status = RETURN_UNSUPPORTED;
-    goto Done;
+  if ((TempQword & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
+    return CacheUncacheable;
   }
 
   //
-  // Check if Fixed MTRR
+  // If address is less than 1M, then try to go through the fixed MTRR
   //
-  Status = RETURN_SUCCESS;
-  while ((BaseAddress < BASE_1MB) && (Length > 0) && Status == RETURN_SUCCESS) 
{
-    PreMtrrChange (&MtrrContext);
-    Status = ProgramFixedMtrr (MemoryType, &BaseAddress, &Length);
-    PostMtrrChange (&MtrrContext);
-    if (RETURN_ERROR (Status)) {
-      goto Done;
+  if (Address < BASE_1MB) {
+    if ((TempQword & MTRR_LIB_CACHE_FIXED_MTRR_ENABLED) != 0) {
+      //
+      // Go through the fixed MTRR
+      //
+      for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
+         if (Address >= mMtrrLibFixedMtrrTable[Index].BaseAddress &&
+             Address  < (
+                          mMtrrLibFixedMtrrTable[Index].BaseAddress +
+                          (mMtrrLibFixedMtrrTable[Index].Length * 8)
+                        )
+            ) {
+           SubIndex =
+             ((UINTN)Address - mMtrrLibFixedMtrrTable[Index].BaseAddress) /
+               mMtrrLibFixedMtrrTable[Index].Length;
+           TempQword = AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr);
+           MtrrType =  RShiftU64 (TempQword, SubIndex * 8) & 0xFF;
+           return GetMemoryCacheTypeFromMtrrType (MtrrType);
+         }
+      }
     }
   }
-
-  if (Length == 0) {
-    //
-    // A Length of 0 can only make sense for fixed MTTR ranges.
-    // Since we just handled the fixed MTRRs, we can skip the
-    // variable MTRR section.
-    //
-    goto Done;
-  }
+  MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask);
+  MtrrGetMemoryAttributeInVariableMtrr(
+    MtrrValidBitsMask,
+    MtrrValidAddressMask,
+    VariableMtrr
+    );
 
   //
-  // Since memory ranges below 1MB will be overridden by the fixed MTRRs,
-  // we can set the base to 0 to save variable MTRRs.
+  // Go through the variable MTRR
   //
-  if (BaseAddress == BASE_1MB) {
-    BaseAddress = 0;
-    Length += SIZE_1MB;
+  VariableMtrrCount = GetVariableMtrrCount ();
+  ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);
+
+  for (Index = 0; Index < VariableMtrrCount; Index++) {
+    if (VariableMtrr[Index].Valid) {
+      if (Address >= VariableMtrr[Index].BaseAddress &&
+          Address < 
VariableMtrr[Index].BaseAddress+VariableMtrr[Index].Length) {
+        TempMtrrType = VariableMtrr[Index].Type;
+        MtrrType = MtrrPrecedence (MtrrType, TempMtrrType);
+      }
+    }
   }
+  CacheType = GetMemoryCacheTypeFromMtrrType (MtrrType);
 
-  //
-  // Check for overlap
-  //
-  UsedMtrr = MtrrGetMemoryAttributeInVariableMtrr (MtrrValidBitsMask, 
MtrrValidAddressMask, VariableMtrr);
-  OverLap = CheckMemoryAttributeOverlap (BaseAddress, BaseAddress + Length - 
1, VariableMtrr);
-  if (OverLap) {
+  return CacheType;
+}
+
+
+
+/**
+  This function prints all MTRRs for debugging.
+**/
+VOID
+EFIAPI
+MtrrDebugPrintAllMtrrs (
+  VOID
+  )
+{
+  DEBUG_CODE (
+    MTRR_SETTINGS  MtrrSettings;
+    UINTN          Index;
+    UINTN          Index1;
+    UINTN          VariableMtrrCount;
+    UINT64         Base;
+    UINT64         Limit;
+    UINT64         MtrrBase;
+    UINT64         MtrrLimit;
+    UINT64         RangeBase;
+    UINT64         RangeLimit;
+    UINT64         NoRangeBase;
+    UINT64         NoRangeLimit;
+    UINT32         RegEax;
+    UINTN          MemoryType;
+    UINTN          PreviousMemoryType;
+    BOOLEAN        Found;
+
+    if (!IsMtrrSupported ()) {
+      return;
+    }
+
+    DEBUG((DEBUG_CACHE, "MTRR Settings\n"));
+    DEBUG((DEBUG_CACHE, "=============\n"));
+
+    MtrrGetAllMtrrs (&MtrrSettings);
+    DEBUG((DEBUG_CACHE, "MTRR Default Type: %016lx\n", 
MtrrSettings.MtrrDefType));
+    for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
+      DEBUG((DEBUG_CACHE, "Fixed MTRR[%02d]   : %016lx\n", Index, 
MtrrSettings.Fixed.Mtrr[Index]));
+    }
+
+    VariableMtrrCount = GetVariableMtrrCount ();
+    for (Index = 0; Index < VariableMtrrCount; Index++) {
+      DEBUG((DEBUG_CACHE, "Variable MTRR[%02d]: Base=%016lx Mask=%016lx\n",
+        Index,
+        MtrrSettings.Variables.Mtrr[Index].Base,
+        MtrrSettings.Variables.Mtrr[Index].Mask
+        ));
+    }
+    DEBUG((DEBUG_CACHE, "\n"));
+    DEBUG((DEBUG_CACHE, "MTRR Ranges\n"));
+    DEBUG((DEBUG_CACHE, "====================================\n"));
+
+    Base = 0;
+    PreviousMemoryType = MTRR_CACHE_INVALID_TYPE;
+    for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
+      Base = mMtrrLibFixedMtrrTable[Index].BaseAddress;
+      for (Index1 = 0; Index1 < 8; Index1++) {
+      MemoryType = (UINTN)(RShiftU64 (MtrrSettings.Fixed.Mtrr[Index], Index1 * 
8) & 0xff);
+        if (MemoryType > CacheWriteBack) {
+          MemoryType = MTRR_CACHE_INVALID_TYPE;
+        }
+        if (MemoryType != PreviousMemoryType) {
+          if (PreviousMemoryType != MTRR_CACHE_INVALID_TYPE) {
+            DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1));
+          }
+          PreviousMemoryType = MemoryType;
+          DEBUG((DEBUG_CACHE, "%a:%016lx-", 
mMtrrMemoryCacheTypeShortName[MemoryType], Base));
+        }
+        Base += mMtrrLibFixedMtrrTable[Index].Length;
+      }
+    }
+    DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1));
+
+    VariableMtrrCount = GetVariableMtrrCount ();
+
+    Limit        = BIT36 - 1;
+    AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+    if (RegEax >= 0x80000008) {
+      AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
+      Limit = LShiftU64 (1, RegEax & 0xff) - 1;
+    }
+    Base = BASE_1MB;
+    PreviousMemoryType = MTRR_CACHE_INVALID_TYPE;
+    do {
+      MemoryType = MtrrGetMemoryAttribute (Base);
+      if (MemoryType > CacheWriteBack) {
+        MemoryType = MTRR_CACHE_INVALID_TYPE;
+      }
+
+      if (MemoryType != PreviousMemoryType) {
+        if (PreviousMemoryType != MTRR_CACHE_INVALID_TYPE) {
+          DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1));
+        }
+        PreviousMemoryType = MemoryType;
+        DEBUG((DEBUG_CACHE, "%a:%016lx-", 
mMtrrMemoryCacheTypeShortName[MemoryType], Base));
+      }
+
+      RangeBase    = BASE_1MB;
+      NoRangeBase  = BASE_1MB;
+      RangeLimit   = Limit;
+      NoRangeLimit = Limit;
+
+      for (Index = 0, Found = FALSE; Index < VariableMtrrCount; Index++) {
+        if ((MtrrSettings.Variables.Mtrr[Index].Mask & BIT11) == 0) {
+          //
+          // If mask is not valid, then do not display range
+          //
+          continue;
+        }
+        MtrrBase  = (MtrrSettings.Variables.Mtrr[Index].Base & (~(SIZE_4KB - 
1)));
+        MtrrLimit = MtrrBase + ((~(MtrrSettings.Variables.Mtrr[Index].Mask & 
(~(SIZE_4KB - 1)))) & Limit);
+
+        if (Base >= MtrrBase && Base < MtrrLimit) {
+          Found = TRUE;
+        }
+
+        if (Base >= MtrrBase && MtrrBase > RangeBase) {
+          RangeBase = MtrrBase;
+        }
+        if (Base > MtrrLimit && MtrrLimit > RangeBase) {
+          RangeBase = MtrrLimit + 1;
+        }
+        if (Base < MtrrBase && MtrrBase < RangeLimit) {
+          RangeLimit = MtrrBase - 1;
+        }
+        if (Base < MtrrLimit && MtrrLimit <= RangeLimit) {
+          RangeLimit = MtrrLimit;
+        }
+
+        if (Base > MtrrLimit && NoRangeBase < MtrrLimit) {
+          NoRangeBase = MtrrLimit + 1;
+        }
+        if (Base < MtrrBase && NoRangeLimit > MtrrBase) {
+          NoRangeLimit = MtrrBase - 1;
+        }
+      }
+
+      if (Found) {
+        Base = RangeLimit + 1;
+      } else {
+        Base = NoRangeLimit + 1;
+      }
+    } while (Base < Limit);
+    DEBUG((DEBUG_CACHE, "%016lx\n\n", Base - 1));
+  );
+}
+/**
+  This function attempts to set the attributes for a memory range.
+
+  @param[in]       BaseAddress       The physical address that is the start
+                                     address of a memory region.
+  @param[in]       Length            The size in bytes of the memory region.
+  @param[in]       Attribute         The bit mask of attributes to set for the
+                                     memory region.
+
+  @retval RETURN_SUCCESS            The attributes were set for the memory
+                                    region.
+  @retval RETURN_INVALID_PARAMETER  Length is zero.
+  @retval RETURN_UNSUPPORTED        The processor does not support one or
+                                    more bytes of the memory resource range
+                                    specified by BaseAddress and Length.
+  @retval RETURN_UNSUPPORTED        The bit mask of attributes is not support
+                                    for the memory resource range specified
+                                    by BaseAddress and Length.
+  @retval RETURN_ACCESS_DENIED      The attributes for the memory resource
+                                    range specified by BaseAddress and Length
+                                    cannot be modified.
+  @retval RETURN_OUT_OF_RESOURCES   There are not enough system resources to
+                                    modify the attributes of the memory
+                                    resource range.
+
+**/
+RETURN_STATUS
+EFIAPI
+MtrrSetMemoryAttribute (
+  IN PHYSICAL_ADDRESS        BaseAddress,
+  IN UINT64                  Length,
+  IN MTRR_MEMORY_CACHE_TYPE  Attribute
+  )
+{
+  UINT64                    TempQword;
+  RETURN_STATUS             Status;
+  UINT64                    MemoryType;
+  UINT64                    Alignment;
+  BOOLEAN                   OverLap;
+  BOOLEAN                   Positive;
+  UINT32                    MsrNum;
+  UINTN                     MtrrNumber;
+  VARIABLE_MTRR             VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];
+  UINT32                    UsedMtrr;
+  UINT64                    MtrrValidBitsMask;
+  UINT64                    MtrrValidAddressMask;
+  BOOLEAN                   OverwriteExistingMtrr;
+  UINT32                    FirmwareVariableMtrrCount;
+  UINT32                    VariableMtrrEnd;
+  MTRR_CONTEXT              MtrrContext;
+
+  DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttribute() %a:%016lx-%016lx\n", 
mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length));
+
+  if (!IsMtrrSupported ()) {
+    Status = RETURN_UNSUPPORTED;
+    goto Done;
+  }
+
+  FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCount ();
+  VariableMtrrEnd = MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (2 * 
GetVariableMtrrCount ()) - 1;
+
+  MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask);
+
+  TempQword = 0;
+  MemoryType = (UINT64)Attribute;
+  OverwriteExistingMtrr = FALSE;
+
+  //
+  // Check for an invalid parameter
+  //
+  if (Length == 0) {
+    Status = RETURN_INVALID_PARAMETER;
+    goto Done;
+  }
+
+  if (
+       (BaseAddress & ~MtrrValidAddressMask) != 0 ||
+       (Length & ~MtrrValidAddressMask) != 0
+     ) {
+    Status = RETURN_UNSUPPORTED;
+    goto Done;
+  }
+
+  //
+  // Check if Fixed MTRR
+  //
+  Status = RETURN_SUCCESS;
+  while ((BaseAddress < BASE_1MB) && (Length > 0) && Status == RETURN_SUCCESS) 
{
+    PreMtrrChange (&MtrrContext);
+    Status = ProgramFixedMtrr (MemoryType, &BaseAddress, &Length);
+    PostMtrrChange (&MtrrContext);
+    if (RETURN_ERROR (Status)) {
+      goto Done;
+    }
+  }
+
+  if (Length == 0) {
+    //
+    // A Length of 0 can only make sense for fixed MTTR ranges.
+    // Since we just handled the fixed MTRRs, we can skip the
+    // variable MTRR section.
+    //
+    goto Done;
+  }
+
+  //
+  // Since memory ranges below 1MB will be overridden by the fixed MTRRs,
+  // we can set the base to 0 to save variable MTRRs.
+  //
+  if (BaseAddress == BASE_1MB) {
+    BaseAddress = 0;
+    Length += SIZE_1MB;
+  }
+
+  //
+  // Check for overlap
+  //
+  UsedMtrr = MtrrGetMemoryAttributeInVariableMtrr (MtrrValidBitsMask, 
MtrrValidAddressMask, VariableMtrr);
+  OverLap = CheckMemoryAttributeOverlap (BaseAddress, BaseAddress + Length - 
1, VariableMtrr);
+  if (OverLap) {
     Status = CombineMemoryAttribute (MemoryType, &BaseAddress, &Length, 
VariableMtrr, &UsedMtrr, &OverwriteExistingMtrr);
     if (RETURN_ERROR (Status)) {
       goto Done;
@@ -1183,208 +1522,59 @@ MtrrSetMemoryAttribute (
     for (; MsrNum < VariableMtrrEnd; MsrNum += 2) {
       if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
         break;
-      }
-    }
-
-    ProgramVariableMtrr (
-      MsrNum,
-      BaseAddress,
-      Length,
-      MemoryType,
-      MtrrValidAddressMask
-      );
-    BaseAddress += Length;
-    TempQword   = Length - TempQword;
-    MemoryType  = MTRR_CACHE_UNCACHEABLE;
-  }
-
-  do {
-    //
-    // Find unused MTRR
-    //
-    for (; MsrNum < VariableMtrrEnd; MsrNum += 2) {
-      if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
-        break;
-      }
-    }
-
-    Length = Power2MaxMemory (TempQword);
-    if (!Positive) {
-      BaseAddress -= Length;
-    }
-
-    ProgramVariableMtrr (
-      MsrNum,
-      BaseAddress,
-      Length,
-      MemoryType,
-      MtrrValidAddressMask
-      );
-
-    if (Positive) {
-      BaseAddress += Length;
-    }
-    TempQword -= Length;
-
-  } while (TempQword > 0);
-
-Done:
-  DEBUG((DEBUG_CACHE, "  Status = %r\n", Status));
-  if (!RETURN_ERROR (Status)) {
-    MtrrDebugPrintAllMtrrs ();
-  }
-
-  return Status;
-}
-
-
-/**
-  This function will get the memory cache type of the specific address.
-
-  This function is mainly for debug purpose.
-
-  @param[in]  Address            The specific address
-
-  @return Memory cache type of the specific address
-
-**/
-MTRR_MEMORY_CACHE_TYPE
-EFIAPI
-MtrrGetMemoryAttribute (
-  IN PHYSICAL_ADDRESS   Address
-  )
-{
-  UINT64                  TempQword;
-  UINTN                   Index;
-  UINTN                   SubIndex;
-  UINT64                  MtrrType;
-  UINT64                  TempMtrrType;
-  MTRR_MEMORY_CACHE_TYPE  CacheType;
-  VARIABLE_MTRR           VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];
-  UINT64                  MtrrValidBitsMask;
-  UINT64                  MtrrValidAddressMask;
-  UINTN                   VariableMtrrCount;
-
-  if (!IsMtrrSupported ()) {
-    return CacheUncacheable;
-  }
-
-  //
-  // Check if MTRR is enabled, if not, return UC as attribute
-  //
-  TempQword = AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE);
-  MtrrType = MTRR_CACHE_INVALID_TYPE;
-
-  if ((TempQword & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
-    return CacheUncacheable;
-  }
-
-  //
-  // If address is less than 1M, then try to go through the fixed MTRR
-  //
-  if (Address < BASE_1MB) {
-    if ((TempQword & MTRR_LIB_CACHE_FIXED_MTRR_ENABLED) != 0) {
-      //
-      // Go through the fixed MTRR
-      //
-      for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
-         if (Address >= mMtrrLibFixedMtrrTable[Index].BaseAddress &&
-             Address  < (
-                          mMtrrLibFixedMtrrTable[Index].BaseAddress +
-                          (mMtrrLibFixedMtrrTable[Index].Length * 8)
-                        )
-            ) {
-           SubIndex =
-             ((UINTN)Address - mMtrrLibFixedMtrrTable[Index].BaseAddress) /
-               mMtrrLibFixedMtrrTable[Index].Length;
-           TempQword = AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr);
-           MtrrType =  RShiftU64 (TempQword, SubIndex * 8) & 0xFF;
-           return GetMemoryCacheTypeFromMtrrType (MtrrType);
-         }
-      }
-    }
-  }
-  MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask);
-  MtrrGetMemoryAttributeInVariableMtrr(
-    MtrrValidBitsMask,
-    MtrrValidAddressMask,
-    VariableMtrr
-    );
-
-  //
-  // Go through the variable MTRR
-  //
-  VariableMtrrCount = GetVariableMtrrCount ();
-  ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);
-
-  for (Index = 0; Index < VariableMtrrCount; Index++) {
-    if (VariableMtrr[Index].Valid) {
-      if (Address >= VariableMtrr[Index].BaseAddress &&
-          Address < 
VariableMtrr[Index].BaseAddress+VariableMtrr[Index].Length) {
-        TempMtrrType = VariableMtrr[Index].Type;
-        MtrrType = MtrrPrecedence (MtrrType, TempMtrrType);
-      }
-    }
-  }
-  CacheType = GetMemoryCacheTypeFromMtrrType (MtrrType);
-
-  return CacheType;
-}
-
-
-/**
-  Worker function will get the raw value in variable MTRRs
-
-  @param[out] VariableSettings   A buffer to hold variable MTRRs content.
-
-  @return The VariableSettings input pointer
-
-**/
-MTRR_VARIABLE_SETTINGS*
-MtrrGetVariableMtrrWorker (
-  OUT MTRR_VARIABLE_SETTINGS  *VariableSettings
-  )
-{
-  UINT32  Index;
-  UINT32  VariableMtrrCount;
-
-  VariableMtrrCount = GetVariableMtrrCount ();
-  ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);
-
-  for (Index = 0; Index < VariableMtrrCount; Index++) {
-    VariableSettings->Mtrr[Index].Base =
-      AsmReadMsr64 (MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1));
-    VariableSettings->Mtrr[Index].Mask =
-      AsmReadMsr64 (MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1) + 1);
+      }
+    }
+
+    ProgramVariableMtrr (
+      MsrNum,
+      BaseAddress,
+      Length,
+      MemoryType,
+      MtrrValidAddressMask
+      );
+    BaseAddress += Length;
+    TempQword   = Length - TempQword;
+    MemoryType  = MTRR_CACHE_UNCACHEABLE;
   }
 
-  return  VariableSettings;
-}
+  do {
+    //
+    // Find unused MTRR
+    //
+    for (; MsrNum < VariableMtrrEnd; MsrNum += 2) {
+      if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
+        break;
+      }
+    }
 
-/**
-  This function will get the raw value in variable MTRRs
+    Length = Power2MaxMemory (TempQword);
+    if (!Positive) {
+      BaseAddress -= Length;
+    }
 
-  @param[out]  VariableSettings   A buffer to hold variable MTRRs content.
+    ProgramVariableMtrr (
+      MsrNum,
+      BaseAddress,
+      Length,
+      MemoryType,
+      MtrrValidAddressMask
+      );
 
-  @return The VariableSettings input pointer
+    if (Positive) {
+      BaseAddress += Length;
+    }
+    TempQword -= Length;
 
-**/
-MTRR_VARIABLE_SETTINGS*
-EFIAPI
-MtrrGetVariableMtrr (
-  OUT MTRR_VARIABLE_SETTINGS         *VariableSettings
-  )
-{
-  if (!IsMtrrSupported ()) {
-    return VariableSettings;
+  } while (TempQword > 0);
+
+Done:
+  DEBUG((DEBUG_CACHE, "  Status = %r\n", Status));
+  if (!RETURN_ERROR (Status)) {
+    MtrrDebugPrintAllMtrrs ();
   }
 
-  return MtrrGetVariableMtrrWorker (
-           VariableSettings
-           );
+  return Status;
 }
-
-
 /**
   Worker function setting variable MTRRs
 
@@ -1442,51 +1632,6 @@ MtrrSetVariableMtrr (
 }
 
 /**
-  Worker function gets the content in fixed MTRRs
-
-  @param[out]  FixedSettings  A buffer to hold fixed MTRRs content.
-
-  @retval The pointer of FixedSettings
-
-**/
-MTRR_FIXED_SETTINGS*
-MtrrGetFixedMtrrWorker (
-  OUT MTRR_FIXED_SETTINGS         *FixedSettings
-  )
-{
-  UINT32  Index;
-
-  for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
-      FixedSettings->Mtrr[Index] =
-        AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr);
-  }
-
-  return FixedSettings;
-}
-
-
-/**
-  This function gets the content in fixed MTRRs
-
-  @param[out]  FixedSettings  A buffer to hold fixed MTRRs content.
-
-  @retval The pointer of FixedSettings
-
-**/
-MTRR_FIXED_SETTINGS*
-EFIAPI
-MtrrGetFixedMtrr (
-  OUT MTRR_FIXED_SETTINGS         *FixedSettings
-  )
-{
-  if (!IsMtrrSupported ()) {
-    return FixedSettings;
-  }
-
-  return MtrrGetFixedMtrrWorker (FixedSettings);
-}
-
-/**
   Worker function setting fixed MTRRs
 
   @param[in]  FixedSettings  A buffer to hold fixed Mtrrs content.
@@ -1616,153 +1761,6 @@ MtrrSetAllMtrrs (
 }
 
 /**
-  This function prints all MTRRs for debugging.
-**/
-VOID
-EFIAPI
-MtrrDebugPrintAllMtrrs (
-  VOID
-  )
-{
-  DEBUG_CODE (
-    MTRR_SETTINGS  MtrrSettings;
-    UINTN          Index;
-    UINTN          Index1;
-    UINTN          VariableMtrrCount;
-    UINT64         Base;
-    UINT64         Limit;
-    UINT64         MtrrBase;
-    UINT64         MtrrLimit;
-    UINT64         RangeBase;
-    UINT64         RangeLimit;
-    UINT64         NoRangeBase;
-    UINT64         NoRangeLimit;
-    UINT32         RegEax;
-    UINTN          MemoryType;
-    UINTN          PreviousMemoryType;
-    BOOLEAN        Found;
-
-    if (!IsMtrrSupported ()) {
-      return;
-    }
-
-    DEBUG((DEBUG_CACHE, "MTRR Settings\n"));
-    DEBUG((DEBUG_CACHE, "=============\n"));
-
-    MtrrGetAllMtrrs (&MtrrSettings);
-    DEBUG((DEBUG_CACHE, "MTRR Default Type: %016lx\n", 
MtrrSettings.MtrrDefType));
-    for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
-      DEBUG((DEBUG_CACHE, "Fixed MTRR[%02d]   : %016lx\n", Index, 
MtrrSettings.Fixed.Mtrr[Index]));
-    }
-
-    VariableMtrrCount = GetVariableMtrrCount ();
-    for (Index = 0; Index < VariableMtrrCount; Index++) {
-      DEBUG((DEBUG_CACHE, "Variable MTRR[%02d]: Base=%016lx Mask=%016lx\n",
-        Index,
-        MtrrSettings.Variables.Mtrr[Index].Base,
-        MtrrSettings.Variables.Mtrr[Index].Mask
-        ));
-    }
-    DEBUG((DEBUG_CACHE, "\n"));
-    DEBUG((DEBUG_CACHE, "MTRR Ranges\n"));
-    DEBUG((DEBUG_CACHE, "====================================\n"));
-
-    Base = 0;
-    PreviousMemoryType = MTRR_CACHE_INVALID_TYPE;
-    for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
-      Base = mMtrrLibFixedMtrrTable[Index].BaseAddress;
-      for (Index1 = 0; Index1 < 8; Index1++) {
-      MemoryType = (UINTN)(RShiftU64 (MtrrSettings.Fixed.Mtrr[Index], Index1 * 
8) & 0xff);
-        if (MemoryType > CacheWriteBack) {
-          MemoryType = MTRR_CACHE_INVALID_TYPE;
-        }
-        if (MemoryType != PreviousMemoryType) {
-          if (PreviousMemoryType != MTRR_CACHE_INVALID_TYPE) {
-            DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1));
-          }
-          PreviousMemoryType = MemoryType;
-          DEBUG((DEBUG_CACHE, "%a:%016lx-", 
mMtrrMemoryCacheTypeShortName[MemoryType], Base));
-        }
-        Base += mMtrrLibFixedMtrrTable[Index].Length;
-      }
-    }
-    DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1));
-
-    VariableMtrrCount = GetVariableMtrrCount ();
-
-    Limit        = BIT36 - 1;
-    AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
-    if (RegEax >= 0x80000008) {
-      AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
-      Limit = LShiftU64 (1, RegEax & 0xff) - 1;
-    }
-    Base = BASE_1MB;
-    PreviousMemoryType = MTRR_CACHE_INVALID_TYPE;
-    do {
-      MemoryType = MtrrGetMemoryAttribute (Base);
-      if (MemoryType > CacheWriteBack) {
-        MemoryType = MTRR_CACHE_INVALID_TYPE;
-      }
-
-      if (MemoryType != PreviousMemoryType) {
-        if (PreviousMemoryType != MTRR_CACHE_INVALID_TYPE) {
-          DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1));
-        }
-        PreviousMemoryType = MemoryType;
-        DEBUG((DEBUG_CACHE, "%a:%016lx-", 
mMtrrMemoryCacheTypeShortName[MemoryType], Base));
-      }
-
-      RangeBase    = BASE_1MB;
-      NoRangeBase  = BASE_1MB;
-      RangeLimit   = Limit;
-      NoRangeLimit = Limit;
-
-      for (Index = 0, Found = FALSE; Index < VariableMtrrCount; Index++) {
-        if ((MtrrSettings.Variables.Mtrr[Index].Mask & BIT11) == 0) {
-          //
-          // If mask is not valid, then do not display range
-          //
-          continue;
-        }
-        MtrrBase  = (MtrrSettings.Variables.Mtrr[Index].Base & (~(SIZE_4KB - 
1)));
-        MtrrLimit = MtrrBase + ((~(MtrrSettings.Variables.Mtrr[Index].Mask & 
(~(SIZE_4KB - 1)))) & Limit);
-
-        if (Base >= MtrrBase && Base < MtrrLimit) {
-          Found = TRUE;
-        }
-
-        if (Base >= MtrrBase && MtrrBase > RangeBase) {
-          RangeBase = MtrrBase;
-        }
-        if (Base > MtrrLimit && MtrrLimit > RangeBase) {
-          RangeBase = MtrrLimit + 1;
-        }
-        if (Base < MtrrBase && MtrrBase < RangeLimit) {
-          RangeLimit = MtrrBase - 1;
-        }
-        if (Base < MtrrLimit && MtrrLimit <= RangeLimit) {
-          RangeLimit = MtrrLimit;
-        }
-
-        if (Base > MtrrLimit && NoRangeBase < MtrrLimit) {
-          NoRangeBase = MtrrLimit + 1;
-        }
-        if (Base < MtrrBase && NoRangeLimit > MtrrBase) {
-          NoRangeLimit = MtrrBase - 1;
-        }
-      }
-
-      if (Found) {
-        Base = RangeLimit + 1;
-      } else {
-        Base = NoRangeLimit + 1;
-      }
-    } while (Base < Limit);
-    DEBUG((DEBUG_CACHE, "%016lx\n\n", Base - 1));
-  );
-}
-
-/**
   Checks if MTRR is supported.
 
   @retval TRUE  MTRR is supported.
-- 
1.9.5.msysgit.0

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to