mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-24 06:04:52 +02:00
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
This commit is contained in:
parent
fa25cf38d9
commit
b0fa5d29d0
@ -883,30 +883,27 @@ GetMtrrNumberAndDirection (
|
|||||||
This function programs MTRRs according to the values specified
|
This function programs MTRRs according to the values specified
|
||||||
in the shadow array.
|
in the shadow array.
|
||||||
|
|
||||||
|
@param[in, out] VariableSettings Variable MTRR settings
|
||||||
@param[in] VariableMtrrCount Number of variable MTRRs
|
@param[in] VariableMtrrCount Number of variable MTRRs
|
||||||
@param[in, out] VariableMtrr Shadow of variable MTRR contents
|
@param[in, out] VariableMtrr Shadow of variable MTRR contents
|
||||||
|
|
||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
InvalidateMtrr (
|
InvalidateMtrr (
|
||||||
|
IN OUT MTRR_VARIABLE_SETTINGS *VariableSettings,
|
||||||
IN UINTN VariableMtrrCount,
|
IN UINTN VariableMtrrCount,
|
||||||
IN OUT VARIABLE_MTRR *VariableMtrr
|
IN OUT VARIABLE_MTRR *VariableMtrr
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINTN Index;
|
UINTN Index;
|
||||||
MTRR_CONTEXT MtrrContext;
|
|
||||||
|
|
||||||
PreMtrrChange (&MtrrContext);
|
for (Index = 0; Index < VariableMtrrCount; Index++) {
|
||||||
Index = 0;
|
|
||||||
while (Index < VariableMtrrCount) {
|
|
||||||
if (!VariableMtrr[Index].Valid && VariableMtrr[Index].Used) {
|
if (!VariableMtrr[Index].Valid && VariableMtrr[Index].Used) {
|
||||||
AsmWriteMsr64 (VariableMtrr[Index].Msr, 0);
|
VariableSettings->Mtrr[Index].Base = 0;
|
||||||
AsmWriteMsr64 (VariableMtrr[Index].Msr + 1, 0);
|
VariableSettings->Mtrr[Index].Mask = 0;
|
||||||
VariableMtrr[Index].Used = FALSE;
|
VariableMtrr[Index].Used = FALSE;
|
||||||
}
|
}
|
||||||
Index ++;
|
|
||||||
}
|
}
|
||||||
PostMtrrChange (&MtrrContext);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -915,6 +912,7 @@ InvalidateMtrr (
|
|||||||
|
|
||||||
This function programs variable MTRRs
|
This function programs variable MTRRs
|
||||||
|
|
||||||
|
@param[in, out] VariableSettings Variable MTRR settings.
|
||||||
@param[in] MtrrNumber Index of MTRR to program.
|
@param[in] MtrrNumber Index of MTRR to program.
|
||||||
@param[in] BaseAddress Base address of memory region.
|
@param[in] BaseAddress Base address of memory region.
|
||||||
@param[in] Length Length of memory region.
|
@param[in] Length Length of memory region.
|
||||||
@ -924,34 +922,27 @@ InvalidateMtrr (
|
|||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
ProgramVariableMtrr (
|
ProgramVariableMtrr (
|
||||||
IN UINTN MtrrNumber,
|
IN OUT MTRR_VARIABLE_SETTINGS *VariableSettings,
|
||||||
IN PHYSICAL_ADDRESS BaseAddress,
|
IN UINTN MtrrNumber,
|
||||||
IN UINT64 Length,
|
IN PHYSICAL_ADDRESS BaseAddress,
|
||||||
IN UINT64 MemoryCacheType,
|
IN UINT64 Length,
|
||||||
IN UINT64 MtrrValidAddressMask
|
IN UINT64 MemoryCacheType,
|
||||||
|
IN UINT64 MtrrValidAddressMask
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINT64 TempQword;
|
UINT64 TempQword;
|
||||||
MTRR_CONTEXT MtrrContext;
|
|
||||||
|
|
||||||
PreMtrrChange (&MtrrContext);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// MTRR Physical Base
|
// MTRR Physical Base
|
||||||
//
|
//
|
||||||
TempQword = (BaseAddress & MtrrValidAddressMask) | MemoryCacheType;
|
TempQword = (BaseAddress & MtrrValidAddressMask) | MemoryCacheType;
|
||||||
AsmWriteMsr64 ((UINT32) MtrrNumber, TempQword);
|
VariableSettings->Mtrr[MtrrNumber].Base = TempQword;
|
||||||
|
|
||||||
//
|
//
|
||||||
// MTRR Physical Mask
|
// MTRR Physical Mask
|
||||||
//
|
//
|
||||||
TempQword = ~(Length - 1);
|
TempQword = ~(Length - 1);
|
||||||
AsmWriteMsr64 (
|
VariableSettings->Mtrr[MtrrNumber].Mask = (TempQword & MtrrValidAddressMask) | MTRR_LIB_CACHE_MTRR_ENABLED;
|
||||||
(UINT32) (MtrrNumber + 1),
|
|
||||||
(TempQword & MtrrValidAddressMask) | MTRR_LIB_CACHE_MTRR_ENABLED
|
|
||||||
);
|
|
||||||
|
|
||||||
PostMtrrChange (&MtrrContext);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1393,7 +1384,6 @@ MtrrSetMemoryAttribute (
|
|||||||
UINT64 MtrrValidAddressMask;
|
UINT64 MtrrValidAddressMask;
|
||||||
BOOLEAN OverwriteExistingMtrr;
|
BOOLEAN OverwriteExistingMtrr;
|
||||||
UINT32 FirmwareVariableMtrrCount;
|
UINT32 FirmwareVariableMtrrCount;
|
||||||
UINT32 VariableMtrrEnd;
|
|
||||||
MTRR_CONTEXT MtrrContext;
|
MTRR_CONTEXT MtrrContext;
|
||||||
BOOLEAN MtrrContextValid;
|
BOOLEAN MtrrContextValid;
|
||||||
BOOLEAN FixedSettingsValid[MTRR_NUMBER_OF_FIXED_MTRR];
|
BOOLEAN FixedSettingsValid[MTRR_NUMBER_OF_FIXED_MTRR];
|
||||||
@ -1401,6 +1391,7 @@ MtrrSetMemoryAttribute (
|
|||||||
MTRR_FIXED_SETTINGS WorkingFixedSettings;
|
MTRR_FIXED_SETTINGS WorkingFixedSettings;
|
||||||
UINT32 VariableMtrrCount;
|
UINT32 VariableMtrrCount;
|
||||||
MTRR_VARIABLE_SETTINGS OriginalVariableSettings;
|
MTRR_VARIABLE_SETTINGS OriginalVariableSettings;
|
||||||
|
BOOLEAN ProgramVariableSettings;
|
||||||
MTRR_VARIABLE_SETTINGS WorkingVariableSettings;
|
MTRR_VARIABLE_SETTINGS WorkingVariableSettings;
|
||||||
UINT32 Index;
|
UINT32 Index;
|
||||||
UINT64 ClearMask;
|
UINT64 ClearMask;
|
||||||
@ -1414,16 +1405,14 @@ MtrrSetMemoryAttribute (
|
|||||||
FixedSettingsValid[Index] = FALSE;
|
FixedSettingsValid[Index] = FALSE;
|
||||||
FixedSettingsModified[Index] = FALSE;
|
FixedSettingsModified[Index] = FALSE;
|
||||||
}
|
}
|
||||||
|
ProgramVariableSettings = FALSE;
|
||||||
|
|
||||||
if (!IsMtrrSupported ()) {
|
if (!IsMtrrSupported ()) {
|
||||||
Status = RETURN_UNSUPPORTED;
|
Status = RETURN_UNSUPPORTED;
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
|
|
||||||
FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCountWorker ();
|
MtrrLibInitializeMtrrMask (&MtrrValidBitsMask, &MtrrValidAddressMask);
|
||||||
VariableMtrrEnd = MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (2 * GetVariableMtrrCount ()) - 1;
|
|
||||||
|
|
||||||
MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask);
|
|
||||||
|
|
||||||
TempQword = 0;
|
TempQword = 0;
|
||||||
MemoryType = (UINT64)Attribute;
|
MemoryType = (UINT64)Attribute;
|
||||||
@ -1489,8 +1478,10 @@ MtrrSetMemoryAttribute (
|
|||||||
// Read all variable MTRRs
|
// Read all variable MTRRs
|
||||||
//
|
//
|
||||||
VariableMtrrCount = GetVariableMtrrCountWorker ();
|
VariableMtrrCount = GetVariableMtrrCountWorker ();
|
||||||
|
FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCountWorker ();
|
||||||
MtrrGetVariableMtrrWorker (VariableMtrrCount, &OriginalVariableSettings);
|
MtrrGetVariableMtrrWorker (VariableMtrrCount, &OriginalVariableSettings);
|
||||||
CopyMem (&WorkingVariableSettings, &OriginalVariableSettings, sizeof (WorkingVariableSettings));
|
CopyMem (&WorkingVariableSettings, &OriginalVariableSettings, sizeof (WorkingVariableSettings));
|
||||||
|
ProgramVariableSettings = TRUE;
|
||||||
VariableSettings = &WorkingVariableSettings;
|
VariableSettings = &WorkingVariableSettings;
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -1509,7 +1500,6 @@ MtrrSetMemoryAttribute (
|
|||||||
BaseAddress + Length - 1,
|
BaseAddress + Length - 1,
|
||||||
VariableMtrr
|
VariableMtrr
|
||||||
);
|
);
|
||||||
|
|
||||||
if (OverLap) {
|
if (OverLap) {
|
||||||
Status = CombineMemoryAttribute (
|
Status = CombineMemoryAttribute (
|
||||||
FirmwareVariableMtrrCount,
|
FirmwareVariableMtrrCount,
|
||||||
@ -1528,7 +1518,7 @@ MtrrSetMemoryAttribute (
|
|||||||
//
|
//
|
||||||
// Combined successfully, invalidate the now-unused MTRRs
|
// Combined successfully, invalidate the now-unused MTRRs
|
||||||
//
|
//
|
||||||
InvalidateMtrr(VariableMtrrCount, VariableMtrr);
|
InvalidateMtrr (VariableSettings, VariableMtrrCount, VariableMtrr);
|
||||||
Status = RETURN_SUCCESS;
|
Status = RETURN_SUCCESS;
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
@ -1542,7 +1532,7 @@ MtrrSetMemoryAttribute (
|
|||||||
//
|
//
|
||||||
// Invalidate the now-unused MTRRs
|
// Invalidate the now-unused MTRRs
|
||||||
//
|
//
|
||||||
InvalidateMtrr(VariableMtrrCount, VariableMtrr);
|
InvalidateMtrr (VariableSettings, VariableMtrrCount, VariableMtrr);
|
||||||
goto Done;
|
goto Done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1556,16 +1546,13 @@ MtrrSetMemoryAttribute (
|
|||||||
//
|
//
|
||||||
// Invalidate the now-unused MTRRs
|
// Invalidate the now-unused MTRRs
|
||||||
//
|
//
|
||||||
InvalidateMtrr(VariableMtrrCount, VariableMtrr);
|
InvalidateMtrr (VariableSettings, VariableMtrrCount, VariableMtrr);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Find first unused MTRR
|
// Find first unused MTRR
|
||||||
//
|
//
|
||||||
for (MsrNum = MTRR_LIB_IA32_VARIABLE_MTRR_BASE;
|
for (MsrNum = 0; MsrNum < VariableMtrrCount; MsrNum++) {
|
||||||
MsrNum < VariableMtrrEnd;
|
if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
|
||||||
MsrNum += 2
|
|
||||||
) {
|
|
||||||
if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1584,13 +1571,14 @@ MtrrSetMemoryAttribute (
|
|||||||
//
|
//
|
||||||
// Find unused MTRR
|
// Find unused MTRR
|
||||||
//
|
//
|
||||||
for (; MsrNum < VariableMtrrEnd; MsrNum += 2) {
|
for (; MsrNum < VariableMtrrCount; MsrNum++) {
|
||||||
if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
|
if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProgramVariableMtrr (
|
ProgramVariableMtrr (
|
||||||
|
VariableSettings,
|
||||||
MsrNum,
|
MsrNum,
|
||||||
BaseAddress,
|
BaseAddress,
|
||||||
Alignment,
|
Alignment,
|
||||||
@ -1614,13 +1602,14 @@ MtrrSetMemoryAttribute (
|
|||||||
//
|
//
|
||||||
// Find unused MTRR
|
// Find unused MTRR
|
||||||
//
|
//
|
||||||
for (; MsrNum < VariableMtrrEnd; MsrNum += 2) {
|
for (; MsrNum < VariableMtrrCount; MsrNum++) {
|
||||||
if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
|
if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProgramVariableMtrr (
|
ProgramVariableMtrr (
|
||||||
|
VariableSettings,
|
||||||
MsrNum,
|
MsrNum,
|
||||||
BaseAddress,
|
BaseAddress,
|
||||||
Length,
|
Length,
|
||||||
@ -1636,8 +1625,8 @@ MtrrSetMemoryAttribute (
|
|||||||
//
|
//
|
||||||
// Find unused MTRR
|
// Find unused MTRR
|
||||||
//
|
//
|
||||||
for (; MsrNum < VariableMtrrEnd; MsrNum += 2) {
|
for (; MsrNum < VariableMtrrCount; MsrNum++) {
|
||||||
if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
|
if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1648,6 +1637,7 @@ MtrrSetMemoryAttribute (
|
|||||||
}
|
}
|
||||||
|
|
||||||
ProgramVariableMtrr (
|
ProgramVariableMtrr (
|
||||||
|
VariableSettings,
|
||||||
MsrNum,
|
MsrNum,
|
||||||
BaseAddress,
|
BaseAddress,
|
||||||
Length,
|
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) {
|
if (MtrrContextValid) {
|
||||||
PostMtrrChange (&MtrrContext);
|
PostMtrrChange (&MtrrContext);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user