/** @file\r
MTRR setting library\r
\r
- Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
#include <Library/BaseMemoryLib.h>\r
#include <Library/DebugLib.h>\r
\r
+#define OR_SEED 0x0101010101010101ull\r
+#define CLEAR_SEED 0xFFFFFFFFFFFFFFFFull\r
+\r
//\r
// Context to save and restore when MTRRs are programmed\r
//\r
/**\r
Worker function returns the default MTRR cache type for the system.\r
\r
+ If MtrrSetting is not NULL, returns the default MTRR cache type from input\r
+ MTRR settings buffer.\r
+ If MtrrSetting is NULL, returns the default MTRR cache type from MSR.\r
+\r
+ @param[in] MtrrSetting A buffer holding all MTRRs content.\r
+\r
@return The default MTRR cache type.\r
\r
**/\r
MTRR_MEMORY_CACHE_TYPE\r
MtrrGetDefaultMemoryTypeWorker (\r
- VOID\r
+ IN MTRR_SETTINGS *MtrrSetting\r
)\r
{\r
- return (MTRR_MEMORY_CACHE_TYPE) (AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE) & 0x7);\r
+ if (MtrrSetting == NULL) {\r
+ return (MTRR_MEMORY_CACHE_TYPE) (AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE) & 0x7);\r
+ } else {\r
+ return (MTRR_MEMORY_CACHE_TYPE) (MtrrSetting->MtrrDefType & 0x7);\r
+ }\r
}\r
\r
\r
if (!IsMtrrSupported ()) {\r
return CacheUncacheable;\r
}\r
- return MtrrGetDefaultMemoryTypeWorker ();\r
+ return MtrrGetDefaultMemoryTypeWorker (NULL);\r
}\r
\r
/**\r
/**\r
Worker function will get the raw value in variable MTRRs\r
\r
+ If MtrrSetting is not NULL, gets the variable MTRRs raw value from input\r
+ MTRR settings buffer.\r
+ If MtrrSetting is NULL, gets the variable MTRRs raw value from MTRRs.\r
+\r
+ @param[in] MtrrSetting A buffer holding all MTRRs content.\r
+ @param[in] VariableMtrrCount Number of variable MTRRs.\r
@param[out] VariableSettings A buffer to hold variable MTRRs content.\r
\r
@return The VariableSettings input pointer\r
**/\r
MTRR_VARIABLE_SETTINGS*\r
MtrrGetVariableMtrrWorker (\r
+ IN MTRR_SETTINGS *MtrrSetting,\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
- VariableSettings->Mtrr[Index].Base =\r
- AsmReadMsr64 (MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1));\r
- VariableSettings->Mtrr[Index].Mask =\r
- AsmReadMsr64 (MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1) + 1);\r
+ if (MtrrSetting == NULL) {\r
+ VariableSettings->Mtrr[Index].Base =\r
+ AsmReadMsr64 (MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1));\r
+ VariableSettings->Mtrr[Index].Mask =\r
+ AsmReadMsr64 (MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1) + 1);\r
+ } else {\r
+ VariableSettings->Mtrr[Index].Base = MtrrSetting->Variables.Mtrr[Index].Base;\r
+ VariableSettings->Mtrr[Index].Mask = MtrrSetting->Variables.Mtrr[Index].Mask;\r
+ }\r
}\r
\r
return VariableSettings;\r
}\r
\r
return MtrrGetVariableMtrrWorker (\r
+ NULL,\r
+ GetVariableMtrrCountWorker (),\r
VariableSettings\r
);\r
}\r
@param[in] MemoryCacheType 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
+ @param[in, out] LastMsrNum On input, the last index of the fixed MTRR MSR to program.\r
+ On return, the current index of the fixed MTRR MSR to program.\r
+ @param[out] ReturnClearMask The bits to clear in the fixed MTRR MSR.\r
+ @param[out] ReturnOrMask The bits to set in the fixed MTRR MSR.\r
\r
@retval RETURN_SUCCESS The cache type was updated successfully\r
@retval RETURN_UNSUPPORTED The requested range or cache type was invalid\r
**/\r
RETURN_STATUS\r
ProgramFixedMtrr (\r
- IN UINT64 MemoryCacheType,\r
- IN OUT UINT64 *Base,\r
- IN OUT UINT64 *Length\r
+ IN UINT64 MemoryCacheType,\r
+ IN OUT UINT64 *Base,\r
+ IN OUT UINT64 *Length,\r
+ IN OUT UINT32 *LastMsrNum,\r
+ OUT UINT64 *ReturnClearMask,\r
+ OUT UINT64 *ReturnOrMask\r
)\r
{\r
UINT32 MsrNum;\r
- UINT32 ByteShift;\r
- UINT64 TempQword;\r
+ UINT32 LeftByteShift;\r
+ UINT32 RightByteShift;\r
UINT64 OrMask;\r
UINT64 ClearMask;\r
+ UINT64 SubLength;\r
\r
- TempQword = 0;\r
- OrMask = 0;\r
- ClearMask = 0;\r
-\r
- for (MsrNum = 0; MsrNum < MTRR_NUMBER_OF_FIXED_MTRR; MsrNum++) {\r
+ //\r
+ // Find the fixed MTRR index to be programmed\r
+ //\r
+ for (MsrNum = *LastMsrNum + 1; MsrNum < MTRR_NUMBER_OF_FIXED_MTRR; MsrNum++) {\r
if ((*Base >= mMtrrLibFixedMtrrTable[MsrNum].BaseAddress) &&\r
(*Base <\r
(\r
}\r
}\r
\r
- if (MsrNum == MTRR_NUMBER_OF_FIXED_MTRR) {\r
+ if (MsrNum >= MTRR_NUMBER_OF_FIXED_MTRR) {\r
return RETURN_UNSUPPORTED;\r
}\r
\r
//\r
- // We found the fixed MTRR to be programmed\r
+ // Find the begin offset in fixed MTRR and calculate byte offset of left shift\r
//\r
- for (ByteShift = 0; ByteShift < 8; ByteShift++) {\r
- if (*Base ==\r
- (\r
- mMtrrLibFixedMtrrTable[MsrNum].BaseAddress +\r
- (ByteShift * mMtrrLibFixedMtrrTable[MsrNum].Length)\r
- )\r
- ) {\r
- break;\r
- }\r
- }\r
+ LeftByteShift = ((UINT32)*Base - mMtrrLibFixedMtrrTable[MsrNum].BaseAddress)\r
+ / mMtrrLibFixedMtrrTable[MsrNum].Length;\r
\r
- if (ByteShift == 8) {\r
+ if (LeftByteShift >= 8) {\r
return RETURN_UNSUPPORTED;\r
}\r
\r
- for (\r
- ;\r
- ((ByteShift < 8) && (*Length >= mMtrrLibFixedMtrrTable[MsrNum].Length));\r
- ByteShift++\r
- ) {\r
- OrMask |= LShiftU64 ((UINT64) MemoryCacheType, (UINT32) (ByteShift * 8));\r
- ClearMask |= LShiftU64 ((UINT64) 0xFF, (UINT32) (ByteShift * 8));\r
- *Length -= mMtrrLibFixedMtrrTable[MsrNum].Length;\r
- *Base += mMtrrLibFixedMtrrTable[MsrNum].Length;\r
+ //\r
+ // Find the end offset in fixed MTRR and calculate byte offset of right shift\r
+ //\r
+ SubLength = mMtrrLibFixedMtrrTable[MsrNum].Length * (8 - LeftByteShift);\r
+ if (*Length >= SubLength) {\r
+ RightByteShift = 0;\r
+ } else {\r
+ RightByteShift = 8 - LeftByteShift -\r
+ (UINT32)(*Length) / mMtrrLibFixedMtrrTable[MsrNum].Length;\r
+ if ((LeftByteShift >= 8) ||\r
+ (((UINT32)(*Length) % mMtrrLibFixedMtrrTable[MsrNum].Length) != 0)\r
+ ) {\r
+ return RETURN_UNSUPPORTED;\r
+ }\r
+ //\r
+ // Update SubLength by actual length\r
+ //\r
+ SubLength = *Length;\r
}\r
\r
- if (ByteShift < 8 && (*Length != 0)) {\r
- return RETURN_UNSUPPORTED;\r
+ ClearMask = CLEAR_SEED;\r
+ OrMask = MultU64x32 (OR_SEED, (UINT32)MemoryCacheType);\r
+\r
+ if (LeftByteShift != 0) {\r
+ //\r
+ // Clear the low bits by LeftByteShift\r
+ //\r
+ ClearMask &= LShiftU64 (ClearMask, LeftByteShift * 8);\r
+ OrMask &= LShiftU64 (OrMask, LeftByteShift * 8);\r
}\r
\r
- TempQword =\r
- (AsmReadMsr64 (mMtrrLibFixedMtrrTable[MsrNum].Msr) & ~ClearMask) | OrMask;\r
- AsmWriteMsr64 (mMtrrLibFixedMtrrTable[MsrNum].Msr, TempQword);\r
+ if (RightByteShift != 0) {\r
+ //\r
+ // Clear the high bits by RightByteShift\r
+ //\r
+ ClearMask &= RShiftU64 (ClearMask, RightByteShift * 8);\r
+ OrMask &= RShiftU64 (OrMask, RightByteShift * 8);\r
+ }\r
+\r
+ *Length -= SubLength;\r
+ *Base += SubLength;\r
+\r
+ *LastMsrNum = MsrNum;\r
+ *ReturnClearMask = ClearMask;\r
+ *ReturnOrMask = OrMask;\r
+\r
return RETURN_SUCCESS;\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
+ NULL,\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, 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
- UINTN VariableMtrrCount;\r
- MTRR_CONTEXT MtrrContext;\r
\r
- PreMtrrChange (&MtrrContext);\r
- Index = 0;\r
- VariableMtrrCount = GetVariableMtrrCount ();\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
/**\r
Converts the Memory attribute value to MTRR_MEMORY_CACHE_TYPE.\r
\r
+ If MtrrSetting is not NULL, gets the default memory attribute from input\r
+ MTRR settings buffer.\r
+ If MtrrSetting is NULL, gets the default memory attribute from MSR.\r
+\r
+ @param[in] MtrrSetting A buffer holding all MTRRs content.\r
@param[in] MtrrType MTRR memory type\r
\r
@return The enum item in MTRR_MEMORY_CACHE_TYPE\r
**/\r
MTRR_MEMORY_CACHE_TYPE\r
GetMemoryCacheTypeFromMtrrType (\r
+ IN MTRR_SETTINGS *MtrrSetting,\r
IN UINT64 MtrrType\r
)\r
{\r
// MtrrType is MTRR_CACHE_INVALID_TYPE, that means\r
// no MTRR covers the range\r
//\r
- return MtrrGetDefaultMemoryType ();\r
+ return MtrrGetDefaultMemoryTypeWorker (MtrrSetting);\r
}\r
}\r
\r
return MtrrType;\r
}\r
\r
-\r
-\r
/**\r
- This function will get the memory cache type of the specific address.\r
+ Worker function will get the memory cache type of the specific address.\r
\r
- This function is mainly for debug purpose.\r
+ If MtrrSetting is not NULL, gets the memory cache type from input\r
+ MTRR settings buffer.\r
+ If MtrrSetting is NULL, gets the memory cache type from MTRRs.\r
\r
+ @param[in] MtrrSetting A buffer holding all MTRRs content.\r
@param[in] Address The specific address\r
\r
@return Memory cache type of the specific address\r
\r
**/\r
MTRR_MEMORY_CACHE_TYPE\r
-EFIAPI\r
-MtrrGetMemoryAttribute (\r
+MtrrGetMemoryAttributeByAddressWorker (\r
+ IN MTRR_SETTINGS *MtrrSetting,\r
IN PHYSICAL_ADDRESS Address\r
)\r
{\r
UINT64 MtrrValidBitsMask;\r
UINT64 MtrrValidAddressMask;\r
UINTN VariableMtrrCount;\r
-\r
- if (!IsMtrrSupported ()) {\r
- return CacheUncacheable;\r
- }\r
+ MTRR_VARIABLE_SETTINGS VariableSettings;\r
\r
//\r
// Check if MTRR is enabled, if not, return UC as attribute\r
//\r
- TempQword = AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE);\r
+ if (MtrrSetting == NULL) {\r
+ TempQword = AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE);\r
+ } else {\r
+ TempQword = MtrrSetting->MtrrDefType;\r
+ }\r
MtrrType = MTRR_CACHE_INVALID_TYPE;\r
\r
if ((TempQword & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
SubIndex =\r
((UINTN)Address - mMtrrLibFixedMtrrTable[Index].BaseAddress) /\r
mMtrrLibFixedMtrrTable[Index].Length;\r
- TempQword = AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr);\r
+ if (MtrrSetting == NULL) {\r
+ TempQword = AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr);\r
+ } else {\r
+ TempQword = MtrrSetting->Fixed.Mtrr[Index];\r
+ }\r
MtrrType = RShiftU64 (TempQword, SubIndex * 8) & 0xFF;\r
- return GetMemoryCacheTypeFromMtrrType (MtrrType);\r
+ return GetMemoryCacheTypeFromMtrrType (MtrrSetting, MtrrType);\r
}\r
}\r
}\r
}\r
MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask);\r
- MtrrGetMemoryAttributeInVariableMtrr(\r
- MtrrValidBitsMask,\r
- MtrrValidAddressMask,\r
- VariableMtrr\r
+\r
+ MtrrGetVariableMtrrWorker (\r
+ MtrrSetting,\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
}\r
}\r
}\r
- CacheType = GetMemoryCacheTypeFromMtrrType (MtrrType);\r
+ CacheType = GetMemoryCacheTypeFromMtrrType (MtrrSetting, MtrrType);\r
\r
return CacheType;\r
}\r
\r
\r
+/**\r
+ This function will get the memory cache type of the specific address.\r
+\r
+ This function is mainly for debug purpose.\r
+\r
+ @param[in] Address The specific address\r
+\r
+ @return Memory cache type of the specific address\r
+\r
+**/\r
+MTRR_MEMORY_CACHE_TYPE\r
+EFIAPI\r
+MtrrGetMemoryAttribute (\r
+ IN PHYSICAL_ADDRESS Address\r
+ )\r
+{\r
+ if (!IsMtrrSupported ()) {\r
+ return CacheUncacheable;\r
+ }\r
+\r
+ return MtrrGetMemoryAttributeByAddressWorker (NULL, Address);\r
+}\r
\r
/**\r
- This function prints all MTRRs for debugging.\r
+ Worker function prints all MTRRs for debugging.\r
+\r
+ If MtrrSetting is not NULL, print MTRR settings from from input MTRR\r
+ settings buffer.\r
+ If MtrrSetting is NULL, print MTRR settings from MTRRs.\r
+\r
+ @param MtrrSetting A buffer holding all MTRRs content.\r
**/\r
VOID\r
-EFIAPI\r
-MtrrDebugPrintAllMtrrs (\r
- VOID\r
+MtrrDebugPrintAllMtrrsWorker (\r
+ IN MTRR_SETTINGS *MtrrSetting\r
)\r
{\r
DEBUG_CODE (\r
- MTRR_SETTINGS MtrrSettings;\r
+ MTRR_SETTINGS LocalMtrrs;\r
+ MTRR_SETTINGS *Mtrrs;\r
UINTN Index;\r
UINTN Index1;\r
UINTN VariableMtrrCount;\r
DEBUG((DEBUG_CACHE, "MTRR Settings\n"));\r
DEBUG((DEBUG_CACHE, "=============\n"));\r
\r
- MtrrGetAllMtrrs (&MtrrSettings);\r
- DEBUG((DEBUG_CACHE, "MTRR Default Type: %016lx\n", MtrrSettings.MtrrDefType));\r
+ if (MtrrSetting != NULL) {\r
+ Mtrrs = MtrrSetting;\r
+ } else {\r
+ MtrrGetAllMtrrs (&LocalMtrrs);\r
+ Mtrrs = &LocalMtrrs;\r
+ }\r
+\r
+ DEBUG((DEBUG_CACHE, "MTRR Default Type: %016lx\n", Mtrrs->MtrrDefType));\r
for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {\r
- DEBUG((DEBUG_CACHE, "Fixed MTRR[%02d] : %016lx\n", Index, MtrrSettings.Fixed.Mtrr[Index]));\r
+ DEBUG((DEBUG_CACHE, "Fixed MTRR[%02d] : %016lx\n", Index, Mtrrs->Fixed.Mtrr[Index]));\r
}\r
\r
VariableMtrrCount = GetVariableMtrrCount ();\r
for (Index = 0; Index < VariableMtrrCount; Index++) {\r
DEBUG((DEBUG_CACHE, "Variable MTRR[%02d]: Base=%016lx Mask=%016lx\n",\r
Index,\r
- MtrrSettings.Variables.Mtrr[Index].Base,\r
- MtrrSettings.Variables.Mtrr[Index].Mask\r
+ Mtrrs->Variables.Mtrr[Index].Base,\r
+ Mtrrs->Variables.Mtrr[Index].Mask\r
));\r
}\r
DEBUG((DEBUG_CACHE, "\n"));\r
for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {\r
Base = mMtrrLibFixedMtrrTable[Index].BaseAddress;\r
for (Index1 = 0; Index1 < 8; Index1++) {\r
- MemoryType = (UINTN)(RShiftU64 (MtrrSettings.Fixed.Mtrr[Index], Index1 * 8) & 0xff);\r
+ MemoryType = (UINTN)(RShiftU64 (Mtrrs->Fixed.Mtrr[Index], Index1 * 8) & 0xff);\r
if (MemoryType > CacheWriteBack) {\r
MemoryType = MTRR_CACHE_INVALID_TYPE;\r
}\r
Base = BASE_1MB;\r
PreviousMemoryType = MTRR_CACHE_INVALID_TYPE;\r
do {\r
- MemoryType = MtrrGetMemoryAttribute (Base);\r
+ MemoryType = MtrrGetMemoryAttributeByAddressWorker (Mtrrs, Base);\r
if (MemoryType > CacheWriteBack) {\r
MemoryType = MTRR_CACHE_INVALID_TYPE;\r
}\r
NoRangeLimit = Limit;\r
\r
for (Index = 0, Found = FALSE; Index < VariableMtrrCount; Index++) {\r
- if ((MtrrSettings.Variables.Mtrr[Index].Mask & BIT11) == 0) {\r
+ if ((Mtrrs->Variables.Mtrr[Index].Mask & BIT11) == 0) {\r
//\r
// If mask is not valid, then do not display range\r
//\r
continue;\r
}\r
- MtrrBase = (MtrrSettings.Variables.Mtrr[Index].Base & (~(SIZE_4KB - 1)));\r
- MtrrLimit = MtrrBase + ((~(MtrrSettings.Variables.Mtrr[Index].Mask & (~(SIZE_4KB - 1)))) & Limit);\r
+ MtrrBase = (Mtrrs->Variables.Mtrr[Index].Base & (~(SIZE_4KB - 1)));\r
+ MtrrLimit = MtrrBase + ((~(Mtrrs->Variables.Mtrr[Index].Mask & (~(SIZE_4KB - 1)))) & Limit);\r
\r
if (Base >= MtrrBase && Base < MtrrLimit) {\r
Found = TRUE;\r
DEBUG((DEBUG_CACHE, "%016lx\n\n", Base - 1));\r
);\r
}\r
+\r
+\r
/**\r
- This function attempts to set the attributes for a memory range.\r
+ This function prints all MTRRs for debugging.\r
+**/\r
+VOID\r
+EFIAPI\r
+MtrrDebugPrintAllMtrrs (\r
+ VOID\r
+ )\r
+{\r
+ MtrrDebugPrintAllMtrrsWorker (NULL);\r
+}\r
+\r
+\r
+/**\r
+ Worker function attempts to set the attributes for a memory range.\r
\r
+ If MtrrSettings is not NULL, set the attributes into the input MTRR\r
+ settings buffer.\r
+ If MtrrSettings is NULL, set the attributes into MTRRs registers.\r
+\r
+ @param[in, out] MtrrSetting A buffer holding all MTRRs content.\r
@param[in] BaseAddress The physical address that is the start\r
address of a memory region.\r
@param[in] Length The size in bytes of the memory region.\r
\r
**/\r
RETURN_STATUS\r
-EFIAPI\r
-MtrrSetMemoryAttribute (\r
- IN PHYSICAL_ADDRESS BaseAddress,\r
- IN UINT64 Length,\r
- IN MTRR_MEMORY_CACHE_TYPE Attribute\r
+MtrrSetMemoryAttributeWorker (\r
+ IN OUT MTRR_SETTINGS *MtrrSetting,\r
+ IN PHYSICAL_ADDRESS BaseAddress,\r
+ IN UINT64 Length,\r
+ IN MTRR_MEMORY_CACHE_TYPE Attribute\r
)\r
{\r
UINT64 TempQword;\r
UINT64 MtrrValidAddressMask;\r
BOOLEAN OverwriteExistingMtrr;\r
UINT32 FirmwareVariableMtrrCount;\r
- UINT32 VariableMtrrEnd;\r
MTRR_CONTEXT MtrrContext;\r
-\r
- DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttribute() %a:%016lx-%016lx\n", mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length));\r
+ BOOLEAN MtrrContextValid;\r
+ BOOLEAN FixedSettingsValid[MTRR_NUMBER_OF_FIXED_MTRR];\r
+ BOOLEAN FixedSettingsModified[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
+ UINT64 OrMask;\r
+ UINT64 NewValue;\r
+ MTRR_VARIABLE_SETTINGS *VariableSettings;\r
+\r
+ MtrrContextValid = FALSE;\r
+ VariableMtrrCount = 0;\r
+ ZeroMem (&WorkingFixedSettings, sizeof (WorkingFixedSettings));\r
+ for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {\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 = GetFirmwareVariableMtrrCount ();\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
// Check if Fixed MTRR\r
//\r
Status = RETURN_SUCCESS;\r
- while ((BaseAddress < BASE_1MB) && (Length > 0) && Status == RETURN_SUCCESS) {\r
- PreMtrrChange (&MtrrContext);\r
- Status = ProgramFixedMtrr (MemoryType, &BaseAddress, &Length);\r
- PostMtrrChange (&MtrrContext);\r
- if (RETURN_ERROR (Status)) {\r
- goto Done;\r
+ if (BaseAddress < BASE_1MB) {\r
+ MsrNum = (UINT32)-1;\r
+ while ((BaseAddress < BASE_1MB) && (Length > 0) && Status == RETURN_SUCCESS) {\r
+ Status = ProgramFixedMtrr (MemoryType, &BaseAddress, &Length, &MsrNum, &ClearMask, &OrMask);\r
+ if (RETURN_ERROR (Status)) {\r
+ goto Done;\r
+ }\r
+ if (MtrrSetting != NULL) {\r
+ MtrrSetting->Fixed.Mtrr[MsrNum] = (MtrrSetting->Fixed.Mtrr[MsrNum] & ~ClearMask) | OrMask;\r
+ MtrrSetting->MtrrDefType |= MTRR_LIB_CACHE_FIXED_MTRR_ENABLED;\r
+ } else {\r
+ if (!FixedSettingsValid[MsrNum]) {\r
+ WorkingFixedSettings.Mtrr[MsrNum] = AsmReadMsr64 (mMtrrLibFixedMtrrTable[MsrNum].Msr);\r
+ FixedSettingsValid[MsrNum] = TRUE;\r
+ }\r
+ NewValue = (WorkingFixedSettings.Mtrr[MsrNum] & ~ClearMask) | OrMask;\r
+ if (WorkingFixedSettings.Mtrr[MsrNum] != NewValue) {\r
+ WorkingFixedSettings.Mtrr[MsrNum] = NewValue;\r
+ FixedSettingsModified[MsrNum] = TRUE;\r
+ }\r
+ }\r
}\r
- }\r
\r
- if (Length == 0) {\r
- //\r
- // A Length of 0 can only make sense for fixed MTTR ranges.\r
- // Since we just handled the fixed MTRRs, we can skip the\r
- // variable MTRR section.\r
- //\r
- goto Done;\r
+ if (Length == 0) {\r
+ //\r
+ // A Length of 0 can only make sense for fixed MTTR ranges.\r
+ // Since we just handled the fixed MTRRs, we can skip the\r
+ // variable MTRR section.\r
+ //\r
+ goto Done;\r
+ }\r
}\r
\r
//\r
Length += SIZE_1MB;\r
}\r
\r
+ //\r
+ // Read all variable MTRRs\r
+ //\r
+ VariableMtrrCount = GetVariableMtrrCountWorker ();\r
+ FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCountWorker ();\r
+ if (MtrrSetting != NULL) {\r
+ VariableSettings = &MtrrSetting->Variables;\r
+ } else {\r
+ MtrrGetVariableMtrrWorker (NULL, VariableMtrrCount, &OriginalVariableSettings);\r
+ CopyMem (&WorkingVariableSettings, &OriginalVariableSettings, sizeof (WorkingVariableSettings));\r
+ ProgramVariableSettings = TRUE;\r
+ VariableSettings = &WorkingVariableSettings;\r
+ }\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
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 (VariableSettings, VariableMtrrCount, VariableMtrr);\r
Status = RETURN_SUCCESS;\r
goto Done;\r
}\r
// The memory type is the same with the type specified by\r
// MTRR_LIB_IA32_MTRR_DEF_TYPE.\r
//\r
- if ((!OverwriteExistingMtrr) && (Attribute == MtrrGetDefaultMemoryType ())) {\r
+ if ((!OverwriteExistingMtrr) && (Attribute == MtrrGetDefaultMemoryTypeWorker (MtrrSetting))) {\r
//\r
// Invalidate the now-unused MTRRs\r
//\r
- InvalidateMtrr(VariableMtrr);\r
+ InvalidateMtrr (VariableSettings, VariableMtrrCount, VariableMtrr);\r
goto Done;\r
}\r
\r
//\r
// Invalidate the now-unused MTRRs\r
//\r
- InvalidateMtrr(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
} while (TempQword > 0);\r
\r
Done:\r
+\r
+ //\r
+ // Write fixed MTRRs that have been modified\r
+ //\r
+ for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {\r
+ if (FixedSettingsModified[Index]) {\r
+ if (!MtrrContextValid) {\r
+ PreMtrrChange (&MtrrContext);\r
+ MtrrContextValid = TRUE;\r
+ }\r
+ AsmWriteMsr64 (\r
+ mMtrrLibFixedMtrrTable[Index].Msr,\r
+ WorkingFixedSettings.Mtrr[Index]\r
+ );\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
+\r
DEBUG((DEBUG_CACHE, " Status = %r\n", Status));\r
if (!RETURN_ERROR (Status)) {\r
- MtrrDebugPrintAllMtrrs ();\r
+ if (MtrrSetting != NULL) {\r
+ MtrrSetting->MtrrDefType |= MTRR_LIB_CACHE_MTRR_ENABLED;\r
+ }\r
+ MtrrDebugPrintAllMtrrsWorker (MtrrSetting);\r
}\r
\r
return Status;\r
}\r
+\r
+/**\r
+ This function attempts to set the attributes for a memory range.\r
+\r
+ @param[in] BaseAddress The physical address that is the start\r
+ address of a memory region.\r
+ @param[in] Length The size in bytes of the memory region.\r
+ @param[in] Attributes The bit mask of attributes to set for the\r
+ memory region.\r
+\r
+ @retval RETURN_SUCCESS The attributes were set for the memory\r
+ region.\r
+ @retval RETURN_INVALID_PARAMETER Length is zero.\r
+ @retval RETURN_UNSUPPORTED The processor does not support one or\r
+ more bytes of the memory resource range\r
+ specified by BaseAddress and Length.\r
+ @retval RETURN_UNSUPPORTED The bit mask of attributes is not support\r
+ for the memory resource range specified\r
+ by BaseAddress and Length.\r
+ @retval RETURN_ACCESS_DENIED The attributes for the memory resource\r
+ range specified by BaseAddress and Length\r
+ cannot be modified.\r
+ @retval RETURN_OUT_OF_RESOURCES There are not enough system resources to\r
+ modify the attributes of the memory\r
+ resource range.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+MtrrSetMemoryAttribute (\r
+ IN PHYSICAL_ADDRESS BaseAddress,\r
+ IN UINT64 Length,\r
+ IN MTRR_MEMORY_CACHE_TYPE Attribute\r
+ )\r
+{\r
+ DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttribute() %a:%016lx-%016lx\n", mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length));\r
+ return MtrrSetMemoryAttributeWorker (\r
+ NULL,\r
+ BaseAddress,\r
+ Length,\r
+ Attribute\r
+ );\r
+}\r
+\r
+/**\r
+ This function attempts to set the attributes into MTRR setting buffer for a memory range.\r
+\r
+ @param[in, out] MtrrSetting MTRR setting buffer to be set.\r
+ @param[in] BaseAddress The physical address that is the start address\r
+ of a memory region.\r
+ @param[in] Length The size in bytes of the memory region.\r
+ @param[in] Attribute The bit mask of attributes to set for the\r
+ memory region.\r
+\r
+ @retval RETURN_SUCCESS The attributes were set for the memory region.\r
+ @retval RETURN_INVALID_PARAMETER Length is zero.\r
+ @retval RETURN_UNSUPPORTED The processor does not support one or more bytes of the\r
+ memory resource range specified by BaseAddress and Length.\r
+ @retval RETURN_UNSUPPORTED The bit mask of attributes is not support for the memory resource\r
+ range specified by BaseAddress and Length.\r
+ @retval RETURN_ACCESS_DENIED The attributes for the memory resource range specified by\r
+ BaseAddress and Length cannot be modified.\r
+ @retval RETURN_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of\r
+ the memory resource range.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+MtrrSetMemoryAttributeInMtrrSettings (\r
+ IN OUT MTRR_SETTINGS *MtrrSetting,\r
+ IN PHYSICAL_ADDRESS BaseAddress,\r
+ IN UINT64 Length,\r
+ IN MTRR_MEMORY_CACHE_TYPE Attribute\r
+ )\r
+{\r
+ DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttributeMtrrSettings(%p) %a:%016lx-%016lx\n", MtrrSetting, mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length));\r
+ return MtrrSetMemoryAttributeWorker (\r
+ MtrrSetting,\r
+ BaseAddress,\r
+ Length,\r
+ Attribute\r
+ );\r
+}\r
+\r
/**\r
Worker function setting variable MTRRs\r
\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
PreMtrrChange (&MtrrContext);\r
MtrrSetVariableMtrrWorker (VariableSettings);\r
PostMtrrChange (&MtrrContext);\r
+ MtrrDebugPrintAllMtrrs ();\r
+\r
return VariableSettings;\r
}\r
\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
PreMtrrChange (&MtrrContext);\r
MtrrSetFixedMtrrWorker (FixedSettings);\r
PostMtrrChange (&MtrrContext);\r
+ MtrrDebugPrintAllMtrrs ();\r
\r
return 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
+ NULL,\r
+ GetVariableMtrrCountWorker (),\r
+ &MtrrSetting->Variables\r
+ );\r
\r
//\r
// Get MTRR_DEF_TYPE value\r
return MtrrSetting;\r
}\r
\r
+\r
/**\r
Checks if MTRR is supported.\r
\r