]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/MtrrLib/MtrrLib.c
UefiCpuPkg/MtrrLib: Reduce hardware init when program variable MTRRs
[mirror_edk2.git] / UefiCpuPkg / Library / MtrrLib / MtrrLib.c
index 322f47b0976cfaedca2120042236de877586d9b2..0e76e2f92ad54822c9a00e8b0443fee771eae4f0 100644 (file)
@@ -883,30 +883,27 @@ GetMtrrNumberAndDirection (
   This function programs MTRRs according to the values specified\r
   in the shadow array.\r
 \r
+  @param[in, out]  VariableSettings   Variable MTRR settings\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 OUT MTRR_VARIABLE_SETTINGS  *VariableSettings,\r
   IN     UINTN                   VariableMtrrCount,\r
   IN OUT VARIABLE_MTRR           *VariableMtrr\r
   )\r
 {\r
   UINTN         Index;\r
-  MTRR_CONTEXT  MtrrContext;\r
 \r
-  PreMtrrChange (&MtrrContext);\r
-  Index = 0;\r
-  while (Index < VariableMtrrCount) {\r
+  for (Index = 0; Index < VariableMtrrCount; Index++) {\r
     if (!VariableMtrr[Index].Valid && VariableMtrr[Index].Used) {\r
-       AsmWriteMsr64 (VariableMtrr[Index].Msr, 0);\r
-       AsmWriteMsr64 (VariableMtrr[Index].Msr + 1, 0);\r
+       VariableSettings->Mtrr[Index].Base = 0;\r
+       VariableSettings->Mtrr[Index].Mask = 0;\r
        VariableMtrr[Index].Used = FALSE;\r
     }\r
-    Index ++;\r
   }\r
-  PostMtrrChange (&MtrrContext);\r
 }\r
 \r
 \r
@@ -915,6 +912,7 @@ InvalidateMtrr (
 \r
   This function programs variable MTRRs\r
 \r
+  @param[in, out]  VariableSettings      Variable MTRR settings.\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
@@ -924,34 +922,27 @@ InvalidateMtrr (
 **/\r
 VOID\r
 ProgramVariableMtrr (\r
-  IN UINTN                    MtrrNumber,\r
-  IN PHYSICAL_ADDRESS         BaseAddress,\r
-  IN UINT64                   Length,\r
-  IN UINT64                   MemoryCacheType,\r
-  IN UINT64                   MtrrValidAddressMask\r
+  IN OUT MTRR_VARIABLE_SETTINGS  *VariableSettings,\r
+  IN     UINTN                   MtrrNumber,\r
+  IN     PHYSICAL_ADDRESS        BaseAddress,\r
+  IN     UINT64                  Length,\r
+  IN     UINT64                  MemoryCacheType,\r
+  IN     UINT64                  MtrrValidAddressMask\r
   )\r
 {\r
   UINT64        TempQword;\r
-  MTRR_CONTEXT  MtrrContext;\r
-\r
-  PreMtrrChange (&MtrrContext);\r
 \r
   //\r
   // MTRR Physical Base\r
   //\r
   TempQword = (BaseAddress & MtrrValidAddressMask) | MemoryCacheType;\r
-  AsmWriteMsr64 ((UINT32) MtrrNumber, TempQword);\r
+  VariableSettings->Mtrr[MtrrNumber].Base = TempQword;\r
 \r
   //\r
   // MTRR Physical Mask\r
   //\r
   TempQword = ~(Length - 1);\r
-  AsmWriteMsr64 (\r
-    (UINT32) (MtrrNumber + 1),\r
-    (TempQword & MtrrValidAddressMask) | MTRR_LIB_CACHE_MTRR_ENABLED\r
-    );\r
-\r
-  PostMtrrChange (&MtrrContext);\r
+  VariableSettings->Mtrr[MtrrNumber].Mask = (TempQword & MtrrValidAddressMask) | MTRR_LIB_CACHE_MTRR_ENABLED;\r
 }\r
 \r
 \r
@@ -1393,7 +1384,6 @@ MtrrSetMemoryAttribute (
   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
@@ -1401,6 +1391,7 @@ MtrrSetMemoryAttribute (
   MTRR_FIXED_SETTINGS       WorkingFixedSettings;\r
   UINT32                    VariableMtrrCount;\r
   MTRR_VARIABLE_SETTINGS    OriginalVariableSettings;\r
+  BOOLEAN                   ProgramVariableSettings;\r
   MTRR_VARIABLE_SETTINGS    WorkingVariableSettings;\r
   UINT32                    Index;\r
   UINT64                    ClearMask;\r
@@ -1414,16 +1405,14 @@ MtrrSetMemoryAttribute (
     FixedSettingsValid[Index]    = FALSE;\r
     FixedSettingsModified[Index] = FALSE;\r
   }\r
+  ProgramVariableSettings = FALSE;\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
+  MtrrLibInitializeMtrrMask (&MtrrValidBitsMask, &MtrrValidAddressMask);\r
 \r
   TempQword = 0;\r
   MemoryType = (UINT64)Attribute;\r
@@ -1489,8 +1478,10 @@ MtrrSetMemoryAttribute (
   // Read all variable MTRRs\r
   //\r
   VariableMtrrCount = GetVariableMtrrCountWorker ();\r
+  FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCountWorker ();\r
   MtrrGetVariableMtrrWorker (VariableMtrrCount, &OriginalVariableSettings);\r
   CopyMem (&WorkingVariableSettings, &OriginalVariableSettings, sizeof (WorkingVariableSettings));\r
+  ProgramVariableSettings = TRUE;\r
   VariableSettings = &WorkingVariableSettings;\r
 \r
   //\r
@@ -1509,7 +1500,6 @@ MtrrSetMemoryAttribute (
               BaseAddress + Length - 1,\r
               VariableMtrr\r
               );\r
-\r
   if (OverLap) {\r
     Status = CombineMemoryAttribute (\r
                FirmwareVariableMtrrCount,\r
@@ -1528,7 +1518,7 @@ MtrrSetMemoryAttribute (
       //\r
       // Combined successfully, invalidate the now-unused MTRRs\r
       //\r
-      InvalidateMtrr(VariableMtrrCount, VariableMtrr);\r
+      InvalidateMtrr (VariableSettings, VariableMtrrCount, VariableMtrr);\r
       Status = RETURN_SUCCESS;\r
       goto Done;\r
     }\r
@@ -1542,7 +1532,7 @@ MtrrSetMemoryAttribute (
     //\r
     // Invalidate the now-unused MTRRs\r
     //\r
-    InvalidateMtrr(VariableMtrrCount, VariableMtrr);\r
+    InvalidateMtrr (VariableSettings, VariableMtrrCount, VariableMtrr);\r
     goto Done;\r
   }\r
 \r
@@ -1556,16 +1546,13 @@ MtrrSetMemoryAttribute (
   //\r
   // Invalidate the now-unused MTRRs\r
   //\r
-  InvalidateMtrr(VariableMtrrCount, VariableMtrr);\r
+  InvalidateMtrr (VariableSettings, VariableMtrrCount, VariableMtrr);\r
 \r
   //\r
   // Find first unused MTRR\r
   //\r
-  for (MsrNum = MTRR_LIB_IA32_VARIABLE_MTRR_BASE;\r
-       MsrNum < VariableMtrrEnd;\r
-       MsrNum += 2\r
-      ) {\r
-    if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
+  for (MsrNum = 0; MsrNum < VariableMtrrCount; MsrNum++) {\r
+    if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
       break;\r
     }\r
   }\r
@@ -1584,13 +1571,14 @@ MtrrSetMemoryAttribute (
       //\r
       // Find unused MTRR\r
       //\r
-      for (; MsrNum < VariableMtrrEnd; MsrNum += 2) {\r
-        if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
+      for (; MsrNum < VariableMtrrCount; MsrNum++) {\r
+        if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
           break;\r
         }\r
       }\r
 \r
       ProgramVariableMtrr (\r
+        VariableSettings,\r
         MsrNum,\r
         BaseAddress,\r
         Alignment,\r
@@ -1614,13 +1602,14 @@ MtrrSetMemoryAttribute (
     //\r
     // Find unused MTRR\r
     //\r
-    for (; MsrNum < VariableMtrrEnd; MsrNum += 2) {\r
-      if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
+    for (; MsrNum < VariableMtrrCount; MsrNum++) {\r
+      if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
         break;\r
       }\r
     }\r
 \r
     ProgramVariableMtrr (\r
+      VariableSettings,\r
       MsrNum,\r
       BaseAddress,\r
       Length,\r
@@ -1636,8 +1625,8 @@ MtrrSetMemoryAttribute (
     //\r
     // Find unused MTRR\r
     //\r
-    for (; MsrNum < VariableMtrrEnd; MsrNum += 2) {\r
-      if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
+    for (; MsrNum < VariableMtrrCount; MsrNum++) {\r
+      if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
         break;\r
       }\r
     }\r
@@ -1648,6 +1637,7 @@ MtrrSetMemoryAttribute (
     }\r
 \r
     ProgramVariableMtrr (\r
+      VariableSettings,\r
       MsrNum,\r
       BaseAddress,\r
       Length,\r
@@ -1680,6 +1670,28 @@ Done:
     }\r
   }\r
 \r
+  //\r
+  // Write variable MTRRs\r
+  //\r
+  if (ProgramVariableSettings) {\r
+    for (Index = 0; Index < VariableMtrrCount; Index++) {\r
+      if (WorkingVariableSettings.Mtrr[Index].Base != OriginalVariableSettings.Mtrr[Index].Base ||\r
+          WorkingVariableSettings.Mtrr[Index].Mask != OriginalVariableSettings.Mtrr[Index].Mask    ) {\r
+        if (!MtrrContextValid) {\r
+          PreMtrrChange (&MtrrContext);\r
+          MtrrContextValid = TRUE;\r
+        }\r
+        AsmWriteMsr64 (\r
+          MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1),\r
+          WorkingVariableSettings.Mtrr[Index].Base\r
+          );\r
+        AsmWriteMsr64 (\r
+          MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1) + 1,\r
+          WorkingVariableSettings.Mtrr[Index].Mask\r
+          );\r
+      }\r
+    }\r
+  }\r
   if (MtrrContextValid) {\r
     PostMtrrChange (&MtrrContext);\r
   }\r