mirror of https://github.com/acidanthera/audk.git
UefiCpuPkg/MtrrLib: Refine MtrrGetMemoryAttributeByAddressWorker
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com> Reviewed-by: Jeff Fan <jeff.fan@intel.com>
This commit is contained in:
parent
8051302a36
commit
10c361ad02
|
@ -568,20 +568,19 @@ MtrrLibProgramFixedMtrr (
|
||||||
This function shadows the content of variable MTRRs into an
|
This function shadows the content of variable MTRRs into an
|
||||||
internal array: VariableMtrr.
|
internal array: VariableMtrr.
|
||||||
|
|
||||||
@param[in] VariableSettings The variable MTRR values to shadow
|
@param[in] VariableSettings The variable MTRR values to shadow
|
||||||
@param[in] FirmwareVariableMtrrCount The number of variable MTRRs available to firmware
|
@param[in] VariableMtrrCount The number of variable MTRRs
|
||||||
@param[in] MtrrValidBitsMask The mask for the valid bit of the MTRR
|
@param[in] MtrrValidBitsMask The mask for the valid bit of the MTRR
|
||||||
@param[in] MtrrValidAddressMask The valid address mask for MTRR
|
@param[in] MtrrValidAddressMask The valid address mask for MTRR
|
||||||
@param[out] VariableMtrr The array to shadow variable MTRRs content
|
@param[out] VariableMtrr The array to shadow variable MTRRs content
|
||||||
|
|
||||||
@return The return value of this parameter indicates the
|
@return Number of MTRRs which has been used.
|
||||||
number of MTRRs which has been used.
|
|
||||||
|
|
||||||
**/
|
**/
|
||||||
UINT32
|
UINT32
|
||||||
MtrrGetMemoryAttributeInVariableMtrrWorker (
|
MtrrGetMemoryAttributeInVariableMtrrWorker (
|
||||||
IN MTRR_VARIABLE_SETTINGS *VariableSettings,
|
IN MTRR_VARIABLE_SETTINGS *VariableSettings,
|
||||||
IN UINTN FirmwareVariableMtrrCount,
|
IN UINTN VariableMtrrCount,
|
||||||
IN UINT64 MtrrValidBitsMask,
|
IN UINT64 MtrrValidBitsMask,
|
||||||
IN UINT64 MtrrValidAddressMask,
|
IN UINT64 MtrrValidAddressMask,
|
||||||
OUT VARIABLE_MTRR *VariableMtrr
|
OUT VARIABLE_MTRR *VariableMtrr
|
||||||
|
@ -591,7 +590,7 @@ MtrrGetMemoryAttributeInVariableMtrrWorker (
|
||||||
UINT32 UsedMtrr;
|
UINT32 UsedMtrr;
|
||||||
|
|
||||||
ZeroMem (VariableMtrr, sizeof (VARIABLE_MTRR) * MTRR_NUMBER_OF_VARIABLE_MTRR);
|
ZeroMem (VariableMtrr, sizeof (VARIABLE_MTRR) * MTRR_NUMBER_OF_VARIABLE_MTRR);
|
||||||
for (Index = 0, UsedMtrr = 0; Index < FirmwareVariableMtrrCount; Index++) {
|
for (Index = 0, UsedMtrr = 0; Index < VariableMtrrCount; Index++) {
|
||||||
if ((VariableSettings->Mtrr[Index].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) != 0) {
|
if ((VariableSettings->Mtrr[Index].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) != 0) {
|
||||||
VariableMtrr[Index].Msr = (UINT32)Index;
|
VariableMtrr[Index].Msr = (UINT32)Index;
|
||||||
VariableMtrr[Index].BaseAddress = (VariableSettings->Mtrr[Index].Base & MtrrValidAddressMask);
|
VariableMtrr[Index].BaseAddress = (VariableSettings->Mtrr[Index].Base & MtrrValidAddressMask);
|
||||||
|
@ -724,8 +723,10 @@ MtrrLibGetPositiveMtrrNumber (
|
||||||
Return whether the left MTRR type precedes the right MTRR type.
|
Return whether the left MTRR type precedes the right MTRR type.
|
||||||
|
|
||||||
The MTRR type precedence rules are:
|
The MTRR type precedence rules are:
|
||||||
1. UC precedes any other type
|
1. UC precedes any other type
|
||||||
2. WT precedes WB
|
2. WT precedes WB
|
||||||
|
For further details, please refer the IA32 Software Developer's Manual,
|
||||||
|
Volume 3, Section "MTRR Precedences".
|
||||||
|
|
||||||
@param Left The left MTRR type.
|
@param Left The left MTRR type.
|
||||||
@param Right The right MTRR type.
|
@param Right The right MTRR type.
|
||||||
|
@ -954,46 +955,6 @@ MtrrLibGetMtrrNumber (
|
||||||
return LeastSubtractiveMtrrNumber + MiddleMtrrNumber + LeastRightMtrrNumber;
|
return LeastSubtractiveMtrrNumber + MiddleMtrrNumber + LeastRightMtrrNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Converts the Memory attribute value to MTRR_MEMORY_CACHE_TYPE.
|
|
||||||
|
|
||||||
If MtrrSetting is not NULL, gets the default memory attribute from input
|
|
||||||
MTRR settings buffer.
|
|
||||||
If MtrrSetting is NULL, gets the default memory attribute from MSR.
|
|
||||||
|
|
||||||
@param[in] MtrrSetting A buffer holding all MTRRs content.
|
|
||||||
@param[in] MtrrType MTRR memory type
|
|
||||||
|
|
||||||
@return The enum item in MTRR_MEMORY_CACHE_TYPE
|
|
||||||
|
|
||||||
**/
|
|
||||||
MTRR_MEMORY_CACHE_TYPE
|
|
||||||
GetMemoryCacheTypeFromMtrrType (
|
|
||||||
IN MTRR_SETTINGS *MtrrSetting,
|
|
||||||
IN UINT64 MtrrType
|
|
||||||
)
|
|
||||||
{
|
|
||||||
switch (MtrrType) {
|
|
||||||
case MTRR_CACHE_UNCACHEABLE:
|
|
||||||
return CacheUncacheable;
|
|
||||||
case MTRR_CACHE_WRITE_COMBINING:
|
|
||||||
return CacheWriteCombining;
|
|
||||||
case MTRR_CACHE_WRITE_THROUGH:
|
|
||||||
return CacheWriteThrough;
|
|
||||||
case MTRR_CACHE_WRITE_PROTECTED:
|
|
||||||
return CacheWriteProtected;
|
|
||||||
case MTRR_CACHE_WRITE_BACK:
|
|
||||||
return CacheWriteBack;
|
|
||||||
default:
|
|
||||||
//
|
|
||||||
// MtrrType is MTRR_CACHE_INVALID_TYPE, that means
|
|
||||||
// no MTRR covers the range
|
|
||||||
//
|
|
||||||
return MtrrGetDefaultMemoryTypeWorker (MtrrSetting);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Initializes the valid bits mask and valid address mask for MTRRs.
|
Initializes the valid bits mask and valid address mask for MTRRs.
|
||||||
|
|
||||||
|
@ -1030,71 +991,34 @@ MtrrLibInitializeMtrrMask (
|
||||||
Determines the real attribute of a memory range.
|
Determines the real attribute of a memory range.
|
||||||
|
|
||||||
This function is to arbitrate the real attribute of the memory when
|
This function is to arbitrate the real attribute of the memory when
|
||||||
there are 2 MTRRs covers the same memory range. For further details,
|
there are 2 MTRRs covers the same memory range. For further details,
|
||||||
please refer the IA32 Software Developer's Manual, Volume 3,
|
please refer the IA32 Software Developer's Manual, Volume 3,
|
||||||
Section 10.11.4.1.
|
Section "MTRR Precedences".
|
||||||
|
|
||||||
@param[in] MtrrType1 The first kind of Memory type
|
@param[in] MtrrType1 The first kind of Memory type
|
||||||
@param[in] MtrrType2 The second kind of memory type
|
@param[in] MtrrType2 The second kind of memory type
|
||||||
|
|
||||||
**/
|
**/
|
||||||
UINT64
|
MTRR_MEMORY_CACHE_TYPE
|
||||||
MtrrLibPrecedence (
|
MtrrLibPrecedence (
|
||||||
IN UINT64 MtrrType1,
|
IN MTRR_MEMORY_CACHE_TYPE MtrrType1,
|
||||||
IN UINT64 MtrrType2
|
IN MTRR_MEMORY_CACHE_TYPE MtrrType2
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINT64 MtrrType;
|
if (MtrrType1 == MtrrType2) {
|
||||||
|
return MtrrType1;
|
||||||
MtrrType = MTRR_CACHE_INVALID_TYPE;
|
|
||||||
switch (MtrrType1) {
|
|
||||||
case MTRR_CACHE_UNCACHEABLE:
|
|
||||||
MtrrType = MTRR_CACHE_UNCACHEABLE;
|
|
||||||
break;
|
|
||||||
case MTRR_CACHE_WRITE_COMBINING:
|
|
||||||
if (
|
|
||||||
MtrrType2==MTRR_CACHE_WRITE_COMBINING ||
|
|
||||||
MtrrType2==MTRR_CACHE_UNCACHEABLE
|
|
||||||
) {
|
|
||||||
MtrrType = MtrrType2;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MTRR_CACHE_WRITE_THROUGH:
|
|
||||||
if (
|
|
||||||
MtrrType2==MTRR_CACHE_WRITE_THROUGH ||
|
|
||||||
MtrrType2==MTRR_CACHE_WRITE_BACK
|
|
||||||
) {
|
|
||||||
MtrrType = MTRR_CACHE_WRITE_THROUGH;
|
|
||||||
} else if(MtrrType2==MTRR_CACHE_UNCACHEABLE) {
|
|
||||||
MtrrType = MTRR_CACHE_UNCACHEABLE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MTRR_CACHE_WRITE_PROTECTED:
|
|
||||||
if (MtrrType2 == MTRR_CACHE_WRITE_PROTECTED ||
|
|
||||||
MtrrType2 == MTRR_CACHE_UNCACHEABLE) {
|
|
||||||
MtrrType = MtrrType2;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MTRR_CACHE_WRITE_BACK:
|
|
||||||
if (
|
|
||||||
MtrrType2== MTRR_CACHE_UNCACHEABLE ||
|
|
||||||
MtrrType2==MTRR_CACHE_WRITE_THROUGH ||
|
|
||||||
MtrrType2== MTRR_CACHE_WRITE_BACK
|
|
||||||
) {
|
|
||||||
MtrrType = MtrrType2;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MTRR_CACHE_INVALID_TYPE:
|
|
||||||
MtrrType = MtrrType2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MtrrType2 == MTRR_CACHE_INVALID_TYPE) {
|
ASSERT (
|
||||||
MtrrType = MtrrType1;
|
MtrrLibTypeLeftPrecedeRight (MtrrType1, MtrrType2) ||
|
||||||
|
MtrrLibTypeLeftPrecedeRight (MtrrType2, MtrrType1)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (MtrrLibTypeLeftPrecedeRight (MtrrType1, MtrrType2)) {
|
||||||
|
return MtrrType1;
|
||||||
|
} else {
|
||||||
|
return MtrrType2;
|
||||||
}
|
}
|
||||||
return MtrrType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1116,29 +1040,27 @@ MtrrGetMemoryAttributeByAddressWorker (
|
||||||
IN PHYSICAL_ADDRESS Address
|
IN PHYSICAL_ADDRESS Address
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINT64 TempQword;
|
MSR_IA32_MTRR_DEF_TYPE_REGISTER DefType;
|
||||||
UINTN Index;
|
UINT64 FixedMtrr;
|
||||||
UINTN SubIndex;
|
UINTN Index;
|
||||||
UINT64 MtrrType;
|
UINTN SubIndex;
|
||||||
UINT64 TempMtrrType;
|
MTRR_MEMORY_CACHE_TYPE MtrrType;
|
||||||
MTRR_MEMORY_CACHE_TYPE CacheType;
|
VARIABLE_MTRR VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];
|
||||||
VARIABLE_MTRR VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];
|
UINT64 MtrrValidBitsMask;
|
||||||
UINT64 MtrrValidBitsMask;
|
UINT64 MtrrValidAddressMask;
|
||||||
UINT64 MtrrValidAddressMask;
|
UINT32 VariableMtrrCount;
|
||||||
UINTN VariableMtrrCount;
|
MTRR_VARIABLE_SETTINGS VariableSettings;
|
||||||
MTRR_VARIABLE_SETTINGS VariableSettings;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check if MTRR is enabled, if not, return UC as attribute
|
// Check if MTRR is enabled, if not, return UC as attribute
|
||||||
//
|
//
|
||||||
if (MtrrSetting == NULL) {
|
if (MtrrSetting == NULL) {
|
||||||
TempQword = AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE);
|
DefType.Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE);
|
||||||
} else {
|
} else {
|
||||||
TempQword = MtrrSetting->MtrrDefType;
|
DefType.Uint64 = MtrrSetting->MtrrDefType;
|
||||||
}
|
}
|
||||||
MtrrType = MTRR_CACHE_INVALID_TYPE;
|
|
||||||
|
|
||||||
if ((TempQword & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
|
if (DefType.Bits.E == 0) {
|
||||||
return CacheUncacheable;
|
return CacheUncacheable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1146,65 +1068,66 @@ MtrrGetMemoryAttributeByAddressWorker (
|
||||||
// If address is less than 1M, then try to go through the fixed MTRR
|
// If address is less than 1M, then try to go through the fixed MTRR
|
||||||
//
|
//
|
||||||
if (Address < BASE_1MB) {
|
if (Address < BASE_1MB) {
|
||||||
if ((TempQword & MTRR_LIB_CACHE_FIXED_MTRR_ENABLED) != 0) {
|
if (DefType.Bits.FE != 0) {
|
||||||
//
|
//
|
||||||
// Go through the fixed MTRR
|
// Go through the fixed MTRR
|
||||||
//
|
//
|
||||||
for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
|
for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
|
||||||
if (Address >= mMtrrLibFixedMtrrTable[Index].BaseAddress &&
|
if (Address >= mMtrrLibFixedMtrrTable[Index].BaseAddress &&
|
||||||
Address < (
|
Address < mMtrrLibFixedMtrrTable[Index].BaseAddress +
|
||||||
mMtrrLibFixedMtrrTable[Index].BaseAddress +
|
(mMtrrLibFixedMtrrTable[Index].Length * 8)) {
|
||||||
(mMtrrLibFixedMtrrTable[Index].Length * 8)
|
SubIndex =
|
||||||
)
|
((UINTN) Address - mMtrrLibFixedMtrrTable[Index].BaseAddress) /
|
||||||
) {
|
mMtrrLibFixedMtrrTable[Index].Length;
|
||||||
SubIndex =
|
if (MtrrSetting == NULL) {
|
||||||
((UINTN)Address - mMtrrLibFixedMtrrTable[Index].BaseAddress) /
|
FixedMtrr = AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr);
|
||||||
mMtrrLibFixedMtrrTable[Index].Length;
|
} else {
|
||||||
if (MtrrSetting == NULL) {
|
FixedMtrr = MtrrSetting->Fixed.Mtrr[Index];
|
||||||
TempQword = AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr);
|
}
|
||||||
} else {
|
return (MTRR_MEMORY_CACHE_TYPE) (RShiftU64 (FixedMtrr, SubIndex * 8) & 0xFF);
|
||||||
TempQword = MtrrSetting->Fixed.Mtrr[Index];
|
}
|
||||||
}
|
|
||||||
MtrrType = RShiftU64 (TempQword, SubIndex * 8) & 0xFF;
|
|
||||||
return GetMemoryCacheTypeFromMtrrType (MtrrSetting, MtrrType);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask);
|
|
||||||
|
|
||||||
MtrrGetVariableMtrrWorker (
|
VariableMtrrCount = GetVariableMtrrCountWorker ();
|
||||||
MtrrSetting,
|
ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);
|
||||||
GetVariableMtrrCountWorker (),
|
MtrrGetVariableMtrrWorker (MtrrSetting, VariableMtrrCount, &VariableSettings);
|
||||||
&VariableSettings
|
|
||||||
);
|
|
||||||
|
|
||||||
|
MtrrLibInitializeMtrrMask (&MtrrValidBitsMask, &MtrrValidAddressMask);
|
||||||
MtrrGetMemoryAttributeInVariableMtrrWorker (
|
MtrrGetMemoryAttributeInVariableMtrrWorker (
|
||||||
&VariableSettings,
|
&VariableSettings,
|
||||||
GetFirmwareVariableMtrrCountWorker (),
|
VariableMtrrCount,
|
||||||
MtrrValidBitsMask,
|
MtrrValidBitsMask,
|
||||||
MtrrValidAddressMask,
|
MtrrValidAddressMask,
|
||||||
VariableMtrr
|
VariableMtrr
|
||||||
);
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Go through the variable MTRR
|
// Go through the variable MTRR
|
||||||
//
|
//
|
||||||
VariableMtrrCount = GetVariableMtrrCountWorker ();
|
MtrrType = CacheInvalid;
|
||||||
ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);
|
|
||||||
|
|
||||||
for (Index = 0; Index < VariableMtrrCount; Index++) {
|
for (Index = 0; Index < VariableMtrrCount; Index++) {
|
||||||
if (VariableMtrr[Index].Valid) {
|
if (VariableMtrr[Index].Valid) {
|
||||||
if (Address >= VariableMtrr[Index].BaseAddress &&
|
if (Address >= VariableMtrr[Index].BaseAddress &&
|
||||||
Address < VariableMtrr[Index].BaseAddress+VariableMtrr[Index].Length) {
|
Address < VariableMtrr[Index].BaseAddress + VariableMtrr[Index].Length) {
|
||||||
TempMtrrType = VariableMtrr[Index].Type;
|
if (MtrrType == CacheInvalid) {
|
||||||
MtrrType = MtrrLibPrecedence (MtrrType, TempMtrrType);
|
MtrrType = (MTRR_MEMORY_CACHE_TYPE) VariableMtrr[Index].Type;
|
||||||
|
} else {
|
||||||
|
MtrrType = MtrrLibPrecedence (MtrrType, (MTRR_MEMORY_CACHE_TYPE) VariableMtrr[Index].Type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CacheType = GetMemoryCacheTypeFromMtrrType (MtrrSetting, MtrrType);
|
|
||||||
|
|
||||||
return CacheType;
|
//
|
||||||
|
// If there is no MTRR which covers the Address, use the default MTRR type.
|
||||||
|
//
|
||||||
|
if (MtrrType == CacheInvalid) {
|
||||||
|
MtrrType = (MTRR_MEMORY_CACHE_TYPE) DefType.Bits.Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MtrrType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue