summaryrefslogtreecommitdiff
path: root/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
diff options
context:
space:
mode:
authorMichael Kinney <michael.d.kinney@intel.com>2015-12-08 05:23:44 +0000
committervanjeff <vanjeff@Edk2>2015-12-08 05:23:44 +0000
commitfa25cf38d988778ef3237e17fc93c1fa0c9e9f8a (patch)
treefe0e47cd5906369617ad314f37be74d632b4d545 /UefiCpuPkg/Library/MtrrLib/MtrrLib.c
parentd0baed7db51382d17efe92b1fc8fb741052f116a (diff)
downloadedk2-platforms-fa25cf38d988778ef3237e17fc93c1fa0c9e9f8a.tar.xz
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
Diffstat (limited to 'UefiCpuPkg/Library/MtrrLib/MtrrLib.c')
-rw-r--r--UefiCpuPkg/Library/MtrrLib/MtrrLib.c90
1 files changed, 70 insertions, 20 deletions
diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
index 697dc4352f..322f47b097 100644
--- a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
+++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
@@ -415,6 +415,9 @@ MtrrGetVariableMtrr (
@param[in] MemoryCacheType The memory type to set.
@param[in, out] Base The base address 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_UNSUPPORTED The requested range or cache type was invalid
@@ -423,9 +426,12 @@ MtrrGetVariableMtrr (
**/
RETURN_STATUS
ProgramFixedMtrr (
- IN UINT64 MemoryCacheType,
- IN OUT UINT64 *Base,
- IN OUT UINT64 *Length
+ IN UINT64 MemoryCacheType,
+ IN OUT UINT64 *Base,
+ IN OUT UINT64 *Length,
+ OUT UINT32 *ReturnMsrNum,
+ OUT UINT64 *ReturnClearMask,
+ OUT UINT64 *ReturnOrMask
)
{
UINT32 MsrNum;
@@ -488,9 +494,10 @@ ProgramFixedMtrr (
return RETURN_UNSUPPORTED;
}
- TempQword =
- (AsmReadMsr64 (mMtrrLibFixedMtrrTable[MsrNum].Msr) & ~ClearMask) | OrMask;
- AsmWriteMsr64 (mMtrrLibFixedMtrrTable[MsrNum].Msr, TempQword);
+ *ReturnMsrNum = MsrNum;
+ *ReturnClearMask = ClearMask;
+ *ReturnOrMask = OrMask;
+
return RETURN_SUCCESS;
}
@@ -1388,12 +1395,25 @@ MtrrSetMemoryAttribute (
UINT32 FirmwareVariableMtrrCount;
UINT32 VariableMtrrEnd;
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;
MTRR_VARIABLE_SETTINGS OriginalVariableSettings;
MTRR_VARIABLE_SETTINGS WorkingVariableSettings;
+ UINT32 Index;
+ UINT64 ClearMask;
+ UINT64 OrMask;
+ UINT64 NewValue;
MTRR_VARIABLE_SETTINGS *VariableSettings;
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 ()) {
Status = RETURN_UNSUPPORTED;
@@ -1429,22 +1449,31 @@ MtrrSetMemoryAttribute (
// Check if Fixed MTRR
//
Status = RETURN_SUCCESS;
- while ((BaseAddress < BASE_1MB) && (Length > 0) && Status == RETURN_SUCCESS) {
- PreMtrrChange (&MtrrContext);
- Status = ProgramFixedMtrr (MemoryType, &BaseAddress, &Length);
- PostMtrrChange (&MtrrContext);
- if (RETURN_ERROR (Status)) {
- goto Done;
+ if (BaseAddress < BASE_1MB) {
+ while ((BaseAddress < BASE_1MB) && (Length > 0) && Status == RETURN_SUCCESS) {
+ Status = ProgramFixedMtrr (MemoryType, &BaseAddress, &Length, &MsrNum, &ClearMask, &OrMask);
+ 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;
+ 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;
+ }
}
//
@@ -1634,6 +1663,27 @@ MtrrSetMemoryAttribute (
} while (TempQword > 0);
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));
if (!RETURN_ERROR (Status)) {
MtrrDebugPrintAllMtrrs ();