From: Ruiyu Ni <ruiyu.ni@intel.com>
To: edk2-devel@lists.01.org
Cc: Jeff Fan <jeff.fan@intel.com>
Subject: [PATCH 09/10] UefiCpuPkg/MtrrLib: Refine MtrrGetMemoryAttributeByAddressWorker
Date: Wed, 29 Mar 2017 11:03:45 +0800 [thread overview]
Message-ID: <20170329030346.249872-10-ruiyu.ni@intel.com> (raw)
In-Reply-To: <20170329030346.249872-1-ruiyu.ni@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Cc: Jeff Fan <jeff.fan@intel.com>
---
UefiCpuPkg/Library/MtrrLib/MtrrLib.c | 237 ++++++++++++-----------------------
1 file changed, 80 insertions(+), 157 deletions(-)
diff --git a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
index 34e6ad6..920cc5f 100644
--- a/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
+++ b/UefiCpuPkg/Library/MtrrLib/MtrrLib.c
@@ -568,20 +568,19 @@ MtrrLibProgramFixedMtrr (
This function shadows the content of variable MTRRs into an
internal array: VariableMtrr.
- @param[in] VariableSettings The variable MTRR values to shadow
- @param[in] FirmwareVariableMtrrCount The number of variable MTRRs available to firmware
- @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
+ @param[in] VariableSettings The variable MTRR values to shadow
+ @param[in] VariableMtrrCount The number of variable MTRRs
+ @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 parameter indicates the
- number of MTRRs which has been used.
+ @return Number of MTRRs which has been used.
**/
UINT32
MtrrGetMemoryAttributeInVariableMtrrWorker (
IN MTRR_VARIABLE_SETTINGS *VariableSettings,
- IN UINTN FirmwareVariableMtrrCount,
+ IN UINTN VariableMtrrCount,
IN UINT64 MtrrValidBitsMask,
IN UINT64 MtrrValidAddressMask,
OUT VARIABLE_MTRR *VariableMtrr
@@ -591,7 +590,7 @@ MtrrGetMemoryAttributeInVariableMtrrWorker (
UINT32 UsedMtrr;
ZeroMem (VariableMtrr, sizeof (VARIABLE_MTRR) * MTRR_NUMBER_OF_VARIABLE_MTRR);
- for (Index = 0, UsedMtrr = 0; Index < FirmwareVariableMtrrCount; Index++) {
+ for (Index = 0, UsedMtrr = 0; Index < VariableMtrrCount; Index++) {
if ((VariableSettings->Mtrr[Index].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) != 0) {
VariableMtrr[Index].Msr = (UINT32)Index;
VariableMtrr[Index].BaseAddress = (VariableSettings->Mtrr[Index].Base & MtrrValidAddressMask);
@@ -724,8 +723,10 @@ MtrrLibGetPositiveMtrrNumber (
Return whether the left MTRR type precedes the right MTRR type.
The MTRR type precedence rules are:
- 1. UC precedes any other type
- 2. WT precedes WB
+ 1. UC precedes any other type
+ 2. WT precedes WB
+ For further details, please refer the IA32 Software Developer's Manual,
+ Volume 3, Section "MTRR Precedences".
@param Left The left MTRR type.
@param Right The right MTRR type.
@@ -954,46 +955,6 @@ MtrrLibGetMtrrNumber (
return LeastSubtractiveMtrrNumber + MiddleMtrrNumber + LeastRightMtrrNumber;
}
-
-/**
- Converts the Memory attribute value to MTRR_MEMORY_CACHE_TYPE.
-
- If MtrrSetting is not NULL, gets the default memory attribute from input
- MTRR settings buffer.
- If MtrrSetting is NULL, gets the default memory attribute from MSR.
-
- @param[in] MtrrSetting A buffer holding all MTRRs content.
- @param[in] MtrrType MTRR memory type
-
- @return The enum item in MTRR_MEMORY_CACHE_TYPE
-
-**/
-MTRR_MEMORY_CACHE_TYPE
-GetMemoryCacheTypeFromMtrrType (
- IN MTRR_SETTINGS *MtrrSetting,
- IN UINT64 MtrrType
- )
-{
- switch (MtrrType) {
- case MTRR_CACHE_UNCACHEABLE:
- return CacheUncacheable;
- case MTRR_CACHE_WRITE_COMBINING:
- return CacheWriteCombining;
- case MTRR_CACHE_WRITE_THROUGH:
- return CacheWriteThrough;
- case MTRR_CACHE_WRITE_PROTECTED:
- return CacheWriteProtected;
- case MTRR_CACHE_WRITE_BACK:
- return CacheWriteBack;
- default:
- //
- // MtrrType is MTRR_CACHE_INVALID_TYPE, that means
- // no MTRR covers the range
- //
- return MtrrGetDefaultMemoryTypeWorker (MtrrSetting);
- }
-}
-
/**
Initializes the valid bits mask and valid address mask for MTRRs.
@@ -1030,71 +991,34 @@ MtrrLibInitializeMtrrMask (
Determines the real attribute of a memory range.
This function is to arbitrate the real attribute of the memory when
- there are 2 MTRRs 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.
+ Section "MTRR Precedences".
@param[in] MtrrType1 The first kind of Memory type
@param[in] MtrrType2 The second kind of memory type
**/
-UINT64
+MTRR_MEMORY_CACHE_TYPE
MtrrLibPrecedence (
- IN UINT64 MtrrType1,
- IN UINT64 MtrrType2
+ IN MTRR_MEMORY_CACHE_TYPE MtrrType1,
+ IN MTRR_MEMORY_CACHE_TYPE MtrrType2
)
{
- UINT64 MtrrType;
-
- MtrrType = MTRR_CACHE_INVALID_TYPE;
- switch (MtrrType1) {
- case MTRR_CACHE_UNCACHEABLE:
- MtrrType = MTRR_CACHE_UNCACHEABLE;
- break;
- case MTRR_CACHE_WRITE_COMBINING:
- if (
- MtrrType2==MTRR_CACHE_WRITE_COMBINING ||
- MtrrType2==MTRR_CACHE_UNCACHEABLE
- ) {
- MtrrType = MtrrType2;
- }
- break;
- case MTRR_CACHE_WRITE_THROUGH:
- if (
- MtrrType2==MTRR_CACHE_WRITE_THROUGH ||
- MtrrType2==MTRR_CACHE_WRITE_BACK
- ) {
- MtrrType = MTRR_CACHE_WRITE_THROUGH;
- } else if(MtrrType2==MTRR_CACHE_UNCACHEABLE) {
- MtrrType = MTRR_CACHE_UNCACHEABLE;
- }
- break;
- case MTRR_CACHE_WRITE_PROTECTED:
- if (MtrrType2 == MTRR_CACHE_WRITE_PROTECTED ||
- MtrrType2 == MTRR_CACHE_UNCACHEABLE) {
- MtrrType = MtrrType2;
- }
- break;
- case MTRR_CACHE_WRITE_BACK:
- if (
- MtrrType2== MTRR_CACHE_UNCACHEABLE ||
- MtrrType2==MTRR_CACHE_WRITE_THROUGH ||
- MtrrType2== MTRR_CACHE_WRITE_BACK
- ) {
- MtrrType = MtrrType2;
- }
- break;
- case MTRR_CACHE_INVALID_TYPE:
- MtrrType = MtrrType2;
- break;
- default:
- break;
+ if (MtrrType1 == MtrrType2) {
+ return MtrrType1;
}
- if (MtrrType2 == MTRR_CACHE_INVALID_TYPE) {
- MtrrType = MtrrType1;
+ ASSERT (
+ MtrrLibTypeLeftPrecedeRight (MtrrType1, MtrrType2) ||
+ MtrrLibTypeLeftPrecedeRight (MtrrType2, MtrrType1)
+ );
+
+ if (MtrrLibTypeLeftPrecedeRight (MtrrType1, MtrrType2)) {
+ return MtrrType1;
+ } else {
+ return MtrrType2;
}
- return MtrrType;
}
/**
@@ -1116,29 +1040,27 @@ MtrrGetMemoryAttributeByAddressWorker (
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;
- MTRR_VARIABLE_SETTINGS VariableSettings;
+ MSR_IA32_MTRR_DEF_TYPE_REGISTER DefType;
+ UINT64 FixedMtrr;
+ UINTN Index;
+ UINTN SubIndex;
+ MTRR_MEMORY_CACHE_TYPE MtrrType;
+ VARIABLE_MTRR VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];
+ UINT64 MtrrValidBitsMask;
+ UINT64 MtrrValidAddressMask;
+ UINT32 VariableMtrrCount;
+ MTRR_VARIABLE_SETTINGS VariableSettings;
//
// Check if MTRR is enabled, if not, return UC as attribute
//
if (MtrrSetting == NULL) {
- TempQword = AsmReadMsr64 (MTRR_LIB_IA32_MTRR_DEF_TYPE);
+ DefType.Uint64 = AsmReadMsr64 (MSR_IA32_MTRR_DEF_TYPE);
} else {
- TempQword = MtrrSetting->MtrrDefType;
+ DefType.Uint64 = MtrrSetting->MtrrDefType;
}
- MtrrType = MTRR_CACHE_INVALID_TYPE;
- if ((TempQword & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {
+ if (DefType.Bits.E == 0) {
return CacheUncacheable;
}
@@ -1146,65 +1068,66 @@ MtrrGetMemoryAttributeByAddressWorker (
// 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) {
+ if (DefType.Bits.FE != 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;
- if (MtrrSetting == NULL) {
- TempQword = AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr);
- } else {
- TempQword = MtrrSetting->Fixed.Mtrr[Index];
- }
- MtrrType = RShiftU64 (TempQword, SubIndex * 8) & 0xFF;
- return GetMemoryCacheTypeFromMtrrType (MtrrSetting, MtrrType);
- }
+ if (Address >= mMtrrLibFixedMtrrTable[Index].BaseAddress &&
+ Address < mMtrrLibFixedMtrrTable[Index].BaseAddress +
+ (mMtrrLibFixedMtrrTable[Index].Length * 8)) {
+ SubIndex =
+ ((UINTN) Address - mMtrrLibFixedMtrrTable[Index].BaseAddress) /
+ mMtrrLibFixedMtrrTable[Index].Length;
+ if (MtrrSetting == NULL) {
+ FixedMtrr = AsmReadMsr64 (mMtrrLibFixedMtrrTable[Index].Msr);
+ } else {
+ FixedMtrr = MtrrSetting->Fixed.Mtrr[Index];
+ }
+ return (MTRR_MEMORY_CACHE_TYPE) (RShiftU64 (FixedMtrr, SubIndex * 8) & 0xFF);
+ }
}
}
}
- MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask);
- MtrrGetVariableMtrrWorker (
- MtrrSetting,
- GetVariableMtrrCountWorker (),
- &VariableSettings
- );
+ VariableMtrrCount = GetVariableMtrrCountWorker ();
+ ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);
+ MtrrGetVariableMtrrWorker (MtrrSetting, VariableMtrrCount, &VariableSettings);
+ MtrrLibInitializeMtrrMask (&MtrrValidBitsMask, &MtrrValidAddressMask);
MtrrGetMemoryAttributeInVariableMtrrWorker (
- &VariableSettings,
- GetFirmwareVariableMtrrCountWorker (),
- MtrrValidBitsMask,
- MtrrValidAddressMask,
- VariableMtrr
- );
+ &VariableSettings,
+ VariableMtrrCount,
+ MtrrValidBitsMask,
+ MtrrValidAddressMask,
+ VariableMtrr
+ );
//
// Go through the variable MTRR
//
- VariableMtrrCount = GetVariableMtrrCountWorker ();
- ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);
-
+ MtrrType = CacheInvalid;
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 = MtrrLibPrecedence (MtrrType, TempMtrrType);
+ Address < VariableMtrr[Index].BaseAddress + VariableMtrr[Index].Length) {
+ if (MtrrType == CacheInvalid) {
+ MtrrType = (MTRR_MEMORY_CACHE_TYPE) VariableMtrr[Index].Type;
+ } else {
+ MtrrType = MtrrLibPrecedence (MtrrType, (MTRR_MEMORY_CACHE_TYPE) VariableMtrr[Index].Type);
+ }
}
}
}
- CacheType = GetMemoryCacheTypeFromMtrrType (MtrrSetting, MtrrType);
- return CacheType;
+ //
+ // If there is no MTRR which covers the Address, use the default MTRR type.
+ //
+ if (MtrrType == CacheInvalid) {
+ MtrrType = (MTRR_MEMORY_CACHE_TYPE) DefType.Bits.Type;
+ }
+
+ return MtrrType;
}
--
2.9.0.windows.1
next prev parent reply other threads:[~2017-03-29 3:03 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-03-29 3:03 [PATCH 00/10] Use a better algorithm to calculate MTRR Ruiyu Ni
2017-03-29 3:03 ` [PATCH 01/10] UefiCpuPkg/MtrrLib: Correct typo in comments and remove TABs Ruiyu Ni
2017-03-29 3:03 ` [PATCH 02/10] UefiCpuPkg/MtrrLib: Add CacheInvalid enum type to MtrrLib.h Ruiyu Ni
2017-03-29 3:03 ` [PATCH 03/10] UefiCpuPkg/MtrrLib: IsMtrrSupported uses definitions in Msr.h Ruiyu Ni
2017-03-29 3:03 ` [PATCH 04/10] UefiCpuPkg/MtrrLib: GetVariableMtrrCountWorker " Ruiyu Ni
2017-03-29 3:03 ` [PATCH 05/10] UefiCpuPkg/MtrrLib: Add MtrrLib prefix to ProgramFixedMtrr Ruiyu Ni
2017-03-29 3:03 ` [PATCH 06/10] UefiCpuPkg/MtrrLib: Add MtrrLib prefix to several internal functions Ruiyu Ni
2017-03-29 3:03 ` [PATCH 07/10] UefiCpuPkg/MtrrLib: MtrrLibInitializeMtrrMask() uses definitions in CpuId.h Ruiyu Ni
2017-03-29 3:03 ` [PATCH 08/10] UefiCpuPkg/MtrrLib: Use a better algorithm to calculate MTRR Ruiyu Ni
2017-03-29 3:03 ` Ruiyu Ni [this message]
2017-03-29 3:03 ` [PATCH 10/10] UefiCpuPkg/MtrrLib: All functions use definitions in Msr.h Ruiyu Ni
2017-03-31 5:03 ` [PATCH 00/10] Use a better algorithm to calculate MTRR Fan, Jeff
2017-03-31 9:10 ` Laszlo Ersek
2017-03-31 14:25 ` Ni, Ruiyu
2017-03-31 15:04 ` Laszlo Ersek
-- strict thread matches above, loose matches on Subject: below --
2016-09-02 13:58 [PATCH 00/10] Enhance MtrrLib to find out the optimal MTRR solution Ruiyu Ni
2016-09-02 13:58 ` [PATCH 09/10] UefiCpuPkg/MtrrLib: Refine MtrrGetMemoryAttributeByAddressWorker Ruiyu Ni
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170329030346.249872-10-ruiyu.ni@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox