]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/MtrrLib/MtrrLib.c
UefiCpuPkg/MtrrLib: Reduce hardware init when program fixed MTRRs
[mirror_edk2.git] / UefiCpuPkg / Library / MtrrLib / MtrrLib.c
index a65560542c88f186c9eb0137b60b9d0def565dbc..322f47b0976cfaedca2120042236de877586d9b2 100644 (file)
@@ -86,7 +86,7 @@ CONST FIXED_MTRR  mMtrrLibFixedMtrrTable[] = {
     MTRR_LIB_IA32_MTRR_FIX4K_F8000,\r
     0xF8000,\r
     SIZE_4KB\r
-  },\r
+  }\r
 };\r
 \r
 //\r
@@ -103,6 +103,24 @@ GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mMtrrMemoryCacheTypeShortName[] = {
   "R*"   // Invalid\r
 };\r
 \r
+/**\r
+  Worker function returns the variable MTRR count for the CPU.\r
+\r
+  @return Variable MTRR count\r
+\r
+**/\r
+UINT32\r
+GetVariableMtrrCountWorker (\r
+  VOID\r
+  )\r
+{\r
+  UINT32  VariableMtrrCount;\r
+\r
+  VariableMtrrCount = (UINT32)(AsmReadMsr64 (MTRR_LIB_IA32_MTRR_CAP) & MTRR_LIB_IA32_MTRR_CAP_VCNT_MASK);\r
+  ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);\r
+  return VariableMtrrCount;\r
+}\r
+\r
 /**\r
   Returns the variable MTRR count for the CPU.\r
 \r
@@ -115,16 +133,33 @@ GetVariableMtrrCount (
   VOID\r
   )\r
 {\r
-  UINT32  VariableMtrrCount;\r
-\r
   if (!IsMtrrSupported ()) {\r
     return 0;\r
   }\r
+  return GetVariableMtrrCountWorker ();\r
+}\r
 \r
-  VariableMtrrCount = (UINT32)(AsmReadMsr64 (MTRR_LIB_IA32_MTRR_CAP) & MTRR_LIB_IA32_MTRR_CAP_VCNT_MASK);\r
-  ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);\r
+/**\r
+  Worker function returns the firmware usable variable MTRR count for the CPU.\r
 \r
-  return VariableMtrrCount;\r
+  @return Firmware usable variable MTRR count\r
+\r
+**/\r
+UINT32\r
+GetFirmwareVariableMtrrCountWorker (\r
+  VOID\r
+  )\r
+{\r
+  UINT32  VariableMtrrCount;\r
+  UINT32  ReservedMtrrNumber;\r
+\r
+  VariableMtrrCount = GetVariableMtrrCountWorker ();\r
+  ReservedMtrrNumber = PcdGet32 (PcdCpuNumberOfReservedVariableMtrrs);\r
+  if (VariableMtrrCount < ReservedMtrrNumber) {\r
+    return 0;\r
+  }\r
+\r
+  return VariableMtrrCount - ReservedMtrrNumber;\r
 }\r
 \r
 /**\r
@@ -139,16 +174,27 @@ GetFirmwareVariableMtrrCount (
   VOID\r
   )\r
 {\r
-  UINT32  VariableMtrrCount;\r
-\r
-  VariableMtrrCount = GetVariableMtrrCount ();\r
-  if (VariableMtrrCount < RESERVED_FIRMWARE_VARIABLE_MTRR_NUMBER) {\r
+  if (!IsMtrrSupported ()) {\r
     return 0;\r
   }\r
+  return GetFirmwareVariableMtrrCountWorker ();\r
+}\r
+\r
+/**\r
+  Worker function returns the default MTRR cache type for the system.\r
+\r
+  @return  The default MTRR cache type.\r
 \r
-  return VariableMtrrCount - RESERVED_FIRMWARE_VARIABLE_MTRR_NUMBER;\r
+**/\r
+MTRR_MEMORY_CACHE_TYPE\r
+MtrrGetDefaultMemoryTypeWorker (\r
+  VOID\r
+  )\r
+{\r
+  return (MTRR_MEMORY_CACHE_TYPE) (AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE) & 0x7);\r
 }\r
 \r
+\r
 /**\r
   Returns the default MTRR cache type for the system.\r
 \r
@@ -164,8 +210,7 @@ MtrrGetDefaultMemoryType (
   if (!IsMtrrSupported ()) {\r
     return CacheUncacheable;\r
   }\r
-\r
-  return (MTRR_MEMORY_CACHE_TYPE) (AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE) & 0x7);\r
+  return MtrrGetDefaultMemoryTypeWorker ();\r
 }\r
 \r
 /**\r
@@ -186,7 +231,7 @@ PreMtrrChange (
   // Disable interrupts and save current interrupt state\r
   //\r
   MtrrContext->InterruptState = SaveAndDisableInterrupts();\r
-  \r
+\r
   //\r
   // Enter no fill cache mode, CD=1(Bit30), NW=0 (Bit29)\r
   //\r
@@ -204,7 +249,7 @@ PreMtrrChange (
   CpuFlushTlb ();\r
 \r
   //\r
-  // Disable Mtrrs\r
+  // Disable MTRRs\r
   //\r
   AsmMsrBitFieldWrite64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, 10, 11, 0);\r
 }\r
@@ -224,7 +269,7 @@ PostMtrrChangeEnableCache (
   )\r
 {\r
   //\r
-  // Flush all TLBs \r
+  // Flush all TLBs\r
   //\r
   CpuFlushTlb ();\r
 \r
@@ -237,7 +282,7 @@ PostMtrrChangeEnableCache (
   // Restore original CR4 value\r
   //\r
   AsmWriteCr4 (MtrrContext->Cr4);\r
-  \r
+\r
   //\r
   // Restore original interrupt state\r
   //\r
@@ -266,13 +311,113 @@ PostMtrrChange (
   PostMtrrChangeEnableCache (MtrrContext);\r
 }\r
 \r
+/**\r
+  Worker function gets the content in fixed MTRRs\r
+\r
+  @param[out]  FixedSettings  A buffer to hold fixed MTRRs content.\r
+\r
+  @retval The pointer of FixedSettings\r
+\r
+**/\r
+MTRR_FIXED_SETTINGS*\r
+MtrrGetFixedMtrrWorker (\r
+  OUT MTRR_FIXED_SETTINGS         *FixedSettings\r
+  )\r
+{\r
+  UINT32  Index;\r
+\r
+  for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {\r
+      FixedSettings->Mtrr[Index] =\r
+        AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr);\r
+  }\r
+\r
+  return FixedSettings;\r
+}\r
+\r
+\r
+/**\r
+  This function gets the content in fixed MTRRs\r
+\r
+  @param[out]  FixedSettings  A buffer to hold fixed MTRRs content.\r
+\r
+  @retval The pointer of FixedSettings\r
+\r
+**/\r
+MTRR_FIXED_SETTINGS*\r
+EFIAPI\r
+MtrrGetFixedMtrr (\r
+  OUT MTRR_FIXED_SETTINGS         *FixedSettings\r
+  )\r
+{\r
+  if (!IsMtrrSupported ()) {\r
+    return FixedSettings;\r
+  }\r
+\r
+  return MtrrGetFixedMtrrWorker (FixedSettings);\r
+}\r
+\r
+\r
+/**\r
+  Worker function will get the raw value in variable MTRRs\r
+\r
+  @param[out] VariableSettings   A buffer to hold variable MTRRs content.\r
+\r
+  @return The VariableSettings input pointer\r
+\r
+**/\r
+MTRR_VARIABLE_SETTINGS*\r
+MtrrGetVariableMtrrWorker (\r
+  IN  UINT32                  VariableMtrrCount,\r
+  OUT MTRR_VARIABLE_SETTINGS  *VariableSettings\r
+  )\r
+{\r
+  UINT32  Index;\r
+\r
+  ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);\r
+\r
+  for (Index = 0; Index < VariableMtrrCount; Index++) {\r
+    VariableSettings->Mtrr[Index].Base =\r
+      AsmReadMsr64 (MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1));\r
+    VariableSettings->Mtrr[Index].Mask =\r
+      AsmReadMsr64 (MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1) + 1);\r
+  }\r
+\r
+  return  VariableSettings;\r
+}\r
+\r
+/**\r
+  This function will get the raw value in variable MTRRs\r
+\r
+  @param[out]  VariableSettings   A buffer to hold variable MTRRs content.\r
+\r
+  @return The VariableSettings input pointer\r
+\r
+**/\r
+MTRR_VARIABLE_SETTINGS*\r
+EFIAPI\r
+MtrrGetVariableMtrr (\r
+  OUT MTRR_VARIABLE_SETTINGS         *VariableSettings\r
+  )\r
+{\r
+  if (!IsMtrrSupported ()) {\r
+    return VariableSettings;\r
+  }\r
+\r
+  return MtrrGetVariableMtrrWorker (\r
+           GetVariableMtrrCountWorker (),\r
+           VariableSettings\r
+           );\r
+}\r
 \r
 /**\r
   Programs fixed MTRRs registers.\r
 \r
-  @param  MemoryCacheType  The memory type to set.\r
-  @param  Base             The base address of memory range.\r
-  @param  Length           The length of memory range.\r
+  @param[in]      MemoryCacheType  The memory type to set.\r
+  @param[in, out] Base             The base address of memory range.\r
+  @param[in, out] Length           The length of memory range.\r
+  @param[out]     ReturnMsrNum     The index of the fixed MTRR MSR to program.\r
+  @param[out]     ReturnClearMask  The bits to clear in the fixed MTRR MSR.\r
+  @param[out]     ReturnOrMask     The bits to set in the fixed MTRR MSR.\r
 \r
   @retval RETURN_SUCCESS      The cache type was updated successfully\r
   @retval RETURN_UNSUPPORTED  The requested range or cache type was invalid\r
@@ -281,9 +426,12 @@ PostMtrrChange (
 **/\r
 RETURN_STATUS\r
 ProgramFixedMtrr (\r
-  IN     UINT64     MemoryCacheType,\r
-  IN OUT UINT64     *Base,\r
-  IN OUT UINT64     *Length\r
+  IN     UINT64               MemoryCacheType,\r
+  IN OUT UINT64               *Base,\r
+  IN OUT UINT64               *Length,\r
+  OUT    UINT32               *ReturnMsrNum,\r
+  OUT    UINT64               *ReturnClearMask,\r
+  OUT    UINT64               *ReturnOrMask\r
   )\r
 {\r
   UINT32  MsrNum;\r
@@ -346,22 +494,67 @@ ProgramFixedMtrr (
     return RETURN_UNSUPPORTED;\r
   }\r
 \r
-  TempQword =\r
-    (AsmReadMsr64 (mMtrrLibFixedMtrrTable[MsrNum].Msr) & ~ClearMask) | OrMask;\r
-  AsmWriteMsr64 (mMtrrLibFixedMtrrTable[MsrNum].Msr, TempQword);\r
+  *ReturnMsrNum    = MsrNum;\r
+  *ReturnClearMask = ClearMask;\r
+  *ReturnOrMask    = OrMask;\r
+\r
   return RETURN_SUCCESS;\r
 }\r
 \r
 \r
 /**\r
-  Get the attribute of variable MTRRs.\r
+  Worker function gets the attribute of variable MTRRs.\r
+\r
+  This function shadows the content of variable MTRRs into an\r
+  internal array: VariableMtrr.\r
+\r
+  @param[in]   VariableSettings           The variable MTRR values to shadow\r
+  @param[in]   FirmwareVariableMtrrCount  The number of variable MTRRs available to firmware\r
+  @param[in]   MtrrValidBitsMask          The mask for the valid bit of the MTRR\r
+  @param[in]   MtrrValidAddressMask       The valid address mask for MTRR\r
+  @param[out]  VariableMtrr               The array to shadow variable MTRRs content\r
+\r
+  @return                       The return value of this parameter indicates the\r
+                                number of MTRRs which has been used.\r
+\r
+**/\r
+UINT32\r
+MtrrGetMemoryAttributeInVariableMtrrWorker (\r
+  IN  MTRR_VARIABLE_SETTINGS  *VariableSettings,\r
+  IN  UINTN                   FirmwareVariableMtrrCount,\r
+  IN  UINT64                  MtrrValidBitsMask,\r
+  IN  UINT64                  MtrrValidAddressMask,\r
+  OUT VARIABLE_MTRR           *VariableMtrr\r
+  )\r
+{\r
+  UINTN   Index;\r
+  UINT32  UsedMtrr;\r
+\r
+  ZeroMem (VariableMtrr, sizeof (VARIABLE_MTRR) * MTRR_NUMBER_OF_VARIABLE_MTRR);\r
+  for (Index = 0, UsedMtrr = 0; Index < FirmwareVariableMtrrCount; Index++) {\r
+    if ((VariableSettings->Mtrr[Index].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) != 0) {\r
+      VariableMtrr[Index].Msr         = (UINT32)Index;\r
+      VariableMtrr[Index].BaseAddress = (VariableSettings->Mtrr[Index].Base & MtrrValidAddressMask);\r
+      VariableMtrr[Index].Length      = ((~(VariableSettings->Mtrr[Index].Mask & MtrrValidAddressMask)) & MtrrValidBitsMask) + 1;\r
+      VariableMtrr[Index].Type        = (VariableSettings->Mtrr[Index].Base & 0x0ff);\r
+      VariableMtrr[Index].Valid       = TRUE;\r
+      VariableMtrr[Index].Used        = TRUE;\r
+      UsedMtrr++;\r
+    }\r
+  }\r
+  return UsedMtrr;\r
+}\r
+\r
+\r
+/**\r
+  Gets the attribute of variable MTRRs.\r
 \r
   This function shadows the content of variable MTRRs into an\r
   internal array: VariableMtrr.\r
 \r
-  @param  MtrrValidBitsMask     The mask for the valid bit of the MTRR\r
-  @param  MtrrValidAddressMask  The valid address mask for MTRR\r
-  @param  VariableMtrr          The array to shadow variable MTRRs content\r
+  @param[in]   MtrrValidBitsMask     The mask for the valid bit of the MTRR\r
+  @param[in]   MtrrValidAddressMask  The valid address mask for MTRR\r
+  @param[out]  VariableMtrr          The array to shadow variable MTRRs content\r
 \r
   @return                       The return value of this paramter indicates the\r
                                 number of MTRRs which has been used.\r
@@ -375,55 +568,35 @@ MtrrGetMemoryAttributeInVariableMtrr (
   OUT VARIABLE_MTRR             *VariableMtrr\r
   )\r
 {\r
-  UINTN   Index;\r
-  UINT32  MsrNum;\r
-  UINT32  UsedMtrr;\r
-  UINT32  FirmwareVariableMtrrCount;\r
-  UINT32  VariableMtrrEnd;\r
+  MTRR_VARIABLE_SETTINGS  VariableSettings;\r
 \r
   if (!IsMtrrSupported ()) {\r
     return 0;\r
   }\r
 \r
-  FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCount ();\r
-  VariableMtrrEnd = MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (2 * GetVariableMtrrCount ()) - 1;\r
-\r
-  ZeroMem (VariableMtrr, sizeof (VARIABLE_MTRR) * MTRR_NUMBER_OF_VARIABLE_MTRR);\r
-  UsedMtrr = 0;\r
+  MtrrGetVariableMtrrWorker (\r
+    GetVariableMtrrCountWorker (),\r
+    &VariableSettings\r
+    );\r
 \r
-  for (MsrNum = MTRR_LIB_IA32_VARIABLE_MTRR_BASE, Index = 0;\r
-       (\r
-         (MsrNum < VariableMtrrEnd) &&\r
-         (Index < FirmwareVariableMtrrCount)\r
-       );\r
-       MsrNum += 2\r
-      ) {\r
-    if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) != 0) {\r
-      VariableMtrr[Index].Msr          = MsrNum;\r
-      VariableMtrr[Index].BaseAddress  = (AsmReadMsr64 (MsrNum) &\r
-                                          MtrrValidAddressMask);\r
-      VariableMtrr[Index].Length       = ((~(AsmReadMsr64 (MsrNum + 1) &\r
-                                             MtrrValidAddressMask)\r
-                                          ) &\r
-                                          MtrrValidBitsMask\r
-                                         ) + 1;\r
-      VariableMtrr[Index].Type         = (AsmReadMsr64 (MsrNum) & 0x0ff);\r
-      VariableMtrr[Index].Valid        = TRUE;\r
-      VariableMtrr[Index].Used         = TRUE;\r
-      UsedMtrr = UsedMtrr  + 1;\r
-      Index++;\r
-    }\r
-  }\r
-  return UsedMtrr;\r
+  return MtrrGetMemoryAttributeInVariableMtrrWorker (\r
+           &VariableSettings,\r
+           GetFirmwareVariableMtrrCountWorker (),\r
+           MtrrValidBitsMask,\r
+           MtrrValidAddressMask,\r
+           VariableMtrr\r
+           );\r
 }\r
 \r
 \r
 /**\r
   Checks overlap between given memory range and MTRRs.\r
 \r
-  @param  Start            The start address of memory range.\r
-  @param  End              The end address of memory range.\r
-  @param  VariableMtrr     The array to shadow variable MTRRs content\r
+  @param[in]  FirmwareVariableMtrrCount  The number of variable MTRRs available\r
+                                         to firmware.\r
+  @param[in]  Start                      The start address of memory range.\r
+  @param[in]  End                        The end address of memory range.\r
+  @param[in]  VariableMtrr               The array to shadow variable MTRRs content\r
 \r
   @retval TRUE             Overlap exists.\r
   @retval FALSE            No overlap.\r
@@ -431,14 +604,15 @@ MtrrGetMemoryAttributeInVariableMtrr (
 **/\r
 BOOLEAN\r
 CheckMemoryAttributeOverlap (\r
-  IN PHYSICAL_ADDRESS     Start,\r
-  IN PHYSICAL_ADDRESS     End,\r
-  IN VARIABLE_MTRR      *VariableMtrr\r
+  IN UINTN             FirmwareVariableMtrrCount,\r
+  IN PHYSICAL_ADDRESS  Start,\r
+  IN PHYSICAL_ADDRESS  End,\r
+  IN VARIABLE_MTRR     *VariableMtrr\r
   )\r
 {\r
   UINT32  Index;\r
 \r
-  for (Index = 0; Index < 6; Index++) {\r
+  for (Index = 0; Index < FirmwareVariableMtrrCount; Index++) {\r
     if (\r
          VariableMtrr[Index].Valid &&\r
          !(\r
@@ -459,9 +633,9 @@ CheckMemoryAttributeOverlap (
 /**\r
   Marks a variable MTRR as non-valid.\r
 \r
-  @param  Index         The index of the array VariableMtrr to be invalidated\r
-  @param  VariableMtrr  The array to shadow variable MTRRs content\r
-  @param  UsedMtrr      The number of MTRRs which has already been used\r
+  @param[in]   Index         The index of the array VariableMtrr to be invalidated\r
+  @param[in]   VariableMtrr  The array to shadow variable MTRRs content\r
+  @param[out]  UsedMtrr      The number of MTRRs which has already been used\r
 \r
 **/\r
 VOID\r
@@ -477,16 +651,18 @@ InvalidateShadowMtrr (
 \r
 \r
 /**\r
-  Combine memory attributes.\r
+  Combines memory attributes.\r
 \r
   If overlap exists between given memory range and MTRRs, try to combine them.\r
 \r
-  @param  Attributes             The memory type to set.\r
-  @param  Base                   The base address of memory range.\r
-  @param  Length                 The length of memory range.\r
-  @param  VariableMtrr           The array to shadow variable MTRRs content\r
-  @param  UsedMtrr               The number of MTRRs which has already been used\r
-  @param  OverwriteExistingMtrr  Returns whether an existing MTRR was used\r
+  @param[in]       FirmwareVariableMtrrCount  The number of variable MTRRs\r
+                                              available to firmware.\r
+  @param[in]       Attributes                 The memory type to set.\r
+  @param[in, out]  Base                       The base address of memory range.\r
+  @param[in, out]  Length                     The length of memory range.\r
+  @param[in]       VariableMtrr               The array to shadow variable MTRRs content\r
+  @param[in, out]  UsedMtrr                   The number of MTRRs which has already been used\r
+  @param[out]      OverwriteExistingMtrr      Returns whether an existing MTRR was used\r
 \r
   @retval EFI_SUCCESS            Memory region successfully combined.\r
   @retval EFI_ACCESS_DENIED      Memory region cannot be combined.\r
@@ -494,6 +670,7 @@ InvalidateShadowMtrr (
 **/\r
 RETURN_STATUS\r
 CombineMemoryAttribute (\r
+  IN     UINT32             FirmwareVariableMtrrCount,\r
   IN     UINT64             Attributes,\r
   IN OUT UINT64             *Base,\r
   IN OUT UINT64             *Length,\r
@@ -507,11 +684,8 @@ CombineMemoryAttribute (
   UINT64  CombineEnd;\r
   UINT64  MtrrEnd;\r
   UINT64  EndAddress;\r
-  UINT32  FirmwareVariableMtrrCount;\r
   BOOLEAN CoveredByExistingMtrr;\r
 \r
-  FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCount ();\r
-\r
   *OverwriteExistingMtrr = FALSE;\r
   CoveredByExistingMtrr = FALSE;\r
   EndAddress = *Base +*Length - 1;\r
@@ -534,7 +708,7 @@ CombineMemoryAttribute (
     //\r
     if (Attributes == VariableMtrr[Index].Type) {\r
       //\r
-      // if the Mtrr range contain the request range, set a flag, then continue to \r
+      // if the MTRR range contain the request range, set a flag, then continue to\r
       // invalidate any MTRR of the same request range with higher priority cache type.\r
       //\r
       if (VariableMtrr[Index].BaseAddress <= *Base && MtrrEnd >= EndAddress) {\r
@@ -595,9 +769,10 @@ CombineMemoryAttribute (
 \r
 \r
 /**\r
-  Calculate the maximum value which is a power of 2, but less the MemoryLength.\r
+  Calculates the maximum value which is a power of 2, but less the MemoryLength.\r
+\r
+  @param[in]  MemoryLength        The number to pass in.\r
 \r
-  @param  MemoryLength        The number to pass in.\r
   @return The maximum value which is align to power of 2 and less the MemoryLength\r
 \r
 **/\r
@@ -624,21 +799,22 @@ Power2MaxMemory (
 \r
 \r
 /**\r
-  Determine the MTRR numbers used to program a memory range.\r
+  Determines the MTRR numbers used to program a memory range.\r
 \r
-  This function first checks the alignment of the base address. If the alignment of the base address <= Length,\r
-  cover the memory range (BaseAddress, alignment) by a MTRR, then BaseAddress += alignment and Length -= alignment.\r
-  Repeat the step until alignment > Length.\r
+  This function first checks the alignment of the base address.\r
+  If the alignment of the base address <= Length, cover the memory range\r
+ (BaseAddress, alignment) by a MTRR, then BaseAddress += alignment and\r
+  Length -= alignment. Repeat the step until alignment > Length.\r
 \r
-  Then this function determines which direction of programming the variable MTRRs for the remaining length\r
-  will use fewer MTRRs.\r
+  Then this function determines which direction of programming the variable\r
+  MTRRs for the remaining length will use fewer MTRRs.\r
 \r
-  @param  BaseAddress Length of Memory to program MTRR\r
-  @param  Length      Length of Memory to program MTRR\r
-  @param  MtrrNumber  Pointer to the number of necessary MTRRs\r
+  @param[in]  BaseAddress Length of Memory to program MTRR\r
+  @param[in]  Length      Length of Memory to program MTRR\r
+  @param[in]  MtrrNumber  Pointer to the number of necessary MTRRs\r
 \r
   @retval TRUE        Positive direction is better.\r
-          FALSE       Negtive direction is better.\r
+          FALSE       Negative direction is better.\r
 \r
 **/\r
 BOOLEAN\r
@@ -707,21 +883,21 @@ GetMtrrNumberAndDirection (
   This function programs MTRRs according to the values specified\r
   in the shadow array.\r
 \r
-  @param  VariableMtrr   The array to shadow variable MTRRs content\r
+  @param[in]       VariableMtrrCount  Number of variable MTRRs\r
+  @param[in, out]  VariableMtrr       Shadow of variable MTRR contents\r
 \r
 **/\r
 VOID\r
 InvalidateMtrr (\r
-   IN     VARIABLE_MTRR      *VariableMtrr\r
-   )\r
+  IN     UINTN                   VariableMtrrCount,\r
+  IN OUT VARIABLE_MTRR           *VariableMtrr\r
+  )\r
 {\r
   UINTN         Index;\r
-  UINTN         VariableMtrrCount;\r
   MTRR_CONTEXT  MtrrContext;\r
 \r
   PreMtrrChange (&MtrrContext);\r
   Index = 0;\r
-  VariableMtrrCount = GetVariableMtrrCount ();\r
   while (Index < VariableMtrrCount) {\r
     if (!VariableMtrr[Index].Valid && VariableMtrr[Index].Used) {\r
        AsmWriteMsr64 (VariableMtrr[Index].Msr, 0);\r
@@ -739,11 +915,11 @@ InvalidateMtrr (
 \r
   This function programs variable MTRRs\r
 \r
-  @param  MtrrNumber            Index of MTRR to program.\r
-  @param  BaseAddress           Base address of memory region.\r
-  @param  Length                Length of memory region.\r
-  @param  MemoryCacheType       Memory type to set.\r
-  @param  MtrrValidAddressMask  The valid address mask for MTRR\r
+  @param[in]       MtrrNumber            Index of MTRR to program.\r
+  @param[in]       BaseAddress           Base address of memory region.\r
+  @param[in]       Length                Length of memory region.\r
+  @param[in]       MemoryCacheType       Memory type to set.\r
+  @param[in]       MtrrValidAddressMask  The valid address mask for MTRR\r
 \r
 **/\r
 VOID\r
@@ -780,9 +956,9 @@ ProgramVariableMtrr (
 \r
 \r
 /**\r
-  Convert the Memory attibute value to MTRR_MEMORY_CACHE_TYPE.\r
+  Converts the Memory attribute value to MTRR_MEMORY_CACHE_TYPE.\r
 \r
-  @param  MtrrType  MTRR memory type\r
+  @param[in]  MtrrType           MTRR memory type\r
 \r
   @return The enum item in MTRR_MEMORY_CACHE_TYPE\r
 \r
@@ -806,7 +982,7 @@ GetMemoryCacheTypeFromMtrrType (
   default:\r
     //\r
     // MtrrType is MTRR_CACHE_INVALID_TYPE, that means\r
-    // no mtrr covers the range\r
+    // no MTRR covers the range\r
     //\r
     return MtrrGetDefaultMemoryType ();\r
   }\r
@@ -817,8 +993,8 @@ GetMemoryCacheTypeFromMtrrType (
 \r
   This function initializes the valid bits mask and valid address mask for MTRRs.\r
 \r
-  @param  MtrrValidBitsMask     The mask for the valid bit of the MTRR\r
-  @param  MtrrValidAddressMask  The valid address mask for the MTRR\r
+  @param[out]  MtrrValidBitsMask     The mask for the valid bit of the MTRR\r
+  @param[out]  MtrrValidAddressMask  The valid address mask for the MTRR\r
 \r
 **/\r
 VOID\r
@@ -847,21 +1023,21 @@ MtrrLibInitializeMtrrMask (
 \r
 \r
 /**\r
-  Determing the real attribute of a memory range.\r
+  Determines the real attribute of a memory range.\r
 \r
   This function is to arbitrate the real attribute of the memory when\r
-  there are 2 MTRR covers the same memory range.  For further details,\r
+  there are 2 MTRRs covers the same memory range.  For further details,\r
   please refer the IA32 Software Developer's Manual, Volume 3,\r
   Section 10.11.4.1.\r
 \r
-  @param  MtrrType1    the first kind of Memory type\r
-  @param  MtrrType2    the second kind of memory type\r
+  @param[in]  MtrrType1    The first kind of Memory type\r
+  @param[in]  MtrrType2    The second kind of memory type\r
 \r
 **/\r
 UINT64\r
 MtrrPrecedence (\r
-  UINT64    MtrrType1,\r
-  UINT64    MtrrType2\r
+  IN UINT64    MtrrType1,\r
+  IN UINT64    MtrrType2\r
   )\r
 {\r
   UINT64 MtrrType;\r
@@ -918,79 +1094,347 @@ MtrrPrecedence (
 }\r
 \r
 \r
+\r
 /**\r
-  This function attempts to set the attributes for a memory range.\r
+  This function will get the memory cache type of the specific address.\r
 \r
-  @param  BaseAddress            The physical address that is the start\r
-                                 address of a memory region.\r
-  @param  Length                 The size in bytes of the memory region.\r
-  @param  Attributes             The bit mask of attributes to set for the\r
-                                 memory region.\r
+  This function is mainly for debug purpose.\r
 \r
-  @retval RETURN_SUCCESS            The attributes were set for the memory\r
-                                    region.\r
-  @retval RETURN_INVALID_PARAMETER  Length is zero.\r
-  @retval RETURN_UNSUPPORTED        The processor does not support one or\r
-                                    more bytes of the memory resource range\r
-                                    specified by BaseAddress and Length.\r
-  @retval RETURN_UNSUPPORTED        The bit mask of attributes is not support\r
-                                    for the memory resource range specified\r
-                                    by BaseAddress and Length.\r
-  @retval RETURN_ACCESS_DENIED      The attributes for the memory resource\r
-                                    range specified by BaseAddress and Length\r
-                                    cannot be modified.\r
-  @retval RETURN_OUT_OF_RESOURCES   There are not enough system resources to\r
-                                    modify the attributes of the memory\r
-                                    resource range.\r
+  @param[in]  Address            The specific address\r
+\r
+  @return Memory cache type of the specific address\r
 \r
 **/\r
-RETURN_STATUS\r
+MTRR_MEMORY_CACHE_TYPE\r
 EFIAPI\r
-MtrrSetMemoryAttribute (\r
-  IN PHYSICAL_ADDRESS        BaseAddress,\r
-  IN UINT64                  Length,\r
-  IN MTRR_MEMORY_CACHE_TYPE  Attribute\r
+MtrrGetMemoryAttribute (\r
+  IN PHYSICAL_ADDRESS   Address\r
   )\r
 {\r
-  UINT64                    TempQword;\r
-  RETURN_STATUS             Status;\r
-  UINT64                    MemoryType;\r
-  UINT64                    Alignment;\r
-  BOOLEAN                   OverLap;\r
-  BOOLEAN                   Positive;\r
-  UINT32                    MsrNum;\r
-  UINTN                     MtrrNumber;\r
-  VARIABLE_MTRR             VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];\r
-  UINT32                    UsedMtrr;\r
-  UINT64                    MtrrValidBitsMask;\r
-  UINT64                    MtrrValidAddressMask;\r
-  BOOLEAN                   OverwriteExistingMtrr;\r
-  UINT32                    FirmwareVariableMtrrCount;\r
-  UINT32                    VariableMtrrEnd;\r
-  MTRR_CONTEXT              MtrrContext;\r
-\r
-  DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttribute() %a:%016lx-%016lx\n", mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length));\r
+  UINT64                  TempQword;\r
+  UINTN                   Index;\r
+  UINTN                   SubIndex;\r
+  UINT64                  MtrrType;\r
+  UINT64                  TempMtrrType;\r
+  MTRR_MEMORY_CACHE_TYPE  CacheType;\r
+  VARIABLE_MTRR           VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];\r
+  UINT64                  MtrrValidBitsMask;\r
+  UINT64                  MtrrValidAddressMask;\r
+  UINTN                   VariableMtrrCount;\r
+  MTRR_VARIABLE_SETTINGS  VariableSettings;\r
 \r
   if (!IsMtrrSupported ()) {\r
-    Status = RETURN_UNSUPPORTED;\r
-    goto Done;\r
+    return CacheUncacheable;\r
   }\r
 \r
-  FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCount ();\r
-  VariableMtrrEnd = MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (2 * GetVariableMtrrCount ()) - 1;\r
-\r
-  MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask);\r
-\r
-  TempQword = 0;\r
-  MemoryType = (UINT64)Attribute;\r
-  OverwriteExistingMtrr = FALSE;\r
-\r
   //\r
-  // Check for an invalid parameter\r
+  // Check if MTRR is enabled, if not, return UC as attribute\r
   //\r
-  if (Length == 0) {\r
-    Status = RETURN_INVALID_PARAMETER;\r
-    goto Done;\r
+  TempQword = AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE);\r
+  MtrrType = MTRR_CACHE_INVALID_TYPE;\r
+\r
+  if ((TempQword & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
+    return CacheUncacheable;\r
+  }\r
+\r
+  //\r
+  // If address is less than 1M, then try to go through the fixed MTRR\r
+  //\r
+  if (Address < BASE_1MB) {\r
+    if ((TempQword & MTRR_LIB_CACHE_FIXED_MTRR_ENABLED) != 0) {\r
+      //\r
+      // Go through the fixed MTRR\r
+      //\r
+      for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {\r
+         if (Address >= mMtrrLibFixedMtrrTable[Index].BaseAddress &&\r
+             Address  < (\r
+                          mMtrrLibFixedMtrrTable[Index].BaseAddress +\r
+                          (mMtrrLibFixedMtrrTable[Index].Length * 8)\r
+                        )\r
+            ) {\r
+           SubIndex =\r
+             ((UINTN)Address - mMtrrLibFixedMtrrTable[Index].BaseAddress) /\r
+               mMtrrLibFixedMtrrTable[Index].Length;\r
+           TempQword = AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr);\r
+           MtrrType =  RShiftU64 (TempQword, SubIndex * 8) & 0xFF;\r
+           return GetMemoryCacheTypeFromMtrrType (MtrrType);\r
+         }\r
+      }\r
+    }\r
+  }\r
+  MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask);\r
+\r
+  MtrrGetVariableMtrrWorker (\r
+    GetVariableMtrrCountWorker (),\r
+    &VariableSettings\r
+    );\r
+\r
+  MtrrGetMemoryAttributeInVariableMtrrWorker (\r
+           &VariableSettings,\r
+           GetFirmwareVariableMtrrCountWorker (),\r
+           MtrrValidBitsMask,\r
+           MtrrValidAddressMask,\r
+           VariableMtrr\r
+           );\r
+\r
+  //\r
+  // Go through the variable MTRR\r
+  //\r
+  VariableMtrrCount = GetVariableMtrrCountWorker ();\r
+  ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);\r
+\r
+  for (Index = 0; Index < VariableMtrrCount; Index++) {\r
+    if (VariableMtrr[Index].Valid) {\r
+      if (Address >= VariableMtrr[Index].BaseAddress &&\r
+          Address < VariableMtrr[Index].BaseAddress+VariableMtrr[Index].Length) {\r
+        TempMtrrType = VariableMtrr[Index].Type;\r
+        MtrrType = MtrrPrecedence (MtrrType, TempMtrrType);\r
+      }\r
+    }\r
+  }\r
+  CacheType = GetMemoryCacheTypeFromMtrrType (MtrrType);\r
+\r
+  return CacheType;\r
+}\r
+\r
+\r
+\r
+/**\r
+  This function prints all MTRRs for debugging.\r
+**/\r
+VOID\r
+EFIAPI\r
+MtrrDebugPrintAllMtrrs (\r
+  VOID\r
+  )\r
+{\r
+  DEBUG_CODE (\r
+    MTRR_SETTINGS  MtrrSettings;\r
+    UINTN          Index;\r
+    UINTN          Index1;\r
+    UINTN          VariableMtrrCount;\r
+    UINT64         Base;\r
+    UINT64         Limit;\r
+    UINT64         MtrrBase;\r
+    UINT64         MtrrLimit;\r
+    UINT64         RangeBase;\r
+    UINT64         RangeLimit;\r
+    UINT64         NoRangeBase;\r
+    UINT64         NoRangeLimit;\r
+    UINT32         RegEax;\r
+    UINTN          MemoryType;\r
+    UINTN          PreviousMemoryType;\r
+    BOOLEAN        Found;\r
+\r
+    if (!IsMtrrSupported ()) {\r
+      return;\r
+    }\r
+\r
+    DEBUG((DEBUG_CACHE, "MTRR Settings\n"));\r
+    DEBUG((DEBUG_CACHE, "=============\n"));\r
+\r
+    MtrrGetAllMtrrs (&MtrrSettings);\r
+    DEBUG((DEBUG_CACHE, "MTRR Default Type: %016lx\n", MtrrSettings.MtrrDefType));\r
+    for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {\r
+      DEBUG((DEBUG_CACHE, "Fixed MTRR[%02d]   : %016lx\n", Index, MtrrSettings.Fixed.Mtrr[Index]));\r
+    }\r
+\r
+    VariableMtrrCount = GetVariableMtrrCount ();\r
+    for (Index = 0; Index < VariableMtrrCount; Index++) {\r
+      DEBUG((DEBUG_CACHE, "Variable MTRR[%02d]: Base=%016lx Mask=%016lx\n",\r
+        Index,\r
+        MtrrSettings.Variables.Mtrr[Index].Base,\r
+        MtrrSettings.Variables.Mtrr[Index].Mask\r
+        ));\r
+    }\r
+    DEBUG((DEBUG_CACHE, "\n"));\r
+    DEBUG((DEBUG_CACHE, "MTRR Ranges\n"));\r
+    DEBUG((DEBUG_CACHE, "====================================\n"));\r
+\r
+    Base = 0;\r
+    PreviousMemoryType = MTRR_CACHE_INVALID_TYPE;\r
+    for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {\r
+      Base = mMtrrLibFixedMtrrTable[Index].BaseAddress;\r
+      for (Index1 = 0; Index1 < 8; Index1++) {\r
+      MemoryType = (UINTN)(RShiftU64 (MtrrSettings.Fixed.Mtrr[Index], Index1 * 8) & 0xff);\r
+        if (MemoryType > CacheWriteBack) {\r
+          MemoryType = MTRR_CACHE_INVALID_TYPE;\r
+        }\r
+        if (MemoryType != PreviousMemoryType) {\r
+          if (PreviousMemoryType != MTRR_CACHE_INVALID_TYPE) {\r
+            DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1));\r
+          }\r
+          PreviousMemoryType = MemoryType;\r
+          DEBUG((DEBUG_CACHE, "%a:%016lx-", mMtrrMemoryCacheTypeShortName[MemoryType], Base));\r
+        }\r
+        Base += mMtrrLibFixedMtrrTable[Index].Length;\r
+      }\r
+    }\r
+    DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1));\r
+\r
+    VariableMtrrCount = GetVariableMtrrCount ();\r
+\r
+    Limit        = BIT36 - 1;\r
+    AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
+    if (RegEax >= 0x80000008) {\r
+      AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);\r
+      Limit = LShiftU64 (1, RegEax & 0xff) - 1;\r
+    }\r
+    Base = BASE_1MB;\r
+    PreviousMemoryType = MTRR_CACHE_INVALID_TYPE;\r
+    do {\r
+      MemoryType = MtrrGetMemoryAttribute (Base);\r
+      if (MemoryType > CacheWriteBack) {\r
+        MemoryType = MTRR_CACHE_INVALID_TYPE;\r
+      }\r
+\r
+      if (MemoryType != PreviousMemoryType) {\r
+        if (PreviousMemoryType != MTRR_CACHE_INVALID_TYPE) {\r
+          DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1));\r
+        }\r
+        PreviousMemoryType = MemoryType;\r
+        DEBUG((DEBUG_CACHE, "%a:%016lx-", mMtrrMemoryCacheTypeShortName[MemoryType], Base));\r
+      }\r
+\r
+      RangeBase    = BASE_1MB;\r
+      NoRangeBase  = BASE_1MB;\r
+      RangeLimit   = Limit;\r
+      NoRangeLimit = Limit;\r
+\r
+      for (Index = 0, Found = FALSE; Index < VariableMtrrCount; Index++) {\r
+        if ((MtrrSettings.Variables.Mtrr[Index].Mask & BIT11) == 0) {\r
+          //\r
+          // If mask is not valid, then do not display range\r
+          //\r
+          continue;\r
+        }\r
+        MtrrBase  = (MtrrSettings.Variables.Mtrr[Index].Base & (~(SIZE_4KB - 1)));\r
+        MtrrLimit = MtrrBase + ((~(MtrrSettings.Variables.Mtrr[Index].Mask & (~(SIZE_4KB - 1)))) & Limit);\r
+\r
+        if (Base >= MtrrBase && Base < MtrrLimit) {\r
+          Found = TRUE;\r
+        }\r
+\r
+        if (Base >= MtrrBase && MtrrBase > RangeBase) {\r
+          RangeBase = MtrrBase;\r
+        }\r
+        if (Base > MtrrLimit && MtrrLimit > RangeBase) {\r
+          RangeBase = MtrrLimit + 1;\r
+        }\r
+        if (Base < MtrrBase && MtrrBase < RangeLimit) {\r
+          RangeLimit = MtrrBase - 1;\r
+        }\r
+        if (Base < MtrrLimit && MtrrLimit <= RangeLimit) {\r
+          RangeLimit = MtrrLimit;\r
+        }\r
+\r
+        if (Base > MtrrLimit && NoRangeBase < MtrrLimit) {\r
+          NoRangeBase = MtrrLimit + 1;\r
+        }\r
+        if (Base < MtrrBase && NoRangeLimit > MtrrBase) {\r
+          NoRangeLimit = MtrrBase - 1;\r
+        }\r
+      }\r
+\r
+      if (Found) {\r
+        Base = RangeLimit + 1;\r
+      } else {\r
+        Base = NoRangeLimit + 1;\r
+      }\r
+    } while (Base < Limit);\r
+    DEBUG((DEBUG_CACHE, "%016lx\n\n", Base - 1));\r
+  );\r
+}\r
+/**\r
+  This function attempts to set the attributes for a memory range.\r
+\r
+  @param[in]       BaseAddress       The physical address that is the start\r
+                                     address of a memory region.\r
+  @param[in]       Length            The size in bytes of the memory region.\r
+  @param[in]       Attribute         The bit mask of attributes to set for the\r
+                                     memory region.\r
+\r
+  @retval RETURN_SUCCESS            The attributes were set for the memory\r
+                                    region.\r
+  @retval RETURN_INVALID_PARAMETER  Length is zero.\r
+  @retval RETURN_UNSUPPORTED        The processor does not support one or\r
+                                    more bytes of the memory resource range\r
+                                    specified by BaseAddress and Length.\r
+  @retval RETURN_UNSUPPORTED        The bit mask of attributes is not support\r
+                                    for the memory resource range specified\r
+                                    by BaseAddress and Length.\r
+  @retval RETURN_ACCESS_DENIED      The attributes for the memory resource\r
+                                    range specified by BaseAddress and Length\r
+                                    cannot be modified.\r
+  @retval RETURN_OUT_OF_RESOURCES   There are not enough system resources to\r
+                                    modify the attributes of the memory\r
+                                    resource range.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+MtrrSetMemoryAttribute (\r
+  IN PHYSICAL_ADDRESS        BaseAddress,\r
+  IN UINT64                  Length,\r
+  IN MTRR_MEMORY_CACHE_TYPE  Attribute\r
+  )\r
+{\r
+  UINT64                    TempQword;\r
+  RETURN_STATUS             Status;\r
+  UINT64                    MemoryType;\r
+  UINT64                    Alignment;\r
+  BOOLEAN                   OverLap;\r
+  BOOLEAN                   Positive;\r
+  UINT32                    MsrNum;\r
+  UINTN                     MtrrNumber;\r
+  VARIABLE_MTRR             VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];\r
+  UINT32                    UsedMtrr;\r
+  UINT64                    MtrrValidBitsMask;\r
+  UINT64                    MtrrValidAddressMask;\r
+  BOOLEAN                   OverwriteExistingMtrr;\r
+  UINT32                    FirmwareVariableMtrrCount;\r
+  UINT32                    VariableMtrrEnd;\r
+  MTRR_CONTEXT              MtrrContext;\r
+  BOOLEAN                   MtrrContextValid;\r
+  BOOLEAN                   FixedSettingsValid[MTRR_NUMBER_OF_FIXED_MTRR];\r
+  BOOLEAN                   FixedSettingsModified[MTRR_NUMBER_OF_FIXED_MTRR];\r
+  MTRR_FIXED_SETTINGS       WorkingFixedSettings;\r
+  UINT32                    VariableMtrrCount;\r
+  MTRR_VARIABLE_SETTINGS    OriginalVariableSettings;\r
+  MTRR_VARIABLE_SETTINGS    WorkingVariableSettings;\r
+  UINT32                    Index;\r
+  UINT64                    ClearMask;\r
+  UINT64                    OrMask;\r
+  UINT64                    NewValue;\r
+  MTRR_VARIABLE_SETTINGS    *VariableSettings;\r
+\r
+  DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttribute() %a:%016lx-%016lx\n", mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length));\r
+  MtrrContextValid = FALSE;\r
+  for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {\r
+    FixedSettingsValid[Index]    = FALSE;\r
+    FixedSettingsModified[Index] = FALSE;\r
+  }\r
+\r
+  if (!IsMtrrSupported ()) {\r
+    Status = RETURN_UNSUPPORTED;\r
+    goto Done;\r
+  }\r
+\r
+  FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCountWorker ();\r
+  VariableMtrrEnd = MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (2 * GetVariableMtrrCount ()) - 1;\r
+\r
+  MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask);\r
+\r
+  TempQword = 0;\r
+  MemoryType = (UINT64)Attribute;\r
+  OverwriteExistingMtrr = FALSE;\r
+\r
+  //\r
+  // Check for an invalid parameter\r
+  //\r
+  if (Length == 0) {\r
+    Status = RETURN_INVALID_PARAMETER;\r
+    goto Done;\r
   }\r
 \r
   if (\r
@@ -1005,22 +1449,31 @@ MtrrSetMemoryAttribute (
   // Check if Fixed MTRR\r
   //\r
   Status = RETURN_SUCCESS;\r
-  while ((BaseAddress < BASE_1MB) && (Length > 0) && Status == RETURN_SUCCESS) {\r
-    PreMtrrChange (&MtrrContext);\r
-    Status = ProgramFixedMtrr (MemoryType, &BaseAddress, &Length);\r
-    PostMtrrChange (&MtrrContext);\r
-    if (RETURN_ERROR (Status)) {\r
-      goto Done;\r
+  if (BaseAddress < BASE_1MB) {\r
+    while ((BaseAddress < BASE_1MB) && (Length > 0) && Status == RETURN_SUCCESS) {\r
+      Status = ProgramFixedMtrr (MemoryType, &BaseAddress, &Length, &MsrNum, &ClearMask, &OrMask);\r
+      if (RETURN_ERROR (Status)) {\r
+        goto Done;\r
+      }\r
+      if (!FixedSettingsValid[MsrNum]) {\r
+        WorkingFixedSettings.Mtrr[MsrNum] = AsmReadMsr64 (mMtrrLibFixedMtrrTable[MsrNum].Msr);\r
+        FixedSettingsValid[MsrNum] = TRUE;\r
+      }\r
+      NewValue = (WorkingFixedSettings.Mtrr[MsrNum] & ~ClearMask) | OrMask;\r
+      if (WorkingFixedSettings.Mtrr[MsrNum] != NewValue) {\r
+        WorkingFixedSettings.Mtrr[MsrNum] = NewValue;\r
+        FixedSettingsModified[MsrNum] = TRUE;\r
+      }\r
     }\r
-  }\r
 \r
-  if (Length == 0) {\r
-    //\r
-    // A Length of 0 can only make sense for fixed MTTR ranges.\r
-    // Since we just handled the fixed MTRRs, we can skip the\r
-    // variable MTRR section.\r
-    //\r
-    goto Done;\r
+    if (Length == 0) {\r
+      //\r
+      // A Length of 0 can only make sense for fixed MTTR ranges.\r
+      // Since we just handled the fixed MTRRs, we can skip the\r
+      // variable MTRR section.\r
+      //\r
+      goto Done;\r
+    }\r
   }\r
 \r
   //\r
@@ -1032,13 +1485,41 @@ MtrrSetMemoryAttribute (
     Length += SIZE_1MB;\r
   }\r
 \r
+  //\r
+  // Read all variable MTRRs\r
+  //\r
+  VariableMtrrCount = GetVariableMtrrCountWorker ();\r
+  MtrrGetVariableMtrrWorker (VariableMtrrCount, &OriginalVariableSettings);\r
+  CopyMem (&WorkingVariableSettings, &OriginalVariableSettings, sizeof (WorkingVariableSettings));\r
+  VariableSettings = &WorkingVariableSettings;\r
+\r
   //\r
   // Check for overlap\r
   //\r
-  UsedMtrr = MtrrGetMemoryAttributeInVariableMtrr (MtrrValidBitsMask, MtrrValidAddressMask, VariableMtrr);\r
-  OverLap = CheckMemoryAttributeOverlap (BaseAddress, BaseAddress + Length - 1, VariableMtrr);\r
+  UsedMtrr = MtrrGetMemoryAttributeInVariableMtrrWorker (\r
+               VariableSettings,\r
+               FirmwareVariableMtrrCount,\r
+               MtrrValidBitsMask,\r
+               MtrrValidAddressMask,\r
+               VariableMtrr\r
+               );\r
+  OverLap = CheckMemoryAttributeOverlap (\r
+              FirmwareVariableMtrrCount,\r
+              BaseAddress,\r
+              BaseAddress + Length - 1,\r
+              VariableMtrr\r
+              );\r
+\r
   if (OverLap) {\r
-    Status = CombineMemoryAttribute (MemoryType, &BaseAddress, &Length, VariableMtrr, &UsedMtrr, &OverwriteExistingMtrr);\r
+    Status = CombineMemoryAttribute (\r
+               FirmwareVariableMtrrCount,\r
+               MemoryType,\r
+               &BaseAddress,\r
+               &Length,\r
+               VariableMtrr,\r
+               &UsedMtrr,\r
+               &OverwriteExistingMtrr\r
+               );\r
     if (RETURN_ERROR (Status)) {\r
       goto Done;\r
     }\r
@@ -1047,7 +1528,7 @@ MtrrSetMemoryAttribute (
       //\r
       // Combined successfully, invalidate the now-unused MTRRs\r
       //\r
-      InvalidateMtrr(VariableMtrr);\r
+      InvalidateMtrr(VariableMtrrCount, VariableMtrr);\r
       Status = RETURN_SUCCESS;\r
       goto Done;\r
     }\r
@@ -1061,7 +1542,7 @@ MtrrSetMemoryAttribute (
     //\r
     // Invalidate the now-unused MTRRs\r
     //\r
-    InvalidateMtrr(VariableMtrr);\r
+    InvalidateMtrr(VariableMtrrCount, VariableMtrr);\r
     goto Done;\r
   }\r
 \r
@@ -1075,7 +1556,7 @@ MtrrSetMemoryAttribute (
   //\r
   // Invalidate the now-unused MTRRs\r
   //\r
-  InvalidateMtrr(VariableMtrr);\r
+  InvalidateMtrr(VariableMtrrCount, VariableMtrr);\r
 \r
   //\r
   // Find first unused MTRR\r
@@ -1135,195 +1616,85 @@ MtrrSetMemoryAttribute (
     //\r
     for (; MsrNum < VariableMtrrEnd; MsrNum += 2) {\r
       if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
-        break;\r
-      }\r
-    }\r
-\r
-    ProgramVariableMtrr (\r
-      MsrNum,\r
-      BaseAddress,\r
-      Length,\r
-      MemoryType,\r
-      MtrrValidAddressMask\r
-      );\r
-    BaseAddress += Length;\r
-    TempQword   = Length - TempQword;\r
-    MemoryType  = MTRR_CACHE_UNCACHEABLE;\r
-  }\r
-\r
-  do {\r
-    //\r
-    // Find unused MTRR\r
-    //\r
-    for (; MsrNum < VariableMtrrEnd; MsrNum += 2) {\r
-      if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
-        break;\r
-      }\r
-    }\r
-\r
-    Length = Power2MaxMemory (TempQword);\r
-    if (!Positive) {\r
-      BaseAddress -= Length;\r
-    }\r
-\r
-    ProgramVariableMtrr (\r
-      MsrNum,\r
-      BaseAddress,\r
-      Length,\r
-      MemoryType,\r
-      MtrrValidAddressMask\r
-      );\r
-\r
-    if (Positive) {\r
-      BaseAddress += Length;\r
-    }\r
-    TempQword -= Length;\r
-\r
-  } while (TempQword > 0);\r
-\r
-Done:\r
-  DEBUG((DEBUG_CACHE, "  Status = %r\n", Status));\r
-  if (!RETURN_ERROR (Status)) {\r
-    MtrrDebugPrintAllMtrrs ();\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  This function will get the memory cache type of the specific address.\r
-\r
-  This function is mainly for debug purpose.\r
-\r
-  @param  Address   The specific address\r
-\r
-  @return Memory cache type of the sepcific address\r
-\r
-**/\r
-MTRR_MEMORY_CACHE_TYPE\r
-EFIAPI\r
-MtrrGetMemoryAttribute (\r
-  IN PHYSICAL_ADDRESS   Address\r
-  )\r
-{\r
-  UINT64                  TempQword;\r
-  UINTN                   Index;\r
-  UINTN                   SubIndex;\r
-  UINT64                  MtrrType;\r
-  UINT64                  TempMtrrType;\r
-  MTRR_MEMORY_CACHE_TYPE  CacheType;\r
-  VARIABLE_MTRR           VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];\r
-  UINT64                  MtrrValidBitsMask;\r
-  UINT64                  MtrrValidAddressMask;\r
-  UINTN                   VariableMtrrCount;\r
-\r
-  if (!IsMtrrSupported ()) {\r
-    return CacheUncacheable;\r
-  }\r
-\r
-  //\r
-  // Check if MTRR is enabled, if not, return UC as attribute\r
-  //\r
-  TempQword = AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE);\r
-  MtrrType = MTRR_CACHE_INVALID_TYPE;\r
-\r
-  if ((TempQword & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
-    return CacheUncacheable;\r
-  }\r
-\r
-  //\r
-  // If address is less than 1M, then try to go through the fixed MTRR\r
-  //\r
-  if (Address < BASE_1MB) {\r
-    if ((TempQword & MTRR_LIB_CACHE_FIXED_MTRR_ENABLED) != 0) {\r
-      //\r
-      // Go through the fixed MTRR\r
-      //\r
-      for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {\r
-         if (Address >= mMtrrLibFixedMtrrTable[Index].BaseAddress &&\r
-             Address  < (\r
-                          mMtrrLibFixedMtrrTable[Index].BaseAddress +\r
-                          (mMtrrLibFixedMtrrTable[Index].Length * 8)\r
-                        )\r
-            ) {\r
-           SubIndex =\r
-             ((UINTN)Address - mMtrrLibFixedMtrrTable[Index].BaseAddress) /\r
-               mMtrrLibFixedMtrrTable[Index].Length;\r
-           TempQword = AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr);\r
-           MtrrType =  RShiftU64 (TempQword, SubIndex * 8) & 0xFF;\r
-           return GetMemoryCacheTypeFromMtrrType (MtrrType);\r
-         }\r
+        break;\r
       }\r
     }\r
-  }\r
-  MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask);\r
-  MtrrGetMemoryAttributeInVariableMtrr(\r
-    MtrrValidBitsMask,\r
-    MtrrValidAddressMask,\r
-    VariableMtrr\r
-    );\r
 \r
-  //\r
-  // Go through the variable MTRR\r
-  //\r
-  VariableMtrrCount = GetVariableMtrrCount ();\r
-  ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);\r
+    ProgramVariableMtrr (\r
+      MsrNum,\r
+      BaseAddress,\r
+      Length,\r
+      MemoryType,\r
+      MtrrValidAddressMask\r
+      );\r
+    BaseAddress += Length;\r
+    TempQword   = Length - TempQword;\r
+    MemoryType  = MTRR_CACHE_UNCACHEABLE;\r
+  }\r
 \r
-  for (Index = 0; Index < VariableMtrrCount; Index++) {\r
-    if (VariableMtrr[Index].Valid) {\r
-      if (Address >= VariableMtrr[Index].BaseAddress &&\r
-          Address < VariableMtrr[Index].BaseAddress+VariableMtrr[Index].Length) {\r
-        TempMtrrType = VariableMtrr[Index].Type;\r
-        MtrrType = MtrrPrecedence (MtrrType, TempMtrrType);\r
+  do {\r
+    //\r
+    // Find unused MTRR\r
+    //\r
+    for (; MsrNum < VariableMtrrEnd; MsrNum += 2) {\r
+      if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
+        break;\r
       }\r
     }\r
-  }\r
-  CacheType = GetMemoryCacheTypeFromMtrrType (MtrrType);\r
-\r
-  return CacheType;\r
-}\r
 \r
+    Length = Power2MaxMemory (TempQword);\r
+    if (!Positive) {\r
+      BaseAddress -= Length;\r
+    }\r
 \r
-/**\r
-  This function will get the raw value in variable MTRRs\r
+    ProgramVariableMtrr (\r
+      MsrNum,\r
+      BaseAddress,\r
+      Length,\r
+      MemoryType,\r
+      MtrrValidAddressMask\r
+      );\r
 \r
-  @param  VariableSettings   A buffer to hold variable MTRRs content.\r
+    if (Positive) {\r
+      BaseAddress += Length;\r
+    }\r
+    TempQword -= Length;\r
 \r
-  @return The VariableSettings input pointer\r
+  } while (TempQword > 0);\r
 \r
-**/\r
-MTRR_VARIABLE_SETTINGS*\r
-EFIAPI\r
-MtrrGetVariableMtrr (\r
-  OUT MTRR_VARIABLE_SETTINGS         *VariableSettings\r
-  )\r
-{\r
-  UINT32  Index;\r
-  UINT32  VariableMtrrCount;\r
+Done:\r
 \r
-  if (!IsMtrrSupported ()) {\r
-    return VariableSettings;\r
+  //\r
+  // Write fixed MTRRs that have been modified\r
+  //\r
+  for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {\r
+    if (FixedSettingsModified[Index]) {\r
+      if (!MtrrContextValid) {\r
+        PreMtrrChange (&MtrrContext);\r
+        MtrrContextValid = TRUE;\r
+      }\r
+      AsmWriteMsr64 (\r
+        mMtrrLibFixedMtrrTable[Index].Msr,\r
+        WorkingFixedSettings.Mtrr[Index]\r
+        );\r
+    }\r
   }\r
 \r
-  VariableMtrrCount = GetVariableMtrrCount ();\r
-  ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);\r
+  if (MtrrContextValid) {\r
+    PostMtrrChange (&MtrrContext);\r
+  }\r
 \r
-  for (Index = 0; Index < VariableMtrrCount; Index++) {\r
-    VariableSettings->Mtrr[Index].Base =\r
-      AsmReadMsr64 (MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1));\r
-    VariableSettings->Mtrr[Index].Mask =\r
-      AsmReadMsr64 (MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1) + 1);\r
+  DEBUG((DEBUG_CACHE, "  Status = %r\n", Status));\r
+  if (!RETURN_ERROR (Status)) {\r
+    MtrrDebugPrintAllMtrrs ();\r
   }\r
 \r
-  return  VariableSettings;\r
+  return Status;\r
 }\r
-\r
-\r
 /**\r
   Worker function setting variable MTRRs\r
 \r
-  @param  VariableSettings   A buffer to hold variable MTRRs content.\r
+  @param[in]  VariableSettings   A buffer to hold variable MTRRs content.\r
 \r
 **/\r
 VOID\r
@@ -1334,7 +1705,7 @@ MtrrSetVariableMtrrWorker (
   UINT32  Index;\r
   UINT32  VariableMtrrCount;\r
 \r
-  VariableMtrrCount = GetVariableMtrrCount ();\r
+  VariableMtrrCount = GetVariableMtrrCountWorker ();\r
   ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);\r
 \r
   for (Index = 0; Index < VariableMtrrCount; Index++) {\r
@@ -1353,7 +1724,7 @@ MtrrSetVariableMtrrWorker (
 /**\r
   This function sets variable MTRRs\r
 \r
-  @param  VariableSettings   A buffer to hold variable MTRRs content.\r
+  @param[in]  VariableSettings   A buffer to hold variable MTRRs content.\r
 \r
   @return The pointer of VariableSettings\r
 \r
@@ -1376,39 +1747,10 @@ MtrrSetVariableMtrr (
   return  VariableSettings;\r
 }\r
 \r
-\r
-/**\r
-  This function gets the content in fixed MTRRs\r
-\r
-  @param  FixedSettings  A buffer to hold fixed Mtrrs content.\r
-\r
-  @retval The pointer of FixedSettings\r
-\r
-**/\r
-MTRR_FIXED_SETTINGS*\r
-EFIAPI\r
-MtrrGetFixedMtrr (\r
-  OUT MTRR_FIXED_SETTINGS         *FixedSettings\r
-  )\r
-{\r
-  UINT32  Index;\r
-\r
-  if (!IsMtrrSupported ()) {\r
-    return FixedSettings;\r
-  }\r
-\r
-  for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {\r
-      FixedSettings->Mtrr[Index] =\r
-        AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr);\r
-  };\r
-\r
-  return FixedSettings;\r
-}\r
-\r
 /**\r
   Worker function setting fixed MTRRs\r
 \r
-  @param  FixedSettings  A buffer to hold fixed Mtrrs content.\r
+  @param[in]  FixedSettings  A buffer to hold fixed MTRRs content.\r
 \r
 **/\r
 VOID\r
@@ -1430,7 +1772,7 @@ MtrrSetFixedMtrrWorker (
 /**\r
   This function sets fixed MTRRs\r
 \r
-  @param  FixedSettings  A buffer to hold fixed Mtrrs content.\r
+  @param[in]  FixedSettings  A buffer to hold fixed MTRRs content.\r
 \r
   @retval The pointer of FixedSettings\r
 \r
@@ -1458,7 +1800,7 @@ MtrrSetFixedMtrr (
 /**\r
   This function gets the content in all MTRRs (variable and fixed)\r
 \r
-  @param  MtrrSetting  A buffer to hold all Mtrrs content.\r
+  @param[out]  MtrrSetting  A buffer to hold all MTRRs content.\r
 \r
   @retval the pointer of MtrrSetting\r
 \r
@@ -1476,12 +1818,15 @@ MtrrGetAllMtrrs (
   //\r
   // Get fixed MTRRs\r
   //\r
-  MtrrGetFixedMtrr (&MtrrSetting->Fixed);\r
+  MtrrGetFixedMtrrWorker (&MtrrSetting->Fixed);\r
 \r
   //\r
   // Get variable MTRRs\r
   //\r
-  MtrrGetVariableMtrr (&MtrrSetting->Variables);\r
+  MtrrGetVariableMtrrWorker (\r
+    GetVariableMtrrCountWorker (),\r
+    &MtrrSetting->Variables\r
+    );\r
 \r
   //\r
   // Get MTRR_DEF_TYPE value\r
@@ -1495,7 +1840,7 @@ MtrrGetAllMtrrs (
 /**\r
   This function sets all MTRRs (variable and fixed)\r
 \r
-  @param  MtrrSetting  A buffer holding all MTRRs content.\r
+  @param[in]  MtrrSetting  A buffer holding all MTRRs content.\r
 \r
   @retval The pointer of MtrrSetting\r
 \r
@@ -1534,153 +1879,6 @@ MtrrSetAllMtrrs (
   return MtrrSetting;\r
 }\r
 \r
-/**\r
-  This function prints all MTRRs for debugging.\r
-**/\r
-VOID\r
-EFIAPI\r
-MtrrDebugPrintAllMtrrs (\r
-  VOID\r
-  )\r
-{\r
-  DEBUG_CODE (\r
-    MTRR_SETTINGS  MtrrSettings;\r
-    UINTN          Index;\r
-    UINTN          Index1;\r
-    UINTN          VariableMtrrCount;\r
-    UINT64         Base;\r
-    UINT64         Limit;\r
-    UINT64         MtrrBase;\r
-    UINT64         MtrrLimit;\r
-    UINT64         RangeBase;\r
-    UINT64         RangeLimit;\r
-    UINT64         NoRangeBase;\r
-    UINT64         NoRangeLimit;\r
-    UINT32         RegEax;\r
-    UINTN          MemoryType;\r
-    UINTN          PreviousMemoryType;\r
-    BOOLEAN        Found;\r
-\r
-    if (!IsMtrrSupported ()) {\r
-      return;\r
-    }\r
-\r
-    DEBUG((DEBUG_CACHE, "MTRR Settings\n"));\r
-    DEBUG((DEBUG_CACHE, "=============\n"));\r
-    \r
-    MtrrGetAllMtrrs (&MtrrSettings);\r
-    DEBUG((DEBUG_CACHE, "MTRR Default Type: %016lx\n", MtrrSettings.MtrrDefType));\r
-    for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {\r
-      DEBUG((DEBUG_CACHE, "Fixed MTRR[%02d]   : %016lx\n", Index, MtrrSettings.Fixed.Mtrr[Index]));\r
-    }\r
-\r
-    VariableMtrrCount = GetVariableMtrrCount ();\r
-    for (Index = 0; Index < VariableMtrrCount; Index++) {\r
-      DEBUG((DEBUG_CACHE, "Variable MTRR[%02d]: Base=%016lx Mask=%016lx\n",\r
-        Index,\r
-        MtrrSettings.Variables.Mtrr[Index].Base,\r
-        MtrrSettings.Variables.Mtrr[Index].Mask\r
-        ));\r
-    }\r
-    DEBUG((DEBUG_CACHE, "\n"));\r
-    DEBUG((DEBUG_CACHE, "MTRR Ranges\n"));\r
-    DEBUG((DEBUG_CACHE, "====================================\n"));\r
-\r
-    Base = 0;\r
-    PreviousMemoryType = MTRR_CACHE_INVALID_TYPE;\r
-    for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {\r
-      Base = mMtrrLibFixedMtrrTable[Index].BaseAddress;\r
-      for (Index1 = 0; Index1 < 8; Index1++) {\r
-      MemoryType = (UINTN)(RShiftU64 (MtrrSettings.Fixed.Mtrr[Index], Index1 * 8) & 0xff);\r
-        if (MemoryType > CacheWriteBack) {\r
-          MemoryType = MTRR_CACHE_INVALID_TYPE;\r
-        }            \r
-        if (MemoryType != PreviousMemoryType) {\r
-          if (PreviousMemoryType != MTRR_CACHE_INVALID_TYPE) {\r
-            DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1));\r
-          }\r
-          PreviousMemoryType = MemoryType;\r
-          DEBUG((DEBUG_CACHE, "%a:%016lx-", mMtrrMemoryCacheTypeShortName[MemoryType], Base));\r
-        }\r
-        Base += mMtrrLibFixedMtrrTable[Index].Length;\r
-      }\r
-    }\r
-    DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1));\r
-\r
-    VariableMtrrCount = GetVariableMtrrCount ();\r
-\r
-    Limit        = BIT36 - 1;\r
-    AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
-    if (RegEax >= 0x80000008) {\r
-      AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);\r
-      Limit = LShiftU64 (1, RegEax & 0xff) - 1;\r
-    }\r
-    Base = BASE_1MB;\r
-    PreviousMemoryType = MTRR_CACHE_INVALID_TYPE;\r
-    do {\r
-      MemoryType = MtrrGetMemoryAttribute (Base);\r
-      if (MemoryType > CacheWriteBack) {\r
-        MemoryType = MTRR_CACHE_INVALID_TYPE;\r
-      }\r
-\r
-      if (MemoryType != PreviousMemoryType) {\r
-        if (PreviousMemoryType != MTRR_CACHE_INVALID_TYPE) {\r
-          DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1));\r
-        }\r
-        PreviousMemoryType = MemoryType;\r
-        DEBUG((DEBUG_CACHE, "%a:%016lx-", mMtrrMemoryCacheTypeShortName[MemoryType], Base));\r
-      }\r
-      \r
-      RangeBase    = BASE_1MB;        \r
-      NoRangeBase  = BASE_1MB;\r
-      RangeLimit   = Limit;\r
-      NoRangeLimit = Limit;\r
-      \r
-      for (Index = 0, Found = FALSE; Index < VariableMtrrCount; Index++) {\r
-        if ((MtrrSettings.Variables.Mtrr[Index].Mask & BIT11) == 0) {\r
-          //\r
-          // If mask is not valid, then do not display range\r
-          //\r
-          continue;\r
-        }\r
-        MtrrBase  = (MtrrSettings.Variables.Mtrr[Index].Base & (~(SIZE_4KB - 1)));\r
-        MtrrLimit = MtrrBase + ((~(MtrrSettings.Variables.Mtrr[Index].Mask & (~(SIZE_4KB - 1)))) & Limit);\r
-\r
-        if (Base >= MtrrBase && Base < MtrrLimit) {\r
-          Found = TRUE;\r
-        }\r
-        \r
-        if (Base >= MtrrBase && MtrrBase > RangeBase) {\r
-          RangeBase = MtrrBase;\r
-        }\r
-        if (Base > MtrrLimit && MtrrLimit > RangeBase) {\r
-          RangeBase = MtrrLimit + 1;\r
-        }\r
-        if (Base < MtrrBase && MtrrBase < RangeLimit) {\r
-          RangeLimit = MtrrBase - 1;\r
-        }\r
-        if (Base < MtrrLimit && MtrrLimit <= RangeLimit) {\r
-          RangeLimit = MtrrLimit;\r
-        }\r
-        \r
-        if (Base > MtrrLimit && NoRangeBase < MtrrLimit) {\r
-          NoRangeBase = MtrrLimit + 1;\r
-        }\r
-        if (Base < MtrrBase && NoRangeLimit > MtrrBase) {\r
-          NoRangeLimit = MtrrBase - 1;\r
-        }\r
-      }\r
-      \r
-      if (Found) {\r
-        Base = RangeLimit + 1;\r
-      } else {\r
-        Base = NoRangeLimit + 1;\r
-      }\r
-    } while (Base < Limit);\r
-    DEBUG((DEBUG_CACHE, "%016lx\n\n", Base - 1));\r
-  );\r
-}\r
-\r
 /**\r
   Checks if MTRR is supported.\r
 \r