**/\r
MTRR_VARIABLE_SETTINGS*\r
MtrrGetVariableMtrrWorker (\r
+ IN UINT32 VariableMtrrCount,\r
OUT MTRR_VARIABLE_SETTINGS *VariableSettings\r
)\r
{\r
UINT32 Index;\r
- UINT32 VariableMtrrCount;\r
\r
- VariableMtrrCount = GetVariableMtrrCount ();\r
ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);\r
\r
for (Index = 0; Index < VariableMtrrCount; Index++) {\r
}\r
\r
return MtrrGetVariableMtrrWorker (\r
+ GetVariableMtrrCountWorker (),\r
VariableSettings\r
);\r
}\r
}\r
\r
\r
+/**\r
+ Worker function gets the attribute of variable MTRRs.\r
+\r
+ This function shadows the content of variable MTRRs into an\r
+ internal array: VariableMtrr.\r
+\r
+ @param[in] VariableSettings The variable MTRR values to shadow\r
+ @param[in] FirmwareVariableMtrrCount The number of variable MTRRs available to firmware\r
+ @param[in] MtrrValidBitsMask The mask for the valid bit of the MTRR\r
+ @param[in] MtrrValidAddressMask The valid address mask for MTRR\r
+ @param[out] VariableMtrr The array to shadow variable MTRRs content\r
+\r
+ @return The return value of this parameter indicates the\r
+ number of MTRRs which has been used.\r
+\r
+**/\r
+UINT32\r
+MtrrGetMemoryAttributeInVariableMtrrWorker (\r
+ IN MTRR_VARIABLE_SETTINGS *VariableSettings,\r
+ IN UINTN FirmwareVariableMtrrCount,\r
+ IN UINT64 MtrrValidBitsMask,\r
+ IN UINT64 MtrrValidAddressMask,\r
+ OUT VARIABLE_MTRR *VariableMtrr\r
+ )\r
+{\r
+ UINTN Index;\r
+ UINT32 UsedMtrr;\r
+\r
+ ZeroMem (VariableMtrr, sizeof (VARIABLE_MTRR) * MTRR_NUMBER_OF_VARIABLE_MTRR);\r
+ for (Index = 0, UsedMtrr = 0; Index < FirmwareVariableMtrrCount; Index++) {\r
+ if ((VariableSettings->Mtrr[Index].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) != 0) {\r
+ VariableMtrr[Index].Msr = (UINT32)Index;\r
+ VariableMtrr[Index].BaseAddress = (VariableSettings->Mtrr[Index].Base & MtrrValidAddressMask);\r
+ VariableMtrr[Index].Length = ((~(VariableSettings->Mtrr[Index].Mask & MtrrValidAddressMask)) & MtrrValidBitsMask) + 1;\r
+ VariableMtrr[Index].Type = (VariableSettings->Mtrr[Index].Base & 0x0ff);\r
+ VariableMtrr[Index].Valid = TRUE;\r
+ VariableMtrr[Index].Used = TRUE;\r
+ UsedMtrr++;\r
+ }\r
+ }\r
+ return UsedMtrr;\r
+}\r
+\r
+\r
/**\r
Gets the attribute of variable MTRRs.\r
\r
OUT VARIABLE_MTRR *VariableMtrr\r
)\r
{\r
- UINTN Index;\r
- UINT32 MsrNum;\r
- UINT32 UsedMtrr;\r
- UINT32 FirmwareVariableMtrrCount;\r
- UINT32 VariableMtrrEnd;\r
+ MTRR_VARIABLE_SETTINGS VariableSettings;\r
\r
if (!IsMtrrSupported ()) {\r
return 0;\r
}\r
\r
- FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCount ();\r
- VariableMtrrEnd = MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (2 * GetVariableMtrrCount ()) - 1;\r
-\r
- ZeroMem (VariableMtrr, sizeof (VARIABLE_MTRR) * MTRR_NUMBER_OF_VARIABLE_MTRR);\r
- UsedMtrr = 0;\r
+ MtrrGetVariableMtrrWorker (\r
+ GetVariableMtrrCountWorker (),\r
+ &VariableSettings\r
+ );\r
\r
- for (MsrNum = MTRR_LIB_IA32_VARIABLE_MTRR_BASE, Index = 0;\r
- (\r
- (MsrNum < VariableMtrrEnd) &&\r
- (Index < FirmwareVariableMtrrCount)\r
- );\r
- MsrNum += 2\r
- ) {\r
- if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) != 0) {\r
- VariableMtrr[Index].Msr = MsrNum;\r
- VariableMtrr[Index].BaseAddress = (AsmReadMsr64 (MsrNum) &\r
- MtrrValidAddressMask);\r
- VariableMtrr[Index].Length = ((~(AsmReadMsr64 (MsrNum + 1) &\r
- MtrrValidAddressMask)\r
- ) &\r
- MtrrValidBitsMask\r
- ) + 1;\r
- VariableMtrr[Index].Type = (AsmReadMsr64 (MsrNum) & 0x0ff);\r
- VariableMtrr[Index].Valid = TRUE;\r
- VariableMtrr[Index].Used = TRUE;\r
- UsedMtrr = UsedMtrr + 1;\r
- Index++;\r
- }\r
- }\r
- return UsedMtrr;\r
+ return MtrrGetMemoryAttributeInVariableMtrrWorker (\r
+ &VariableSettings,\r
+ GetFirmwareVariableMtrrCountWorker (),\r
+ MtrrValidBitsMask,\r
+ MtrrValidAddressMask,\r
+ VariableMtrr\r
+ );\r
}\r
\r
\r
/**\r
Checks overlap between given memory range and MTRRs.\r
\r
+ @param[in] FirmwareVariableMtrrCount The number of variable MTRRs available\r
+ to firmware.\r
@param[in] Start The start address of memory range.\r
@param[in] End The end address of memory range.\r
@param[in] VariableMtrr The array to shadow variable MTRRs content\r
**/\r
BOOLEAN\r
CheckMemoryAttributeOverlap (\r
- IN PHYSICAL_ADDRESS Start,\r
- IN PHYSICAL_ADDRESS End,\r
- IN VARIABLE_MTRR *VariableMtrr\r
+ IN UINTN FirmwareVariableMtrrCount,\r
+ IN PHYSICAL_ADDRESS Start,\r
+ IN PHYSICAL_ADDRESS End,\r
+ IN VARIABLE_MTRR *VariableMtrr\r
)\r
{\r
UINT32 Index;\r
\r
- for (Index = 0; Index < 6; Index++) {\r
+ for (Index = 0; Index < FirmwareVariableMtrrCount; Index++) {\r
if (\r
VariableMtrr[Index].Valid &&\r
!(\r
\r
If overlap exists between given memory range and MTRRs, try to combine them.\r
\r
+ @param[in] FirmwareVariableMtrrCount The number of variable MTRRs\r
+ available to firmware.\r
@param[in] Attributes The memory type to set.\r
@param[in, out] Base The base address of memory range.\r
@param[in, out] Length The length of memory range.\r
**/\r
RETURN_STATUS\r
CombineMemoryAttribute (\r
+ IN UINT32 FirmwareVariableMtrrCount,\r
IN UINT64 Attributes,\r
IN OUT UINT64 *Base,\r
IN OUT UINT64 *Length,\r
UINT64 CombineEnd;\r
UINT64 MtrrEnd;\r
UINT64 EndAddress;\r
- UINT32 FirmwareVariableMtrrCount;\r
BOOLEAN CoveredByExistingMtrr;\r
\r
- FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCount ();\r
-\r
*OverwriteExistingMtrr = FALSE;\r
CoveredByExistingMtrr = FALSE;\r
EndAddress = *Base +*Length - 1;\r
This function programs MTRRs according to the values specified\r
in the shadow array.\r
\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 UINTN VariableMtrrCount,\r
IN OUT VARIABLE_MTRR *VariableMtrr\r
)\r
{\r
UINTN Index;\r
- UINTN VariableMtrrCount;\r
MTRR_CONTEXT MtrrContext;\r
\r
PreMtrrChange (&MtrrContext);\r
Index = 0;\r
- VariableMtrrCount = GetVariableMtrrCount ();\r
while (Index < VariableMtrrCount) {\r
if (!VariableMtrr[Index].Valid && VariableMtrr[Index].Used) {\r
AsmWriteMsr64 (VariableMtrr[Index].Msr, 0);\r
UINT64 MtrrValidBitsMask;\r
UINT64 MtrrValidAddressMask;\r
UINTN VariableMtrrCount;\r
+ MTRR_VARIABLE_SETTINGS VariableSettings;\r
\r
if (!IsMtrrSupported ()) {\r
return CacheUncacheable;\r
}\r
}\r
MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask);\r
- MtrrGetMemoryAttributeInVariableMtrr(\r
- MtrrValidBitsMask,\r
- MtrrValidAddressMask,\r
- VariableMtrr\r
+\r
+ MtrrGetVariableMtrrWorker (\r
+ GetVariableMtrrCountWorker (),\r
+ &VariableSettings\r
);\r
\r
+ MtrrGetMemoryAttributeInVariableMtrrWorker (\r
+ &VariableSettings,\r
+ GetFirmwareVariableMtrrCountWorker (),\r
+ MtrrValidBitsMask,\r
+ MtrrValidAddressMask,\r
+ VariableMtrr\r
+ );\r
+\r
//\r
// Go through the variable MTRR\r
//\r
- VariableMtrrCount = GetVariableMtrrCount ();\r
+ VariableMtrrCount = GetVariableMtrrCountWorker ();\r
ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);\r
\r
for (Index = 0; Index < VariableMtrrCount; Index++) {\r
UINT32 FirmwareVariableMtrrCount;\r
UINT32 VariableMtrrEnd;\r
MTRR_CONTEXT MtrrContext;\r
+ UINT32 VariableMtrrCount;\r
+ MTRR_VARIABLE_SETTINGS OriginalVariableSettings;\r
+ MTRR_VARIABLE_SETTINGS WorkingVariableSettings;\r
+ MTRR_VARIABLE_SETTINGS *VariableSettings;\r
\r
DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttribute() %a:%016lx-%016lx\n", mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length));\r
\r
goto Done;\r
}\r
\r
- FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCount ();\r
+ FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCountWorker ();\r
VariableMtrrEnd = MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (2 * GetVariableMtrrCount ()) - 1;\r
\r
MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask);\r
Length += SIZE_1MB;\r
}\r
\r
+ //\r
+ // Read all variable MTRRs\r
+ //\r
+ VariableMtrrCount = GetVariableMtrrCountWorker ();\r
+ MtrrGetVariableMtrrWorker (VariableMtrrCount, &OriginalVariableSettings);\r
+ CopyMem (&WorkingVariableSettings, &OriginalVariableSettings, sizeof (WorkingVariableSettings));\r
+ VariableSettings = &WorkingVariableSettings;\r
+\r
//\r
// Check for overlap\r
//\r
- UsedMtrr = MtrrGetMemoryAttributeInVariableMtrr (MtrrValidBitsMask, MtrrValidAddressMask, VariableMtrr);\r
- OverLap = CheckMemoryAttributeOverlap (BaseAddress, BaseAddress + Length - 1, VariableMtrr);\r
+ UsedMtrr = MtrrGetMemoryAttributeInVariableMtrrWorker (\r
+ VariableSettings,\r
+ FirmwareVariableMtrrCount,\r
+ MtrrValidBitsMask,\r
+ MtrrValidAddressMask,\r
+ VariableMtrr\r
+ );\r
+ OverLap = CheckMemoryAttributeOverlap (\r
+ FirmwareVariableMtrrCount,\r
+ BaseAddress,\r
+ BaseAddress + Length - 1,\r
+ VariableMtrr\r
+ );\r
+\r
if (OverLap) {\r
- Status = CombineMemoryAttribute (MemoryType, &BaseAddress, &Length, VariableMtrr, &UsedMtrr, &OverwriteExistingMtrr);\r
+ Status = CombineMemoryAttribute (\r
+ FirmwareVariableMtrrCount,\r
+ MemoryType,\r
+ &BaseAddress,\r
+ &Length,\r
+ VariableMtrr,\r
+ &UsedMtrr,\r
+ &OverwriteExistingMtrr\r
+ );\r
if (RETURN_ERROR (Status)) {\r
goto Done;\r
}\r
//\r
// Combined successfully, invalidate the now-unused MTRRs\r
//\r
- InvalidateMtrr(VariableMtrr);\r
+ InvalidateMtrr(VariableMtrrCount, VariableMtrr);\r
Status = RETURN_SUCCESS;\r
goto Done;\r
}\r
//\r
// Invalidate the now-unused MTRRs\r
//\r
- InvalidateMtrr(VariableMtrr);\r
+ InvalidateMtrr(VariableMtrrCount, VariableMtrr);\r
goto Done;\r
}\r
\r
//\r
// Invalidate the now-unused MTRRs\r
//\r
- InvalidateMtrr(VariableMtrr);\r
+ InvalidateMtrr(VariableMtrrCount, VariableMtrr);\r
\r
//\r
// Find first unused MTRR\r
UINT32 Index;\r
UINT32 VariableMtrrCount;\r
\r
- VariableMtrrCount = GetVariableMtrrCount ();\r
+ VariableMtrrCount = GetVariableMtrrCountWorker ();\r
ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);\r
\r
for (Index = 0; Index < VariableMtrrCount; Index++) {\r
/**\r
Worker function setting fixed MTRRs\r
\r
- @param[in] FixedSettings A buffer to hold fixed Mtrrs content.\r
+ @param[in] FixedSettings A buffer to hold fixed MTRRs content.\r
\r
**/\r
VOID\r
/**\r
This function sets fixed MTRRs\r
\r
- @param[in] FixedSettings A buffer to hold fixed Mtrrs content.\r
+ @param[in] FixedSettings A buffer to hold fixed MTRRs content.\r
\r
@retval The pointer of FixedSettings\r
\r
/**\r
This function gets the content in all MTRRs (variable and fixed)\r
\r
- @param[out] MtrrSetting A buffer to hold all Mtrrs content.\r
+ @param[out] MtrrSetting A buffer to hold all MTRRs content.\r
\r
@retval the pointer of MtrrSetting\r
\r
//\r
// Get fixed MTRRs\r
//\r
- MtrrGetFixedMtrr (&MtrrSetting->Fixed);\r
+ MtrrGetFixedMtrrWorker (&MtrrSetting->Fixed);\r
\r
//\r
// Get variable MTRRs\r
//\r
- MtrrGetVariableMtrr (&MtrrSetting->Variables);\r
+ MtrrGetVariableMtrrWorker (\r
+ GetVariableMtrrCountWorker (),\r
+ &MtrrSetting->Variables\r
+ );\r
\r
//\r
// Get MTRR_DEF_TYPE value\r