X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=UefiCpuPkg%2FLibrary%2FMtrrLib%2FMtrrLib.c;h=ea2b211e0580191a5bde922fc5cac6efcb0741b1;hb=85b7f65b39f7e5873b1bb9b99c601b3865e55f93;hp=5f1a22c5fd1cf963caca42190ba323af4392a081;hpb=91ec78241c81a1af766fc5d8cb6c3abf3b0d6b32;p=mirror_edk2.git diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c index 5f1a22c5fd..ea2b211e05 100644 --- a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c +++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c @@ -1,7 +1,7 @@ /** @file MTRR setting library - Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.
+ Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -20,6 +20,14 @@ #include #include +// +// Context to save and restore when MTRRs are programmed +// +typedef struct { + UINTN Cr4; + BOOLEAN InterruptState; +} MTRR_CONTEXT; + // // This table defines the offset, base and length of the fixed MTRRs // @@ -78,7 +86,7 @@ CONST FIXED_MTRR mMtrrLibFixedMtrrTable[] = { MTRR_LIB_IA32_MTRR_FIX4K_F8000, 0xF8000, SIZE_4KB - }, + } }; // @@ -95,6 +103,24 @@ GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mMtrrMemoryCacheTypeShortName[] = { "R*" // Invalid }; +/** + Worker function returns the variable MTRR count for the CPU. + + @return Variable MTRR count + +**/ +UINT32 +GetVariableMtrrCountWorker ( + VOID + ) +{ + UINT32 VariableMtrrCount; + + VariableMtrrCount = (UINT32)(AsmReadMsr64 (MTRR_LIB_IA32_MTRR_CAP) & MTRR_LIB_IA32_MTRR_CAP_VCNT_MASK); + ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR); + return VariableMtrrCount; +} + /** Returns the variable MTRR count for the CPU. @@ -107,16 +133,33 @@ GetVariableMtrrCount ( VOID ) { - UINT32 VariableMtrrCount; - if (!IsMtrrSupported ()) { return 0; } + return GetVariableMtrrCountWorker (); +} - VariableMtrrCount = (UINT32)(AsmReadMsr64 (MTRR_LIB_IA32_MTRR_CAP) & MTRR_LIB_IA32_MTRR_CAP_VCNT_MASK); - ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR); +/** + Worker function returns the firmware usable variable MTRR count for the CPU. - return VariableMtrrCount; + @return Firmware usable variable MTRR count + +**/ +UINT32 +GetFirmwareVariableMtrrCountWorker ( + VOID + ) +{ + UINT32 VariableMtrrCount; + UINT32 ReservedMtrrNumber; + + VariableMtrrCount = GetVariableMtrrCountWorker (); + ReservedMtrrNumber = PcdGet32 (PcdCpuNumberOfReservedVariableMtrrs); + if (VariableMtrrCount < ReservedMtrrNumber) { + return 0; + } + + return VariableMtrrCount - ReservedMtrrNumber; } /** @@ -131,16 +174,27 @@ GetFirmwareVariableMtrrCount ( VOID ) { - UINT32 VariableMtrrCount; - - VariableMtrrCount = GetVariableMtrrCount (); - if (VariableMtrrCount < RESERVED_FIRMWARE_VARIABLE_MTRR_NUMBER) { + if (!IsMtrrSupported ()) { return 0; } + return GetFirmwareVariableMtrrCountWorker (); +} + +/** + Worker function returns the default MTRR cache type for the system. + + @return The default MTRR cache type. - return VariableMtrrCount - RESERVED_FIRMWARE_VARIABLE_MTRR_NUMBER; +**/ +MTRR_MEMORY_CACHE_TYPE +MtrrGetDefaultMemoryTypeWorker ( + VOID + ) +{ + return (MTRR_MEMORY_CACHE_TYPE) (AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE) & 0x7); } + /** Returns the default MTRR cache type for the system. @@ -156,8 +210,7 @@ MtrrGetDefaultMemoryType ( if (!IsMtrrSupported ()) { return CacheUncacheable; } - - return (MTRR_MEMORY_CACHE_TYPE) (AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE) & 0x7); + return MtrrGetDefaultMemoryTypeWorker (); } /** @@ -166,15 +219,18 @@ MtrrGetDefaultMemoryType ( This function will do some preparation for programming MTRRs: disable cache, invalid cache and disable MTRR caching functionality - @return CR4 value before changing. + @param[out] MtrrContext Pointer to context to save **/ -UINTN +VOID PreMtrrChange ( - VOID + OUT MTRR_CONTEXT *MtrrContext ) { - UINTN Value; + // + // Disable interrupts and save current interrupt state + // + MtrrContext->InterruptState = SaveAndDisableInterrupts(); // // Enter no fill cache mode, CD=1(Bit30), NW=0 (Bit29) @@ -184,8 +240,8 @@ PreMtrrChange ( // // Save original CR4 value and clear PGE flag (Bit 7) // - Value = AsmReadCr4 (); - AsmWriteCr4 (Value & (~BIT7)); + MtrrContext->Cr4 = AsmReadCr4 (); + AsmWriteCr4 (MtrrContext->Cr4 & (~BIT7)); // // Flush all TLBs @@ -193,38 +249,27 @@ PreMtrrChange ( CpuFlushTlb (); // - // Disable Mtrrs + // Disable MTRRs // AsmMsrBitFieldWrite64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, 10, 11, 0); - - // - // Return original CR4 value - // - return Value; } - /** Cleaning up after programming MTRRs. This function will do some clean up after programming MTRRs: - enable MTRR caching functionality, and enable cache + Flush all TLBs, re-enable caching, restore CR4. - @param Cr4 CR4 value to restore + @param[in] MtrrContext Pointer to context to restore **/ VOID -PostMtrrChange ( - UINTN Cr4 +PostMtrrChangeEnableCache ( + IN MTRR_CONTEXT *MtrrContext ) { // - // Enable Cache MTRR - // - AsmMsrBitFieldWrite64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, 10, 11, 3); - - // - // Flush all TLBs + // Flush all TLBs // CpuFlushTlb (); @@ -236,16 +281,140 @@ PostMtrrChange ( // // Restore original CR4 value // - AsmWriteCr4 (Cr4); + AsmWriteCr4 (MtrrContext->Cr4); + + // + // Restore original interrupt state + // + SetInterruptState (MtrrContext->InterruptState); +} + +/** + Cleaning up after programming MTRRs. + + This function will do some clean up after programming MTRRs: + enable MTRR caching functionality, and enable cache + + @param[in] MtrrContext Pointer to context to restore + +**/ +VOID +PostMtrrChange ( + IN MTRR_CONTEXT *MtrrContext + ) +{ + // + // Enable Cache MTRR + // + AsmMsrBitFieldWrite64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, 10, 11, 3); + + PostMtrrChangeEnableCache (MtrrContext); +} + +/** + Worker function gets the content in fixed MTRRs + + @param[out] FixedSettings A buffer to hold fixed MTRRs content. + + @retval The pointer of FixedSettings + +**/ +MTRR_FIXED_SETTINGS* +MtrrGetFixedMtrrWorker ( + OUT MTRR_FIXED_SETTINGS *FixedSettings + ) +{ + UINT32 Index; + + for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) { + FixedSettings->Mtrr[Index] = + AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr); + } + + return FixedSettings; +} + + +/** + This function gets the content in fixed MTRRs + + @param[out] FixedSettings A buffer to hold fixed MTRRs content. + + @retval The pointer of FixedSettings + +**/ +MTRR_FIXED_SETTINGS* +EFIAPI +MtrrGetFixedMtrr ( + OUT MTRR_FIXED_SETTINGS *FixedSettings + ) +{ + if (!IsMtrrSupported ()) { + return FixedSettings; + } + + return MtrrGetFixedMtrrWorker (FixedSettings); +} + + +/** + Worker function will get the raw value in variable MTRRs + + @param[out] VariableSettings A buffer to hold variable MTRRs content. + + @return The VariableSettings input pointer + +**/ +MTRR_VARIABLE_SETTINGS* +MtrrGetVariableMtrrWorker ( + OUT MTRR_VARIABLE_SETTINGS *VariableSettings + ) +{ + UINT32 Index; + UINT32 VariableMtrrCount; + + VariableMtrrCount = GetVariableMtrrCount (); + ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR); + + for (Index = 0; Index < VariableMtrrCount; Index++) { + VariableSettings->Mtrr[Index].Base = + AsmReadMsr64 (MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1)); + VariableSettings->Mtrr[Index].Mask = + AsmReadMsr64 (MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1) + 1); + } + + return VariableSettings; } +/** + This function will get the raw value in variable MTRRs + + @param[out] VariableSettings A buffer to hold variable MTRRs content. + + @return The VariableSettings input pointer + +**/ +MTRR_VARIABLE_SETTINGS* +EFIAPI +MtrrGetVariableMtrr ( + OUT MTRR_VARIABLE_SETTINGS *VariableSettings + ) +{ + if (!IsMtrrSupported ()) { + return VariableSettings; + } + + return MtrrGetVariableMtrrWorker ( + VariableSettings + ); +} /** Programs fixed MTRRs registers. - @param MemoryCacheType The memory type to set. - @param Base The base address of memory range. - @param Length The length of memory range. + @param[in] MemoryCacheType The memory type to set. + @param[in, out] Base The base address of memory range. + @param[in, out] 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 @@ -327,14 +496,14 @@ ProgramFixedMtrr ( /** - Get the attribute of variable MTRRs. + Gets the attribute of variable MTRRs. This function shadows the content of variable MTRRs into an internal array: VariableMtrr. - @param MtrrValidBitsMask The mask for the valid bit of the MTRR - @param MtrrValidAddressMask The valid address mask for MTRR - @param VariableMtrr The array to shadow variable MTRRs content + @param[in] MtrrValidBitsMask The mask for the valid bit of the MTRR + @param[in] MtrrValidAddressMask The valid address mask for MTRR + @param[out] VariableMtrr The array to shadow variable MTRRs content @return The return value of this paramter indicates the number of MTRRs which has been used. @@ -394,9 +563,9 @@ MtrrGetMemoryAttributeInVariableMtrr ( /** Checks overlap between given memory range and MTRRs. - @param Start The start address of memory range. - @param End The end address of memory range. - @param VariableMtrr The array to shadow variable MTRRs content + @param[in] Start The start address of memory range. + @param[in] End The end address of memory range. + @param[in] VariableMtrr The array to shadow variable MTRRs content @retval TRUE Overlap exists. @retval FALSE No overlap. @@ -432,9 +601,9 @@ CheckMemoryAttributeOverlap ( /** Marks a variable MTRR as non-valid. - @param Index The index of the array VariableMtrr to be invalidated - @param VariableMtrr The array to shadow variable MTRRs content - @param UsedMtrr The number of MTRRs which has already been used + @param[in] Index The index of the array VariableMtrr to be invalidated + @param[in] VariableMtrr The array to shadow variable MTRRs content + @param[out] UsedMtrr The number of MTRRs which has already been used **/ VOID @@ -450,16 +619,16 @@ InvalidateShadowMtrr ( /** - Combine memory attributes. + Combines memory attributes. If overlap exists between given memory range and MTRRs, try to combine them. - @param Attributes The memory type to set. - @param Base The base address of memory range. - @param Length The length of memory range. - @param VariableMtrr The array to shadow variable MTRRs content - @param UsedMtrr The number of MTRRs which has already been used - @param OverwriteExistingMtrr Returns whether an existing MTRR was used + @param[in] Attributes The memory type to set. + @param[in, out] Base The base address of memory range. + @param[in, out] Length The length of memory range. + @param[in] VariableMtrr The array to shadow variable MTRRs content + @param[in, out] UsedMtrr The number of MTRRs which has already been used + @param[out] OverwriteExistingMtrr Returns whether an existing MTRR was used @retval EFI_SUCCESS Memory region successfully combined. @retval EFI_ACCESS_DENIED Memory region cannot be combined. @@ -507,7 +676,7 @@ CombineMemoryAttribute ( // if (Attributes == VariableMtrr[Index].Type) { // - // if the Mtrr range contain the request range, set a flag, then continue to + // if the MTRR range contain the request range, set a flag, then continue to // invalidate any MTRR of the same request range with higher priority cache type. // if (VariableMtrr[Index].BaseAddress <= *Base && MtrrEnd >= EndAddress) { @@ -568,9 +737,10 @@ CombineMemoryAttribute ( /** - Calculate the maximum value which is a power of 2, but less the MemoryLength. + Calculates the maximum value which is a power of 2, but less the MemoryLength. + + @param[in] MemoryLength The number to pass in. - @param MemoryLength The number to pass in. @return The maximum value which is align to power of 2 and less the MemoryLength **/ @@ -597,21 +767,22 @@ Power2MaxMemory ( /** - Determine the MTRR numbers used to program a memory range. + Determines the MTRR numbers used to program a memory range. - This function first checks the alignment of the base address. If the alignment of the base address <= Length, - cover the memory range (BaseAddress, alignment) by a MTRR, then BaseAddress += alignment and Length -= alignment. - Repeat the step until alignment > Length. + This function first checks the alignment of the base address. + If the alignment of the base address <= Length, cover the memory range + (BaseAddress, alignment) by a MTRR, then BaseAddress += alignment and + Length -= alignment. Repeat the step until alignment > Length. - Then this function determines which direction of programming the variable MTRRs for the remaining length - will use fewer MTRRs. + Then this function determines which direction of programming the variable + MTRRs for the remaining length will use fewer MTRRs. - @param BaseAddress Length of Memory to program MTRR - @param Length Length of Memory to program MTRR - @param MtrrNumber Pointer to the number of necessary MTRRs + @param[in] BaseAddress Length of Memory to program MTRR + @param[in] Length Length of Memory to program MTRR + @param[in] MtrrNumber Pointer to the number of necessary MTRRs @retval TRUE Positive direction is better. - FALSE Negtive direction is better. + FALSE Negative direction is better. **/ BOOLEAN @@ -680,19 +851,19 @@ GetMtrrNumberAndDirection ( This function programs MTRRs according to the values specified in the shadow array. - @param VariableMtrr The array to shadow variable MTRRs content + @param[in, out] VariableMtrr Shadow of variable MTRR contents **/ VOID InvalidateMtrr ( - IN VARIABLE_MTRR *VariableMtrr - ) + IN OUT VARIABLE_MTRR *VariableMtrr + ) { - UINTN Index; - UINTN Cr4; - UINTN VariableMtrrCount; + UINTN Index; + UINTN VariableMtrrCount; + MTRR_CONTEXT MtrrContext; - Cr4 = PreMtrrChange (); + PreMtrrChange (&MtrrContext); Index = 0; VariableMtrrCount = GetVariableMtrrCount (); while (Index < VariableMtrrCount) { @@ -703,7 +874,7 @@ InvalidateMtrr ( } Index ++; } - PostMtrrChange (Cr4); + PostMtrrChange (&MtrrContext); } @@ -712,11 +883,11 @@ InvalidateMtrr ( This function programs variable MTRRs - @param MtrrNumber Index of MTRR to program. - @param BaseAddress Base address of memory region. - @param Length Length of memory region. - @param MemoryCacheType Memory type to set. - @param MtrrValidAddressMask The valid address mask for MTRR + @param[in] MtrrNumber Index of MTRR to program. + @param[in] BaseAddress Base address of memory region. + @param[in] Length Length of memory region. + @param[in] MemoryCacheType Memory type to set. + @param[in] MtrrValidAddressMask The valid address mask for MTRR **/ VOID @@ -728,10 +899,10 @@ ProgramVariableMtrr ( IN UINT64 MtrrValidAddressMask ) { - UINT64 TempQword; - UINTN Cr4; + UINT64 TempQword; + MTRR_CONTEXT MtrrContext; - Cr4 = PreMtrrChange (); + PreMtrrChange (&MtrrContext); // // MTRR Physical Base @@ -748,14 +919,14 @@ ProgramVariableMtrr ( (TempQword & MtrrValidAddressMask) | MTRR_LIB_CACHE_MTRR_ENABLED ); - PostMtrrChange (Cr4); + PostMtrrChange (&MtrrContext); } /** - Convert the Memory attibute value to MTRR_MEMORY_CACHE_TYPE. + Converts the Memory attribute value to MTRR_MEMORY_CACHE_TYPE. - @param MtrrType MTRR memory type + @param[in] MtrrType MTRR memory type @return The enum item in MTRR_MEMORY_CACHE_TYPE @@ -779,9 +950,9 @@ GetMemoryCacheTypeFromMtrrType ( default: // // MtrrType is MTRR_CACHE_INVALID_TYPE, that means - // no mtrr covers the range + // no MTRR covers the range // - return CacheUncacheable; + return MtrrGetDefaultMemoryType (); } } @@ -790,8 +961,8 @@ GetMemoryCacheTypeFromMtrrType ( This function initializes the valid bits mask and valid address mask for MTRRs. - @param MtrrValidBitsMask The mask for the valid bit of the MTRR - @param MtrrValidAddressMask The valid address mask for the MTRR + @param[out] MtrrValidBitsMask The mask for the valid bit of the MTRR + @param[out] MtrrValidAddressMask The valid address mask for the MTRR **/ VOID @@ -813,28 +984,28 @@ MtrrLibInitializeMtrrMask ( *MtrrValidBitsMask = LShiftU64 (1, PhysicalAddressBits) - 1; *MtrrValidAddressMask = *MtrrValidBitsMask & 0xfffffffffffff000ULL; } else { - *MtrrValidBitsMask = MTRR_LIB_CACHE_VALID_ADDRESS; - *MtrrValidAddressMask = 0xFFFFFFFF; + *MtrrValidBitsMask = MTRR_LIB_MSR_VALID_MASK; + *MtrrValidAddressMask = MTRR_LIB_CACHE_VALID_ADDRESS; } } /** - Determing the real attribute of a memory range. + Determines the real attribute of a memory range. This function is to arbitrate the real attribute of the memory when - there are 2 MTRR covers the same memory range. For further details, + there are 2 MTRRs covers the same memory range. For further details, please refer the IA32 Software Developer's Manual, Volume 3, Section 10.11.4.1. - @param MtrrType1 the first kind of Memory type - @param MtrrType2 the second kind of memory type + @param[in] MtrrType1 The first kind of Memory type + @param[in] MtrrType2 The second kind of memory type **/ UINT64 MtrrPrecedence ( - UINT64 MtrrType1, - UINT64 MtrrType2 + IN UINT64 MtrrType1, + IN UINT64 MtrrType2 ) { UINT64 MtrrType; @@ -891,79 +1062,321 @@ MtrrPrecedence ( } + /** - This function attempts to set the attributes for a memory range. + This function will get the memory cache type of the specific address. - @param BaseAddress The physical address that is the start - address of a memory region. - @param Length The size in bytes of the memory region. - @param Attributes The bit mask of attributes to set for the - memory region. + This function is mainly for debug purpose. - @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. + @param[in] Address The specific address + + @return Memory cache type of the specific address **/ -RETURN_STATUS +MTRR_MEMORY_CACHE_TYPE EFIAPI -MtrrSetMemoryAttribute ( - IN PHYSICAL_ADDRESS BaseAddress, - IN UINT64 Length, - IN MTRR_MEMORY_CACHE_TYPE Attribute +MtrrGetMemoryAttribute ( + IN PHYSICAL_ADDRESS Address ) { - UINT64 TempQword; - RETURN_STATUS Status; - UINT64 MemoryType; - UINT64 Alignment; - BOOLEAN OverLap; - BOOLEAN Positive; - UINT32 MsrNum; - UINTN MtrrNumber; - VARIABLE_MTRR VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR]; - UINT32 UsedMtrr; - UINT64 MtrrValidBitsMask; - UINT64 MtrrValidAddressMask; - UINTN Cr4; - BOOLEAN OverwriteExistingMtrr; - UINT32 FirmwareVariableMtrrCount; - UINT32 VariableMtrrEnd; - - DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttribute() %a:%016lx-%016lx\n", mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length)); + UINT64 TempQword; + UINTN Index; + UINTN SubIndex; + UINT64 MtrrType; + UINT64 TempMtrrType; + MTRR_MEMORY_CACHE_TYPE CacheType; + VARIABLE_MTRR VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR]; + UINT64 MtrrValidBitsMask; + UINT64 MtrrValidAddressMask; + UINTN VariableMtrrCount; if (!IsMtrrSupported ()) { - Status = RETURN_UNSUPPORTED; - goto Done; + return CacheUncacheable; } - FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCount (); - VariableMtrrEnd = MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (2 * GetVariableMtrrCount ()) - 1; - - MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask); - - TempQword = 0; - MemoryType = (UINT64)Attribute; - OverwriteExistingMtrr = FALSE; - // - // Check for an invalid parameter + // Check if MTRR is enabled, if not, return UC as attribute // - if (Length == 0) { - Status = RETURN_INVALID_PARAMETER; - goto Done; + TempQword = AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE); + MtrrType = MTRR_CACHE_INVALID_TYPE; + + if ((TempQword & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) { + return CacheUncacheable; + } + + // + // If address is less than 1M, then try to go through the fixed MTRR + // + if (Address < BASE_1MB) { + if ((TempQword & MTRR_LIB_CACHE_FIXED_MTRR_ENABLED) != 0) { + // + // Go through the fixed MTRR + // + for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) { + if (Address >= mMtrrLibFixedMtrrTable[Index].BaseAddress && + Address < ( + mMtrrLibFixedMtrrTable[Index].BaseAddress + + (mMtrrLibFixedMtrrTable[Index].Length * 8) + ) + ) { + SubIndex = + ((UINTN)Address - mMtrrLibFixedMtrrTable[Index].BaseAddress) / + mMtrrLibFixedMtrrTable[Index].Length; + TempQword = AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr); + MtrrType = RShiftU64 (TempQword, SubIndex * 8) & 0xFF; + return GetMemoryCacheTypeFromMtrrType (MtrrType); + } + } + } + } + MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask); + MtrrGetMemoryAttributeInVariableMtrr( + MtrrValidBitsMask, + MtrrValidAddressMask, + VariableMtrr + ); + + // + // Go through the variable MTRR + // + VariableMtrrCount = GetVariableMtrrCount (); + ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR); + + for (Index = 0; Index < VariableMtrrCount; Index++) { + if (VariableMtrr[Index].Valid) { + if (Address >= VariableMtrr[Index].BaseAddress && + Address < VariableMtrr[Index].BaseAddress+VariableMtrr[Index].Length) { + TempMtrrType = VariableMtrr[Index].Type; + MtrrType = MtrrPrecedence (MtrrType, TempMtrrType); + } + } + } + CacheType = GetMemoryCacheTypeFromMtrrType (MtrrType); + + return CacheType; +} + + + +/** + This function prints all MTRRs for debugging. +**/ +VOID +EFIAPI +MtrrDebugPrintAllMtrrs ( + VOID + ) +{ + DEBUG_CODE ( + MTRR_SETTINGS MtrrSettings; + UINTN Index; + UINTN Index1; + UINTN VariableMtrrCount; + UINT64 Base; + UINT64 Limit; + UINT64 MtrrBase; + UINT64 MtrrLimit; + UINT64 RangeBase; + UINT64 RangeLimit; + UINT64 NoRangeBase; + UINT64 NoRangeLimit; + UINT32 RegEax; + UINTN MemoryType; + UINTN PreviousMemoryType; + BOOLEAN Found; + + if (!IsMtrrSupported ()) { + return; + } + + DEBUG((DEBUG_CACHE, "MTRR Settings\n")); + DEBUG((DEBUG_CACHE, "=============\n")); + + MtrrGetAllMtrrs (&MtrrSettings); + DEBUG((DEBUG_CACHE, "MTRR Default Type: %016lx\n", MtrrSettings.MtrrDefType)); + for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) { + DEBUG((DEBUG_CACHE, "Fixed MTRR[%02d] : %016lx\n", Index, MtrrSettings.Fixed.Mtrr[Index])); + } + + VariableMtrrCount = GetVariableMtrrCount (); + for (Index = 0; Index < VariableMtrrCount; Index++) { + DEBUG((DEBUG_CACHE, "Variable MTRR[%02d]: Base=%016lx Mask=%016lx\n", + Index, + MtrrSettings.Variables.Mtrr[Index].Base, + MtrrSettings.Variables.Mtrr[Index].Mask + )); + } + DEBUG((DEBUG_CACHE, "\n")); + DEBUG((DEBUG_CACHE, "MTRR Ranges\n")); + DEBUG((DEBUG_CACHE, "====================================\n")); + + Base = 0; + PreviousMemoryType = MTRR_CACHE_INVALID_TYPE; + for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) { + Base = mMtrrLibFixedMtrrTable[Index].BaseAddress; + for (Index1 = 0; Index1 < 8; Index1++) { + MemoryType = (UINTN)(RShiftU64 (MtrrSettings.Fixed.Mtrr[Index], Index1 * 8) & 0xff); + if (MemoryType > CacheWriteBack) { + MemoryType = MTRR_CACHE_INVALID_TYPE; + } + if (MemoryType != PreviousMemoryType) { + if (PreviousMemoryType != MTRR_CACHE_INVALID_TYPE) { + DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1)); + } + PreviousMemoryType = MemoryType; + DEBUG((DEBUG_CACHE, "%a:%016lx-", mMtrrMemoryCacheTypeShortName[MemoryType], Base)); + } + Base += mMtrrLibFixedMtrrTable[Index].Length; + } + } + DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1)); + + VariableMtrrCount = GetVariableMtrrCount (); + + Limit = BIT36 - 1; + AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); + if (RegEax >= 0x80000008) { + AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL); + Limit = LShiftU64 (1, RegEax & 0xff) - 1; + } + Base = BASE_1MB; + PreviousMemoryType = MTRR_CACHE_INVALID_TYPE; + do { + MemoryType = MtrrGetMemoryAttribute (Base); + if (MemoryType > CacheWriteBack) { + MemoryType = MTRR_CACHE_INVALID_TYPE; + } + + if (MemoryType != PreviousMemoryType) { + if (PreviousMemoryType != MTRR_CACHE_INVALID_TYPE) { + DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1)); + } + PreviousMemoryType = MemoryType; + DEBUG((DEBUG_CACHE, "%a:%016lx-", mMtrrMemoryCacheTypeShortName[MemoryType], Base)); + } + + RangeBase = BASE_1MB; + NoRangeBase = BASE_1MB; + RangeLimit = Limit; + NoRangeLimit = Limit; + + for (Index = 0, Found = FALSE; Index < VariableMtrrCount; Index++) { + if ((MtrrSettings.Variables.Mtrr[Index].Mask & BIT11) == 0) { + // + // If mask is not valid, then do not display range + // + continue; + } + MtrrBase = (MtrrSettings.Variables.Mtrr[Index].Base & (~(SIZE_4KB - 1))); + MtrrLimit = MtrrBase + ((~(MtrrSettings.Variables.Mtrr[Index].Mask & (~(SIZE_4KB - 1)))) & Limit); + + if (Base >= MtrrBase && Base < MtrrLimit) { + Found = TRUE; + } + + if (Base >= MtrrBase && MtrrBase > RangeBase) { + RangeBase = MtrrBase; + } + if (Base > MtrrLimit && MtrrLimit > RangeBase) { + RangeBase = MtrrLimit + 1; + } + if (Base < MtrrBase && MtrrBase < RangeLimit) { + RangeLimit = MtrrBase - 1; + } + if (Base < MtrrLimit && MtrrLimit <= RangeLimit) { + RangeLimit = MtrrLimit; + } + + if (Base > MtrrLimit && NoRangeBase < MtrrLimit) { + NoRangeBase = MtrrLimit + 1; + } + if (Base < MtrrBase && NoRangeLimit > MtrrBase) { + NoRangeLimit = MtrrBase - 1; + } + } + + if (Found) { + Base = RangeLimit + 1; + } else { + Base = NoRangeLimit + 1; + } + } while (Base < Limit); + DEBUG((DEBUG_CACHE, "%016lx\n\n", Base - 1)); + ); +} +/** + 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] 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 +MtrrSetMemoryAttribute ( + IN PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN MTRR_MEMORY_CACHE_TYPE Attribute + ) +{ + UINT64 TempQword; + RETURN_STATUS Status; + UINT64 MemoryType; + UINT64 Alignment; + BOOLEAN OverLap; + BOOLEAN Positive; + UINT32 MsrNum; + UINTN MtrrNumber; + VARIABLE_MTRR VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR]; + UINT32 UsedMtrr; + UINT64 MtrrValidBitsMask; + UINT64 MtrrValidAddressMask; + BOOLEAN OverwriteExistingMtrr; + UINT32 FirmwareVariableMtrrCount; + UINT32 VariableMtrrEnd; + MTRR_CONTEXT MtrrContext; + + DEBUG((DEBUG_CACHE, "MtrrSetMemoryAttribute() %a:%016lx-%016lx\n", mMtrrMemoryCacheTypeShortName[Attribute], BaseAddress, Length)); + + if (!IsMtrrSupported ()) { + Status = RETURN_UNSUPPORTED; + goto Done; + } + + FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCount (); + VariableMtrrEnd = MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (2 * GetVariableMtrrCount ()) - 1; + + MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask); + + TempQword = 0; + MemoryType = (UINT64)Attribute; + OverwriteExistingMtrr = FALSE; + + // + // Check for an invalid parameter + // + if (Length == 0) { + Status = RETURN_INVALID_PARAMETER; + goto Done; } if ( @@ -979,9 +1392,9 @@ MtrrSetMemoryAttribute ( // Status = RETURN_SUCCESS; while ((BaseAddress < BASE_1MB) && (Length > 0) && Status == RETURN_SUCCESS) { - Cr4 = PreMtrrChange (); + PreMtrrChange (&MtrrContext); Status = ProgramFixedMtrr (MemoryType, &BaseAddress, &Length); - PostMtrrChange (Cr4); + PostMtrrChange (&MtrrContext); if (RETURN_ERROR (Status)) { goto Done; } @@ -1026,16 +1439,6 @@ MtrrSetMemoryAttribute ( } } - // - // Program Variable MTRRs - // - // Avoid hardcode here and read data dynamically - // - if (UsedMtrr >= FirmwareVariableMtrrCount) { - Status = RETURN_OUT_OF_RESOURCES; - goto Done; - } - // // The memory type is the same with the type specified by // MTRR_LIB_IA32_MTRR_DEF_TYPE. @@ -1089,224 +1492,93 @@ MtrrSetMemoryAttribute ( for (; MsrNum < VariableMtrrEnd; MsrNum += 2) { if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) { break; - } - } - - ProgramVariableMtrr ( - MsrNum, - BaseAddress, - Alignment, - MemoryType, - MtrrValidAddressMask - ); - BaseAddress += Alignment; - Length -= Alignment; - } while (TRUE); - - if (Length == 0) { - goto Done; - } - } - - TempQword = Length; - - if (!Positive) { - Length = Power2MaxMemory (LShiftU64 (TempQword, 1)); - - // - // Find unused MTRR - // - for (; MsrNum < VariableMtrrEnd; MsrNum += 2) { - if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) { - break; - } - } - - ProgramVariableMtrr ( - MsrNum, - BaseAddress, - Length, - MemoryType, - MtrrValidAddressMask - ); - BaseAddress += Length; - TempQword = Length - TempQword; - MemoryType = MTRR_CACHE_UNCACHEABLE; - } - - do { - // - // Find unused MTRR - // - for (; MsrNum < VariableMtrrEnd; MsrNum += 2) { - if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) { - break; - } - } - - Length = Power2MaxMemory (TempQword); - if (!Positive) { - BaseAddress -= Length; - } - - ProgramVariableMtrr ( - MsrNum, - BaseAddress, - Length, - MemoryType, - MtrrValidAddressMask - ); - - if (Positive) { - BaseAddress += Length; - } - TempQword -= Length; - - } while (TempQword > 0); - -Done: - DEBUG((DEBUG_CACHE, " Status = %r\n", Status)); - if (!RETURN_ERROR (Status)) { - MtrrDebugPrintAllMtrrs (); - } - - return Status; -} - - -/** - This function will get the memory cache type of the specific address. - - This function is mainly for debug purpose. - - @param Address The specific address - - @return Memory cache type of the sepcific address - -**/ -MTRR_MEMORY_CACHE_TYPE -EFIAPI -MtrrGetMemoryAttribute ( - IN PHYSICAL_ADDRESS Address - ) -{ - UINT64 TempQword; - UINTN Index; - UINTN SubIndex; - UINT64 MtrrType; - UINT64 TempMtrrType; - MTRR_MEMORY_CACHE_TYPE CacheType; - VARIABLE_MTRR VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR]; - UINT64 MtrrValidBitsMask; - UINT64 MtrrValidAddressMask; - UINTN VariableMtrrCount; - - if (!IsMtrrSupported ()) { - return CacheUncacheable; - } - - // - // Check if MTRR is enabled, if not, return UC as attribute - // - TempQword = AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE); - MtrrType = MTRR_CACHE_INVALID_TYPE; - - if ((TempQword & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) { - return CacheUncacheable; - } - - // - // If address is less than 1M, then try to go through the fixed MTRR - // - if (Address < BASE_1MB) { - if ((TempQword & MTRR_LIB_CACHE_FIXED_MTRR_ENABLED) != 0) { - // - // Go through the fixed MTRR - // - for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) { - if (Address >= mMtrrLibFixedMtrrTable[Index].BaseAddress && - Address < ( - mMtrrLibFixedMtrrTable[Index].BaseAddress + - (mMtrrLibFixedMtrrTable[Index].Length * 8) - ) - ) { - SubIndex = - ((UINTN)Address - mMtrrLibFixedMtrrTable[Index].BaseAddress) / - mMtrrLibFixedMtrrTable[Index].Length; - TempQword = AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr); - MtrrType = RShiftU64 (TempQword, SubIndex * 8) & 0xFF; - return GetMemoryCacheTypeFromMtrrType (MtrrType); - } - } - } - } - MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask); - MtrrGetMemoryAttributeInVariableMtrr( - MtrrValidBitsMask, - MtrrValidAddressMask, - VariableMtrr - ); - - // - // Go through the variable MTRR - // - VariableMtrrCount = GetVariableMtrrCount (); - ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR); - - for (Index = 0; Index < VariableMtrrCount; Index++) { - if (VariableMtrr[Index].Valid) { - if (Address >= VariableMtrr[Index].BaseAddress && - Address < VariableMtrr[Index].BaseAddress+VariableMtrr[Index].Length) { - TempMtrrType = VariableMtrr[Index].Type; - MtrrType = MtrrPrecedence (MtrrType, TempMtrrType); + } } + + ProgramVariableMtrr ( + MsrNum, + BaseAddress, + Alignment, + MemoryType, + MtrrValidAddressMask + ); + BaseAddress += Alignment; + Length -= Alignment; + } while (TRUE); + + if (Length == 0) { + goto Done; } } - CacheType = GetMemoryCacheTypeFromMtrrType (MtrrType); - return CacheType; -} + TempQword = Length; + if (!Positive) { + Length = Power2MaxMemory (LShiftU64 (TempQword, 1)); -/** - This function will get the raw value in variable MTRRs + // + // Find unused MTRR + // + for (; MsrNum < VariableMtrrEnd; MsrNum += 2) { + if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) { + break; + } + } - @param VariableSettings A buffer to hold variable MTRRs content. + ProgramVariableMtrr ( + MsrNum, + BaseAddress, + Length, + MemoryType, + MtrrValidAddressMask + ); + BaseAddress += Length; + TempQword = Length - TempQword; + MemoryType = MTRR_CACHE_UNCACHEABLE; + } - @return The VariableSettings input pointer + do { + // + // Find unused MTRR + // + for (; MsrNum < VariableMtrrEnd; MsrNum += 2) { + if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) { + break; + } + } -**/ -MTRR_VARIABLE_SETTINGS* -EFIAPI -MtrrGetVariableMtrr ( - OUT MTRR_VARIABLE_SETTINGS *VariableSettings - ) -{ - UINT32 Index; - UINT32 VariableMtrrCount; + Length = Power2MaxMemory (TempQword); + if (!Positive) { + BaseAddress -= Length; + } - if (!IsMtrrSupported ()) { - return VariableSettings; - } + ProgramVariableMtrr ( + MsrNum, + BaseAddress, + Length, + MemoryType, + MtrrValidAddressMask + ); - VariableMtrrCount = GetVariableMtrrCount (); - ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR); + if (Positive) { + BaseAddress += Length; + } + TempQword -= Length; - for (Index = 0; Index < VariableMtrrCount; Index++) { - VariableSettings->Mtrr[Index].Base = - AsmReadMsr64 (MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1)); - VariableSettings->Mtrr[Index].Mask = - AsmReadMsr64 (MTRR_LIB_IA32_VARIABLE_MTRR_BASE + (Index << 1) + 1); + } while (TempQword > 0); + +Done: + DEBUG((DEBUG_CACHE, " Status = %r\n", Status)); + if (!RETURN_ERROR (Status)) { + MtrrDebugPrintAllMtrrs (); } - return VariableSettings; + return Status; } - - /** Worker function setting variable MTRRs - @param VariableSettings A buffer to hold variable MTRRs content. + @param[in] VariableSettings A buffer to hold variable MTRRs content. **/ VOID @@ -1336,7 +1608,7 @@ MtrrSetVariableMtrrWorker ( /** This function sets variable MTRRs - @param VariableSettings A buffer to hold variable MTRRs content. + @param[in] VariableSettings A buffer to hold variable MTRRs content. @return The pointer of VariableSettings @@ -1347,51 +1619,22 @@ MtrrSetVariableMtrr ( IN MTRR_VARIABLE_SETTINGS *VariableSettings ) { - UINTN Cr4; + MTRR_CONTEXT MtrrContext; if (!IsMtrrSupported ()) { return VariableSettings; } - Cr4 = PreMtrrChange (); + PreMtrrChange (&MtrrContext); MtrrSetVariableMtrrWorker (VariableSettings); - PostMtrrChange (Cr4); + PostMtrrChange (&MtrrContext); return VariableSettings; } - -/** - This function gets the content in fixed MTRRs - - @param FixedSettings A buffer to hold fixed Mtrrs content. - - @retval The pointer of FixedSettings - -**/ -MTRR_FIXED_SETTINGS* -EFIAPI -MtrrGetFixedMtrr ( - OUT MTRR_FIXED_SETTINGS *FixedSettings - ) -{ - UINT32 Index; - - if (!IsMtrrSupported ()) { - return FixedSettings; - } - - for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) { - FixedSettings->Mtrr[Index] = - AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr); - }; - - return FixedSettings; -} - /** Worker function setting fixed MTRRs - @param FixedSettings A buffer to hold fixed Mtrrs content. + @param[in] FixedSettings A buffer to hold fixed Mtrrs content. **/ VOID @@ -1413,7 +1656,7 @@ MtrrSetFixedMtrrWorker ( /** This function sets fixed MTRRs - @param FixedSettings A buffer to hold fixed Mtrrs content. + @param[in] FixedSettings A buffer to hold fixed Mtrrs content. @retval The pointer of FixedSettings @@ -1424,15 +1667,15 @@ MtrrSetFixedMtrr ( IN MTRR_FIXED_SETTINGS *FixedSettings ) { - UINTN Cr4; + MTRR_CONTEXT MtrrContext; if (!IsMtrrSupported ()) { return FixedSettings; } - Cr4 = PreMtrrChange (); + PreMtrrChange (&MtrrContext); MtrrSetFixedMtrrWorker (FixedSettings); - PostMtrrChange (Cr4); + PostMtrrChange (&MtrrContext); return FixedSettings; } @@ -1441,7 +1684,7 @@ MtrrSetFixedMtrr ( /** This function gets the content in all MTRRs (variable and fixed) - @param MtrrSetting A buffer to hold all Mtrrs content. + @param[out] MtrrSetting A buffer to hold all Mtrrs content. @retval the pointer of MtrrSetting @@ -1478,7 +1721,7 @@ MtrrGetAllMtrrs ( /** This function sets all MTRRs (variable and fixed) - @param MtrrSetting A buffer holding all MTRRs content. + @param[in] MtrrSetting A buffer holding all MTRRs content. @retval The pointer of MtrrSetting @@ -1489,13 +1732,13 @@ MtrrSetAllMtrrs ( IN MTRR_SETTINGS *MtrrSetting ) { - UINTN Cr4; + MTRR_CONTEXT MtrrContext; if (!IsMtrrSupported ()) { return MtrrSetting; } - Cr4 = PreMtrrChange (); + PreMtrrChange (&MtrrContext); // // Set fixed MTRRs @@ -1512,158 +1755,11 @@ MtrrSetAllMtrrs ( // AsmWriteMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE, MtrrSetting->MtrrDefType); - PostMtrrChange (Cr4); + PostMtrrChangeEnableCache (&MtrrContext); return MtrrSetting; } -/** - This function prints all MTRRs for debugging. -**/ -VOID -EFIAPI -MtrrDebugPrintAllMtrrs ( - VOID - ) -{ - DEBUG_CODE ( - MTRR_SETTINGS MtrrSettings; - UINTN Index; - UINTN Index1; - UINTN VariableMtrrCount; - UINT64 Base; - UINT64 Limit; - UINT64 MtrrBase; - UINT64 MtrrLimit; - UINT64 RangeBase; - UINT64 RangeLimit; - UINT64 NoRangeBase; - UINT64 NoRangeLimit; - UINT32 RegEax; - UINTN MemoryType; - UINTN PreviousMemoryType; - BOOLEAN Found; - - if (!IsMtrrSupported ()) { - return; - } - - DEBUG((DEBUG_CACHE, "MTRR Settings\n")); - DEBUG((DEBUG_CACHE, "=============\n")); - - MtrrGetAllMtrrs (&MtrrSettings); - DEBUG((DEBUG_CACHE, "MTRR Default Type: %016lx\n", MtrrSettings.MtrrDefType)); - for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) { - DEBUG((DEBUG_CACHE, "Fixed MTRR[%02d] : %016lx\n", Index, MtrrSettings.Fixed.Mtrr[Index])); - } - - VariableMtrrCount = GetVariableMtrrCount (); - for (Index = 0; Index < VariableMtrrCount; Index++) { - DEBUG((DEBUG_CACHE, "Variable MTRR[%02d]: Base=%016lx Mask=%016lx\n", - Index, - MtrrSettings.Variables.Mtrr[Index].Base, - MtrrSettings.Variables.Mtrr[Index].Mask - )); - } - DEBUG((DEBUG_CACHE, "\n")); - DEBUG((DEBUG_CACHE, "MTRR Ranges\n")); - DEBUG((DEBUG_CACHE, "====================================\n")); - - Base = 0; - PreviousMemoryType = MTRR_CACHE_INVALID_TYPE; - for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) { - Base = mMtrrLibFixedMtrrTable[Index].BaseAddress; - for (Index1 = 0; Index1 < 8; Index1++) { - MemoryType = (UINTN)(RShiftU64 (MtrrSettings.Fixed.Mtrr[Index], Index1 * 8) & 0xff); - if (MemoryType > CacheWriteBack) { - MemoryType = MTRR_CACHE_INVALID_TYPE; - } - if (MemoryType != PreviousMemoryType) { - if (PreviousMemoryType != MTRR_CACHE_INVALID_TYPE) { - DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1)); - } - PreviousMemoryType = MemoryType; - DEBUG((DEBUG_CACHE, "%a:%016lx-", mMtrrMemoryCacheTypeShortName[MemoryType], Base)); - } - Base += mMtrrLibFixedMtrrTable[Index].Length; - } - } - DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1)); - - VariableMtrrCount = GetVariableMtrrCount (); - - Base = BASE_1MB; - PreviousMemoryType = MTRR_CACHE_INVALID_TYPE; - do { - MemoryType = MtrrGetMemoryAttribute (Base); - if (MemoryType > CacheWriteBack) { - MemoryType = MTRR_CACHE_INVALID_TYPE; - } - - if (MemoryType != PreviousMemoryType) { - if (PreviousMemoryType != MTRR_CACHE_INVALID_TYPE) { - DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1)); - } - PreviousMemoryType = MemoryType; - DEBUG((DEBUG_CACHE, "%a:%016lx-", mMtrrMemoryCacheTypeShortName[MemoryType], Base)); - } - - RangeBase = BASE_1MB; - NoRangeBase = BASE_1MB; - Limit = BIT36 - 1; - AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); - if (RegEax >= 0x80000008) { - AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL); - Limit = LShiftU64 (1, RegEax & 0xff) - 1; - } - RangeLimit = Limit; - NoRangeLimit = Limit; - - for (Index = 0, Found = FALSE; Index < VariableMtrrCount; Index++) { - if ((MtrrSettings.Variables.Mtrr[Index].Mask & BIT11) == 0) { - // - // If mask is not valid, then do not display range - // - continue; - } - MtrrBase = (MtrrSettings.Variables.Mtrr[Index].Base & (~(SIZE_4KB - 1))); - MtrrLimit = MtrrBase + ((~(MtrrSettings.Variables.Mtrr[Index].Mask & (~(SIZE_4KB - 1)))) & Limit); - - if (Base >= MtrrBase && Base < MtrrLimit) { - Found = TRUE; - } - - if (Base >= MtrrBase && MtrrBase > RangeBase) { - RangeBase = MtrrBase; - } - if (Base > MtrrLimit && MtrrLimit > RangeBase) { - RangeBase = MtrrLimit + 1; - } - if (Base < MtrrBase && MtrrBase < RangeLimit) { - RangeLimit = MtrrBase - 1; - } - if (Base < MtrrLimit && MtrrLimit <= RangeLimit) { - RangeLimit = MtrrLimit; - } - - if (Base > MtrrLimit && NoRangeBase < MtrrLimit) { - NoRangeBase = MtrrLimit + 1; - } - if (Base < MtrrBase && NoRangeLimit > MtrrBase) { - NoRangeLimit = MtrrBase - 1; - } - } - - if (Found) { - Base = RangeLimit + 1; - } else { - Base = NoRangeLimit + 1; - } - } while (Found); - DEBUG((DEBUG_CACHE, "%016lx\n\n", Base - 1)); - ); -} - /** Checks if MTRR is supported.