]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/MtrrLib/MtrrLib.c
UefiCpuPkg/MtrrLib: Add comments to recommend to use batch-set API
[mirror_edk2.git] / UefiCpuPkg / Library / MtrrLib / MtrrLib.c
index 200becdd4a2500eb3145788bc2f97a19a47c3aae..dfce9a996b3b80ae2a1494fabc2aa6e0389ea215 100644 (file)
@@ -1,11 +1,11 @@
 /** @file\r
   MTRR setting library\r
 \r
-  @par Note: \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 - 2017, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2008 - 2018, 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
@@ -32,8 +32,8 @@
 #define SCRATCH_BUFFER_SIZE           (4 * SIZE_4KB)\r
 #define MTRR_LIB_ASSERT_ALIGNED(B, L) ASSERT ((B & ~(L - 1)) == B);\r
 \r
-#define M(x,y) ((x) * VectorCount + (y))\r
-#define O(x,y) ((y) * VectorCount + (x))\r
+#define M(x,y) ((x) * VertexCount + (y))\r
+#define O(x,y) ((y) * VertexCount + (x))\r
 \r
 //\r
 // Context to save and restore when MTRRs are programmed\r
@@ -47,7 +47,7 @@ typedef struct {
   UINT64                 Address;\r
   UINT64                 Alignment;\r
   UINT64                 Length;\r
-  UINT8                  Type : 7;\r
+  MTRR_MEMORY_CACHE_TYPE Type : 7;\r
 \r
   //\r
   // Temprary use for calculating the best MTRR settings.\r
@@ -1142,21 +1142,21 @@ MtrrLibGetNumberOfTypes (
 }\r
 \r
 /**\r
-  Calculate the least MTRR number from vector Start to Stop and update\r
-  the Previous of all vectors from Start to Stop is updated to reflect\r
+  Calculate the least MTRR number from vertex Start to Stop and update\r
+  the Previous of all vertices from Start to Stop is updated to reflect\r
   how the memory range is covered by MTRR.\r
 \r
-  @param VectorCount     The count of vectors in the graph.\r
-  @param Vector          Array holding all vectors.\r
-  @param Weight          2-dimention array holding weights between vectors.\r
-  @param Start           Start vector.\r
-  @param Stop            Stop vector.\r
+  @param VertexCount     The count of vertices in the graph.\r
+  @param Vertices        Array holding all vertices.\r
+  @param Weight          2-dimention array holding weights between vertices.\r
+  @param Start           Start vertex.\r
+  @param Stop            Stop vertex.\r
   @param IncludeOptional TRUE to count the optional weight.\r
 **/\r
 VOID\r
 MtrrLibCalculateLeastMtrrs (\r
-  IN UINT16                      VectorCount,\r
-  IN MTRR_LIB_ADDRESS            *Vector,\r
+  IN UINT16                      VertexCount,\r
+  IN MTRR_LIB_ADDRESS            *Vertices,\r
   IN OUT CONST UINT8             *Weight,\r
   IN UINT16                      Start,\r
   IN UINT16                      Stop,\r
@@ -1170,52 +1170,51 @@ MtrrLibCalculateLeastMtrrs (
   UINT8                          Optional;\r
 \r
   for (Index = Start; Index <= Stop; Index++) {\r
-    Vector[Index].Visited = FALSE;\r
-    Vector[Index].Previous = VectorCount;\r
+    Vertices[Index].Visited = FALSE;\r
     Mandatory = Weight[M(Start,Index)];\r
-    Vector[Index].Weight = Mandatory;\r
+    Vertices[Index].Weight = Mandatory;\r
     if (Mandatory != MAX_WEIGHT) {\r
       Optional = IncludeOptional ? Weight[O(Start, Index)] : 0;\r
-      Vector[Index].Weight += Optional;\r
-      ASSERT (Vector[Index].Weight >= Optional);\r
+      Vertices[Index].Weight += Optional;\r
+      ASSERT (Vertices[Index].Weight >= Optional);\r
     }\r
   }\r
 \r
   MinI = Start;\r
   MinWeight = 0;\r
-  while (!Vector[Stop].Visited) {\r
+  while (!Vertices[Stop].Visited) {\r
     //\r
-    // Update the weight from the shortest vector to other unvisited vectors\r
+    // Update the weight from the shortest vertex to other unvisited vertices\r
     //\r
     for (Index = Start + 1; Index <= Stop; Index++) {\r
-      if (!Vector[Index].Visited) {\r
+      if (!Vertices[Index].Visited) {\r
         Mandatory = Weight[M(MinI, Index)];\r
         if (Mandatory != MAX_WEIGHT) {\r
           Optional = IncludeOptional ? Weight[O(MinI, Index)] : 0;\r
-          if (MinWeight + Mandatory + Optional <= Vector[Index].Weight) {\r
-            Vector[Index].Weight   = MinWeight + Mandatory + Optional;\r
-            Vector[Index].Previous = MinI; // Previous is Start based.\r
+          if (MinWeight + Mandatory + Optional <= Vertices[Index].Weight) {\r
+            Vertices[Index].Weight   = MinWeight + Mandatory + Optional;\r
+            Vertices[Index].Previous = MinI; // Previous is Start based.\r
           }\r
         }\r
       }\r
     }\r
 \r
     //\r
-    // Find the shortest vector from Start\r
+    // Find the shortest vertex from Start\r
     //\r
-    MinI      = VectorCount;\r
+    MinI      = VertexCount;\r
     MinWeight = MAX_WEIGHT;\r
     for (Index = Start + 1; Index <= Stop; Index++) {\r
-      if (!Vector[Index].Visited && MinWeight > Vector[Index].Weight) {\r
+      if (!Vertices[Index].Visited && MinWeight > Vertices[Index].Weight) {\r
         MinI      = Index;\r
-        MinWeight = Vector[Index].Weight;\r
+        MinWeight = Vertices[Index].Weight;\r
       }\r
     }\r
 \r
     //\r
-    // Mark the shortest vector from Start as visited\r
+    // Mark the shortest vertex from Start as visited\r
     //\r
-    Vector[MinI].Visited = TRUE;\r
+    Vertices[MinI].Visited = TRUE;\r
   }\r
 }\r
 \r
@@ -1288,17 +1287,17 @@ MtrrLibIsPowerOfTwo (
 }\r
 \r
 /**\r
-  Calculate the subtractive path from vector Start to Stop.\r
+  Calculate the subtractive path from vertex Start to Stop.\r
 \r
   @param DefaultType  Default memory type.\r
   @param A0           Alignment to use when base address is 0.\r
   @param Ranges       Array holding memory type settings for all memory regions.\r
   @param RangeCount   The count of memory ranges the array holds.\r
-  @param VectorCount  The count of vectors in the graph.\r
-  @param Vector       Array holding all vectors.\r
-  @param Weight       2-dimention array holding weights between vectors.\r
-  @param Start        Start vector.\r
-  @param Stop         Stop vector.\r
+  @param VertexCount  The count of vertices in the graph.\r
+  @param Vertices     Array holding all vertices.\r
+  @param Weight       2-dimention array holding weights between vertices.\r
+  @param Start        Start vertex.\r
+  @param Stop         Stop vertex.\r
   @param Types        Type bit mask of memory range from Start to Stop.\r
   @param TypeCount    Number of different memory types from Start to Stop.\r
   @param Mtrrs        Array holding all MTRR settings.\r
@@ -1315,8 +1314,8 @@ MtrrLibCalculateSubtractivePath (
   IN UINT64                      A0,\r
   IN CONST MTRR_MEMORY_RANGE     *Ranges,\r
   IN UINTN                       RangeCount,\r
-  IN UINT16                      VectorCount,\r
-  IN MTRR_LIB_ADDRESS            *Vector,\r
+  IN UINT16                      VertexCount,\r
+  IN MTRR_LIB_ADDRESS            *Vertices,\r
   IN OUT UINT8                   *Weight,\r
   IN UINT16                      Start,\r
   IN UINT16                      Stop,\r
@@ -1342,8 +1341,8 @@ MtrrLibCalculateSubtractivePath (
   MTRR_MEMORY_CACHE_TYPE         LowestType;\r
   MTRR_MEMORY_CACHE_TYPE         LowestPrecedentType;\r
 \r
-  Base   = Vector[Start].Address;\r
-  Length = Vector[Stop].Address - Base;\r
+  Base   = Vertices[Start].Address;\r
+  Length = Vertices[Stop].Address - Base;\r
 \r
   LowestType = MtrrLibLowestType (Types);\r
 \r
@@ -1404,18 +1403,18 @@ MtrrLibCalculateSubtractivePath (
       // We might use positive or subtractive, depending on which way uses less MTRR\r
       //\r
       for (SubStart = Start; SubStart <= Stop; SubStart++) {\r
-        if (Vector[SubStart].Address == HBase) {\r
+        if (Vertices[SubStart].Address == HBase) {\r
           break;\r
         }\r
       }\r
 \r
       for (SubStop = SubStart; SubStop <= Stop; SubStop++) {\r
-        if (Vector[SubStop].Address == HBase + HLength) {\r
+        if (Vertices[SubStop].Address == HBase + HLength) {\r
           break;\r
         }\r
       }\r
-      ASSERT (Vector[SubStart].Address == HBase);\r
-      ASSERT (Vector[SubStop].Address == HBase + HLength);\r
+      ASSERT (Vertices[SubStart].Address == HBase);\r
+      ASSERT (Vertices[SubStop].Address == HBase + HLength);\r
 \r
       if ((TypeCount == 2) || (SubStart == SubStop - 1)) {\r
         //\r
@@ -1429,7 +1428,7 @@ MtrrLibCalculateSubtractivePath (
           while (SubStart != SubStop) {\r
             Status = MtrrLibAppendVariableMtrr (\r
               Mtrrs, MtrrCapacity, MtrrCount,\r
-              Vector[SubStart].Address, Vector[SubStart].Length, (MTRR_MEMORY_CACHE_TYPE) Vector[SubStart].Type\r
+              Vertices[SubStart].Address, Vertices[SubStart].Length, Vertices[SubStart].Type\r
             );\r
             if (RETURN_ERROR (Status)) {\r
               return Status;\r
@@ -1439,21 +1438,22 @@ MtrrLibCalculateSubtractivePath (
         }\r
       } else {\r
         ASSERT (TypeCount == 3);\r
-        MtrrLibCalculateLeastMtrrs (VectorCount, Vector, Weight, SubStart, SubStop, TRUE);\r
+        MtrrLibCalculateLeastMtrrs (VertexCount, Vertices, Weight, SubStart, SubStop, TRUE);\r
 \r
         if (Mtrrs == NULL) {\r
-          Weight[M (Start, Stop)] += Vector[SubStop].Weight;\r
+          Weight[M (Start, Stop)] += Vertices[SubStop].Weight;\r
         } else {\r
           // When we need to collect the optimal path from SubStart to SubStop\r
           while (SubStop != SubStart) {\r
             Cur = SubStop;\r
-            Pre = Vector[Cur].Previous;\r
+            Pre = Vertices[Cur].Previous;\r
             SubStop = Pre;\r
 \r
-            if (Weight[M (Pre, Cur)] != 0) {\r
+            if (Weight[M (Pre, Cur)] + Weight[O (Pre, Cur)] != 0) {\r
               Status = MtrrLibAppendVariableMtrr (\r
                 Mtrrs, MtrrCapacity, MtrrCount,\r
-                Vector[Pre].Address, Vector[Cur].Address - Vector[Pre].Address, LowestPrecedentType\r
+                Vertices[Pre].Address, Vertices[Cur].Address - Vertices[Pre].Address,\r
+                (Pre != Cur - 1) ? LowestPrecedentType : Vertices[Pre].Type\r
               );\r
               if (RETURN_ERROR (Status)) {\r
                 return Status;\r
@@ -1463,7 +1463,7 @@ MtrrLibCalculateSubtractivePath (
               Status = MtrrLibCalculateSubtractivePath (\r
                 DefaultType, A0,\r
                 Ranges, RangeCount,\r
-                VectorCount, Vector, Weight,\r
+                VertexCount, Vertices, Weight,\r
                 Pre, Cur, PrecedentTypes, 2,\r
                 Mtrrs, MtrrCapacity, MtrrCount\r
               );\r
@@ -1526,10 +1526,10 @@ MtrrLibCalculateMtrrs (
   UINT64                    Length;\r
   UINT64                    Alignment;\r
   UINT64                    SubLength;\r
-  MTRR_LIB_ADDRESS          *Vector;\r
+  MTRR_LIB_ADDRESS          *Vertices;\r
   UINT8                     *Weight;\r
-  UINT32                    VectorIndex;\r
-  UINT32                    VectorCount;\r
+  UINT32                    VertexIndex;\r
+  UINT32                    VertexCount;\r
   UINTN                     RequiredScratchSize;\r
   UINT8                     TypeCount;\r
   UINT16                    Start;\r
@@ -1542,10 +1542,10 @@ MtrrLibCalculateMtrrs (
   MTRR_LIB_ASSERT_ALIGNED (Base0, Base1 - Base0);\r
 \r
   //\r
-  // Count the number of vectors.\r
+  // Count the number of vertices.\r
   //\r
-  Vector = (MTRR_LIB_ADDRESS*)Scratch;\r
-  for (VectorIndex = 0, Index = 0; Index < RangeCount; Index++) {\r
+  Vertices = (MTRR_LIB_ADDRESS*)Scratch;\r
+  for (VertexIndex = 0, Index = 0; Index < RangeCount; Index++) {\r
     Base = Ranges[Index].BaseAddress;\r
     Length = Ranges[Index].Length;\r
     while (Length != 0) {\r
@@ -1554,58 +1554,71 @@ MtrrLibCalculateMtrrs (
       if (SubLength > Length) {\r
         SubLength = GetPowerOfTwo64 (Length);\r
       }\r
-      if (VectorIndex < *ScratchSize / sizeof (*Vector)) {\r
-        Vector[VectorIndex].Address   = Base;\r
-        Vector[VectorIndex].Alignment = Alignment;\r
-        Vector[VectorIndex].Type      = Ranges[Index].Type;\r
-        Vector[VectorIndex].Length    = SubLength;\r
+      if (VertexIndex < *ScratchSize / sizeof (*Vertices)) {\r
+        Vertices[VertexIndex].Address   = Base;\r
+        Vertices[VertexIndex].Alignment = Alignment;\r
+        Vertices[VertexIndex].Type      = Ranges[Index].Type;\r
+        Vertices[VertexIndex].Length    = SubLength;\r
       }\r
       Base   += SubLength;\r
       Length -= SubLength;\r
-      VectorIndex++;\r
+      VertexIndex++;\r
     }\r
   }\r
   //\r
-  // Vector[VectorIndex] = Base1, so whole vector count is (VectorIndex + 1).\r
+  // Vertices[VertexIndex] = Base1, so whole vertex count is (VertexIndex + 1).\r
   //\r
-  VectorCount = VectorIndex + 1;\r
+  VertexCount = VertexIndex + 1;\r
   DEBUG ((\r
-    DEBUG_CACHE, "VectorCount (%016lx - %016lx) = %d\n", \r
-    Ranges[0].BaseAddress, Ranges[RangeCount - 1].BaseAddress + Ranges[RangeCount - 1].Length, VectorCount\r
+    DEBUG_CACHE, "  Count of vertices (%016llx - %016llx) = %d\n",\r
+    Ranges[0].BaseAddress, Ranges[RangeCount - 1].BaseAddress + Ranges[RangeCount - 1].Length, VertexCount\r
     ));\r
-  ASSERT (VectorCount < MAX_UINT16);\r
+  ASSERT (VertexCount < MAX_UINT16);\r
 \r
-  RequiredScratchSize = VectorCount * sizeof (*Vector) + VectorCount * VectorCount * sizeof (*Weight);\r
+  RequiredScratchSize = VertexCount * sizeof (*Vertices) + VertexCount * VertexCount * sizeof (*Weight);\r
   if (*ScratchSize < RequiredScratchSize) {\r
     *ScratchSize = RequiredScratchSize;\r
     return RETURN_BUFFER_TOO_SMALL;\r
   }\r
-  Vector[VectorCount - 1].Address = Base1;\r
+  Vertices[VertexCount - 1].Address = Base1;\r
+\r
+  Weight = (UINT8 *) &Vertices[VertexCount];\r
+  for (VertexIndex = 0; VertexIndex < VertexCount; VertexIndex++) {\r
+    //\r
+    // Set optional weight between vertices and self->self to 0\r
+    //\r
+    SetMem (&Weight[M(VertexIndex, 0)], VertexIndex + 1, 0);\r
+    //\r
+    // Set mandatory weight between vertices to MAX_WEIGHT\r
+    //\r
+    SetMem (&Weight[M (VertexIndex, VertexIndex + 1)], VertexCount - VertexIndex - 1, MAX_WEIGHT);\r
+\r
+    // Final result looks like:\r
+    //   00 FF FF FF\r
+    //   00 00 FF FF\r
+    //   00 00 00 FF\r
+    //   00 00 00 00\r
+  }\r
 \r
-  Weight = (UINT8 *) &Vector[VectorCount];\r
   //\r
-  // Set mandatory weight between any vector to max\r
-  // Set optional weight and between any vector and self->self to 0\r
-  // E.g.:\r
-  //   00 FF FF FF\r
-  //   00 00 FF FF\r
-  //   00 00 00 FF\r
-  //   00 00 00 00\r
+  // Set mandatory weight and optional weight for adjacent vertices\r
   //\r
-  for (VectorIndex = 0; VectorIndex < VectorCount; VectorIndex++) {\r
-    SetMem (&Weight[M(VectorIndex, 0)], VectorIndex + 1, 0);\r
-    if (VectorIndex != VectorCount - 1) {\r
-      Weight[M (VectorIndex, VectorIndex + 1)] = (DefaultType == Vector[VectorIndex].Type) ? 0 : 1;\r
-      SetMem (&Weight[M (VectorIndex, VectorIndex + 2)], VectorCount - VectorIndex - 2, MAX_WEIGHT);\r
+  for (VertexIndex = 0; VertexIndex < VertexCount - 1; VertexIndex++) {\r
+    if (Vertices[VertexIndex].Type != DefaultType) {\r
+      Weight[M (VertexIndex, VertexIndex + 1)] = 1;\r
+      Weight[O (VertexIndex, VertexIndex + 1)] = 0;\r
+    } else {\r
+      Weight[M (VertexIndex, VertexIndex + 1)] = 0;\r
+      Weight[O (VertexIndex, VertexIndex + 1)] = 1;\r
     }\r
   }\r
 \r
   for (TypeCount = 2; TypeCount <= 3; TypeCount++) {\r
-    for (Start = 0; Start < VectorCount; Start++) {\r
-      for (Stop = Start + 2; Stop < VectorCount; Stop++) {\r
-        ASSERT (Vector[Stop].Address > Vector[Start].Address);\r
-        Length = Vector[Stop].Address - Vector[Start].Address;\r
-        if (Length > Vector[Start].Alignment) {\r
+    for (Start = 0; Start < VertexCount; Start++) {\r
+      for (Stop = Start + 2; Stop < VertexCount; Stop++) {\r
+        ASSERT (Vertices[Stop].Address > Vertices[Start].Address);\r
+        Length = Vertices[Stop].Address - Vertices[Start].Address;\r
+        if (Length > Vertices[Start].Alignment) {\r
           //\r
           // Pickup a new Start when [Start, Stop) cannot be described by one MTRR.\r
           //\r
@@ -1613,7 +1626,7 @@ MtrrLibCalculateMtrrs (
         }\r
         if ((Weight[M(Start, Stop)] == MAX_WEIGHT) && MtrrLibIsPowerOfTwo (Length)) {\r
           if (MtrrLibGetNumberOfTypes (\r
-                Ranges, RangeCount, Vector[Start].Address, Vector[Stop].Address - Vector[Start].Address, &Type\r
+                Ranges, RangeCount, Vertices[Start].Address, Vertices[Stop].Address - Vertices[Start].Address, &Type\r
                 ) == TypeCount) {\r
             //\r
             // Update the Weight[Start, Stop] using subtractive path.\r
@@ -1621,7 +1634,7 @@ MtrrLibCalculateMtrrs (
             MtrrLibCalculateSubtractivePath (\r
               DefaultType, A0,\r
               Ranges, RangeCount,\r
-              (UINT16)VectorCount, Vector, Weight,\r
+              (UINT16)VertexCount, Vertices, Weight,\r
               Start, Stop, Type, TypeCount,\r
               NULL, 0, NULL\r
               );\r
@@ -1638,17 +1651,17 @@ MtrrLibCalculateMtrrs (
   }\r
 \r
   Status = RETURN_SUCCESS;\r
-  MtrrLibCalculateLeastMtrrs ((UINT16) VectorCount, Vector, Weight, 0, (UINT16) VectorCount - 1, FALSE);\r
-  Stop = (UINT16) VectorCount - 1;\r
+  MtrrLibCalculateLeastMtrrs ((UINT16) VertexCount, Vertices, Weight, 0, (UINT16) VertexCount - 1, FALSE);\r
+  Stop = (UINT16) VertexCount - 1;\r
   while (Stop != 0) {\r
-    Start = Vector[Stop].Previous;\r
+    Start = Vertices[Stop].Previous;\r
     TypeCount = MAX_UINT8;\r
     Type = 0;\r
     if (Weight[M(Start, Stop)] != 0) {\r
-      TypeCount = MtrrLibGetNumberOfTypes (Ranges, RangeCount, Vector[Start].Address, Vector[Stop].Address - Vector[Start].Address, &Type);\r
+      TypeCount = MtrrLibGetNumberOfTypes (Ranges, RangeCount, Vertices[Start].Address, Vertices[Stop].Address - Vertices[Start].Address, &Type);\r
       Status = MtrrLibAppendVariableMtrr (\r
         Mtrrs, MtrrCapacity, MtrrCount,\r
-        Vector[Start].Address, Vector[Stop].Address - Vector[Start].Address, \r
+        Vertices[Start].Address, Vertices[Stop].Address - Vertices[Start].Address,\r
         MtrrLibLowestType (Type)\r
         );\r
       if (RETURN_ERROR (Status)) {\r
@@ -1662,13 +1675,13 @@ MtrrLibCalculateMtrrs (
       //\r
       if (TypeCount == MAX_UINT8) {\r
         TypeCount = MtrrLibGetNumberOfTypes (\r
-                      Ranges, RangeCount, Vector[Start].Address, Vector[Stop].Address - Vector[Start].Address, &Type\r
+                      Ranges, RangeCount, Vertices[Start].Address, Vertices[Stop].Address - Vertices[Start].Address, &Type\r
                       );\r
       }\r
       Status = MtrrLibCalculateSubtractivePath (\r
                  DefaultType, A0,\r
                  Ranges, RangeCount,\r
-                 (UINT16) VectorCount, Vector, Weight, Start, Stop,\r
+                 (UINT16) VertexCount, Vertices, Weight, Start, Stop,\r
                  Type, TypeCount,\r
                  Mtrrs, MtrrCapacity, MtrrCount\r
                  );\r
@@ -1683,7 +1696,7 @@ MtrrLibCalculateMtrrs (
 \r
 \r
 /**\r
-  Apply the variable MTRR settings to memory range array.\r
+  Apply the fixed MTRR settings to memory range array.\r
 \r
   @param Fixed             The fixed MTRR settings.\r
   @param Ranges            Return the memory range array holding memory type\r
@@ -1775,7 +1788,7 @@ MtrrLibApplyVariableMtrrs (
   // 2. Set other types than WB or UC\r
   //\r
   for (Index = 0; Index < VariableMtrrCount; Index++) {\r
-    if ((VariableMtrr[Index].Length != 0) && \r
+    if ((VariableMtrr[Index].Length != 0) &&\r
         (VariableMtrr[Index].Type != CacheWriteBack) && (VariableMtrr[Index].Type != CacheUncacheable)) {\r
       Status = MtrrLibSetMemoryType (\r
                  Ranges, RangeCapacity, RangeCount,\r
@@ -1968,7 +1981,7 @@ MtrrLibSetMemoryRanges (
   UINTN                     BiggestScratchSize;\r
 \r
   *VariableMtrrCount = 0;\r
-  \r
+\r
   //\r
   // Since the whole ranges need multiple calls of MtrrLibCalculateMtrrs().\r
   // Each call needs different scratch buffer size.\r
@@ -2123,8 +2136,8 @@ MtrrLibSetBelow1MBMemoryAttribute (
   //\r
   // (Value & ~0 | 0) still equals to (Value)\r
   //\r
-  SetMem64 (ClearMasks, sizeof (ClearMasks), 0);\r
-  SetMem64 (OrMasks, sizeof (OrMasks), 0);\r
+  SetMem (ClearMasks, sizeof (ClearMasks), 0);\r
+  SetMem (OrMasks, sizeof (OrMasks), 0);\r
 \r
   MsrIndex = (UINT32)-1;\r
   while ((BaseAddress < BASE_1MB) && (Length != 0)) {\r
@@ -2158,7 +2171,7 @@ MtrrLibSetBelow1MBMemoryAttribute (
                                 When range overlap happens, the last one takes higher priority.\r
                                 When the function returns, either all the attributes are set successfully,\r
                                 or none of them is set.\r
-  @param[in]                    Count of MTRR_MEMORY_RANGE.\r
+  @param[in]       RangeCount   Count of MTRR_MEMORY_RANGE.\r
 \r
   @retval RETURN_SUCCESS            The attributes were set for all the memory ranges.\r
   @retval RETURN_INVALID_PARAMETER  Length in any range is zero.\r
@@ -2209,6 +2222,7 @@ MtrrSetMemoryAttributesInMtrrSettings (
   MTRR_CONTEXT              MtrrContext;\r
   BOOLEAN                   MtrrContextValid;\r
 \r
+  Status = RETURN_SUCCESS;\r
   MtrrLibInitializeMtrrMask (&MtrrValidBitsMask, &MtrrValidAddressMask);\r
 \r
   //\r
@@ -2226,24 +2240,53 @@ MtrrSetMemoryAttributesInMtrrSettings (
   Above1MbExist             = FALSE;\r
   OriginalVariableMtrrCount = 0;\r
 \r
+  //\r
+  // 0. Dump the requests.\r
+  //\r
+  DEBUG_CODE (\r
+    DEBUG ((DEBUG_CACHE, "Mtrr: Set Mem Attribute to %a, ScratchSize = %x%a",\r
+            (MtrrSetting == NULL) ? "Hardware" : "Buffer", *ScratchSize,\r
+            (RangeCount <= 1) ? "," : "\n"\r
+            ));\r
+    for (Index = 0; Index < RangeCount; Index++) {\r
+      DEBUG ((DEBUG_CACHE, " %a: [%016lx, %016lx)\n",\r
+              mMtrrMemoryCacheTypeShortName[MIN (Ranges[Index].Type, CacheInvalid)],\r
+              Ranges[Index].BaseAddress, Ranges[Index].BaseAddress + Ranges[Index].Length\r
+              ));\r
+    }\r
+  );\r
+\r
   //\r
   // 1. Validate the parameters.\r
   //\r
+  if (!IsMtrrSupported ()) {\r
+    Status = RETURN_UNSUPPORTED;\r
+    goto Exit;\r
+  }\r
+\r
   for (Index = 0; Index < RangeCount; Index++) {\r
     if (Ranges[Index].Length == 0) {\r
-      return RETURN_INVALID_PARAMETER;\r
+      Status = RETURN_INVALID_PARAMETER;\r
+      goto Exit;\r
     }\r
     if (((Ranges[Index].BaseAddress & ~MtrrValidAddressMask) != 0) ||\r
-        ((Ranges[Index].Length & ~MtrrValidAddressMask) != 0)\r
+        ((((Ranges[Index].BaseAddress + Ranges[Index].Length) & ~MtrrValidAddressMask) != 0) &&\r
+          (Ranges[Index].BaseAddress + Ranges[Index].Length) != MtrrValidBitsMask + 1)\r
         ) {\r
-      return RETURN_UNSUPPORTED;\r
+      //\r
+      // Either the BaseAddress or the Limit doesn't follow the alignment requirement.\r
+      // Note: It's still valid if Limit doesn't follow the alignment requirement but equals to MAX Address.\r
+      //\r
+      Status = RETURN_UNSUPPORTED;\r
+      goto Exit;\r
     }\r
     if ((Ranges[Index].Type != CacheUncacheable) &&\r
         (Ranges[Index].Type != CacheWriteCombining) &&\r
         (Ranges[Index].Type != CacheWriteThrough) &&\r
         (Ranges[Index].Type != CacheWriteProtected) &&\r
         (Ranges[Index].Type != CacheWriteBack)) {\r
-      return RETURN_INVALID_PARAMETER;\r
+      Status = RETURN_INVALID_PARAMETER;\r
+      goto Exit;\r
     }\r
     if (Ranges[Index].BaseAddress + Ranges[Index].Length > BASE_1MB) {\r
       Above1MbExist = TRUE;\r
@@ -2309,7 +2352,7 @@ MtrrSetMemoryAttributesInMtrrSettings (
       if (Status == RETURN_ALREADY_STARTED) {\r
         Status = RETURN_SUCCESS;\r
       } else if (Status == RETURN_OUT_OF_RESOURCES) {\r
-        return Status;\r
+        goto Exit;\r
       } else {\r
         ASSERT_RETURN_ERROR (Status);\r
         Modified = TRUE;\r
@@ -2327,7 +2370,7 @@ MtrrSetMemoryAttributesInMtrrSettings (
                  WorkingVariableMtrr, FirmwareVariableMtrrCount + 1, &WorkingVariableMtrrCount\r
                  );\r
       if (RETURN_ERROR (Status)) {\r
-        return Status;\r
+        goto Exit;\r
       }\r
 \r
       //\r
@@ -2346,7 +2389,8 @@ MtrrSetMemoryAttributesInMtrrSettings (
       }\r
 \r
       if (WorkingVariableMtrrCount > FirmwareVariableMtrrCount) {\r
-        return RETURN_OUT_OF_RESOURCES;\r
+        Status = RETURN_OUT_OF_RESOURCES;\r
+        goto Exit;\r
       }\r
 \r
       //\r
@@ -2375,7 +2419,7 @@ MtrrSetMemoryAttributesInMtrrSettings (
                Ranges[Index].BaseAddress, Ranges[Index].Length, Ranges[Index].Type\r
                );\r
     if (RETURN_ERROR (Status)) {\r
-      return Status;\r
+      goto Exit;\r
     }\r
   }\r
 \r
@@ -2441,7 +2485,12 @@ MtrrSetMemoryAttributesInMtrrSettings (
     }\r
   }\r
 \r
-  return RETURN_SUCCESS;\r
+Exit:\r
+  DEBUG ((DEBUG_CACHE, "  Result = %r\n", Status));\r
+  if (!RETURN_ERROR (Status)) {\r
+    MtrrDebugPrintAllMtrrsWorker (MtrrSetting);\r
+  }\r
+  return Status;\r
 }\r
 \r
 /**\r
@@ -2464,7 +2513,14 @@ MtrrSetMemoryAttributesInMtrrSettings (
                                     BaseAddress and Length cannot be modified.\r
   @retval RETURN_OUT_OF_RESOURCES   There are not enough system resources to modify the attributes of\r
                                     the memory resource range.\r
-  @retval RETURN_BUFFER_TOO_SMALL   The scratch buffer is too small for MTRR calculation.\r
+                                    Multiple memory range attributes setting by calling this API multiple\r
+                                    times may fail with status RETURN_OUT_OF_RESOURCES. It may not mean\r
+                                    the number of CPU MTRRs are too small to set such memory attributes.\r
+                                    Pass the multiple memory range attributes to one call of\r
+                                    MtrrSetMemoryAttributesInMtrrSettings() may succeed.\r
+  @retval RETURN_BUFFER_TOO_SMALL   The fixed internal scratch buffer is too small for MTRR calculation.\r
+                                    Caller should use MtrrSetMemoryAttributesInMtrrSettings() to specify\r
+                                    external scratch buffer.\r
 **/\r
 RETURN_STATUS\r
 EFIAPI\r
@@ -2475,28 +2531,15 @@ MtrrSetMemoryAttributeInMtrrSettings (
   IN MTRR_MEMORY_CACHE_TYPE  Attribute\r
   )\r
 {\r
-  RETURN_STATUS              Status;\r
   UINT8                      Scratch[SCRATCH_BUFFER_SIZE];\r
   UINTN                      ScratchSize;\r
   MTRR_MEMORY_RANGE          Range;\r
 \r
-  if (!IsMtrrSupported ()) {\r
-    return RETURN_UNSUPPORTED;\r
-  }\r
-\r
   Range.BaseAddress = BaseAddress;\r
   Range.Length      = Length;\r
   Range.Type        = Attribute;\r
   ScratchSize = sizeof (Scratch);\r
-  Status = MtrrSetMemoryAttributesInMtrrSettings (MtrrSetting, Scratch, &ScratchSize, &Range, 1);\r
-  DEBUG ((DEBUG_CACHE, "MtrrSetMemoryAttribute(MtrrSettings = %p) %s: [%016lx, %016lx) - %x\n",\r
-          MtrrSetting,\r
-          mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, BaseAddress + Length, Status));\r
-\r
-  if (!RETURN_ERROR (Status)) {\r
-    MtrrDebugPrintAllMtrrsWorker (MtrrSetting);\r
-  }\r
-  return Status;\r
+  return MtrrSetMemoryAttributesInMtrrSettings (MtrrSetting, Scratch, &ScratchSize, &Range, 1);\r
 }\r
 \r
 /**\r
@@ -2523,7 +2566,14 @@ MtrrSetMemoryAttributeInMtrrSettings (
   @retval RETURN_OUT_OF_RESOURCES   There are not enough system resources to\r
                                     modify the attributes of the memory\r
                                     resource range.\r
-  @retval RETURN_BUFFER_TOO_SMALL   The scratch buffer is too small for MTRR calculation.\r
+                                    Multiple memory range attributes setting by calling this API multiple\r
+                                    times may fail with status RETURN_OUT_OF_RESOURCES. It may not mean\r
+                                    the number of CPU MTRRs are too small to set such memory attributes.\r
+                                    Pass the multiple memory range attributes to one call of\r
+                                    MtrrSetMemoryAttributesInMtrrSettings() may succeed.\r
+  @retval RETURN_BUFFER_TOO_SMALL   The fixed internal scratch buffer is too small for MTRR calculation.\r
+                                    Caller should use MtrrSetMemoryAttributesInMtrrSettings() to specify\r
+                                    external scratch buffer.\r
 **/\r
 RETURN_STATUS\r
 EFIAPI\r
@@ -2788,6 +2838,7 @@ MtrrDebugPrintAllMtrrsWorker (
     UINT64            MtrrValidBitsMask;\r
     UINT64            MtrrValidAddressMask;\r
     UINT32            VariableMtrrCount;\r
+    BOOLEAN           ContainVariableMtrr;\r
     MTRR_MEMORY_RANGE Ranges[\r
       ARRAY_SIZE (mMtrrLibFixedMtrrTable) * sizeof (UINT64) + 2 * ARRAY_SIZE (Mtrrs->Variables.Mtrr) + 1\r
       ];\r
@@ -2809,13 +2860,13 @@ MtrrDebugPrintAllMtrrsWorker (
     //\r
     // Dump RAW MTRR contents\r
     //\r
-    DEBUG((DEBUG_CACHE, "MTRR Settings\n"));\r
-    DEBUG((DEBUG_CACHE, "=============\n"));\r
-    DEBUG((DEBUG_CACHE, "MTRR Default Type: %016lx\n", Mtrrs->MtrrDefType));\r
+    DEBUG ((DEBUG_CACHE, "MTRR Settings:\n"));\r
+    DEBUG ((DEBUG_CACHE, "=============\n"));\r
+    DEBUG ((DEBUG_CACHE, "MTRR Default Type: %016lx\n", Mtrrs->MtrrDefType));\r
     for (Index = 0; Index < ARRAY_SIZE (mMtrrLibFixedMtrrTable); Index++) {\r
-      DEBUG((DEBUG_CACHE, "Fixed MTRR[%02d]   : %016lx\n", Index, Mtrrs->Fixed.Mtrr[Index]));\r
+      DEBUG ((DEBUG_CACHE, "Fixed MTRR[%02d]   : %016lx\n", Index, Mtrrs->Fixed.Mtrr[Index]));\r
     }\r
-\r
+    ContainVariableMtrr = FALSE;\r
     for (Index = 0; Index < VariableMtrrCount; Index++) {\r
       if (((MSR_IA32_MTRR_PHYSMASK_REGISTER *)&Mtrrs->Variables.Mtrr[Index].Mask)->Bits.V == 0) {\r
         //\r
@@ -2823,18 +2874,22 @@ MtrrDebugPrintAllMtrrsWorker (
         //\r
         continue;\r
       }\r
+      ContainVariableMtrr = TRUE;\r
       DEBUG ((DEBUG_CACHE, "Variable MTRR[%02d]: Base=%016lx Mask=%016lx\n",\r
         Index,\r
         Mtrrs->Variables.Mtrr[Index].Base,\r
         Mtrrs->Variables.Mtrr[Index].Mask\r
         ));\r
     }\r
+    if (!ContainVariableMtrr) {\r
+      DEBUG ((DEBUG_CACHE, "Variable MTRR    : None.\n"));\r
+    }\r
     DEBUG((DEBUG_CACHE, "\n"));\r
 \r
     //\r
     // Dump MTRR setting in ranges\r
     //\r
-    DEBUG((DEBUG_CACHE, "MTRR Ranges\n"));\r
+    DEBUG((DEBUG_CACHE, "Memory Ranges:\n"));\r
     DEBUG((DEBUG_CACHE, "====================================\n"));\r
     MtrrLibInitializeMtrrMask (&MtrrValidBitsMask, &MtrrValidAddressMask);\r
     Ranges[0].BaseAddress = 0;\r