Only adjust functions order and there is no any real functionality impact. Cc: Feng Tian <feng.t...@intel.com> Cc: Michael Kinney <michael.d.kin...@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jeff Fan <jeff....@intel.com> --- UefiCpuPkg/Library/MtrrLib/MtrrLib.c | 956 +++++++++++++++++------------------ 1 file changed, 477 insertions(+), 479 deletions(-)
diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c index b1c12aa..ea2b211 100644 --- a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c +++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c @@ -311,6 +311,103 @@ PostMtrrChange ( 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. @@ -965,126 +1062,368 @@ 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[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. + 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; - BOOLEAN OverwriteExistingMtrr; - UINT32 FirmwareVariableMtrrCount; - UINT32 VariableMtrrEnd; - MTRR_CONTEXT MtrrContext; - - 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 ( - (BaseAddress & ~MtrrValidAddressMask) != 0 || - (Length & ~MtrrValidAddressMask) != 0 - ) { - Status = RETURN_UNSUPPORTED; - goto Done; + if ((TempQword & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) { + return CacheUncacheable; } // - // Check if Fixed MTRR + // If address is less than 1M, then try to go through the fixed MTRR // - Status = RETURN_SUCCESS; - while ((BaseAddress < BASE_1MB) && (Length > 0) && Status == RETURN_SUCCESS) { - PreMtrrChange (&MtrrContext); - Status = ProgramFixedMtrr (MemoryType, &BaseAddress, &Length); - PostMtrrChange (&MtrrContext); - if (RETURN_ERROR (Status)) { - goto Done; + 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); + } + } } } - - if (Length == 0) { - // - // A Length of 0 can only make sense for fixed MTTR ranges. - // Since we just handled the fixed MTRRs, we can skip the - // variable MTRR section. - // - goto Done; - } + MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask); + MtrrGetMemoryAttributeInVariableMtrr( + MtrrValidBitsMask, + MtrrValidAddressMask, + VariableMtrr + ); // - // Since memory ranges below 1MB will be overridden by the fixed MTRRs, - // we can set the base to 0 to save variable MTRRs. + // Go through the variable MTRR // - if (BaseAddress == BASE_1MB) { - BaseAddress = 0; - Length += SIZE_1MB; + 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); - // - // Check for overlap - // - UsedMtrr = MtrrGetMemoryAttributeInVariableMtrr (MtrrValidBitsMask, MtrrValidAddressMask, VariableMtrr); - OverLap = CheckMemoryAttributeOverlap (BaseAddress, BaseAddress + Length - 1, VariableMtrr); - if (OverLap) { + 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 ( + (BaseAddress & ~MtrrValidAddressMask) != 0 || + (Length & ~MtrrValidAddressMask) != 0 + ) { + Status = RETURN_UNSUPPORTED; + goto Done; + } + + // + // Check if Fixed MTRR + // + Status = RETURN_SUCCESS; + while ((BaseAddress < BASE_1MB) && (Length > 0) && Status == RETURN_SUCCESS) { + PreMtrrChange (&MtrrContext); + Status = ProgramFixedMtrr (MemoryType, &BaseAddress, &Length); + PostMtrrChange (&MtrrContext); + if (RETURN_ERROR (Status)) { + goto Done; + } + } + + if (Length == 0) { + // + // A Length of 0 can only make sense for fixed MTTR ranges. + // Since we just handled the fixed MTRRs, we can skip the + // variable MTRR section. + // + goto Done; + } + + // + // Since memory ranges below 1MB will be overridden by the fixed MTRRs, + // we can set the base to 0 to save variable MTRRs. + // + if (BaseAddress == BASE_1MB) { + BaseAddress = 0; + Length += SIZE_1MB; + } + + // + // Check for overlap + // + UsedMtrr = MtrrGetMemoryAttributeInVariableMtrr (MtrrValidBitsMask, MtrrValidAddressMask, VariableMtrr); + OverLap = CheckMemoryAttributeOverlap (BaseAddress, BaseAddress + Length - 1, VariableMtrr); + if (OverLap) { Status = CombineMemoryAttribute (MemoryType, &BaseAddress, &Length, VariableMtrr, &UsedMtrr, &OverwriteExistingMtrr); if (RETURN_ERROR (Status)) { goto Done; @@ -1183,208 +1522,59 @@ MtrrSetMemoryAttribute ( 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[in] Address The specific address - - @return Memory cache type of the specific 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); - } - } - } - CacheType = GetMemoryCacheTypeFromMtrrType (MtrrType); - - return CacheType; -} - - -/** - 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); + } + } + + ProgramVariableMtrr ( + MsrNum, + BaseAddress, + Length, + MemoryType, + MtrrValidAddressMask + ); + BaseAddress += Length; + TempQword = Length - TempQword; + MemoryType = MTRR_CACHE_UNCACHEABLE; } - return VariableSettings; -} + do { + // + // Find unused MTRR + // + for (; MsrNum < VariableMtrrEnd; MsrNum += 2) { + if ((AsmReadMsr64 (MsrNum + 1) & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) { + break; + } + } -/** - This function will get the raw value in variable MTRRs + Length = Power2MaxMemory (TempQword); + if (!Positive) { + BaseAddress -= Length; + } - @param[out] VariableSettings A buffer to hold variable MTRRs content. + ProgramVariableMtrr ( + MsrNum, + BaseAddress, + Length, + MemoryType, + MtrrValidAddressMask + ); - @return The VariableSettings input pointer + if (Positive) { + BaseAddress += Length; + } + TempQword -= Length; -**/ -MTRR_VARIABLE_SETTINGS* -EFIAPI -MtrrGetVariableMtrr ( - OUT MTRR_VARIABLE_SETTINGS *VariableSettings - ) -{ - if (!IsMtrrSupported ()) { - return VariableSettings; + } while (TempQword > 0); + +Done: + DEBUG((DEBUG_CACHE, " Status = %r\n", Status)); + if (!RETURN_ERROR (Status)) { + MtrrDebugPrintAllMtrrs (); } - return MtrrGetVariableMtrrWorker ( - VariableSettings - ); + return Status; } - - /** Worker function setting variable MTRRs @@ -1442,51 +1632,6 @@ MtrrSetVariableMtrr ( } /** - 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 setting fixed MTRRs @param[in] FixedSettings A buffer to hold fixed Mtrrs content. @@ -1616,153 +1761,6 @@ MtrrSetAllMtrrs ( } /** - 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)); - ); -} - -/** Checks if MTRR is supported. @retval TRUE MTRR is supported. -- 1.9.5.msysgit.0 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel