]> git.proxmox.com Git - mirror_edk2.git/commitdiff
UefiCpuPkg/MtrrLib: Reduce hardware init when program fixed MTRRs
authorMichael Kinney <michael.d.kinney@intel.com>
Tue, 8 Dec 2015 05:23:44 +0000 (05:23 +0000)
committervanjeff <vanjeff@Edk2>
Tue, 8 Dec 2015 05:23:44 +0000 (05:23 +0000)
When MtrrSetMemoryAttribute() programs fixed MTRRs, it may disable/enable cache
and disable/enable MTRRs several times. This updating tries to do operation in
local variable and does the hardware initialization one time only.

Cc: Feng Tian <feng.tian@intel.com>
Cc: Michael Kinney <michael.d.kinney@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Michael Kinney <michael.d.kinney@intel.com>
Signed-off-by: Jeff Fan <jeff.fan@intel.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19157 6f19259b-4bc3-4df7-8a09-765794883524

UefiCpuPkg/Library/MtrrLib/MtrrLib.c

index 697dc4352f61dd1540035ebdd139ed97d0c9e16f..322f47b0976cfaedca2120042236de877586d9b2 100644 (file)
@@ -415,6 +415,9 @@ MtrrGetVariableMtrr (
   @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[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
 \r
   @retval RETURN_SUCCESS      The cache type was updated successfully\r
   @retval RETURN_UNSUPPORTED  The requested range or cache type was invalid\r
@@ -423,9 +426,12 @@ MtrrGetVariableMtrr (
 **/\r
 RETURN_STATUS\r
 ProgramFixedMtrr (\r
 **/\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
   )\r
 {\r
   UINT32  MsrNum;\r
@@ -488,9 +494,10 @@ ProgramFixedMtrr (
     return RETURN_UNSUPPORTED;\r
   }\r
 \r
     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
   return RETURN_SUCCESS;\r
 }\r
 \r
@@ -1388,12 +1395,25 @@ MtrrSetMemoryAttribute (
   UINT32                    FirmwareVariableMtrrCount;\r
   UINT32                    VariableMtrrEnd;\r
   MTRR_CONTEXT              MtrrContext;\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                    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
   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
 \r
   if (!IsMtrrSupported ()) {\r
     Status = RETURN_UNSUPPORTED;\r
@@ -1429,22 +1449,31 @@ MtrrSetMemoryAttribute (
   // Check if Fixed MTRR\r
   //\r
   Status = RETURN_SUCCESS;\r
   // 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
 \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
   }\r
 \r
   //\r
@@ -1634,6 +1663,27 @@ MtrrSetMemoryAttribute (
   } while (TempQword > 0);\r
 \r
 Done:\r
   } while (TempQword > 0);\r
 \r
 Done:\r
+\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
+  if (MtrrContextValid) {\r
+    PostMtrrChange (&MtrrContext);\r
+  }\r
+\r
   DEBUG((DEBUG_CACHE, "  Status = %r\n", Status));\r
   if (!RETURN_ERROR (Status)) {\r
     MtrrDebugPrintAllMtrrs ();\r
   DEBUG((DEBUG_CACHE, "  Status = %r\n", Status));\r
   if (!RETURN_ERROR (Status)) {\r
     MtrrDebugPrintAllMtrrs ();\r