REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3394
Add new API GetMaxPlatformAddressBits to get the max platform address bits. Max physical address bits can be get from CPUID. When TME-MK feature is enabled, the upper bits of the max physical address bits are repurposed for usage as a KeyID. Therefore, the max platform addressable bits is the max physical address bits minus the upper bits used for KeyID if TME-MK is enable. Cc: Michael D Kinney <michael.d.kin...@intel.com> Cc: Liming Gao <gaolim...@byosoft.com.cn> Signed-off-by: Zhiguang Liu <zhiguang....@intel.com> --- MdePkg/Include/Library/CpuLib.h | 25 +++++++ MdePkg/Library/BaseCpuLib/X86BaseCpuLib.c | 81 +++++++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/MdePkg/Include/Library/CpuLib.h b/MdePkg/Include/Library/CpuLib.h index 3f29937dc7..a9bac083b7 100644 --- a/MdePkg/Include/Library/CpuLib.h +++ b/MdePkg/Include/Library/CpuLib.h @@ -87,6 +87,31 @@ GetCpuSteppingId ( VOID ); +/** + Get the max platform addressable bits. + Max physical address bits can be get from CPUID. When TME-MK feature + is enabled, the upper bits of the max physical address bits are + repurposed for usage as a KeyID. + Therefore, the max platform addressable bits is the max physical + address bits minus the upper bits used for KeyID if TME-MK is enable. + + @param[out] ValidAddressMask Bitmask with valid address bits set to + one; other bits are clear. Optional + parameter. + + @param[out] ValidPageBaseAddressMask Bitmask with valid page base address + bits set to one; other bits are clear. + Optional parameter. + + @return The max platform addressable bits. +**/ +UINT8 +EFIAPI +GetMaxPlatformAddressBits ( + OUT UINT64 *ValidAddressMask OPTIONAL, + OUT UINT64 *ValidPageBaseAddressMask OPTIONAL + ); + #endif #endif diff --git a/MdePkg/Library/BaseCpuLib/X86BaseCpuLib.c b/MdePkg/Library/BaseCpuLib/X86BaseCpuLib.c index 1cad32a4be..7b15cb3d73 100644 --- a/MdePkg/Library/BaseCpuLib/X86BaseCpuLib.c +++ b/MdePkg/Library/BaseCpuLib/X86BaseCpuLib.c @@ -14,6 +14,8 @@ #include <Library/BaseLib.h> #include <Library/CpuLib.h> +#include <Register/Intel/ArchitecturalMsr.h> +#include <Uefi/UefiBaseType.h> /** Determine if the standard CPU signature is "AuthenticAMD". @@ -79,3 +81,82 @@ GetCpuSteppingId ( return (UINT8)Eax.Bits.SteppingId; } + +/** + Get the max platform addressable bits. + Max physical address bits can be get from CPUID. When TME-MK feature + is enabled, the upper bits of the max physical address bits are + repurposed for usage as a KeyID. + Therefore, the max platform addressable bits is the max physical + address bits minus the upper bits used for KeyID if TME-MK is enable. + + @param[out] ValidAddressMask Bitmask with valid address bits set to + one; other bits are clear. Optional + parameter. + + @param[out] ValidPageBaseAddressMask Bitmask with valid page base address + bits set to one; other bits are clear. + Optional parameter. + + @return The max platform addressable bits. +**/ +UINT8 +EFIAPI +GetMaxPlatformAddressBits ( + OUT UINT64 *ValidAddressMask OPTIONAL, + OUT UINT64 *ValidPageBaseAddressMask OPTIONAL + ) +{ + UINT32 MaxExtendedFunction; + CPUID_VIR_PHY_ADDRESS_SIZE_EAX VirPhyAddressSize; + UINT64 AddressMask; + UINT64 PageBaseAddressMask; + UINT32 MaxFunction; + CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_ECX ExtendedFeatureFlagsEcx; + MSR_IA32_TME_ACTIVATE_REGISTER TmeActivate; + MSR_IA32_TME_CAPABILITY_REGISTER TmeCapability; + + AsmCpuid (CPUID_EXTENDED_FUNCTION, &MaxExtendedFunction, NULL, NULL, NULL); + if (MaxExtendedFunction >= CPUID_VIR_PHY_ADDRESS_SIZE) { + AsmCpuid ( + CPUID_VIR_PHY_ADDRESS_SIZE, + &VirPhyAddressSize.Uint32, + NULL, + NULL, + NULL + ); + } else { + VirPhyAddressSize.Bits.PhysicalAddressBits = 36; + } + + // + // CPUID enumeration of MAX_PA is unaffected by TME-MK activation and will continue + // to report the maximum physical address bits available for software to use, + // irrespective of the number of KeyID bits. + // So, we need to check if TME is enabled and adjust the PA size accordingly. + // + AsmCpuid (CPUID_SIGNATURE, &MaxFunction, NULL, NULL, NULL); + if (MaxFunction >= CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS) { + AsmCpuidEx (CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS, 0, NULL, NULL, &ExtendedFeatureFlagsEcx.Uint32, NULL); + if (ExtendedFeatureFlagsEcx.Bits.TME_EN == 1) { + TmeActivate.Uint64 = AsmReadMsr64 (MSR_IA32_TME_ACTIVATE); + TmeCapability.Uint64 = AsmReadMsr64 (MSR_IA32_TME_CAPABILITY); + if ((TmeActivate.Bits.TmeEnable == 1) && (TmeCapability.Bits.MkTmeMaxKeyidBits != 0)) { + VirPhyAddressSize.Bits.PhysicalAddressBits -= TmeActivate.Bits.MkTmeKeyidBits; + } + } + } + + AddressMask = LShiftU64 (1, VirPhyAddressSize.Bits.PhysicalAddressBits) - 1; + PageBaseAddressMask = AddressMask & ~(UINT64)EFI_PAGE_MASK; + + if (ValidAddressMask != NULL) { + *ValidAddressMask = AddressMask; + } + + if (ValidPageBaseAddressMask != NULL) { + *ValidPageBaseAddressMask = PageBaseAddressMask; + } + + return (UINT8)VirPhyAddressSize.Bits.PhysicalAddressBits; +} -- 2.31.1.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#105909): https://edk2.groups.io/g/devel/message/105909 Mute This Topic: https://groups.io/mt/99399598/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-