diff options
author | Michael Kinney <michael.d.kinney@intel.com> | 2015-12-08 05:24:18 +0000 |
---|---|---|
committer | vanjeff <vanjeff@Edk2> | 2015-12-08 05:24:18 +0000 |
commit | b0fa5d29d08e61fd7f2178aa3b455e41374b36c4 (patch) | |
tree | f379413c6c84919e0ac62e71611ae6d533b5061f | |
parent | fa25cf38d988778ef3237e17fc93c1fa0c9e9f8a (diff) | |
download | edk2-b0fa5d29d08e61fd7f2178aa3b455e41374b36c4.tar.gz edk2-b0fa5d29d08e61fd7f2178aa3b455e41374b36c4.tar.bz2 edk2-b0fa5d29d08e61fd7f2178aa3b455e41374b36c4.zip |
UefiCpuPkg/MtrrLib: Reduce hardware init when program variable MTRRs
When MtrrSetMemoryAttribute() programs variable 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@19158 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r-- | UefiCpuPkg/Library/MtrrLib/MtrrLib.c | 98 |
1 files changed, 55 insertions, 43 deletions
diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c index 322f47b097..0e76e2f92a 100644 --- a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c +++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c @@ -883,30 +883,27 @@ GetMtrrNumberAndDirection ( This function programs MTRRs according to the values specified
in the shadow array.
+ @param[in, out] VariableSettings Variable MTRR settings
@param[in] VariableMtrrCount Number of variable MTRRs
@param[in, out] VariableMtrr Shadow of variable MTRR contents
**/
VOID
InvalidateMtrr (
+ IN OUT MTRR_VARIABLE_SETTINGS *VariableSettings,
IN UINTN VariableMtrrCount,
IN OUT VARIABLE_MTRR *VariableMtrr
)
{
UINTN Index;
- MTRR_CONTEXT MtrrContext;
- PreMtrrChange (&MtrrContext);
- Index = 0;
- while (Index < VariableMtrrCount) {
+ for (Index = 0; Index < VariableMtrrCount; Index++) {
if (!VariableMtrr[Index].Valid && VariableMtrr[Index].Used) {
- AsmWriteMsr64 (VariableMtrr[Index].Msr, 0);
- AsmWriteMsr64 (VariableMtrr[Index].Msr + 1, 0);
+ VariableSettings->Mtrr[Index].Base = 0;
+ VariableSettings->Mtrr[Index].Mask = 0;
VariableMtrr[Index].Used = FALSE;
}
- Index ++;
}
- PostMtrrChange (&MtrrContext);
}
@@ -915,6 +912,7 @@ InvalidateMtrr ( This function programs variable MTRRs
+ @param[in, out] VariableSettings Variable MTRR settings.
@param[in] MtrrNumber Index of MTRR to program.
@param[in] BaseAddress Base address of memory region.
@param[in] Length Length of memory region.
@@ -924,34 +922,27 @@ InvalidateMtrr ( **/
VOID
ProgramVariableMtrr (
- IN UINTN MtrrNumber,
- IN PHYSICAL_ADDRESS BaseAddress,
- IN UINT64 Length,
- IN UINT64 MemoryCacheType,
- IN UINT64 MtrrValidAddressMask
+ IN OUT MTRR_VARIABLE_SETTINGS *VariableSettings,
+ IN UINTN MtrrNumber,
+ IN PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 MemoryCacheType,
+ IN UINT64 MtrrValidAddressMask
)
{
UINT64 TempQword;
- MTRR_CONTEXT MtrrContext;
-
- PreMtrrChange (&MtrrContext);
//
// MTRR Physical Base
//
TempQword = (BaseAddress & MtrrValidAddressMask) | MemoryCacheType;
- AsmWriteMsr64 ((UINT32) MtrrNumber, TempQword);
+ VariableSettings->Mtrr[MtrrNumber].Base = TempQword;
//
// MTRR Physical Mask
//
TempQword = ~(Length - 1);
- AsmWriteMsr64 (
- (UINT32) (MtrrNumber + 1),
- (TempQword & MtrrValidAddressMask) | MTRR_LIB_CACHE_MTRR_ENABLED
- );
-
- PostMtrrChange (&MtrrContext);
+ VariableSettings->Mtrr[MtrrNumber].Mask = (TempQword & MtrrValidAddressMask) | MTRR_LIB_CACHE_MTRR_ENABLED;
}
@@ -1393,7 +1384,6 @@ MtrrSetMemoryAttribute ( UINT64 MtrrValidAddressMask;
BOOLEAN OverwriteExistingMtrr;
UINT32 FirmwareVariableMtrrCount;
- UINT32 VariableMtrrEnd;
MTRR_CONTEXT MtrrContext;
BOOLEAN MtrrContextValid;
BOOLEAN FixedSettingsValid[MTRR_NUMBER_OF_FIXED_MTRR];
@@ -1401,6 +1391,7 @@ MtrrSetMemoryAttribute ( MTRR_FIXED_SETTINGS WorkingFixedSettings;
UINT32 VariableMtrrCount;
MTRR_VARIABLE_SETTINGS OriginalVariableSettings;
+ BOOLEAN ProgramVariableSettings;
MTRR_VARIABLE_SETTINGS WorkingVariableSettings;
UINT32 Index;
UINT64 ClearMask;
@@ -1414,16 +1405,14 @@ MtrrSetMemoryAttribute ( FixedSettingsValid[Index] = FALSE;
FixedSettingsModified[Index] = FALSE;
}
+ ProgramVariableSettings = FALSE;
if (!IsMtrrSupported ()) {
Status = RETURN_UNSUPPORTED;
goto Done;
}
- FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCountWorker ();
- VariableMtrrEnd = MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (2 * GetVariableMtrrCount ()) - 1;
-
- MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask);
+ MtrrLibInitializeMtrrMask (&MtrrValidBitsMask, &MtrrValidAddressMask);
TempQword = 0;
MemoryType = (UINT64)Attribute;
@@ -1489,8 +1478,10 @@ MtrrSetMemoryAttribute ( // Read all variable MTRRs
//
VariableMtrrCount = GetVariableMtrrCountWorker ();
+ FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCountWorker ();
MtrrGetVariableMtrrWorker (VariableMtrrCount, &OriginalVariableSettings);
CopyMem (&WorkingVariableSettings, &OriginalVariableSettings, sizeof (WorkingVariableSettings));
+ ProgramVariableSettings = TRUE;
VariableSettings = &WorkingVariableSettings;
//
@@ -1509,7 +1500,6 @@ MtrrSetMemoryAttribute ( BaseAddress + Length - 1,
VariableMtrr
);
-
if (OverLap) {
Status = CombineMemoryAttribute (
FirmwareVariableMtrrCount,
@@ -1528,7 +1518,7 @@ MtrrSetMemoryAttribute ( //
// Combined successfully, invalidate the now-unused MTRRs
//
- InvalidateMtrr(VariableMtrrCount, VariableMtrr);
+ InvalidateMtrr (VariableSettings, VariableMtrrCount, VariableMtrr);
Status = RETURN_SUCCESS;
goto Done;
}
@@ -1542,7 +1532,7 @@ MtrrSetMemoryAttribute ( //
// Invalidate the now-unused MTRRs
//
- InvalidateMtrr(VariableMtrrCount, VariableMtrr);
+ InvalidateMtrr (VariableSettings, VariableMtrrCount, VariableMtrr);
goto Done;
}
@@ -1556,16 +1546,13 @@ MtrrSetMemoryAttribute ( //
// Invalidate the now-unused MTRRs
//
- InvalidateMtrr(VariableMtrrCount, VariableMtrr);
+ InvalidateMtrr (VariableSettings, VariableMtrrCount, VariableMtrr);
//
// Find first unused MTRR
//
- for (MsrNum = MTRR_LIB_IA32_VARIABLE_MTRR_BASE;
- MsrNum < VariableMtrrEnd;
- MsrNum += 2
- ) {
- if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
+ for (MsrNum = 0; MsrNum < VariableMtrrCount; MsrNum++) {
+ if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
break;
}
}
@@ -1584,13 +1571,14 @@ MtrrSetMemoryAttribute ( //
// Find unused MTRR
//
- for (; MsrNum < VariableMtrrEnd; MsrNum += 2) {
- if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
+ for (; MsrNum < VariableMtrrCount; MsrNum++) {
+ if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
break;
}
}
ProgramVariableMtrr (
+ VariableSettings,
MsrNum,
BaseAddress,
Alignment,
@@ -1614,13 +1602,14 @@ MtrrSetMemoryAttribute ( //
// Find unused MTRR
//
- for (; MsrNum < VariableMtrrEnd; MsrNum += 2) {
- if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
+ for (; MsrNum < VariableMtrrCount; MsrNum++) {
+ if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
break;
}
}
ProgramVariableMtrr (
+ VariableSettings,
MsrNum,
BaseAddress,
Length,
@@ -1636,8 +1625,8 @@ MtrrSetMemoryAttribute ( //
// Find unused MTRR
//
- for (; MsrNum < VariableMtrrEnd; MsrNum += 2) {
- if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
+ for (; MsrNum < VariableMtrrCount; MsrNum++) {
+ if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
break;
}
}
@@ -1648,6 +1637,7 @@ MtrrSetMemoryAttribute ( }
ProgramVariableMtrr (
+ VariableSettings,
MsrNum,
BaseAddress,
Length,
@@ -1680,6 +1670,28 @@ Done: }
}
+ //
+ // Write variable MTRRs
+ //
+ if (ProgramVariableSettings) {
+ for (Index = 0; Index < VariableMtrrCount; Index++) {
+ if (WorkingVariableSettings.Mtrr[Index].Base != OriginalVariableSettings.Mtrr[Index].Base ||
+ WorkingVariableSettings.Mtrr[Index].Mask != OriginalVariableSettings.Mtrr[Index].Mask ) {
+ if (!MtrrContextValid) {
+ PreMtrrChange (&MtrrContext);
+ MtrrContextValid = TRUE;
+ }
+ AsmWriteMsr64 (
+ MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1),
+ WorkingVariableSettings.Mtrr[Index].Base
+ );
+ AsmWriteMsr64 (
+ MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1) + 1,
+ WorkingVariableSettings.Mtrr[Index].Mask
+ );
+ }
+ }
+ }
if (MtrrContextValid) {
PostMtrrChange (&MtrrContext);
}
|