diff options
Diffstat (limited to 'IntelFspPkg/Library/BaseCacheLib/CacheLib.c')
-rw-r--r-- | IntelFspPkg/Library/BaseCacheLib/CacheLib.c | 697 |
1 files changed, 0 insertions, 697 deletions
diff --git a/IntelFspPkg/Library/BaseCacheLib/CacheLib.c b/IntelFspPkg/Library/BaseCacheLib/CacheLib.c deleted file mode 100644 index 927cee13d3..0000000000 --- a/IntelFspPkg/Library/BaseCacheLib/CacheLib.c +++ /dev/null @@ -1,697 +0,0 @@ -/** @file
-
- Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <Uefi.h>
-#include <Library/BaseLib.h>
-#include <Library/CacheLib.h>
-#include <Library/CacheAsRamLib.h>
-#include "CacheLibInternal.h"
-
-/**
- Search the memory cache type for specific memory from MTRR.
-
- @param[in] MemoryAddress the address of target memory
- @param[in] MemoryLength the length of target memory
- @param[in] ValidMtrrAddressMask the MTRR address mask
- @param[out] UsedMsrNum the used MSR number
- @param[out] UsedMemoryCacheType the cache type for the target memory
-
- @retval EFI_SUCCESS The memory is found in MTRR and cache type is returned
- @retval EFI_NOT_FOUND The memory is not found in MTRR
-
-**/
-EFI_STATUS
-SearchForExactMtrr (
- IN EFI_PHYSICAL_ADDRESS MemoryAddress,
- IN UINT64 MemoryLength,
- IN UINT64 ValidMtrrAddressMask,
- OUT UINT32 *UsedMsrNum,
- OUT EFI_MEMORY_CACHE_TYPE *MemoryCacheType
- );
-
-/**
- Check if CacheType match current default setting.
-
- @param[in] MemoryCacheType input cache type to be checked.
-
- @retval TRUE MemoryCacheType is default MTRR setting.
- @retval FALSE MemoryCacheType is NOT default MTRR setting.
-**/
-BOOLEAN
-IsDefaultType (
- IN EFI_MEMORY_CACHE_TYPE MemoryCacheType
- );
-
-/**
- Return MTRR alignment requirement for base address and size.
-
- @param[in] BaseAddress Base address.
- @param[in] Size Size.
-
- @retval Zero Alligned.
- @retval Non-Zero Not alligned.
-
-**/
-UINT32
-CheckMtrrAlignment (
- IN UINT64 BaseAddress,
- IN UINT64 Size
- );
-
-typedef struct {
- UINT32 Msr;
- UINT32 BaseAddress;
- UINT32 Length;
-} EFI_FIXED_MTRR;
-
-EFI_FIXED_MTRR mFixedMtrrTable[] = {
- { EFI_MSR_IA32_MTRR_FIX64K_00000, 0, 0x10000},
- { EFI_MSR_IA32_MTRR_FIX16K_80000, 0x80000, 0x4000},
- { EFI_MSR_IA32_MTRR_FIX16K_A0000, 0xA0000, 0x4000},
- { EFI_MSR_IA32_MTRR_FIX4K_C0000, 0xC0000, 0x1000},
- { EFI_MSR_IA32_MTRR_FIX4K_C8000, 0xC8000, 0x1000},
- { EFI_MSR_IA32_MTRR_FIX4K_D0000, 0xD0000, 0x1000},
- { EFI_MSR_IA32_MTRR_FIX4K_D8000, 0xD8000, 0x1000},
- { EFI_MSR_IA32_MTRR_FIX4K_E0000, 0xE0000, 0x1000},
- { EFI_MSR_IA32_MTRR_FIX4K_E8000, 0xE8000, 0x1000},
- { EFI_MSR_IA32_MTRR_FIX4K_F0000, 0xF0000, 0x1000},
- { EFI_MSR_IA32_MTRR_FIX4K_F8000, 0xF8000, 0x1000}
-};
-
-/**
- Given the input, check if the number of MTRR is lesser.
- if positive or subtractive.
-
- @param[in] Input Length of Memory to program MTRR.
-
- @retval Zero do positive.
- @retval Non-Zero do subtractive.
-
-**/
-INT8
-CheckDirection (
- IN UINT64 Input
- )
-{
- return 0;
-}
-
-/**
- Disable cache and its mtrr.
-
- @param[out] OldMtrr To return the Old MTRR value
-
-**/
-VOID
-EfiDisableCacheMtrr (
- OUT UINT64 *OldMtrr
- )
-{
- UINT64 TempQword;
-
- //
- // Disable Cache MTRR
- //
- *OldMtrr = AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE);
- TempQword = (*OldMtrr) & ~B_EFI_MSR_GLOBAL_MTRR_ENABLE & ~B_EFI_MSR_FIXED_MTRR_ENABLE;
- AsmWriteMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE, TempQword);
- AsmDisableCache ();
-}
-
-/**
- Recover cache MTRR.
-
- @param[in] EnableMtrr Whether to enable the MTRR
- @param[in] OldMtrr The saved old MTRR value to restore when not to enable the MTRR
-
-**/
-VOID
-EfiRecoverCacheMtrr (
- IN BOOLEAN EnableMtrr,
- IN UINT64 OldMtrr
- )
-{
- UINT64 TempQword;
-
- //
- // Enable Cache MTRR
- //
- if (EnableMtrr) {
- TempQword = AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE);
- TempQword |= (UINT64)(B_EFI_MSR_GLOBAL_MTRR_ENABLE | B_EFI_MSR_FIXED_MTRR_ENABLE);
- } else {
- TempQword = OldMtrr;
- }
-
- AsmWriteMsr64 (EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE, TempQword);
-
- AsmEnableCache ();
-}
-
-/**
- Programming MTRR according to Memory address, length, and type.
-
- @param[in] MtrrNumber the variable MTRR index number
- @param[in] MemoryAddress the address of target memory
- @param[in] MemoryLength the length of target memory
- @param[in] MemoryCacheType the cache type of target memory
- @param[in] ValidMtrrAddressMask the MTRR address mask
-
-**/
-VOID
-EfiProgramMtrr (
- IN UINTN MtrrNumber,
- IN EFI_PHYSICAL_ADDRESS MemoryAddress,
- IN UINT64 MemoryLength,
- IN EFI_MEMORY_CACHE_TYPE MemoryCacheType,
- IN UINT64 ValidMtrrAddressMask
- )
-{
- UINT64 TempQword;
- UINT64 OldMtrr;
-
- if (MemoryLength == 0) {
- return;
- }
-
- EfiDisableCacheMtrr (&OldMtrr);
-
- //
- // MTRR Physical Base
- //
- TempQword = (MemoryAddress & ValidMtrrAddressMask) | MemoryCacheType;
- AsmWriteMsr64 (MtrrNumber, TempQword);
-
- //
- // MTRR Physical Mask
- //
- TempQword = ~(MemoryLength - 1);
- AsmWriteMsr64 (MtrrNumber + 1, (TempQword & ValidMtrrAddressMask) | B_EFI_MSR_CACHE_MTRR_VALID);
-
- EfiRecoverCacheMtrr (TRUE, OldMtrr);
-}
-
-/**
- Calculate the maximum value which is a power of 2, but less the MemoryLength.
-
- @param[in] MemoryAddress Memory address.
- @param[in] MemoryLength The number to pass in.
-
- @return The maximum value which is align to power of 2 and less the MemoryLength
-
-**/
-UINT64
-Power2MaxMemory (
- IN UINT64 MemoryAddress,
- IN UINT64 MemoryLength
- )
-{
- UINT64 Result;
-
- if (MemoryLength == 0) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Compute inital power of 2 size to return
- //
- Result = GetPowerOfTwo64(MemoryLength);
-
- //
- // Special case base of 0 as all ranges are valid
- //
- if (MemoryAddress == 0) {
- return Result;
- }
-
- //
- // Loop till a value that can be mapped to this base address is found
- //
- while (CheckMtrrAlignment (MemoryAddress, Result) != 0) {
- //
- // Need to try the next smaller power of 2
- //
- Result = RShiftU64 (Result, 1);
- }
-
- return Result;
-}
-
-/**
- Return MTRR alignment requirement for base address and size.
-
- @param[in] BaseAddress Base address.
- @param[in] Size Size.
-
- @retval Zero Alligned.
- @retval Non-Zero Not alligned.
-
-**/
-UINT32
-CheckMtrrAlignment (
- IN UINT64 BaseAddress,
- IN UINT64 Size
- )
-{
- UINT32 ShiftedBase;
- UINT32 ShiftedSize;
-
- //
- // Shift base and size right 12 bits to allow for larger memory sizes. The
- // MTRRs do not use the first 12 bits so this is safe for now. Only supports
- // up to 52 bits of physical address space.
- //
- ShiftedBase = (UINT32) RShiftU64 (BaseAddress, 12);
- ShiftedSize = (UINT32) RShiftU64 (Size, 12);
-
- //
- // Return the results to the caller of the MOD
- //
- return ShiftedBase % ShiftedSize;
-}
-
-/**
- Programs fixed MTRRs registers.
-
- @param[in] MemoryCacheType The memory type to set.
- @param[in] Base The base address of memory range.
- @param[in] Length The length of memory range.
-
- @retval RETURN_SUCCESS The cache type was updated successfully
- @retval RETURN_UNSUPPORTED The requested range or cache type was invalid
- for the fixed MTRRs.
-
-**/
-EFI_STATUS
-ProgramFixedMtrr (
- IN EFI_MEMORY_CACHE_TYPE MemoryCacheType,
- IN UINT64 *Base,
- IN UINT64 *Len
- )
-{
- UINT32 MsrNum;
- UINT32 ByteShift;
- UINT64 TempQword;
- UINT64 OrMask;
- UINT64 ClearMask;
-
- TempQword = 0;
- OrMask = 0;
- ClearMask = 0;
-
- for (MsrNum = 0; MsrNum < V_EFI_FIXED_MTRR_NUMBER; MsrNum++) {
- if ((*Base >= mFixedMtrrTable[MsrNum].BaseAddress) &&
- (*Base < (mFixedMtrrTable[MsrNum].BaseAddress + 8 * mFixedMtrrTable[MsrNum].Length))) {
- break;
- }
- }
- if (MsrNum == V_EFI_FIXED_MTRR_NUMBER ) {
- return EFI_DEVICE_ERROR;
- }
- //
- // We found the fixed MTRR to be programmed
- //
- for (ByteShift=0; ByteShift < 8; ByteShift++) {
- if ( *Base == (mFixedMtrrTable[MsrNum].BaseAddress + ByteShift * mFixedMtrrTable[MsrNum].Length)) {
- break;
- }
- }
- if (ByteShift == 8 ) {
- return EFI_DEVICE_ERROR;
- }
- for (; ((ByteShift<8) && (*Len >= mFixedMtrrTable[MsrNum].Length));ByteShift++) {
- OrMask |= LShiftU64((UINT64) MemoryCacheType, (UINT32) (ByteShift* 8));
- ClearMask |= LShiftU64((UINT64) 0xFF, (UINT32) (ByteShift * 8));
- *Len -= mFixedMtrrTable[MsrNum].Length;
- *Base += mFixedMtrrTable[MsrNum].Length;
- }
- TempQword = (AsmReadMsr64 (mFixedMtrrTable[MsrNum].Msr) & (~ClearMask)) | OrMask;
- AsmWriteMsr64 (mFixedMtrrTable[MsrNum].Msr, TempQword);
-
- return EFI_SUCCESS;
-}
-
-/**
- Check if there is a valid variable MTRR that overlaps the given range.
-
- @param[in] Start Base Address of the range to check.
- @param[in] End End address of the range to check.
-
- @retval TRUE Mtrr overlap.
- @retval FALSE Mtrr not overlap.
-**/
-BOOLEAN
-CheckMtrrOverlap (
- IN EFI_PHYSICAL_ADDRESS Start,
- IN EFI_PHYSICAL_ADDRESS End
- )
-{
- return FALSE;
-}
-
-/**
- Given the memory range and cache type, programs the MTRRs.
-
- @param[in] MemoryAddress Base Address of Memory to program MTRR.
- @param[in] MemoryLength Length of Memory to program MTRR.
- @param[in] MemoryCacheType Cache Type.
-
- @retval EFI_SUCCESS Mtrr are set successfully.
- @retval EFI_LOAD_ERROR No empty MTRRs to use.
- @retval EFI_INVALID_PARAMETER The input parameter is not valid.
- @retval others An error occurs when setting MTTR.
-
-**/
-EFI_STATUS
-EFIAPI
-SetCacheAttributes (
- IN EFI_PHYSICAL_ADDRESS MemoryAddress,
- IN UINT64 MemoryLength,
- IN EFI_MEMORY_CACHE_TYPE MemoryCacheType
- )
-{
- EFI_STATUS Status;
- UINT32 MsrNum, MsrNumEnd;
- UINT64 TempQword;
- UINT32 LastVariableMtrrForBios;
- UINT64 OldMtrr;
- UINT32 UsedMsrNum;
- EFI_MEMORY_CACHE_TYPE UsedMemoryCacheType;
- UINT64 ValidMtrrAddressMask;
- UINT32 Cpuid_RegEax;
-
- AsmCpuid (CPUID_EXTENDED_FUNCTION, &Cpuid_RegEax, NULL, NULL, NULL);
- if (Cpuid_RegEax >= CPUID_VIR_PHY_ADDRESS_SIZE) {
- AsmCpuid (CPUID_VIR_PHY_ADDRESS_SIZE, &Cpuid_RegEax, NULL, NULL, NULL);
- ValidMtrrAddressMask = (LShiftU64((UINT64) 1, (Cpuid_RegEax & 0xFF)) - 1) & (~(UINT64)0x0FFF);
- } else {
- ValidMtrrAddressMask = (LShiftU64((UINT64) 1, 36) - 1) & (~(UINT64)0x0FFF);
- }
-
- //
- // Check for invalid parameter
- //
- if ((MemoryAddress & ~ValidMtrrAddressMask) != 0 || (MemoryLength & ~ValidMtrrAddressMask) != 0) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (MemoryLength == 0) {
- return EFI_INVALID_PARAMETER;
- }
-
- switch (MemoryCacheType) {
- case EFI_CACHE_UNCACHEABLE:
- case EFI_CACHE_WRITECOMBINING:
- case EFI_CACHE_WRITETHROUGH:
- case EFI_CACHE_WRITEPROTECTED:
- case EFI_CACHE_WRITEBACK:
- break;
-
- default:
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check if Fixed MTRR
- //
- if ((MemoryAddress + MemoryLength) <= (1 << 20)) {
- Status = EFI_SUCCESS;
- EfiDisableCacheMtrr (&OldMtrr);
- while ((MemoryLength > 0) && (Status == EFI_SUCCESS)) {
- Status = ProgramFixedMtrr (MemoryCacheType, &MemoryAddress, &MemoryLength);
- }
- EfiRecoverCacheMtrr (TRUE, OldMtrr);
- return Status;
- }
-
- //
- // Search if the range attribute has been set before
- //
- Status = SearchForExactMtrr(
- MemoryAddress,
- MemoryLength,
- ValidMtrrAddressMask,
- &UsedMsrNum,
- &UsedMemoryCacheType
- );
-
- if (!EFI_ERROR(Status)) {
- //
- // Compare if it has the same type as current setting
- //
- if (UsedMemoryCacheType == MemoryCacheType) {
- return EFI_SUCCESS;
- } else {
- //
- // Different type
- //
-
- //
- // Check if the set type is the same as Default Type
- //
- if (IsDefaultType(MemoryCacheType)) {
- //
- // Clear the MTRR
- //
- AsmWriteMsr64(UsedMsrNum, 0);
- AsmWriteMsr64(UsedMsrNum + 1, 0);
-
- return EFI_SUCCESS;
- } else {
- //
- // Modify the MTRR type
- //
- EfiProgramMtrr(UsedMsrNum,
- MemoryAddress,
- MemoryLength,
- MemoryCacheType,
- ValidMtrrAddressMask
- );
- return EFI_SUCCESS;
- }
- }
- }
-
-#if 0
- //
- // @bug - Need to create memory map so that when checking for overlap we
- // can determine if an overlap exists based on all caching requests.
- //
- // Don't waste a variable MTRR if the caching attrib is same as default in MTRR_DEF_TYPE
- //
- if (MemoryCacheType == (AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE) & B_EFI_MSR_CACHE_MEMORY_TYPE)) {
- if (!CheckMtrrOverlap (MemoryAddress, MemoryAddress+MemoryLength-1)) {
- return EFI_SUCCESS;
- }
- }
-#endif
-
- //
- // Find first unused MTRR
- //
- MsrNumEnd = EFI_MSR_CACHE_VARIABLE_MTRR_BASE + (2 * (UINT32)(AsmReadMsr64(EFI_MSR_IA32_MTRR_CAP) & B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT));
- for (MsrNum = EFI_MSR_CACHE_VARIABLE_MTRR_BASE; MsrNum < MsrNumEnd; MsrNum +=2) {
- if ((AsmReadMsr64(MsrNum+1) & B_EFI_MSR_CACHE_MTRR_VALID) == 0 ) {
- break;
- }
- }
-
- //
- // Reserve 1 MTRR pair for OS.
- //
- LastVariableMtrrForBios = MsrNumEnd - 1 - (EFI_CACHE_NUM_VAR_MTRR_PAIRS_FOR_OS * 2);
- if (MsrNum > LastVariableMtrrForBios) {
- return EFI_LOAD_ERROR;
- }
-
- //
- // Special case for 1 MB base address
- //
- if (MemoryAddress == BASE_1MB) {
- MemoryAddress = 0;
- }
-
- //
- // Program MTRRs
- //
- TempQword = MemoryLength;
-
- if (TempQword == Power2MaxMemory(MemoryAddress, TempQword)) {
- EfiProgramMtrr(MsrNum,
- MemoryAddress,
- MemoryLength,
- MemoryCacheType,
- ValidMtrrAddressMask
- );
-
- } else {
- //
- // Fill in MTRRs with values. Direction can not be checked for this method
- // as we are using WB as the default cache type and only setting areas to UC.
- //
- do {
- //
- // Do boundary check so we don't go past last MTRR register
- // for BIOS use. Leave one MTRR pair for OS use.
- //
- if (MsrNum > LastVariableMtrrForBios) {
- return EFI_LOAD_ERROR;
- }
-
- //
- // Set next power of 2 region
- //
- MemoryLength = Power2MaxMemory(MemoryAddress, TempQword);
- EfiProgramMtrr(MsrNum,
- MemoryAddress,
- MemoryLength,
- MemoryCacheType,
- ValidMtrrAddressMask
- );
- MemoryAddress += MemoryLength;
- TempQword -= MemoryLength;
- MsrNum += 2;
- } while (TempQword != 0);
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Reset all the MTRRs to a known state.
-
- @retval EFI_SUCCESS All MTRRs have been reset successfully.
-
-**/
-EFI_STATUS
-EFIAPI
-ResetCacheAttributes (
- VOID
- )
-{
- UINT32 MsrNum, MsrNumEnd;
- UINT16 Index;
- UINT64 OldMtrr;
- UINT64 CacheType;
- BOOLEAN DisableCar;
- Index = 0;
- DisableCar = TRUE;
-
- //
- // Determine default cache type
- //
- CacheType = EFI_CACHE_UNCACHEABLE;
-
- //
- // Set default cache type
- //
- AsmWriteMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE, CacheType);
-
- //
- // Disable CAR
- //
- DisableCacheAsRam (DisableCar);
-
- EfiDisableCacheMtrr (&OldMtrr);
-
- //
- // Reset Fixed MTRRs
- //
- for (Index = 0; Index < V_EFI_FIXED_MTRR_NUMBER; Index++) {
- AsmWriteMsr64 (mFixedMtrrTable[Index].Msr, 0);
- }
-
- //
- // Reset Variable MTRRs
- //
- MsrNumEnd = EFI_MSR_CACHE_VARIABLE_MTRR_BASE + (2 * (UINT32)(AsmReadMsr64(EFI_MSR_IA32_MTRR_CAP) & B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT));
- for (MsrNum = EFI_MSR_CACHE_VARIABLE_MTRR_BASE; MsrNum < MsrNumEnd; MsrNum++) {
- AsmWriteMsr64 (MsrNum, 0);
- }
-
- //
- // Enable Fixed and Variable MTRRs
- //
- EfiRecoverCacheMtrr (TRUE, OldMtrr);
-
- return EFI_SUCCESS;
-}
-
-/**
- Search the memory cache type for specific memory from MTRR.
-
- @param[in] MemoryAddress the address of target memory
- @param[in] MemoryLength the length of target memory
- @param[in] ValidMtrrAddressMask the MTRR address mask
- @param[out] UsedMsrNum the used MSR number
- @param[out] UsedMemoryCacheType the cache type for the target memory
-
- @retval EFI_SUCCESS The memory is found in MTRR and cache type is returned
- @retval EFI_NOT_FOUND The memory is not found in MTRR
-
-**/
-EFI_STATUS
-SearchForExactMtrr (
- IN EFI_PHYSICAL_ADDRESS MemoryAddress,
- IN UINT64 MemoryLength,
- IN UINT64 ValidMtrrAddressMask,
- OUT UINT32 *UsedMsrNum,
- OUT EFI_MEMORY_CACHE_TYPE *UsedMemoryCacheType
- )
-{
- UINT32 MsrNum, MsrNumEnd;
- UINT64 TempQword;
-
- if (MemoryLength == 0) {
- return EFI_INVALID_PARAMETER;
- }
-
- MsrNumEnd = EFI_MSR_CACHE_VARIABLE_MTRR_BASE + (2 * (UINT32)(AsmReadMsr64(EFI_MSR_IA32_MTRR_CAP) & B_EFI_MSR_IA32_MTRR_CAP_VARIABLE_SUPPORT));
- for (MsrNum = EFI_MSR_CACHE_VARIABLE_MTRR_BASE; MsrNum < MsrNumEnd; MsrNum +=2) {
- TempQword = AsmReadMsr64(MsrNum+1);
- if ((TempQword & B_EFI_MSR_CACHE_MTRR_VALID) == 0) {
- continue;
- }
-
- if ((TempQword & ValidMtrrAddressMask) != ((~(MemoryLength - 1)) & ValidMtrrAddressMask)) {
- continue;
- }
-
- TempQword = AsmReadMsr64 (MsrNum);
- if ((TempQword & ValidMtrrAddressMask) != (MemoryAddress & ValidMtrrAddressMask)) {
- continue;
- }
-
- *UsedMemoryCacheType = (EFI_MEMORY_CACHE_TYPE)(TempQword & B_EFI_MSR_CACHE_MEMORY_TYPE);
- *UsedMsrNum = MsrNum;
-
- return EFI_SUCCESS;
- }
-
- return EFI_NOT_FOUND;
-}
-
-/**
- Check if CacheType match current default setting.
-
- @param[in] MemoryCacheType input cache type to be checked.
-
- @retval TRUE MemoryCacheType is default MTRR setting.
- @retval TRUE MemoryCacheType is NOT default MTRR setting.
-**/
-BOOLEAN
-IsDefaultType (
- IN EFI_MEMORY_CACHE_TYPE MemoryCacheType
- )
-{
- if ((AsmReadMsr64(EFI_MSR_CACHE_IA32_MTRR_DEF_TYPE) & B_EFI_MSR_CACHE_MEMORY_TYPE) != MemoryCacheType) {
- return FALSE;
- }
-
- return TRUE;
-}
-
|