]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/MtrrLib/MtrrLib.c
Revert the change in r19143 for BUILDRULEORDER.
[mirror_edk2.git] / UefiCpuPkg / Library / MtrrLib / MtrrLib.c
index 04c6a1c268be3c1d5510491835fd26a2c7af1460..a65560542c88f186c9eb0137b60b9d0def565dbc 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   MTRR setting library\r
 \r
-  Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/DebugLib.h>\r
 \r
+//\r
+// Context to save and restore when MTRRs are programmed\r
+//\r
+typedef struct {\r
+  UINTN    Cr4;\r
+  BOOLEAN  InterruptState;\r
+} MTRR_CONTEXT;\r
+\r
 //\r
 // This table defines the offset, base and length of the fixed MTRRs\r
 //\r
@@ -144,17 +152,21 @@ GetFirmwareVariableMtrrCount (
 /**\r
   Returns the default MTRR cache type for the system.\r
 \r
-  @return  MTRR default type\r
+  @return  The default MTRR cache type.\r
 \r
 **/\r
-UINT64\r
-GetMtrrDefaultMemoryType (\r
+MTRR_MEMORY_CACHE_TYPE\r
+EFIAPI\r
+MtrrGetDefaultMemoryType (\r
   VOID\r
-)\r
+  )\r
 {\r
-  return (AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE) & 0xff);\r
-}\r
+  if (!IsMtrrSupported ()) {\r
+    return CacheUncacheable;\r
+  }\r
 \r
+  return (MTRR_MEMORY_CACHE_TYPE) (AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE) & 0x7);\r
+}\r
 \r
 /**\r
   Preparation before programming MTRR.\r
@@ -162,16 +174,19 @@ GetMtrrDefaultMemoryType (
   This function will do some preparation for programming MTRRs:\r
   disable cache, invalid cache and disable MTRR caching functionality\r
 \r
-  @return  CR4 value before changing.\r
+  @param[out] MtrrContext  Pointer to context to save\r
 \r
 **/\r
-UINTN\r
+VOID\r
 PreMtrrChange (\r
-  VOID\r
+  OUT MTRR_CONTEXT  *MtrrContext\r
   )\r
 {\r
-  UINTN  Value;\r
-\r
+  //\r
+  // Disable interrupts and save current interrupt state\r
+  //\r
+  MtrrContext->InterruptState = SaveAndDisableInterrupts();\r
+  \r
   //\r
   // Enter no fill cache mode, CD=1(Bit30), NW=0 (Bit29)\r
   //\r
@@ -180,8 +195,8 @@ PreMtrrChange (
   //\r
   // Save original CR4 value and clear PGE flag (Bit 7)\r
   //\r
-  Value = AsmReadCr4 ();\r
-  AsmWriteCr4 (Value & (~BIT7));\r
+  MtrrContext->Cr4 = AsmReadCr4 ();\r
+  AsmWriteCr4 (MtrrContext->Cr4 & (~BIT7));\r
 \r
   //\r
   // Flush all TLBs\r
@@ -192,33 +207,22 @@ PreMtrrChange (
   // Disable Mtrrs\r
   //\r
   AsmMsrBitFieldWrite64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, 10, 11, 0);\r
-\r
-  //\r
-  // Return original CR4 value\r
-  //\r
-  return Value;\r
 }\r
 \r
-\r
 /**\r
   Cleaning up after programming MTRRs.\r
 \r
   This function will do some clean up after programming MTRRs:\r
-  enable MTRR caching functionality, and enable cache\r
+  Flush all TLBs,  re-enable caching, restore CR4.\r
 \r
-  @param  Cr4  CR4 value to restore\r
+  @param[in] MtrrContext  Pointer to context to restore\r
 \r
 **/\r
 VOID\r
-PostMtrrChange (\r
-  UINTN Cr4\r
+PostMtrrChangeEnableCache (\r
+  IN MTRR_CONTEXT  *MtrrContext\r
   )\r
 {\r
-  //\r
-  // Enable Cache MTRR\r
-  //\r
-  AsmMsrBitFieldWrite64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, 10, 11, 3);\r
-\r
   //\r
   // Flush all TLBs \r
   //\r
@@ -232,7 +236,34 @@ PostMtrrChange (
   //\r
   // Restore original CR4 value\r
   //\r
-  AsmWriteCr4 (Cr4);\r
+  AsmWriteCr4 (MtrrContext->Cr4);\r
+  \r
+  //\r
+  // Restore original interrupt state\r
+  //\r
+  SetInterruptState (MtrrContext->InterruptState);\r
+}\r
+\r
+/**\r
+  Cleaning up after programming MTRRs.\r
+\r
+  This function will do some clean up after programming MTRRs:\r
+  enable MTRR caching functionality, and enable cache\r
+\r
+  @param[in] MtrrContext  Pointer to context to restore\r
+\r
+**/\r
+VOID\r
+PostMtrrChange (\r
+  IN MTRR_CONTEXT  *MtrrContext\r
+  )\r
+{\r
+  //\r
+  // Enable Cache MTRR\r
+  //\r
+  AsmMsrBitFieldWrite64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, 10, 11, 3);\r
+\r
+  PostMtrrChangeEnableCache (MtrrContext);\r
 }\r
 \r
 \r
@@ -684,11 +715,11 @@ InvalidateMtrr (
    IN     VARIABLE_MTRR      *VariableMtrr\r
    )\r
 {\r
-  UINTN Index;\r
-  UINTN Cr4;\r
-  UINTN VariableMtrrCount;\r
+  UINTN         Index;\r
+  UINTN         VariableMtrrCount;\r
+  MTRR_CONTEXT  MtrrContext;\r
 \r
-  Cr4 = PreMtrrChange ();\r
+  PreMtrrChange (&MtrrContext);\r
   Index = 0;\r
   VariableMtrrCount = GetVariableMtrrCount ();\r
   while (Index < VariableMtrrCount) {\r
@@ -699,7 +730,7 @@ InvalidateMtrr (
     }\r
     Index ++;\r
   }\r
-  PostMtrrChange (Cr4);\r
+  PostMtrrChange (&MtrrContext);\r
 }\r
 \r
 \r
@@ -724,10 +755,10 @@ ProgramVariableMtrr (
   IN UINT64                   MtrrValidAddressMask\r
   )\r
 {\r
-  UINT64  TempQword;\r
-  UINTN   Cr4;\r
+  UINT64        TempQword;\r
+  MTRR_CONTEXT  MtrrContext;\r
 \r
-  Cr4 = PreMtrrChange ();\r
+  PreMtrrChange (&MtrrContext);\r
 \r
   //\r
   // MTRR Physical Base\r
@@ -744,7 +775,7 @@ ProgramVariableMtrr (
     (TempQword & MtrrValidAddressMask) | MTRR_LIB_CACHE_MTRR_ENABLED\r
     );\r
 \r
-  PostMtrrChange (Cr4);\r
+  PostMtrrChange (&MtrrContext);\r
 }\r
 \r
 \r
@@ -777,7 +808,7 @@ GetMemoryCacheTypeFromMtrrType (
     // MtrrType is MTRR_CACHE_INVALID_TYPE, that means\r
     // no mtrr covers the range\r
     //\r
-    return CacheUncacheable;\r
+    return MtrrGetDefaultMemoryType ();\r
   }\r
 }\r
 \r
@@ -809,8 +840,8 @@ MtrrLibInitializeMtrrMask (
     *MtrrValidBitsMask    = LShiftU64 (1, PhysicalAddressBits) - 1;\r
     *MtrrValidAddressMask = *MtrrValidBitsMask & 0xfffffffffffff000ULL;\r
   } else {\r
-    *MtrrValidBitsMask    = MTRR_LIB_CACHE_VALID_ADDRESS;\r
-    *MtrrValidAddressMask = 0xFFFFFFFF;\r
+    *MtrrValidBitsMask    = MTRR_LIB_MSR_VALID_MASK;\r
+    *MtrrValidAddressMask = MTRR_LIB_CACHE_VALID_ADDRESS;\r
   }\r
 }\r
 \r
@@ -933,10 +964,10 @@ MtrrSetMemoryAttribute (
   UINT32                    UsedMtrr;\r
   UINT64                    MtrrValidBitsMask;\r
   UINT64                    MtrrValidAddressMask;\r
-  UINTN                     Cr4;\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
 \r
@@ -975,9 +1006,9 @@ MtrrSetMemoryAttribute (
   //\r
   Status = RETURN_SUCCESS;\r
   while ((BaseAddress < BASE_1MB) && (Length > 0) && Status == RETURN_SUCCESS) {\r
-    Cr4 = PreMtrrChange ();\r
+    PreMtrrChange (&MtrrContext);\r
     Status = ProgramFixedMtrr (MemoryType, &BaseAddress, &Length);\r
-    PostMtrrChange (Cr4);\r
+    PostMtrrChange (&MtrrContext);\r
     if (RETURN_ERROR (Status)) {\r
       goto Done;\r
     }\r
@@ -1022,21 +1053,11 @@ MtrrSetMemoryAttribute (
     }\r
   }\r
 \r
-  //\r
-  // Program Variable MTRRs\r
-  //\r
-  // Avoid hardcode here and read data dynamically\r
-  //\r
-  if (UsedMtrr >= FirmwareVariableMtrrCount) {\r
-    Status = RETURN_OUT_OF_RESOURCES;\r
-    goto Done;\r
-  }\r
-\r
   //\r
   // The memory type is the same with the type specified by\r
   // MTRR_LIB_IA32_MTRR_DEF_TYPE.\r
   //\r
-  if ((!OverwriteExistingMtrr) && (Attribute == GetMtrrDefaultMemoryType ())) {\r
+  if ((!OverwriteExistingMtrr) && (Attribute == MtrrGetDefaultMemoryType ())) {\r
     //\r
     // Invalidate the now-unused MTRRs\r
     //\r
@@ -1343,15 +1364,15 @@ MtrrSetVariableMtrr (
   IN MTRR_VARIABLE_SETTINGS         *VariableSettings\r
   )\r
 {\r
-  UINTN  Cr4;\r
+  MTRR_CONTEXT  MtrrContext;\r
 \r
   if (!IsMtrrSupported ()) {\r
     return VariableSettings;\r
   }\r
 \r
-  Cr4 = PreMtrrChange ();\r
+  PreMtrrChange (&MtrrContext);\r
   MtrrSetVariableMtrrWorker (VariableSettings);\r
-  PostMtrrChange (Cr4);\r
+  PostMtrrChange (&MtrrContext);\r
   return  VariableSettings;\r
 }\r
 \r
@@ -1420,15 +1441,15 @@ MtrrSetFixedMtrr (
   IN MTRR_FIXED_SETTINGS          *FixedSettings\r
   )\r
 {\r
-  UINTN  Cr4;\r
+  MTRR_CONTEXT  MtrrContext;\r
 \r
   if (!IsMtrrSupported ()) {\r
     return FixedSettings;\r
   }\r
 \r
-  Cr4 = PreMtrrChange ();\r
+  PreMtrrChange (&MtrrContext);\r
   MtrrSetFixedMtrrWorker (FixedSettings);\r
-  PostMtrrChange (Cr4);\r
+  PostMtrrChange (&MtrrContext);\r
 \r
   return FixedSettings;\r
 }\r
@@ -1485,13 +1506,13 @@ MtrrSetAllMtrrs (
   IN MTRR_SETTINGS                *MtrrSetting\r
   )\r
 {\r
-  UINTN  Cr4;\r
+  MTRR_CONTEXT  MtrrContext;\r
 \r
   if (!IsMtrrSupported ()) {\r
     return MtrrSetting;\r
   }\r
 \r
-  Cr4 = PreMtrrChange ();\r
+  PreMtrrChange (&MtrrContext);\r
 \r
   //\r
   // Set fixed MTRRs\r
@@ -1508,7 +1529,7 @@ MtrrSetAllMtrrs (
   //\r
   AsmWriteMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, MtrrSetting->MtrrDefType);\r
 \r
-  PostMtrrChange (Cr4);\r
+  PostMtrrChangeEnableCache (&MtrrContext);\r
 \r
   return MtrrSetting;\r
 }\r
@@ -1588,6 +1609,12 @@ MtrrDebugPrintAllMtrrs (
 \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
@@ -1606,12 +1633,6 @@ MtrrDebugPrintAllMtrrs (
       \r
       RangeBase    = BASE_1MB;        \r
       NoRangeBase  = BASE_1MB;\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
       RangeLimit   = Limit;\r
       NoRangeLimit = Limit;\r
       \r
@@ -1655,7 +1676,7 @@ MtrrDebugPrintAllMtrrs (
       } else {\r
         Base = NoRangeLimit + 1;\r
       }\r
-    } while (Found);\r
+    } while (Base < Limit);\r
     DEBUG((DEBUG_CACHE, "%016lx\n\n", Base - 1));\r
   );\r
 }\r