diff options
Diffstat (limited to 'UefiCpuPkg/Library/MtrrLib/MtrrLib.c')
-rw-r--r-- | UefiCpuPkg/Library/MtrrLib/MtrrLib.c | 117 |
1 files changed, 107 insertions, 10 deletions
diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c index 010c15a..96474f6 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
|