mirror of https://github.com/acidanthera/audk.git
UefiCpuPkg/MtrrLib: Update algorithm to calculate optimal settings
The new algorithm converts the problem calculating optimal MTRR settings (using least MTRR registers) to the problem finding the shortest path in a graph. The memory required in extreme but rare case can be up to 256KB, so using local stack buffer is impossible considering current DxeIpl only allocates 128KB stack. The patch changes existing MtrrSetMemoryAttributeInMtrrSettings() and MtrrSetMemoryAttribute() to use the 4-page stack buffer for calculation. The two APIs return BUFFER_TOO_SMALL when the buffer is too small for calculation. The patch adds a new API MtrrSetMemoryAttribute*s*InMtrrSettings() to set multiple-range attributes in one function call. Since every call to MtrrSetMemoryAttributeInMtrrSettings (without-s) or MtrrSetMemoryAttribute() requires to calculate the MTRRs for the whole physical memory, combining multiple calls in one API can significantly reduce the calculation time. In theory, if N times of call to without-s API costs N seconds, the new API only costs 1 second. The new API uses the buffer supplied from caller to calculate MTRRs and returns BUFFER_TOO_SMALL when the buffer is too small for calculation. Test performed: 1. Random test a. Generate random memory settings, use the new algorithm to calculate the MTRRs. b. Read back the MTRRs and check the memory settings match the desired memory settings. c. Repeat the above #1 and #2 100000 times. 2. OVMF 32PEI + 64DXE boot to shell. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Cc: Eric Dong <eric.dong@intel.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
This commit is contained in:
parent
1416ecb4a9
commit
2bbd7e2fbd
|
@ -103,6 +103,12 @@ typedef enum {
|
|||
#define MTRR_CACHE_WRITE_BACK 6
|
||||
#define MTRR_CACHE_INVALID_TYPE 7
|
||||
|
||||
typedef struct {
|
||||
UINT64 BaseAddress;
|
||||
UINT64 Length;
|
||||
MTRR_MEMORY_CACHE_TYPE Type;
|
||||
} MTRR_MEMORY_RANGE;
|
||||
|
||||
/**
|
||||
Returns the variable MTRR count for the CPU.
|
||||
|
||||
|
@ -151,7 +157,7 @@ GetFirmwareVariableMtrrCount (
|
|||
@retval RETURN_OUT_OF_RESOURCES There are not enough system resources to
|
||||
modify the attributes of the memory
|
||||
resource range.
|
||||
|
||||
@retval RETURN_BUFFER_TOO_SMALL The scratch buffer is too small for MTRR calculation.
|
||||
**/
|
||||
RETURN_STATUS
|
||||
EFIAPI
|
||||
|
@ -346,7 +352,7 @@ MtrrGetDefaultMemoryType (
|
|||
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.
|
||||
|
||||
@retval RETURN_BUFFER_TOO_SMALL The scratch buffer is too small for MTRR calculation.
|
||||
**/
|
||||
RETURN_STATUS
|
||||
EFIAPI
|
||||
|
@ -357,4 +363,39 @@ MtrrSetMemoryAttributeInMtrrSettings (
|
|||
IN MTRR_MEMORY_CACHE_TYPE Attribute
|
||||
);
|
||||
|
||||
/**
|
||||
This function attempts to set the attributes into MTRR setting buffer for multiple memory ranges.
|
||||
|
||||
@param[in, out] MtrrSetting MTRR setting buffer to be set.
|
||||
@param[in] Scratch A temporary scratch buffer that is used to perform the calculation.
|
||||
@param[in, out] ScratchSize Pointer to the size in bytes of the scratch buffer.
|
||||
It may be updated to the actual required size when the calculation
|
||||
needs more scratch buffer.
|
||||
@param[in] Ranges Pointer to an array of MTRR_MEMORY_RANGE.
|
||||
When range overlap happens, the last one takes higher priority.
|
||||
When the function returns, either all the attributes are set successfully,
|
||||
or none of them is set.
|
||||
@param[in] Count of MTRR_MEMORY_RANGE.
|
||||
|
||||
@retval RETURN_SUCCESS The attributes were set for all the memory ranges.
|
||||
@retval RETURN_INVALID_PARAMETER Length in any range is zero.
|
||||
@retval RETURN_UNSUPPORTED The processor does not support one or more bytes of the
|
||||
memory resource range specified by BaseAddress and Length in any range.
|
||||
@retval RETURN_UNSUPPORTED The bit mask of attributes is not support for the memory resource
|
||||
range specified by BaseAddress and Length in any range.
|
||||
@retval RETURN_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of
|
||||
the memory resource ranges.
|
||||
@retval RETURN_ACCESS_DENIED The attributes for the memory resource range specified by
|
||||
BaseAddress and Length cannot be modified.
|
||||
@retval RETURN_BUFFER_TOO_SMALL The scratch buffer is too small for MTRR calculation.
|
||||
**/
|
||||
RETURN_STATUS
|
||||
EFIAPI
|
||||
MtrrSetMemoryAttributesInMtrrSettings (
|
||||
IN OUT MTRR_SETTINGS *MtrrSetting,
|
||||
IN VOID *Scratch,
|
||||
IN OUT UINTN *ScratchSize,
|
||||
IN CONST MTRR_MEMORY_RANGE *Ranges,
|
||||
IN UINTN RangeCount
|
||||
);
|
||||
#endif // _MTRR_LIB_H_
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue