]> git.proxmox.com Git - mirror_edk2.git/commitdiff
UefiCpuPkg/MtrrLib: Fixed bug if length is less than Fixed-MTRR range
authorJeff Fan <jeff.fan@intel.com>
Mon, 6 Jun 2016 02:04:11 +0000 (10:04 +0800)
committerJeff Fan <jeff.fan@intel.com>
Tue, 7 Jun 2016 05:09:25 +0000 (13:09 +0800)
Currently, if the memory length to be programmed is less than the remaining size
of one Fixed-MTRR supported, RETURN_UNSUPPORTED returned. This is not correct.
This is one regression at 07e889209034ba94bfac9e765b8a50ef344daef2 when we
updated ProgramFixedMtrr() to remove the loop of calculating Fixed-MTRR Mask.

This fix will calculate Right offset in Fixed-MTRR beside left offset. It
supports small length (less than remaining size supported by Fixed-MTRR) to be
programmed.

Cc: Eric Dong <eric.dong@intel.com>
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: Jeff Fan <jeff.fan@intel.com>
Reviewed-by: Eric Dong <eric.dong@intel.com>
UefiCpuPkg/Library/MtrrLib/MtrrLib.c

index c4a39b554d064b08238d3e896b8d99ca58902b6d..6a6bf765c2befbdaa1285bdb1bb1662d9f09411f 100644 (file)
@@ -20,8 +20,8 @@
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/DebugLib.h>\r
 \r
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/DebugLib.h>\r
 \r
-#define OR_SEED      0x01010101\r
-#define CLEAR_SEED   0xFFFFFFFF\r
+#define OR_SEED      0x0101010101010101ull\r
+#define CLEAR_SEED   0xFFFFFFFFFFFFFFFFull\r
 \r
 //\r
 // Context to save and restore when MTRRs are programmed\r
 \r
 //\r
 // Context to save and restore when MTRRs are programmed\r
@@ -462,14 +462,15 @@ ProgramFixedMtrr (
   )\r
 {\r
   UINT32  MsrNum;\r
   )\r
 {\r
   UINT32  MsrNum;\r
-  UINT32  ByteShift;\r
-  UINT32  OrMask[2];\r
-  UINT32  ClearMask[2];\r
+  UINT32  LeftByteShift;\r
+  UINT32  RightByteShift;\r
+  UINT64  OrMask;\r
+  UINT64  ClearMask;\r
   UINT64  SubLength;\r
 \r
   UINT64  SubLength;\r
 \r
-  *(UINT64 *)OrMask    = 0;\r
-  *(UINT64 *)ClearMask = 0;\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
         (*Base <\r
   for (MsrNum = *LastMsrNum + 1; MsrNum < MTRR_NUMBER_OF_FIXED_MTRR; MsrNum++) {\r
     if ((*Base >= mMtrrLibFixedMtrrTable[MsrNum].BaseAddress) &&\r
         (*Base <\r
@@ -488,36 +489,60 @@ ProgramFixedMtrr (
   }\r
 \r
   //\r
   }\r
 \r
   //\r
-  // We found the fixed MTRR to be programmed\r
+  // Find the begin offset in fixed MTRR and calculate byte offset of left shift\r
   //\r
   //\r
-  ByteShift = ((UINT32)*Base - mMtrrLibFixedMtrrTable[MsrNum].BaseAddress)\r
+  LeftByteShift = ((UINT32)*Base - mMtrrLibFixedMtrrTable[MsrNum].BaseAddress)\r
                / mMtrrLibFixedMtrrTable[MsrNum].Length;\r
 \r
                / mMtrrLibFixedMtrrTable[MsrNum].Length;\r
 \r
-  if (ByteShift >= 8) {\r
+  if (LeftByteShift >= 8) {\r
     return RETURN_UNSUPPORTED;\r
   }\r
 \r
     return RETURN_UNSUPPORTED;\r
   }\r
 \r
-  if (ByteShift < 4) {\r
-    OrMask[0]    = OR_SEED * (UINT32)MemoryCacheType;\r
-    ClearMask[0] = CLEAR_SEED;\r
-    OrMask[1]    = (OR_SEED * (UINT32)MemoryCacheType) >> ((4 - ByteShift) * 8);\r
-    ClearMask[1] = CLEAR_SEED >> ((4 - ByteShift) * 8);\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
+  if (*Length >= SubLength) {\r
+    RightByteShift = 0;\r
   } else {\r
   } else {\r
-    OrMask[0]    = (OR_SEED * (UINT32)MemoryCacheType) >> ((8 - ByteShift) * 8);\r
-    ClearMask[0] = CLEAR_SEED >> ((8 - ByteShift) * 8);\r
+    RightByteShift = 8 - LeftByteShift -\r
+                (UINT32)(*Length) / mMtrrLibFixedMtrrTable[MsrNum].Length;\r
+    if ((LeftByteShift >= 8) ||\r
+        (((UINT32)(*Length) % mMtrrLibFixedMtrrTable[MsrNum].Length) != 0)\r
+        ) {\r
+      return RETURN_UNSUPPORTED;\r
+    }\r
+    //\r
+    // Update SubLength by actual length\r
+    //\r
+    SubLength = *Length;\r
   }\r
 \r
   }\r
 \r
-  SubLength = mMtrrLibFixedMtrrTable[MsrNum].Length * (8 - ByteShift);\r
-  if (*Length < SubLength) {\r
-    return RETURN_UNSUPPORTED;\r
+  ClearMask = CLEAR_SEED;\r
+  OrMask    = MultU64x32 (OR_SEED, (UINT32)MemoryCacheType);\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
+  }\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
   }\r
 \r
   *Length -= SubLength;\r
   *Base   += SubLength;\r
 \r
   *LastMsrNum      = MsrNum;\r
   }\r
 \r
   *Length -= SubLength;\r
   *Base   += SubLength;\r
 \r
   *LastMsrNum      = MsrNum;\r
-  *ReturnClearMask = *(UINT64 *)ClearMask;\r
-  *ReturnOrMask    = *(UINT64 *)OrMask;\r
+  *ReturnClearMask = ClearMask;\r
+  *ReturnOrMask    = OrMask;\r
 \r
   return RETURN_SUCCESS;\r
 }\r
 \r
   return RETURN_SUCCESS;\r
 }\r