summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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