]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/MtrrLib/MtrrLib.c
UefiCpuPkg: Fix typos in comments
[mirror_edk2.git] / UefiCpuPkg / Library / MtrrLib / MtrrLib.c
index 199e165d466a262204d24540e11d8cacd2f3cab7..7783b63d8267e222e2e060d2de5f43b88628e1c1 100644 (file)
@@ -1,7 +1,11 @@
 /** @file\r
   MTRR setting library\r
 \r
-  Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>\r
+  @par Note: \r
+    Most of services in this library instance are suggested to be invoked by BSP only,\r
+    except for MtrrSetAllMtrrs() which is used to sync BSP's MTRR setting to APs.\r
+\r
+  Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
@@ -20,6 +24,9 @@
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/DebugLib.h>\r
 \r
+#define OR_SEED      0x0101010101010101ull\r
+#define CLEAR_SEED   0xFFFFFFFFFFFFFFFFull\r
+\r
 //\r
 // Context to save and restore when MTRRs are programmed\r
 //\r
@@ -438,7 +445,8 @@ 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[out]     ReturnMsrNum     The index of the fixed MTRR MSR to program.\r
+  @param[in, out] LastMsrNum       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
 \r
@@ -452,22 +460,22 @@ ProgramFixedMtrr (
   IN     UINT64               MemoryCacheType,\r
   IN OUT UINT64               *Base,\r
   IN OUT UINT64               *Length,\r
-  OUT    UINT32               *ReturnMsrNum,\r
+  IN OUT UINT32               *LastMsrNum,\r
   OUT    UINT64               *ReturnClearMask,\r
   OUT    UINT64               *ReturnOrMask\r
   )\r
 {\r
   UINT32  MsrNum;\r
-  UINT32  ByteShift;\r
-  UINT64  TempQword;\r
+  UINT32  LeftByteShift;\r
+  UINT32  RightByteShift;\r
   UINT64  OrMask;\r
   UINT64  ClearMask;\r
+  UINT64  SubLength;\r
 \r
-  TempQword = 0;\r
-  OrMask    = 0;\r
-  ClearMask = 0;\r
-\r
-  for (MsrNum = 0; MsrNum < MTRR_NUMBER_OF_FIXED_MTRR; MsrNum++) {\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
             (\r
@@ -480,44 +488,63 @@ ProgramFixedMtrr (
     }\r
   }\r
 \r
-  if (MsrNum == MTRR_NUMBER_OF_FIXED_MTRR) {\r
+  if (MsrNum >= MTRR_NUMBER_OF_FIXED_MTRR) {\r
     return RETURN_UNSUPPORTED;\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
-  for (ByteShift = 0; ByteShift < 8; ByteShift++) {\r
-    if (*Base ==\r
-         (\r
-           mMtrrLibFixedMtrrTable[MsrNum].BaseAddress +\r
-           (ByteShift * mMtrrLibFixedMtrrTable[MsrNum].Length)\r
-         )\r
-       ) {\r
-      break;\r
-    }\r
-  }\r
+  LeftByteShift = ((UINT32)*Base - mMtrrLibFixedMtrrTable[MsrNum].BaseAddress)\r
+               / mMtrrLibFixedMtrrTable[MsrNum].Length;\r
 \r
-  if (ByteShift == 8) {\r
+  if (LeftByteShift >= 8) {\r
     return RETURN_UNSUPPORTED;\r
   }\r
 \r
-  for (\r
-        ;\r
-        ((ByteShift < 8) && (*Length >= mMtrrLibFixedMtrrTable[MsrNum].Length));\r
-        ByteShift++\r
-      ) {\r
-    OrMask |= LShiftU64 ((UINT64) MemoryCacheType, (UINT32) (ByteShift * 8));\r
-    ClearMask |= LShiftU64 ((UINT64) 0xFF, (UINT32) (ByteShift * 8));\r
-    *Length -= mMtrrLibFixedMtrrTable[MsrNum].Length;\r
-    *Base += mMtrrLibFixedMtrrTable[MsrNum].Length;\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
+    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
+  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 (ByteShift < 8 && (*Length != 0)) {\r
-    return RETURN_UNSUPPORTED;\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
-  *ReturnMsrNum    = MsrNum;\r
+  *Length -= SubLength;\r
+  *Base   += SubLength;\r
+\r
+  *LastMsrNum      = MsrNum;\r
   *ReturnClearMask = ClearMask;\r
   *ReturnOrMask    = OrMask;\r
 \r
@@ -579,7 +606,7 @@ MtrrGetMemoryAttributeInVariableMtrrWorker (
   @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 paramter indicates the\r
+  @return                       The return value of this parameter indicates the\r
                                 number of MTRRs which has been used.\r
 \r
 **/\r
@@ -1530,6 +1557,7 @@ MtrrSetMemoryAttributeWorker (
   //\r
   Status = RETURN_SUCCESS;\r
   if (BaseAddress < BASE_1MB) {\r
+    MsrNum = (UINT32)-1;\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
@@ -2079,8 +2107,6 @@ MtrrSetAllMtrrs (
 \r
   PostMtrrChangeEnableCache (&MtrrContext);\r
 \r
-  MtrrDebugPrintAllMtrrs ();\r
-\r
   return MtrrSetting;\r
 }\r
 \r