}\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 = GetFirmwareVariableMtrrCountWorker ();\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
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
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
// 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
+ UsedMtrr = MtrrGetMemoryAttributeInVariableMtrrWorker (\r
+ VariableSettings,\r
+ FirmwareVariableMtrrCount,\r
+ MtrrValidBitsMask,\r
+ MtrrValidAddressMask,\r
+ VariableMtrr\r
+ );\r
OverLap = CheckMemoryAttributeOverlap (\r
FirmwareVariableMtrrCount,\r
BaseAddress,\r