]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/MtrrLib/MtrrLib.c
UefiCpuPkg/MtrrLib: Add MtrrSetMemoryAttributeInMtrrSettings()
[mirror_edk2.git] / UefiCpuPkg / Library / MtrrLib / MtrrLib.c
index a5bfa88016155352df18dabcb33e8ecc180b3361..f5b3460f1316e642ecc4b55f306a57a7277bd8de 100644 (file)
@@ -1424,6 +1424,11 @@ MtrrDebugPrintAllMtrrs (
 /**\r
   Worker function attempts to set the attributes for a memory range.\r
 \r
+  If MtrrSettings is not NULL, set the attributes into the input MTRR\r
+  settings buffer.\r
+  If MtrrSettings is NULL, set the attributes into MTRRs registers.\r
+\r
+  @param[in, out]  MtrrSetting       A buffer holding all MTRRs content.\r
   @param[in]       BaseAddress       The physical address that is the start\r
                                      address of a memory region.\r
   @param[in]       Length            The size in bytes of the memory region.\r
@@ -1448,11 +1453,11 @@ MtrrDebugPrintAllMtrrs (
 \r
 **/\r
 RETURN_STATUS\r
-EFIAPI\r
-MtrrSetMemoryAttribute (\r
-  IN PHYSICAL_ADDRESS        BaseAddress,\r
-  IN UINT64                  Length,\r
-  IN MTRR_MEMORY_CACHE_TYPE  Attribute\r
+MtrrSetMemoryAttributeWorker (\r
+  IN OUT MTRR_SETTINGS           *MtrrSetting,\r
+  IN PHYSICAL_ADDRESS            BaseAddress,\r
+  IN UINT64                      Length,\r
+  IN MTRR_MEMORY_CACHE_TYPE      Attribute\r
   )\r
 {\r
   UINT64                    TempQword;\r
@@ -1484,7 +1489,6 @@ MtrrSetMemoryAttribute (
   UINT64                    NewValue;\r
   MTRR_VARIABLE_SETTINGS    *VariableSettings;\r
 \r
-  DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttribute() %a:%016lx-%016lx\n", mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length));\r
   MtrrContextValid = FALSE;\r
   for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {\r
     FixedSettingsValid[Index]    = FALSE;\r
@@ -1529,14 +1533,19 @@ MtrrSetMemoryAttribute (
       if (RETURN_ERROR (Status)) {\r
         goto Done;\r
       }\r
-      if (!FixedSettingsValid[MsrNum]) {\r
-        WorkingFixedSettings.Mtrr[MsrNum] = AsmReadMsr64 (mMtrrLibFixedMtrrTable[MsrNum].Msr);\r
-        FixedSettingsValid[MsrNum] = TRUE;\r
-      }\r
-      NewValue = (WorkingFixedSettings.Mtrr[MsrNum] & ~ClearMask) | OrMask;\r
-      if (WorkingFixedSettings.Mtrr[MsrNum] != NewValue) {\r
-        WorkingFixedSettings.Mtrr[MsrNum] = NewValue;\r
-        FixedSettingsModified[MsrNum] = TRUE;\r
+      if (MtrrSetting != NULL) {\r
+        MtrrSetting->Fixed.Mtrr[MsrNum] = (MtrrSetting->Fixed.Mtrr[MsrNum] & ~ClearMask) | OrMask;\r
+        MtrrSetting->MtrrDefType |= MTRR_LIB_CACHE_FIXED_MTRR_ENABLED;\r
+      } else {\r
+        if (!FixedSettingsValid[MsrNum]) {\r
+          WorkingFixedSettings.Mtrr[MsrNum] = AsmReadMsr64 (mMtrrLibFixedMtrrTable[MsrNum].Msr);\r
+          FixedSettingsValid[MsrNum] = TRUE;\r
+        }\r
+        NewValue = (WorkingFixedSettings.Mtrr[MsrNum] & ~ClearMask) | OrMask;\r
+        if (WorkingFixedSettings.Mtrr[MsrNum] != NewValue) {\r
+          WorkingFixedSettings.Mtrr[MsrNum] = NewValue;\r
+          FixedSettingsModified[MsrNum] = TRUE;\r
+        }\r
       }\r
     }\r
 \r
@@ -1564,10 +1573,14 @@ MtrrSetMemoryAttribute (
   //\r
   VariableMtrrCount = GetVariableMtrrCountWorker ();\r
   FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCountWorker ();\r
-  MtrrGetVariableMtrrWorker (NULL, VariableMtrrCount, &OriginalVariableSettings);\r
-  CopyMem (&WorkingVariableSettings, &OriginalVariableSettings, sizeof (WorkingVariableSettings));\r
-  ProgramVariableSettings = TRUE;\r
-  VariableSettings = &WorkingVariableSettings;\r
+  if (MtrrSetting != NULL) {\r
+    VariableSettings = &MtrrSetting->Variables;\r
+  } else {\r
+    MtrrGetVariableMtrrWorker (NULL, VariableMtrrCount, &OriginalVariableSettings);\r
+    CopyMem (&WorkingVariableSettings, &OriginalVariableSettings, sizeof (WorkingVariableSettings));\r
+    ProgramVariableSettings = TRUE;\r
+    VariableSettings = &WorkingVariableSettings;\r
+  }\r
 \r
   //\r
   // Check for overlap\r
@@ -1613,7 +1626,7 @@ MtrrSetMemoryAttribute (
   // The memory type is the same with the type specified by\r
   // MTRR_LIB_IA32_MTRR_DEF_TYPE.\r
   //\r
-  if ((!OverwriteExistingMtrr) && (Attribute == MtrrGetDefaultMemoryType ())) {\r
+  if ((!OverwriteExistingMtrr) && (Attribute == MtrrGetDefaultMemoryTypeWorker (MtrrSetting))) {\r
     //\r
     // Invalidate the now-unused MTRRs\r
     //\r
@@ -1783,11 +1796,98 @@ Done:
 \r
   DEBUG((DEBUG_CACHE, "  Status = %r\n", Status));\r
   if (!RETURN_ERROR (Status)) {\r
-    MtrrDebugPrintAllMtrrs ();\r
+    if (MtrrSetting != NULL) {\r
+      MtrrSetting->MtrrDefType |= MTRR_LIB_CACHE_MTRR_ENABLED;\r
+    }\r
+    MtrrDebugPrintAllMtrrsWorker (MtrrSetting);\r
   }\r
 \r
   return Status;\r
 }\r
+\r
+/**\r
+  This function attempts to set the attributes for a memory range.\r
+\r
+  @param[in]  BaseAddress        The physical address that is the start\r
+                                 address of a memory region.\r
+  @param[in]  Length             The size in bytes of the memory region.\r
+  @param[in]  Attributes         The bit mask of attributes to set for the\r
+                                 memory region.\r
+\r
+  @retval RETURN_SUCCESS            The attributes were set for the memory\r
+                                    region.\r
+  @retval RETURN_INVALID_PARAMETER  Length is zero.\r
+  @retval RETURN_UNSUPPORTED        The processor does not support one or\r
+                                    more bytes of the memory resource range\r
+                                    specified by BaseAddress and Length.\r
+  @retval RETURN_UNSUPPORTED        The bit mask of attributes is not support\r
+                                    for the memory resource range specified\r
+                                    by BaseAddress and Length.\r
+  @retval RETURN_ACCESS_DENIED      The attributes for the memory resource\r
+                                    range specified by BaseAddress and Length\r
+                                    cannot be modified.\r
+  @retval RETURN_OUT_OF_RESOURCES   There are not enough system resources to\r
+                                    modify the attributes of the memory\r
+                                    resource range.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+MtrrSetMemoryAttribute (\r
+  IN PHYSICAL_ADDRESS        BaseAddress,\r
+  IN UINT64                  Length,\r
+  IN MTRR_MEMORY_CACHE_TYPE  Attribute\r
+  )\r
+{\r
+  DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttribute() %a:%016lx-%016lx\n", mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length));\r
+  return MtrrSetMemoryAttributeWorker (\r
+           NULL,\r
+           BaseAddress,\r
+           Length,\r
+           Attribute\r
+           );\r
+}\r
+\r
+/**\r
+  This function attempts to set the attributes into MTRR setting buffer for a memory range.\r
+\r
+  @param[in, out]  MtrrSetting  MTRR setting buffer to be set.\r
+  @param[in]       BaseAddress  The physical address that is the start address\r
+                                of a memory region.\r
+  @param[in]       Length       The size in bytes of the memory region.\r
+  @param[in]       Attribute    The bit mask of attributes to set for the\r
+                                memory region.\r
+\r
+  @retval RETURN_SUCCESS            The attributes were set for the memory region.\r
+  @retval RETURN_INVALID_PARAMETER  Length is zero.\r
+  @retval RETURN_UNSUPPORTED        The processor does not support one or more bytes of the\r
+                                    memory resource range specified by BaseAddress and Length.\r
+  @retval RETURN_UNSUPPORTED        The bit mask of attributes is not support for the memory resource\r
+                                    range specified by BaseAddress and Length.\r
+  @retval RETURN_ACCESS_DENIED      The attributes for the memory resource range specified by\r
+                                    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
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+MtrrSetMemoryAttributeInMtrrSettings (\r
+  IN OUT MTRR_SETTINGS       *MtrrSetting,\r
+  IN PHYSICAL_ADDRESS        BaseAddress,\r
+  IN UINT64                  Length,\r
+  IN MTRR_MEMORY_CACHE_TYPE  Attribute\r
+  )\r
+{\r
+  DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttributeMtrrSettings(%p) %a:%016lx-%016lx\n", MtrrSetting, mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length));\r
+  return MtrrSetMemoryAttributeWorker (\r
+           MtrrSetting,\r
+           BaseAddress,\r
+           Length,\r
+           Attribute\r
+           );\r
+}\r
+\r
 /**\r
   Worker function setting variable MTRRs\r
 \r