]> git.proxmox.com Git - mirror_edk2.git/commitdiff
UefiCpuPkg/MtrrLib: Refine MtrrGetMemoryAttributeByAddressWorker
authorRuiyu Ni <ruiyu.ni@intel.com>
Fri, 2 Sep 2016 10:10:45 +0000 (18:10 +0800)
committerRuiyu Ni <ruiyu.ni@intel.com>
Fri, 31 Mar 2017 05:57:34 +0000 (13:57 +0800)
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Jeff Fan <jeff.fan@intel.com>
UefiCpuPkg/Library/MtrrLib/MtrrLib.c

index 31a08a3935c8b87256d47706f5eef38893d6733c..b7e82f5ac5dfae7b14c728c6ccad440f6212ab59 100644 (file)
@@ -568,20 +568,19 @@ MtrrLibProgramFixedMtrr (
   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
+  @param[in]   VariableSettings      The variable MTRR values to shadow\r
+  @param[in]   VariableMtrrCount     The number of variable MTRRs\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
+  @return      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  UINTN                   VariableMtrrCount,\r
   IN  UINT64                  MtrrValidBitsMask,\r
   IN  UINT64                  MtrrValidAddressMask,\r
   OUT VARIABLE_MTRR           *VariableMtrr\r
@@ -591,7 +590,7 @@ MtrrGetMemoryAttributeInVariableMtrrWorker (
   UINT32  UsedMtrr;\r
 \r
   ZeroMem (VariableMtrr, sizeof (VARIABLE_MTRR) * MTRR_NUMBER_OF_VARIABLE_MTRR);\r
-  for (Index = 0, UsedMtrr = 0; Index < FirmwareVariableMtrrCount; Index++) {\r
+  for (Index = 0, UsedMtrr = 0; Index < VariableMtrrCount; 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
@@ -724,8 +723,10 @@ MtrrLibGetPositiveMtrrNumber (
   Return whether the left MTRR type precedes the right MTRR type.\r
 \r
   The MTRR type precedence rules are:\r
-  1. UC precedes any other type\r
-  2. WT precedes WB\r
+    1. UC precedes any other type\r
+    2. WT precedes WB\r
+  For further details, please refer the IA32 Software Developer's Manual,\r
+  Volume 3, Section "MTRR Precedences".\r
 \r
   @param Left  The left MTRR type.\r
   @param Right The right MTRR type.\r
@@ -954,46 +955,6 @@ MtrrLibGetMtrrNumber (
   return LeastSubtractiveMtrrNumber + MiddleMtrrNumber + LeastRightMtrrNumber;\r
 }\r
 \r
-\r
-/**\r
-  Converts the Memory attribute value to MTRR_MEMORY_CACHE_TYPE.\r
-\r
-  If MtrrSetting is not NULL, gets the default memory attribute from input\r
-  MTRR settings buffer.\r
-  If MtrrSetting is NULL, gets the default memory attribute from MSR.\r
-\r
-  @param[in]  MtrrSetting        A buffer holding all MTRRs content.\r
-  @param[in]  MtrrType           MTRR memory type\r
-\r
-  @return The enum item in MTRR_MEMORY_CACHE_TYPE\r
-\r
-**/\r
-MTRR_MEMORY_CACHE_TYPE\r
-GetMemoryCacheTypeFromMtrrType (\r
-  IN MTRR_SETTINGS         *MtrrSetting,\r
-  IN UINT64                MtrrType\r
-  )\r
-{\r
-  switch (MtrrType) {\r
-  case MTRR_CACHE_UNCACHEABLE:\r
-    return CacheUncacheable;\r
-  case MTRR_CACHE_WRITE_COMBINING:\r
-    return CacheWriteCombining;\r
-  case MTRR_CACHE_WRITE_THROUGH:\r
-    return CacheWriteThrough;\r
-  case MTRR_CACHE_WRITE_PROTECTED:\r
-    return CacheWriteProtected;\r
-  case MTRR_CACHE_WRITE_BACK:\r
-    return CacheWriteBack;\r
-  default:\r
-    //\r
-    // MtrrType is MTRR_CACHE_INVALID_TYPE, that means\r
-    // no MTRR covers the range\r
-    //\r
-    return MtrrGetDefaultMemoryTypeWorker (MtrrSetting);\r
-  }\r
-}\r
-\r
 /**\r
   Initializes the valid bits mask and valid address mask for MTRRs.\r
 \r
@@ -1030,71 +991,34 @@ MtrrLibInitializeMtrrMask (
   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 MTRRs 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
+  Section "MTRR Precedences".\r
 \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
+MTRR_MEMORY_CACHE_TYPE\r
 MtrrLibPrecedence (\r
-  IN UINT64    MtrrType1,\r
-  IN UINT64    MtrrType2\r
+  IN MTRR_MEMORY_CACHE_TYPE    MtrrType1,\r
+  IN MTRR_MEMORY_CACHE_TYPE    MtrrType2\r
   )\r
 {\r
-  UINT64 MtrrType;\r
-\r
-  MtrrType = MTRR_CACHE_INVALID_TYPE;\r
-  switch (MtrrType1) {\r
-  case MTRR_CACHE_UNCACHEABLE:\r
-    MtrrType = MTRR_CACHE_UNCACHEABLE;\r
-    break;\r
-  case MTRR_CACHE_WRITE_COMBINING:\r
-    if (\r
-         MtrrType2==MTRR_CACHE_WRITE_COMBINING ||\r
-         MtrrType2==MTRR_CACHE_UNCACHEABLE\r
-       ) {\r
-      MtrrType = MtrrType2;\r
-    }\r
-    break;\r
-  case MTRR_CACHE_WRITE_THROUGH:\r
-    if (\r
-         MtrrType2==MTRR_CACHE_WRITE_THROUGH ||\r
-         MtrrType2==MTRR_CACHE_WRITE_BACK\r
-       ) {\r
-      MtrrType = MTRR_CACHE_WRITE_THROUGH;\r
-    } else if(MtrrType2==MTRR_CACHE_UNCACHEABLE) {\r
-      MtrrType = MTRR_CACHE_UNCACHEABLE;\r
-    }\r
-    break;\r
-  case MTRR_CACHE_WRITE_PROTECTED:\r
-    if (MtrrType2 == MTRR_CACHE_WRITE_PROTECTED ||\r
-        MtrrType2 == MTRR_CACHE_UNCACHEABLE) {\r
-      MtrrType = MtrrType2;\r
-    }\r
-    break;\r
-  case MTRR_CACHE_WRITE_BACK:\r
-    if (\r
-         MtrrType2== MTRR_CACHE_UNCACHEABLE ||\r
-         MtrrType2==MTRR_CACHE_WRITE_THROUGH ||\r
-         MtrrType2== MTRR_CACHE_WRITE_BACK\r
-       ) {\r
-      MtrrType = MtrrType2;\r
-    }\r
-    break;\r
-  case MTRR_CACHE_INVALID_TYPE:\r
-    MtrrType = MtrrType2;\r
-    break;\r
-  default:\r
-    break;\r
+  if (MtrrType1 == MtrrType2) {\r
+    return MtrrType1;\r
   }\r
 \r
-  if (MtrrType2 == MTRR_CACHE_INVALID_TYPE) {\r
-    MtrrType = MtrrType1;\r
+  ASSERT (\r
+    MtrrLibTypeLeftPrecedeRight (MtrrType1, MtrrType2) ||\r
+    MtrrLibTypeLeftPrecedeRight (MtrrType2, MtrrType1)\r
+  );\r
+\r
+  if (MtrrLibTypeLeftPrecedeRight (MtrrType1, MtrrType2)) {\r
+    return MtrrType1;\r
+  } else {\r
+    return MtrrType2;\r
   }\r
-  return MtrrType;\r
 }\r
 \r
 /**\r
@@ -1116,29 +1040,27 @@ MtrrGetMemoryAttributeByAddressWorker (
   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
-  MTRR_VARIABLE_SETTINGS  VariableSettings;\r
+  MSR_IA32_MTRR_DEF_TYPE_REGISTER DefType;\r
+  UINT64                          FixedMtrr;\r
+  UINTN                           Index;\r
+  UINTN                           SubIndex;\r
+  MTRR_MEMORY_CACHE_TYPE          MtrrType;\r
+  VARIABLE_MTRR                   VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];\r
+  UINT64                          MtrrValidBitsMask;\r
+  UINT64                          MtrrValidAddressMask;\r
+  UINT32                          VariableMtrrCount;\r
+  MTRR_VARIABLE_SETTINGS          VariableSettings;\r
 \r
   //\r
   // Check if MTRR is enabled, if not, return UC as attribute\r
   //\r
   if (MtrrSetting == NULL) {\r
-    TempQword = AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE);\r
+    DefType.Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE);\r
   } else {\r
-    TempQword = MtrrSetting->MtrrDefType;\r
+    DefType.Uint64 = MtrrSetting->MtrrDefType;\r
   }\r
-  MtrrType = MTRR_CACHE_INVALID_TYPE;\r
 \r
-  if ((TempQword & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
+  if (DefType.Bits.E == 0) {\r
     return CacheUncacheable;\r
   }\r
 \r
@@ -1146,65 +1068,66 @@ MtrrGetMemoryAttributeByAddressWorker (
   // 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
+    if (DefType.Bits.FE != 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
-           if (MtrrSetting == NULL) {\r
-             TempQword = AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr);\r
-           } else {\r
-             TempQword = MtrrSetting->Fixed.Mtrr[Index];\r
-           }\r
-           MtrrType =  RShiftU64 (TempQword, SubIndex * 8) & 0xFF;\r
-           return GetMemoryCacheTypeFromMtrrType (MtrrSetting, MtrrType);\r
-         }\r
+        if (Address >= mMtrrLibFixedMtrrTable[Index].BaseAddress &&\r
+            Address < mMtrrLibFixedMtrrTable[Index].BaseAddress +\r
+            (mMtrrLibFixedMtrrTable[Index].Length * 8)) {\r
+          SubIndex =\r
+            ((UINTN) Address - mMtrrLibFixedMtrrTable[Index].BaseAddress) /\r
+            mMtrrLibFixedMtrrTable[Index].Length;\r
+          if (MtrrSetting == NULL) {\r
+            FixedMtrr = AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr);\r
+          } else {\r
+            FixedMtrr = MtrrSetting->Fixed.Mtrr[Index];\r
+          }\r
+          return (MTRR_MEMORY_CACHE_TYPE) (RShiftU64 (FixedMtrr, SubIndex * 8) & 0xFF);\r
+        }\r
       }\r
     }\r
   }\r
-  MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask);\r
 \r
-  MtrrGetVariableMtrrWorker (\r
-    MtrrSetting,\r
-    GetVariableMtrrCountWorker (),\r
-    &VariableSettings\r
-    );\r
+  VariableMtrrCount = GetVariableMtrrCountWorker ();\r
+  ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);\r
+  MtrrGetVariableMtrrWorker (MtrrSetting, VariableMtrrCount, &VariableSettings);\r
 \r
+  MtrrLibInitializeMtrrMask (&MtrrValidBitsMask, &MtrrValidAddressMask);\r
   MtrrGetMemoryAttributeInVariableMtrrWorker (\r
-           &VariableSettings,\r
-           GetFirmwareVariableMtrrCountWorker (),\r
-           MtrrValidBitsMask,\r
-           MtrrValidAddressMask,\r
-           VariableMtrr\r
-           );\r
+    &VariableSettings,\r
+    VariableMtrrCount,\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
+  MtrrType = CacheInvalid;\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 = MtrrLibPrecedence (MtrrType, TempMtrrType);\r
+          Address < VariableMtrr[Index].BaseAddress + VariableMtrr[Index].Length) {\r
+        if (MtrrType == CacheInvalid) {\r
+          MtrrType = (MTRR_MEMORY_CACHE_TYPE) VariableMtrr[Index].Type;\r
+        } else {\r
+          MtrrType = MtrrLibPrecedence (MtrrType, (MTRR_MEMORY_CACHE_TYPE) VariableMtrr[Index].Type);\r
+        }\r
       }\r
     }\r
   }\r
-  CacheType = GetMemoryCacheTypeFromMtrrType (MtrrSetting, MtrrType);\r
 \r
-  return CacheType;\r
+  //\r
+  // If there is no MTRR which covers the Address, use the default MTRR type.\r
+  //\r
+  if (MtrrType == CacheInvalid) {\r
+    MtrrType = (MTRR_MEMORY_CACHE_TYPE) DefType.Bits.Type;\r
+  }\r
+\r
+  return MtrrType;\r
 }\r
 \r
 \r