summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuanhaoXie <yuanhao.xie@intel.com>2023-09-11 18:41:34 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2023-10-09 08:22:02 +0000
commit4b7b32f846edbd2970f5b7c34041c2abe9d0724e (patch)
treec2e2dad82cc5f23a974de51ee4449e5d85f27294
parentc032db330805993bb29e4ff3d9daad160f3fb35e (diff)
downloadedk2-4b7b32f846edbd2970f5b7c34041c2abe9d0724e.tar.gz
edk2-4b7b32f846edbd2970f5b7c34041c2abe9d0724e.tar.bz2
edk2-4b7b32f846edbd2970f5b7c34041c2abe9d0724e.zip
UefiCpuPkg/MtrrLib: Add API MtrrGetMemoryAttributesInMtrrSettings.
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.ni@intel.com> Cc: Eric Dong <eric.dong@intel.com> Cc: Rahul Kumar <rahul1.kumar@intel.com> Cc: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Eric Dong <eric.dong@intel.com> Reviewed-by: Ray Ni <ray.ni@intel.com>
-rw-r--r--UefiCpuPkg/Include/Library/MtrrLib.h23
-rw-r--r--UefiCpuPkg/Library/MtrrLib/MtrrLib.c117
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 010c15affe..96474f6f9b 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;
@@ -690,11 +690,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;
@@ -1824,10 +1824,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;
@@ -2958,6 +2958,103 @@ IsMtrrSupported (
}
/**
+ 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.
If MtrrSetting is not NULL, print MTRR settings from input MTRR