UefiCpuPkg/MtrrLib: Reduce hardware init when program fixed MTRRs
When MtrrSetMemoryAttribute() programs fixed MTRRs, it may disable/enable cache and disable/enable MTRRs several times. This updating tries to do operation in local variable and does the hardware initialization one time only. Cc: Feng Tian <feng.tian@intel.com> Cc: Michael Kinney <michael.d.kinney@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Michael Kinney <michael.d.kinney@intel.com> Signed-off-by: Jeff Fan <jeff.fan@intel.com> Reviewed-by: Feng Tian <feng.tian@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19157 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
d0baed7db5
commit
fa25cf38d9
@ -415,6 +415,9 @@ MtrrGetVariableMtrr (
|
|||||||
@param[in] MemoryCacheType The memory type to set.
|
@param[in] MemoryCacheType The memory type to set.
|
||||||
@param[in, out] Base The base address of memory range.
|
@param[in, out] Base The base address of memory range.
|
||||||
@param[in, out] Length The length of memory range.
|
@param[in, out] Length The length of memory range.
|
||||||
|
@param[out] ReturnMsrNum The index of the fixed MTRR MSR to program.
|
||||||
|
@param[out] ReturnClearMask The bits to clear in the fixed MTRR MSR.
|
||||||
|
@param[out] ReturnOrMask The bits to set in the fixed MTRR MSR.
|
||||||
|
|
||||||
@retval RETURN_SUCCESS The cache type was updated successfully
|
@retval RETURN_SUCCESS The cache type was updated successfully
|
||||||
@retval RETURN_UNSUPPORTED The requested range or cache type was invalid
|
@retval RETURN_UNSUPPORTED The requested range or cache type was invalid
|
||||||
@ -423,9 +426,12 @@ MtrrGetVariableMtrr (
|
|||||||
**/
|
**/
|
||||||
RETURN_STATUS
|
RETURN_STATUS
|
||||||
ProgramFixedMtrr (
|
ProgramFixedMtrr (
|
||||||
IN UINT64 MemoryCacheType,
|
IN UINT64 MemoryCacheType,
|
||||||
IN OUT UINT64 *Base,
|
IN OUT UINT64 *Base,
|
||||||
IN OUT UINT64 *Length
|
IN OUT UINT64 *Length,
|
||||||
|
OUT UINT32 *ReturnMsrNum,
|
||||||
|
OUT UINT64 *ReturnClearMask,
|
||||||
|
OUT UINT64 *ReturnOrMask
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINT32 MsrNum;
|
UINT32 MsrNum;
|
||||||
@ -488,9 +494,10 @@ ProgramFixedMtrr (
|
|||||||
return RETURN_UNSUPPORTED;
|
return RETURN_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
TempQword =
|
*ReturnMsrNum = MsrNum;
|
||||||
(AsmReadMsr64 (mMtrrLibFixedMtrrTable[MsrNum].Msr) & ~ClearMask) | OrMask;
|
*ReturnClearMask = ClearMask;
|
||||||
AsmWriteMsr64 (mMtrrLibFixedMtrrTable[MsrNum].Msr, TempQword);
|
*ReturnOrMask = OrMask;
|
||||||
|
|
||||||
return RETURN_SUCCESS;
|
return RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1388,12 +1395,25 @@ MtrrSetMemoryAttribute (
|
|||||||
UINT32 FirmwareVariableMtrrCount;
|
UINT32 FirmwareVariableMtrrCount;
|
||||||
UINT32 VariableMtrrEnd;
|
UINT32 VariableMtrrEnd;
|
||||||
MTRR_CONTEXT MtrrContext;
|
MTRR_CONTEXT MtrrContext;
|
||||||
|
BOOLEAN MtrrContextValid;
|
||||||
|
BOOLEAN FixedSettingsValid[MTRR_NUMBER_OF_FIXED_MTRR];
|
||||||
|
BOOLEAN FixedSettingsModified[MTRR_NUMBER_OF_FIXED_MTRR];
|
||||||
|
MTRR_FIXED_SETTINGS WorkingFixedSettings;
|
||||||
UINT32 VariableMtrrCount;
|
UINT32 VariableMtrrCount;
|
||||||
MTRR_VARIABLE_SETTINGS OriginalVariableSettings;
|
MTRR_VARIABLE_SETTINGS OriginalVariableSettings;
|
||||||
MTRR_VARIABLE_SETTINGS WorkingVariableSettings;
|
MTRR_VARIABLE_SETTINGS WorkingVariableSettings;
|
||||||
|
UINT32 Index;
|
||||||
|
UINT64 ClearMask;
|
||||||
|
UINT64 OrMask;
|
||||||
|
UINT64 NewValue;
|
||||||
MTRR_VARIABLE_SETTINGS *VariableSettings;
|
MTRR_VARIABLE_SETTINGS *VariableSettings;
|
||||||
|
|
||||||
DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttribute() %a:%016lx-%016lx\n", mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length));
|
DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttribute() %a:%016lx-%016lx\n", mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length));
|
||||||
|
MtrrContextValid = FALSE;
|
||||||
|
for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
|
||||||
|
FixedSettingsValid[Index] = FALSE;
|
||||||
|
FixedSettingsModified[Index] = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (!IsMtrrSupported ()) {
|
if (!IsMtrrSupported ()) {
|
||||||
Status = RETURN_UNSUPPORTED;
|
Status = RETURN_UNSUPPORTED;
|
||||||
@ -1429,24 +1449,33 @@ MtrrSetMemoryAttribute (
|
|||||||
// Check if Fixed MTRR
|
// Check if Fixed MTRR
|
||||||
//
|
//
|
||||||
Status = RETURN_SUCCESS;
|
Status = RETURN_SUCCESS;
|
||||||
while ((BaseAddress < BASE_1MB) && (Length > 0) && Status == RETURN_SUCCESS) {
|
if (BaseAddress < BASE_1MB) {
|
||||||
PreMtrrChange (&MtrrContext);
|
while ((BaseAddress < BASE_1MB) && (Length > 0) && Status == RETURN_SUCCESS) {
|
||||||
Status = ProgramFixedMtrr (MemoryType, &BaseAddress, &Length);
|
Status = ProgramFixedMtrr (MemoryType, &BaseAddress, &Length, &MsrNum, &ClearMask, &OrMask);
|
||||||
PostMtrrChange (&MtrrContext);
|
if (RETURN_ERROR (Status)) {
|
||||||
if (RETURN_ERROR (Status)) {
|
goto Done;
|
||||||
|
}
|
||||||
|
if (!FixedSettingsValid[MsrNum]) {
|
||||||
|
WorkingFixedSettings.Mtrr[MsrNum] = AsmReadMsr64 (mMtrrLibFixedMtrrTable[MsrNum].Msr);
|
||||||
|
FixedSettingsValid[MsrNum] = TRUE;
|
||||||
|
}
|
||||||
|
NewValue = (WorkingFixedSettings.Mtrr[MsrNum] & ~ClearMask) | OrMask;
|
||||||
|
if (WorkingFixedSettings.Mtrr[MsrNum] != NewValue) {
|
||||||
|
WorkingFixedSettings.Mtrr[MsrNum] = NewValue;
|
||||||
|
FixedSettingsModified[MsrNum] = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Length == 0) {
|
||||||
|
//
|
||||||
|
// A Length of 0 can only make sense for fixed MTTR ranges.
|
||||||
|
// Since we just handled the fixed MTRRs, we can skip the
|
||||||
|
// variable MTRR section.
|
||||||
|
//
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Length == 0) {
|
|
||||||
//
|
|
||||||
// A Length of 0 can only make sense for fixed MTTR ranges.
|
|
||||||
// Since we just handled the fixed MTRRs, we can skip the
|
|
||||||
// variable MTRR section.
|
|
||||||
//
|
|
||||||
goto Done;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Since memory ranges below 1MB will be overridden by the fixed MTRRs,
|
// Since memory ranges below 1MB will be overridden by the fixed MTRRs,
|
||||||
// we can set the base to 0 to save variable MTRRs.
|
// we can set the base to 0 to save variable MTRRs.
|
||||||
@ -1634,6 +1663,27 @@ MtrrSetMemoryAttribute (
|
|||||||
} while (TempQword > 0);
|
} while (TempQword > 0);
|
||||||
|
|
||||||
Done:
|
Done:
|
||||||
|
|
||||||
|
//
|
||||||
|
// Write fixed MTRRs that have been modified
|
||||||
|
//
|
||||||
|
for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
|
||||||
|
if (FixedSettingsModified[Index]) {
|
||||||
|
if (!MtrrContextValid) {
|
||||||
|
PreMtrrChange (&MtrrContext);
|
||||||
|
MtrrContextValid = TRUE;
|
||||||
|
}
|
||||||
|
AsmWriteMsr64 (
|
||||||
|
mMtrrLibFixedMtrrTable[Index].Msr,
|
||||||
|
WorkingFixedSettings.Mtrr[Index]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MtrrContextValid) {
|
||||||
|
PostMtrrChange (&MtrrContext);
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG((DEBUG_CACHE, " Status = %r\n", Status));
|
DEBUG((DEBUG_CACHE, " Status = %r\n", Status));
|
||||||
if (!RETURN_ERROR (Status)) {
|
if (!RETURN_ERROR (Status)) {
|
||||||
MtrrDebugPrintAllMtrrs ();
|
MtrrDebugPrintAllMtrrs ();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user