]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/MtrrLib/MtrrLib.c
UefiCpuPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / UefiCpuPkg / Library / MtrrLib / MtrrLib.c
index 30b0df030b5618ed7e4663263fd3abb1675f0f88..9415897b481983ac4e723d85ad4583cd079da64f 100644 (file)
@@ -5,14 +5,8 @@
     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 - 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
-  http://opensource.org/licenses/bsd-license.php\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+  Copyright (c) 2008 - 2019, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -449,13 +443,10 @@ MtrrGetVariableMtrrWorker (
 \r
   for (Index = 0; Index < VariableMtrrCount; Index++) {\r
     if (MtrrSetting == NULL) {\r
-      VariableSettings->Mtrr[Index].Mask = AsmReadMsr64 (MSR_IA32_MTRR_PHYSMASK0 + (Index << 1));\r
-      //\r
-      // Skip to read the Base MSR when the Mask.V is not set.\r
-      //\r
-      if (((MSR_IA32_MTRR_PHYSMASK_REGISTER *)&VariableSettings->Mtrr[Index].Mask)->Bits.V != 0) {\r
-        VariableSettings->Mtrr[Index].Base = AsmReadMsr64 (MSR_IA32_MTRR_PHYSBASE0 + (Index << 1));\r
-      }\r
+      VariableSettings->Mtrr[Index].Base =\r
+        AsmReadMsr64 (MSR_IA32_MTRR_PHYSBASE0 + (Index << 1));\r
+      VariableSettings->Mtrr[Index].Mask =\r
+        AsmReadMsr64 (MSR_IA32_MTRR_PHYSMASK0 + (Index << 1));\r
     } else {\r
       VariableSettings->Mtrr[Index].Base = MtrrSetting->Variables.Mtrr[Index].Base;\r
       VariableSettings->Mtrr[Index].Mask = MtrrSetting->Variables.Mtrr[Index].Mask;\r
@@ -2102,8 +2093,8 @@ MtrrLibSetMemoryRanges (
   Set the below-1MB memory attribute to fixed MTRR buffer.\r
   Modified flag array indicates which fixed MTRR is modified.\r
 \r
-  @param [in, out] FixedSettings Fixed MTRR buffer.\r
-  @param [out]     Modified      Flag array indicating which MTRR is modified.\r
+  @param [in, out] ClearMasks    The bits (when set) to clear in the fixed MTRR MSR.\r
+  @param [in, out] OrMasks       The bits to set in the fixed MTRR MSR.\r
   @param [in]      BaseAddress   Base address.\r
   @param [in]      Length        Length.\r
   @param [in]      Type          Memory type.\r
@@ -2114,8 +2105,8 @@ MtrrLibSetMemoryRanges (
 **/\r
 RETURN_STATUS\r
 MtrrLibSetBelow1MBMemoryAttribute (\r
-  IN OUT MTRR_FIXED_SETTINGS     *FixedSettings,\r
-  OUT BOOLEAN                    *Modified,\r
+  IN OUT UINT64                  *ClearMasks,\r
+  IN OUT UINT64                  *OrMasks,\r
   IN PHYSICAL_ADDRESS            BaseAddress,\r
   IN UINT64                      Length,\r
   IN MTRR_MEMORY_CACHE_TYPE      Type\r
@@ -2125,36 +2116,17 @@ MtrrLibSetBelow1MBMemoryAttribute (
   UINT32                    MsrIndex;\r
   UINT64                    ClearMask;\r
   UINT64                    OrMask;\r
-  UINT64                    ClearMasks[ARRAY_SIZE (mMtrrLibFixedMtrrTable)];\r
-  UINT64                    OrMasks[ARRAY_SIZE (mMtrrLibFixedMtrrTable)];\r
-  BOOLEAN                   LocalModified[ARRAY_SIZE (mMtrrLibFixedMtrrTable)];\r
 \r
   ASSERT (BaseAddress < BASE_1MB);\r
 \r
-  SetMem (LocalModified, sizeof (LocalModified), FALSE);\r
-\r
-  //\r
-  // (Value & ~0 | 0) still equals to (Value)\r
-  //\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
     Status = MtrrLibProgramFixedMtrr (Type, &BaseAddress, &Length, &MsrIndex, &ClearMask, &OrMask);\r
     if (RETURN_ERROR (Status)) {\r
       return Status;\r
     }\r
-    ClearMasks[MsrIndex]    = ClearMask;\r
-    OrMasks[MsrIndex]       = OrMask;\r
-    Modified[MsrIndex]      = TRUE;\r
-    LocalModified[MsrIndex] = TRUE;\r
-  }\r
-\r
-  for (MsrIndex = 0; MsrIndex < ARRAY_SIZE (mMtrrLibFixedMtrrTable); MsrIndex++) {\r
-    if (LocalModified[MsrIndex]) {\r
-      FixedSettings->Mtrr[MsrIndex] = (FixedSettings->Mtrr[MsrIndex] & ~ClearMasks[MsrIndex]) | OrMasks[MsrIndex];\r
-    }\r
+    ClearMasks[MsrIndex] = ClearMasks[MsrIndex] | ClearMask;\r
+    OrMasks[MsrIndex]    = (OrMasks[MsrIndex] & ~ClearMask) | OrMask;\r
   }\r
   return RETURN_SUCCESS;\r
 }\r
@@ -2216,8 +2188,8 @@ MtrrSetMemoryAttributesInMtrrSettings (
   MTRR_MEMORY_RANGE         WorkingVariableMtrr[ARRAY_SIZE (MtrrSetting->Variables.Mtrr)];\r
   BOOLEAN                   VariableSettingModified[ARRAY_SIZE (MtrrSetting->Variables.Mtrr)];\r
 \r
-  BOOLEAN                   FixedSettingsModified[ARRAY_SIZE (mMtrrLibFixedMtrrTable)];\r
-  MTRR_FIXED_SETTINGS       WorkingFixedSettings;\r
+  UINT64                    ClearMasks[ARRAY_SIZE (mMtrrLibFixedMtrrTable)];\r
+  UINT64                    OrMasks[ARRAY_SIZE (mMtrrLibFixedMtrrTable)];\r
 \r
   MTRR_CONTEXT              MtrrContext;\r
   BOOLEAN                   MtrrContextValid;\r
@@ -2229,10 +2201,6 @@ MtrrSetMemoryAttributesInMtrrSettings (
   // TRUE indicating the accordingly Variable setting needs modificaiton in OriginalVariableMtrr.\r
   //\r
   SetMem (VariableSettingModified, ARRAY_SIZE (VariableSettingModified), FALSE);\r
-  //\r
-  // TRUE indicating the accordingly Fixed setting needs modification in WorkingFixedSettings.\r
-  //\r
-  SetMem (FixedSettingsModified, ARRAY_SIZE (FixedSettingsModified), FALSE);\r
 \r
   //\r
   // TRUE indicating the caller requests to set variable MTRRs.\r
@@ -2408,14 +2376,17 @@ MtrrSetMemoryAttributesInMtrrSettings (
   //\r
   // 3. Apply the below-1MB memory attribute settings.\r
   //\r
-  ZeroMem (WorkingFixedSettings.Mtrr, sizeof (WorkingFixedSettings.Mtrr));\r
+  // (Value & ~0 | 0) still equals to (Value)\r
+  //\r
+  ZeroMem (ClearMasks, sizeof (ClearMasks));\r
+  ZeroMem (OrMasks, sizeof (OrMasks));\r
   for (Index = 0; Index < RangeCount; Index++) {\r
     if (Ranges[Index].BaseAddress >= BASE_1MB) {\r
       continue;\r
     }\r
 \r
     Status = MtrrLibSetBelow1MBMemoryAttribute (\r
-               &WorkingFixedSettings, FixedSettingsModified,\r
+               ClearMasks, OrMasks,\r
                Ranges[Index].BaseAddress, Ranges[Index].Length, Ranges[Index].Type\r
                );\r
     if (RETURN_ERROR (Status)) {\r
@@ -2427,19 +2398,16 @@ MtrrSetMemoryAttributesInMtrrSettings (
   //\r
   // 4. Write fixed MTRRs that have been modified\r
   //\r
-  for (Index = 0; Index < ARRAY_SIZE (FixedSettingsModified); Index++) {\r
-    if (FixedSettingsModified[Index]) {\r
+  for (Index = 0; Index < ARRAY_SIZE (ClearMasks); Index++) {\r
+    if (ClearMasks[Index] != 0) {\r
       if (MtrrSetting != NULL) {\r
-        MtrrSetting->Fixed.Mtrr[Index] = WorkingFixedSettings.Mtrr[Index];\r
+        MtrrSetting->Fixed.Mtrr[Index] = (MtrrSetting->Fixed.Mtrr[Index] & ~ClearMasks[Index]) | OrMasks[Index];\r
       } else {\r
         if (!MtrrContextValid) {\r
           MtrrLibPreMtrrChange (&MtrrContext);\r
           MtrrContextValid = TRUE;\r
         }\r
-        AsmWriteMsr64 (\r
-          mMtrrLibFixedMtrrTable[Index].Msr,\r
-          WorkingFixedSettings.Mtrr[Index]\r
-        );\r
+        AsmMsrAndThenOr64 (mMtrrLibFixedMtrrTable[Index].Msr, ~ClearMasks[Index], OrMasks[Index]);\r
       }\r
     }\r
   }\r
@@ -2513,7 +2481,14 @@ Exit:
                                     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
@@ -2559,7 +2534,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
@@ -2590,14 +2572,14 @@ MtrrSetVariableMtrrWorker (
   ASSERT (VariableMtrrCount <= ARRAY_SIZE (VariableSettings->Mtrr));\r
 \r
   for (Index = 0; Index < VariableMtrrCount; Index++) {\r
-    //\r
-    // Mask MSR is always updated since caller might need to invalidate the MSR pair.\r
-    // Base MSR is skipped when Mask.V is not set.\r
-    //\r
-    AsmWriteMsr64 (MSR_IA32_MTRR_PHYSMASK0 + (Index << 1), VariableSettings->Mtrr[Index].Mask);\r
-    if (((MSR_IA32_MTRR_PHYSMASK_REGISTER *)&VariableSettings->Mtrr[Index].Mask)->Bits.V != 0) {\r
-      AsmWriteMsr64 (MSR_IA32_MTRR_PHYSBASE0 + (Index << 1), VariableSettings->Mtrr[Index].Base);\r
-    }\r
+    AsmWriteMsr64 (\r
+      MSR_IA32_MTRR_PHYSBASE0 + (Index << 1),\r
+      VariableSettings->Mtrr[Index].Base\r
+      );\r
+    AsmWriteMsr64 (\r
+      MSR_IA32_MTRR_PHYSMASK0 + (Index << 1),\r
+      VariableSettings->Mtrr[Index].Mask\r
+      );\r
   }\r
 }\r
 \r
@@ -2854,7 +2836,7 @@ MtrrDebugPrintAllMtrrsWorker (
     }\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
+      if ((Mtrrs->Variables.Mtrr[Index].Mask & BIT11) == 0) {\r
         //\r
         // If mask is not valid, then do not display range\r
         //\r