MtrrGetMemoryAttributesInMtrrSettings parses the MTRR settings
either from hardware or from the parameter and returns an
array containing the memory cache types of all memory addresses.

This API could elinimate the needs of following APIs:
1. MtrrGetMemoryAttributeInVariableMtr
2. MtrrGetFixedMtrr

Signed-off-by: Ray Ni <ray...@intel.com>
Cc: Eric Dong <eric.d...@intel.com>
Cc: Rahul Kumar <rahul1.ku...@intel.com>
Cc: Gerd Hoffmann <kra...@redhat.com>
---
 UefiCpuPkg/Include/Library/MtrrLib.h |  23 +++++++++++++++++++++++
 UefiCpuPkg/Library/MtrrLib/MtrrLib.c | 117 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 130 insertions(+), 10 deletions(-)

diff --git a/UefiCpuPkg/Include/Library/MtrrLib.h 
b/UefiCpuPkg/Include/Library/MtrrLib.h
index 94cf615901..86cc1aab3b 100644
--- a/UefiCpuPkg/Include/Library/MtrrLib.h
+++ b/UefiCpuPkg/Include/Library/MtrrLib.h
@@ -359,4 +359,27 @@ MtrrSetMemoryAttributesInMtrrSettings (
   IN     UINTN                    RangeCount
   );
 
+/**
+  This function returns a Ranges array containing the memory cache types
+  of all memory addresses.
+
+  @param[in]      MtrrSetting  MTRR setting buffer to parse.
+  @param[out]     Ranges       Pointer to an array of MTRR_MEMORY_RANGE.
+  @param[in,out]  RangeCount   Count of MTRR_MEMORY_RANGE.
+                               On input, the maximum entries the Ranges can 
hold.
+                               On output, the actual entries that the function 
returns.
+
+  @retval RETURN_INVALID_PARAMETER RangeCount is NULL.
+  @retval RETURN_INVALID_PARAMETER *RangeCount is not 0 but Ranges is NULL.
+  @retval RETURN_BUFFER_TOO_SMALL  *RangeCount is too small.
+  @retval RETURN_SUCCESS           Ranges are successfully returned.
+**/
+RETURN_STATUS
+EFIAPI
+MtrrGetMemoryAttributesInMtrrSettings (
+  IN CONST MTRR_SETTINGS      *MtrrSetting OPTIONAL,
+  OUT      MTRR_MEMORY_RANGE  *Ranges,
+  IN OUT   UINTN              *RangeCount
+  );
+
 #endif // _MTRR_LIB_H_
diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c 
b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
index 6ba0c9b37f..61c81c5139 100644
--- a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
+++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
@@ -292,7 +292,7 @@ GetFirmwareVariableMtrrCount (
 **/
 MTRR_MEMORY_CACHE_TYPE
 MtrrGetDefaultMemoryTypeWorker (
-  IN MTRR_SETTINGS  *MtrrSetting
+  IN CONST MTRR_SETTINGS  *MtrrSetting
   )
 {
   MSR_IA32_MTRR_DEF_TYPE_REGISTER  DefType;
@@ -689,11 +689,11 @@ MtrrGetMemoryAttributeInVariableMtrrWorker (
 **/
 UINT32
 MtrrLibGetRawVariableRanges (
-  IN  MTRR_VARIABLE_SETTINGS  *VariableSettings,
-  IN  UINTN                   VariableMtrrCount,
-  IN  UINT64                  MtrrValidBitsMask,
-  IN  UINT64                  MtrrValidAddressMask,
-  OUT MTRR_MEMORY_RANGE       *VariableMtrr
+  IN  CONST MTRR_VARIABLE_SETTINGS  *VariableSettings,
+  IN  UINTN                         VariableMtrrCount,
+  IN  UINT64                        MtrrValidBitsMask,
+  IN  UINT64                        MtrrValidAddressMask,
+  OUT MTRR_MEMORY_RANGE             *VariableMtrr
   )
 {
   UINTN   Index;
@@ -1823,10 +1823,10 @@ MtrrLibCalculateMtrrs (
 **/
 RETURN_STATUS
 MtrrLibApplyFixedMtrrs (
-  IN     MTRR_FIXED_SETTINGS  *Fixed,
-  IN OUT MTRR_MEMORY_RANGE    *Ranges,
-  IN     UINTN                RangeCapacity,
-  IN OUT UINTN                *RangeCount
+  IN     CONST MTRR_FIXED_SETTINGS  *Fixed,
+  IN OUT MTRR_MEMORY_RANGE          *Ranges,
+  IN     UINTN                      RangeCapacity,
+  IN OUT UINTN                      *RangeCount
   )
 {
   RETURN_STATUS           Status;
@@ -2956,6 +2956,103 @@ IsMtrrSupported (
   return MtrrLibIsMtrrSupported (NULL, NULL);
 }
 
+/**
+  This function returns a Ranges array containing the memory cache types
+  of all memory addresses.
+
+  @param[in]      MtrrSetting  MTRR setting buffer to parse.
+  @param[out]     Ranges       Pointer to an array of MTRR_MEMORY_RANGE.
+  @param[in,out]  RangeCount   Count of MTRR_MEMORY_RANGE.
+                               On input, the maximum entries the Ranges can 
hold.
+                               On output, the actual entries that the function 
returns.
+
+  @retval RETURN_INVALID_PARAMETER RangeCount is NULL.
+  @retval RETURN_INVALID_PARAMETER *RangeCount is not 0 but Ranges is NULL.
+  @retval RETURN_BUFFER_TOO_SMALL  *RangeCount is too small.
+  @retval RETURN_SUCCESS           Ranges are successfully returned.
+**/
+RETURN_STATUS
+EFIAPI
+MtrrGetMemoryAttributesInMtrrSettings (
+  IN CONST MTRR_SETTINGS      *MtrrSetting OPTIONAL,
+  OUT      MTRR_MEMORY_RANGE  *Ranges,
+  IN OUT   UINTN              *RangeCount
+  )
+{
+  RETURN_STATUS                    Status;
+  MTRR_SETTINGS                    LocalMtrrs;
+  CONST MTRR_SETTINGS              *Mtrrs;
+  MSR_IA32_MTRR_DEF_TYPE_REGISTER  *MtrrDefType;
+  UINTN                            LocalRangeCount;
+  UINT64                           MtrrValidBitsMask;
+  UINT64                           MtrrValidAddressMask;
+  UINT32                           VariableMtrrCount;
+  MTRR_MEMORY_RANGE                RawVariableRanges[ARRAY_SIZE 
(Mtrrs->Variables.Mtrr)];
+  MTRR_MEMORY_RANGE                LocalRanges[
+                                               ARRAY_SIZE 
(mMtrrLibFixedMtrrTable) * sizeof (UINT64) + 2 * ARRAY_SIZE 
(Mtrrs->Variables.Mtrr) + 1
+  ];
+
+  if (RangeCount == NULL) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if ((*RangeCount != 0) && (Ranges == NULL)) {
+    return RETURN_INVALID_PARAMETER;
+  }
+
+  if (MtrrSetting != NULL) {
+    Mtrrs = MtrrSetting;
+  } else {
+    MtrrGetAllMtrrs (&LocalMtrrs);
+    Mtrrs = &LocalMtrrs;
+  }
+
+  MtrrDefType = (MSR_IA32_MTRR_DEF_TYPE_REGISTER *)&Mtrrs->MtrrDefType;
+
+  LocalRangeCount = 1;
+  MtrrLibInitializeMtrrMask (&MtrrValidBitsMask, &MtrrValidAddressMask);
+  LocalRanges[0].BaseAddress = 0;
+  LocalRanges[0].Length      = MtrrValidBitsMask + 1;
+
+  if (MtrrDefType->Bits.E == 0) {
+    LocalRanges[0].Type = CacheUncacheable;
+  } else {
+    LocalRanges[0].Type = MtrrGetDefaultMemoryTypeWorker (Mtrrs);
+
+    VariableMtrrCount = GetVariableMtrrCountWorker ();
+    ASSERT (VariableMtrrCount <= ARRAY_SIZE (MtrrSetting->Variables.Mtrr));
+
+    MtrrLibGetRawVariableRanges (
+      &Mtrrs->Variables,
+      VariableMtrrCount,
+      MtrrValidBitsMask,
+      MtrrValidAddressMask,
+      RawVariableRanges
+      );
+    Status = MtrrLibApplyVariableMtrrs (
+               RawVariableRanges,
+               VariableMtrrCount,
+               LocalRanges,
+               ARRAY_SIZE (LocalRanges),
+               &LocalRangeCount
+               );
+    ASSERT_RETURN_ERROR (Status);
+
+    if (MtrrDefType->Bits.FE == 1) {
+      MtrrLibApplyFixedMtrrs (&Mtrrs->Fixed, LocalRanges, ARRAY_SIZE 
(LocalRanges), &LocalRangeCount);
+    }
+  }
+
+  if (*RangeCount < LocalRangeCount) {
+    *RangeCount = LocalRangeCount;
+    return RETURN_BUFFER_TOO_SMALL;
+  }
+
+  CopyMem (Ranges, LocalRanges, LocalRangeCount * sizeof (LocalRanges[0]));
+  *RangeCount = LocalRangeCount;
+  return RETURN_SUCCESS;
+}
+
 /**
   Worker function prints all MTRRs for debugging.
 
-- 
2.36.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#108569): https://edk2.groups.io/g/devel/message/108569
Mute This Topic: https://groups.io/mt/101331032/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to