This function programs MTRRs according to the values specified\r
in the shadow array.\r
\r
+ @param[in, out] VariableSettings Variable MTRR settings\r
@param[in] VariableMtrrCount Number of variable MTRRs\r
@param[in, out] VariableMtrr Shadow of variable MTRR contents\r
\r
**/\r
VOID\r
InvalidateMtrr (\r
+ IN OUT MTRR_VARIABLE_SETTINGS *VariableSettings,\r
IN UINTN VariableMtrrCount,\r
IN OUT VARIABLE_MTRR *VariableMtrr\r
)\r
{\r
UINTN Index;\r
- MTRR_CONTEXT MtrrContext;\r
\r
- PreMtrrChange (&MtrrContext);\r
- Index = 0;\r
- while (Index < VariableMtrrCount) {\r
+ for (Index = 0; Index < VariableMtrrCount; Index++) {\r
if (!VariableMtrr[Index].Valid && VariableMtrr[Index].Used) {\r
- AsmWriteMsr64 (VariableMtrr[Index].Msr, 0);\r
- AsmWriteMsr64 (VariableMtrr[Index].Msr + 1, 0);\r
+ VariableSettings->Mtrr[Index].Base = 0;\r
+ VariableSettings->Mtrr[Index].Mask = 0;\r
VariableMtrr[Index].Used = FALSE;\r
}\r
- Index ++;\r
}\r
- PostMtrrChange (&MtrrContext);\r
}\r
\r
\r
\r
This function programs variable MTRRs\r
\r
+ @param[in, out] VariableSettings Variable MTRR settings.\r
@param[in] MtrrNumber Index of MTRR to program.\r
@param[in] BaseAddress Base address of memory region.\r
@param[in] Length Length of memory region.\r
**/\r
VOID\r
ProgramVariableMtrr (\r
- IN UINTN MtrrNumber,\r
- IN PHYSICAL_ADDRESS BaseAddress,\r
- IN UINT64 Length,\r
- IN UINT64 MemoryCacheType,\r
- IN UINT64 MtrrValidAddressMask\r
+ IN OUT MTRR_VARIABLE_SETTINGS *VariableSettings,\r
+ IN UINTN MtrrNumber,\r
+ IN PHYSICAL_ADDRESS BaseAddress,\r
+ IN UINT64 Length,\r
+ IN UINT64 MemoryCacheType,\r
+ IN UINT64 MtrrValidAddressMask\r
)\r
{\r
UINT64 TempQword;\r
- MTRR_CONTEXT MtrrContext;\r
-\r
- PreMtrrChange (&MtrrContext);\r
\r
//\r
// MTRR Physical Base\r
//\r
TempQword = (BaseAddress & MtrrValidAddressMask) | MemoryCacheType;\r
- AsmWriteMsr64 ((UINT32) MtrrNumber, TempQword);\r
+ VariableSettings->Mtrr[MtrrNumber].Base = TempQword;\r
\r
//\r
// MTRR Physical Mask\r
//\r
TempQword = ~(Length - 1);\r
- AsmWriteMsr64 (\r
- (UINT32) (MtrrNumber + 1),\r
- (TempQword & MtrrValidAddressMask) | MTRR_LIB_CACHE_MTRR_ENABLED\r
- );\r
-\r
- PostMtrrChange (&MtrrContext);\r
+ VariableSettings->Mtrr[MtrrNumber].Mask = (TempQword & MtrrValidAddressMask) | MTRR_LIB_CACHE_MTRR_ENABLED;\r
}\r
\r
\r
UINT64 MtrrValidAddressMask;\r
BOOLEAN OverwriteExistingMtrr;\r
UINT32 FirmwareVariableMtrrCount;\r
- UINT32 VariableMtrrEnd;\r
MTRR_CONTEXT MtrrContext;\r
BOOLEAN MtrrContextValid;\r
BOOLEAN FixedSettingsValid[MTRR_NUMBER_OF_FIXED_MTRR];\r
MTRR_FIXED_SETTINGS WorkingFixedSettings;\r
UINT32 VariableMtrrCount;\r
MTRR_VARIABLE_SETTINGS OriginalVariableSettings;\r
+ BOOLEAN ProgramVariableSettings;\r
MTRR_VARIABLE_SETTINGS WorkingVariableSettings;\r
UINT32 Index;\r
UINT64 ClearMask;\r
FixedSettingsValid[Index] = FALSE;\r
FixedSettingsModified[Index] = FALSE;\r
}\r
+ ProgramVariableSettings = FALSE;\r
\r
if (!IsMtrrSupported ()) {\r
Status = RETURN_UNSUPPORTED;\r
goto Done;\r
}\r
\r
- FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCountWorker ();\r
- VariableMtrrEnd = MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (2 * GetVariableMtrrCount ()) - 1;\r
-\r
- MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask);\r
+ MtrrLibInitializeMtrrMask (&MtrrValidBitsMask, &MtrrValidAddressMask);\r
\r
TempQword = 0;\r
MemoryType = (UINT64)Attribute;\r
// Read all variable MTRRs\r
//\r
VariableMtrrCount = GetVariableMtrrCountWorker ();\r
+ FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCountWorker ();\r
MtrrGetVariableMtrrWorker (VariableMtrrCount, &OriginalVariableSettings);\r
CopyMem (&WorkingVariableSettings, &OriginalVariableSettings, sizeof (WorkingVariableSettings));\r
+ ProgramVariableSettings = TRUE;\r
VariableSettings = &WorkingVariableSettings;\r
\r
//\r
BaseAddress + Length - 1,\r
VariableMtrr\r
);\r
-\r
if (OverLap) {\r
Status = CombineMemoryAttribute (\r
FirmwareVariableMtrrCount,\r
//\r
// Combined successfully, invalidate the now-unused MTRRs\r
//\r
- InvalidateMtrr(VariableMtrrCount, VariableMtrr);\r
+ InvalidateMtrr (VariableSettings, VariableMtrrCount, VariableMtrr);\r
Status = RETURN_SUCCESS;\r
goto Done;\r
}\r
//\r
// Invalidate the now-unused MTRRs\r
//\r
- InvalidateMtrr(VariableMtrrCount, VariableMtrr);\r
+ InvalidateMtrr (VariableSettings, VariableMtrrCount, VariableMtrr);\r
goto Done;\r
}\r
\r
//\r
// Invalidate the now-unused MTRRs\r
//\r
- InvalidateMtrr(VariableMtrrCount, VariableMtrr);\r
+ InvalidateMtrr (VariableSettings, VariableMtrrCount, VariableMtrr);\r
\r
//\r
// Find first unused MTRR\r
//\r
- for (MsrNum = MTRR_LIB_IA32_VARIABLE_MTRR_BASE;\r
- MsrNum < VariableMtrrEnd;\r
- MsrNum += 2\r
- ) {\r
- if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
+ for (MsrNum = 0; MsrNum < VariableMtrrCount; MsrNum++) {\r
+ if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
break;\r
}\r
}\r
//\r
// Find unused MTRR\r
//\r
- for (; MsrNum < VariableMtrrEnd; MsrNum += 2) {\r
- if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
+ for (; MsrNum < VariableMtrrCount; MsrNum++) {\r
+ if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
break;\r
}\r
}\r
\r
ProgramVariableMtrr (\r
+ VariableSettings,\r
MsrNum,\r
BaseAddress,\r
Alignment,\r
//\r
// Find unused MTRR\r
//\r
- for (; MsrNum < VariableMtrrEnd; MsrNum += 2) {\r
- if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
+ for (; MsrNum < VariableMtrrCount; MsrNum++) {\r
+ if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
break;\r
}\r
}\r
\r
ProgramVariableMtrr (\r
+ VariableSettings,\r
MsrNum,\r
BaseAddress,\r
Length,\r
//\r
// Find unused MTRR\r
//\r
- for (; MsrNum < VariableMtrrEnd; MsrNum += 2) {\r
- if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
+ for (; MsrNum < VariableMtrrCount; MsrNum++) {\r
+ if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
break;\r
}\r
}\r
}\r
\r
ProgramVariableMtrr (\r
+ VariableSettings,\r
MsrNum,\r
BaseAddress,\r
Length,\r
}\r
}\r
\r
+ //\r
+ // Write variable MTRRs\r
+ //\r
+ if (ProgramVariableSettings) {\r
+ for (Index = 0; Index < VariableMtrrCount; Index++) {\r
+ if (WorkingVariableSettings.Mtrr[Index].Base != OriginalVariableSettings.Mtrr[Index].Base ||\r
+ WorkingVariableSettings.Mtrr[Index].Mask != OriginalVariableSettings.Mtrr[Index].Mask ) {\r
+ if (!MtrrContextValid) {\r
+ PreMtrrChange (&MtrrContext);\r
+ MtrrContextValid = TRUE;\r
+ }\r
+ AsmWriteMsr64 (\r
+ MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1),\r
+ WorkingVariableSettings.Mtrr[Index].Base\r
+ );\r
+ AsmWriteMsr64 (\r
+ MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1) + 1,\r
+ WorkingVariableSettings.Mtrr[Index].Mask\r
+ );\r
+ }\r
+ }\r
+ }\r
if (MtrrContextValid) {\r
PostMtrrChange (&MtrrContext);\r
}\r