summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--UefiCpuPkg/Include/Library/MtrrLib.h31
-rw-r--r--UefiCpuPkg/Library/MtrrLib/MtrrLib.c140
2 files changed, 151 insertions, 20 deletions
diff --git a/UefiCpuPkg/Include/Library/MtrrLib.h b/UefiCpuPkg/Include/Library/MtrrLib.h
index 884c7bb699..36cd2cd6d5 100644
--- a/UefiCpuPkg/Include/Library/MtrrLib.h
+++ b/UefiCpuPkg/Include/Library/MtrrLib.h
@@ -352,4 +352,35 @@ MtrrGetDefaultMemoryType (
VOID
);
+/**
+ This function attempts to set the attributes into MTRR setting buffer for a memory range.
+
+ @param[in, out] MtrrSetting MTRR setting buffer to be set.
+ @param[in] BaseAddress The physical address that is the start address
+ of a memory region.
+ @param[in] Length The size in bytes of the memory region.
+ @param[in] Attribute The bit mask of attributes to set for the
+ memory region.
+
+ @retval RETURN_SUCCESS The attributes were set for the memory region.
+ @retval RETURN_INVALID_PARAMETER Length is zero.
+ @retval RETURN_UNSUPPORTED The processor does not support one or more bytes of the
+ memory resource range specified by BaseAddress and Length.
+ @retval RETURN_UNSUPPORTED The bit mask of attributes is not support for the memory resource
+ range specified by BaseAddress and Length.
+ @retval RETURN_ACCESS_DENIED The attributes for the memory resource range specified by
+ BaseAddress and Length cannot be modified.
+ @retval RETURN_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
+ the memory resource range.
+
+**/
+RETURN_STATUS
+EFIAPI
+MtrrSetMemoryAttributeInMtrrSettings (
+ IN OUT MTRR_SETTINGS *MtrrSetting,
+ IN PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN MTRR_MEMORY_CACHE_TYPE Attribute
+ );
+
#endif // _MTRR_LIB_H_
diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
index a5bfa88016..f5b3460f13 100644
--- a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
+++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
@@ -1424,6 +1424,11 @@ MtrrDebugPrintAllMtrrs (
/**
Worker function attempts to set the attributes for a memory range.
+ If MtrrSettings is not NULL, set the attributes into the input MTRR
+ settings buffer.
+ If MtrrSettings is NULL, set the attributes into MTRRs registers.
+
+ @param[in, out] MtrrSetting A buffer holding all MTRRs content.
@param[in] BaseAddress The physical address that is the start
address of a memory region.
@param[in] Length The size in bytes of the memory region.
@@ -1448,11 +1453,11 @@ MtrrDebugPrintAllMtrrs (
**/
RETURN_STATUS
-EFIAPI
-MtrrSetMemoryAttribute (
- IN PHYSICAL_ADDRESS BaseAddress,
- IN UINT64 Length,
- IN MTRR_MEMORY_CACHE_TYPE Attribute
+MtrrSetMemoryAttributeWorker (
+ IN OUT MTRR_SETTINGS *MtrrSetting,
+ IN PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN MTRR_MEMORY_CACHE_TYPE Attribute
)
{
UINT64 TempQword;
@@ -1484,7 +1489,6 @@ MtrrSetMemoryAttribute (
UINT64 NewValue;
MTRR_VARIABLE_SETTINGS *VariableSettings;
- DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttribute() %a:%016lx-%016lx\n", mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length));
MtrrContextValid = FALSE;
for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {
FixedSettingsValid[Index] = FALSE;
@@ -1529,14 +1533,19 @@ MtrrSetMemoryAttribute (
if (RETURN_ERROR (Status)) {
goto Done;
}
- if (!FixedSettingsValid[MsrNum]) {
- WorkingFixedSettings.Mtrr[MsrNum] = AsmReadMsr64 (mMtrrLibFixedMtrrTable[MsrNum].Msr);
- FixedSettingsValid[MsrNum] = TRUE;
- }
- NewValue = (WorkingFixedSettings.Mtrr[MsrNum] & ~ClearMask) | OrMask;
- if (WorkingFixedSettings.Mtrr[MsrNum] != NewValue) {
- WorkingFixedSettings.Mtrr[MsrNum] = NewValue;
- FixedSettingsModified[MsrNum] = TRUE;
+ if (MtrrSetting != NULL) {
+ MtrrSetting->Fixed.Mtrr[MsrNum] = (MtrrSetting->Fixed.Mtrr[MsrNum] & ~ClearMask) | OrMask;
+ MtrrSetting->MtrrDefType |= MTRR_LIB_CACHE_FIXED_MTRR_ENABLED;
+ } else {
+ if (!FixedSettingsValid[MsrNum]) {
+ WorkingFixedSettings.Mtrr[MsrNum] = AsmReadMsr64 (mMtrrLibFixedMtrrTable[MsrNum].Msr);
+ FixedSettingsValid[MsrNum] = TRUE;
+ }
+ NewValue = (WorkingFixedSettings.Mtrr[MsrNum] & ~ClearMask) | OrMask;
+ if (WorkingFixedSettings.Mtrr[MsrNum] != NewValue) {
+ WorkingFixedSettings.Mtrr[MsrNum] = NewValue;
+ FixedSettingsModified[MsrNum] = TRUE;
+ }
}
}
@@ -1564,10 +1573,14 @@ MtrrSetMemoryAttribute (
//
VariableMtrrCount = GetVariableMtrrCountWorker ();
FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCountWorker ();
- MtrrGetVariableMtrrWorker (NULL, VariableMtrrCount, &OriginalVariableSettings);
- CopyMem (&WorkingVariableSettings, &OriginalVariableSettings, sizeof (WorkingVariableSettings));
- ProgramVariableSettings = TRUE;
- VariableSettings = &WorkingVariableSettings;
+ if (MtrrSetting != NULL) {
+ VariableSettings = &MtrrSetting->Variables;
+ } else {
+ MtrrGetVariableMtrrWorker (NULL, VariableMtrrCount, &OriginalVariableSettings);
+ CopyMem (&WorkingVariableSettings, &OriginalVariableSettings, sizeof (WorkingVariableSettings));
+ ProgramVariableSettings = TRUE;
+ VariableSettings = &WorkingVariableSettings;
+ }
//
// Check for overlap
@@ -1613,7 +1626,7 @@ MtrrSetMemoryAttribute (
// The memory type is the same with the type specified by
// MTRR_LIB_IA32_MTRR_DEF_TYPE.
//
- if ((!OverwriteExistingMtrr) && (Attribute == MtrrGetDefaultMemoryType ())) {
+ if ((!OverwriteExistingMtrr) && (Attribute == MtrrGetDefaultMemoryTypeWorker (MtrrSetting))) {
//
// Invalidate the now-unused MTRRs
//
@@ -1783,11 +1796,98 @@ Done:
DEBUG((DEBUG_CACHE, " Status = %r\n", Status));
if (!RETURN_ERROR (Status)) {
- MtrrDebugPrintAllMtrrs ();
+ if (MtrrSetting != NULL) {
+ MtrrSetting->MtrrDefType |= MTRR_LIB_CACHE_MTRR_ENABLED;
+ }
+ MtrrDebugPrintAllMtrrsWorker (MtrrSetting);
}
return Status;
}
+
+/**
+ This function attempts to set the attributes for a memory range.
+
+ @param[in] BaseAddress The physical address that is the start
+ address of a memory region.
+ @param[in] Length The size in bytes of the memory region.
+ @param[in] Attributes The bit mask of attributes to set for the
+ memory region.
+
+ @retval RETURN_SUCCESS The attributes were set for the memory
+ region.
+ @retval RETURN_INVALID_PARAMETER Length is zero.
+ @retval RETURN_UNSUPPORTED The processor does not support one or
+ more bytes of the memory resource range
+ specified by BaseAddress and Length.
+ @retval RETURN_UNSUPPORTED The bit mask of attributes is not support
+ for the memory resource range specified
+ by BaseAddress and Length.
+ @retval RETURN_ACCESS_DENIED The attributes for the memory resource
+ range specified by BaseAddress and Length
+ cannot be modified.
+ @retval RETURN_OUT_OF_RESOURCES There are not enough system resources to
+ modify the attributes of the memory
+ resource range.
+
+**/
+RETURN_STATUS
+EFIAPI
+MtrrSetMemoryAttribute (
+ IN PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN MTRR_MEMORY_CACHE_TYPE Attribute
+ )
+{
+ DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttribute() %a:%016lx-%016lx\n", mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length));
+ return MtrrSetMemoryAttributeWorker (
+ NULL,
+ BaseAddress,
+ Length,
+ Attribute
+ );
+}
+
+/**
+ This function attempts to set the attributes into MTRR setting buffer for a memory range.
+
+ @param[in, out] MtrrSetting MTRR setting buffer to be set.
+ @param[in] BaseAddress The physical address that is the start address
+ of a memory region.
+ @param[in] Length The size in bytes of the memory region.
+ @param[in] Attribute The bit mask of attributes to set for the
+ memory region.
+
+ @retval RETURN_SUCCESS The attributes were set for the memory region.
+ @retval RETURN_INVALID_PARAMETER Length is zero.
+ @retval RETURN_UNSUPPORTED The processor does not support one or more bytes of the
+ memory resource range specified by BaseAddress and Length.
+ @retval RETURN_UNSUPPORTED The bit mask of attributes is not support for the memory resource
+ range specified by BaseAddress and Length.
+ @retval RETURN_ACCESS_DENIED The attributes for the memory resource range specified by
+ BaseAddress and Length cannot be modified.
+ @retval RETURN_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
+ the memory resource range.
+
+**/
+RETURN_STATUS
+EFIAPI
+MtrrSetMemoryAttributeInMtrrSettings (
+ IN OUT MTRR_SETTINGS *MtrrSetting,
+ IN PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN MTRR_MEMORY_CACHE_TYPE Attribute
+ )
+{
+ DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttributeMtrrSettings(%p) %a:%016lx-%016lx\n", MtrrSetting, mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length));
+ return MtrrSetMemoryAttributeWorker (
+ MtrrSetting,
+ BaseAddress,
+ Length,
+ Attribute
+ );
+}
+
/**
Worker function setting variable MTRRs