]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/MtrrLib/MtrrLib.c
UefiCpuPkg/MtrrLib: refine MtrrLibProgramFixedMtrr()
[mirror_edk2.git] / UefiCpuPkg / Library / MtrrLib / MtrrLib.c
index cf1af29936ad85846bcaf198445386ac4c2a5bb4..5b21fe11f11147cfeee190797fa798926f367227 100644 (file)
@@ -466,10 +466,10 @@ MtrrGetVariableMtrr (
   @param[in]      Type             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, out] LastMsrNum       On input, the last index of the fixed MTRR MSR to program.\r
+  @param[in, out] LastMsrIndex     On input, the last index of the fixed MTRR MSR to program.\r
                                    On return, the current 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
+  @param[out]     ClearMask        The bits to clear in the fixed MTRR MSR.\r
+  @param[out]     OrMask           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
@@ -481,27 +481,25 @@ MtrrLibProgramFixedMtrr (
   IN     MTRR_MEMORY_CACHE_TYPE  Type,\r
   IN OUT UINT64                  *Base,\r
   IN OUT UINT64                  *Length,\r
-  IN OUT UINT32                  *LastMsrNum,\r
-  OUT    UINT64                  *ReturnClearMask,\r
-  OUT    UINT64                  *ReturnOrMask\r
+  IN OUT UINT32                  *LastMsrIndex,\r
+  OUT    UINT64                  *ClearMask,\r
+  OUT    UINT64                  *OrMask\r
   )\r
 {\r
-  UINT32  MsrNum;\r
+  UINT32  MsrIndex;\r
   UINT32  LeftByteShift;\r
   UINT32  RightByteShift;\r
-  UINT64  OrMask;\r
-  UINT64  ClearMask;\r
   UINT64  SubLength;\r
 \r
   //\r
   // Find the fixed MTRR index to be programmed\r
   //\r
-  for (MsrNum = *LastMsrNum + 1; MsrNum < MTRR_NUMBER_OF_FIXED_MTRR; MsrNum++) {\r
-    if ((*Base >= mMtrrLibFixedMtrrTable[MsrNum].BaseAddress) &&\r
+  for (MsrIndex = *LastMsrIndex + 1; MsrIndex < ARRAY_SIZE (mMtrrLibFixedMtrrTable); MsrIndex++) {\r
+    if ((*Base >= mMtrrLibFixedMtrrTable[MsrIndex].BaseAddress) &&\r
         (*Base <\r
             (\r
-              mMtrrLibFixedMtrrTable[MsrNum].BaseAddress +\r
-              (8 * mMtrrLibFixedMtrrTable[MsrNum].Length)\r
+              mMtrrLibFixedMtrrTable[MsrIndex].BaseAddress +\r
+              (8 * mMtrrLibFixedMtrrTable[MsrIndex].Length)\r
             )\r
           )\r
         ) {\r
@@ -509,65 +507,63 @@ MtrrLibProgramFixedMtrr (
     }\r
   }\r
 \r
-  if (MsrNum == MTRR_NUMBER_OF_FIXED_MTRR) {\r
-    return RETURN_UNSUPPORTED;\r
-  }\r
+  ASSERT (MsrIndex != ARRAY_SIZE (mMtrrLibFixedMtrrTable));\r
 \r
   //\r
   // Find the begin offset in fixed MTRR and calculate byte offset of left shift\r
   //\r
-  LeftByteShift = ((UINT32)*Base - mMtrrLibFixedMtrrTable[MsrNum].BaseAddress)\r
-               / mMtrrLibFixedMtrrTable[MsrNum].Length;\r
-\r
-  if (LeftByteShift >= 8) {\r
+  if ((((UINT32)*Base - mMtrrLibFixedMtrrTable[MsrIndex].BaseAddress) % mMtrrLibFixedMtrrTable[MsrIndex].Length) != 0) {\r
+    //\r
+    // Base address should be aligned to the begin of a certain Fixed MTRR range.\r
+    //\r
     return RETURN_UNSUPPORTED;\r
   }\r
+  LeftByteShift = ((UINT32)*Base - mMtrrLibFixedMtrrTable[MsrIndex].BaseAddress) / mMtrrLibFixedMtrrTable[MsrIndex].Length;\r
+  ASSERT (LeftByteShift < 8);\r
 \r
   //\r
   // Find the end offset in fixed MTRR and calculate byte offset of right shift\r
   //\r
-  SubLength = mMtrrLibFixedMtrrTable[MsrNum].Length * (8 - LeftByteShift);\r
+  SubLength = mMtrrLibFixedMtrrTable[MsrIndex].Length * (8 - LeftByteShift);\r
   if (*Length >= SubLength) {\r
     RightByteShift = 0;\r
   } else {\r
-    RightByteShift = 8 - LeftByteShift -\r
-                (UINT32)(*Length) / mMtrrLibFixedMtrrTable[MsrNum].Length;\r
-    if ((LeftByteShift >= 8) ||\r
-        (((UINT32)(*Length) % mMtrrLibFixedMtrrTable[MsrNum].Length) != 0)\r
-        ) {\r
+    if (((UINT32)(*Length) % mMtrrLibFixedMtrrTable[MsrIndex].Length) != 0) {\r
+      //\r
+      // Length should be aligned to the end of a certain Fixed MTRR range.\r
+      //\r
       return RETURN_UNSUPPORTED;\r
     }\r
+    RightByteShift = 8 - LeftByteShift - (UINT32)(*Length) / mMtrrLibFixedMtrrTable[MsrIndex].Length;\r
     //\r
     // Update SubLength by actual length\r
     //\r
     SubLength = *Length;\r
   }\r
 \r
-  ClearMask = CLEAR_SEED;\r
-  OrMask    = MultU64x32 (OR_SEED, (UINT32) Type);\r
+  *ClearMask = CLEAR_SEED;\r
+  *OrMask    = MultU64x32 (OR_SEED, (UINT32) Type);\r
 \r
   if (LeftByteShift != 0) {\r
     //\r
     // Clear the low bits by LeftByteShift\r
     //\r
-    ClearMask &= LShiftU64 (ClearMask, LeftByteShift * 8);\r
-    OrMask    &= LShiftU64 (OrMask, LeftByteShift * 8);\r
+    *ClearMask &= LShiftU64 (*ClearMask, LeftByteShift * 8);\r
+    *OrMask    &= LShiftU64 (*OrMask,    LeftByteShift * 8);\r
   }\r
 \r
   if (RightByteShift != 0) {\r
     //\r
     // Clear the high bits by RightByteShift\r
     //\r
-    ClearMask &= RShiftU64 (ClearMask, RightByteShift * 8);\r
-    OrMask    &= RShiftU64 (OrMask, RightByteShift * 8);\r
+    *ClearMask &= RShiftU64 (*ClearMask, RightByteShift * 8);\r
+    *OrMask    &= RShiftU64 (*OrMask,    RightByteShift * 8);\r
   }\r
 \r
   *Length -= SubLength;\r
   *Base   += SubLength;\r
 \r
-  *LastMsrNum      = MsrNum;\r
-  *ReturnClearMask = ClearMask;\r
-  *ReturnOrMask    = OrMask;\r
+  *LastMsrIndex    = MsrIndex;\r
 \r
   return RETURN_SUCCESS;\r
 }\r