Skip to content

Commit

Permalink
Implemented Extended Features for Subleaf Ecx=0x1
Browse files Browse the repository at this point in the history
- Implementation
- Modify Test Cases based on new features.
  • Loading branch information
mert-kurttutan authored and gz committed Jul 24, 2024
1 parent ae4e829 commit 6bd7969
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 0 deletions.
102 changes: 102 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,11 +511,16 @@ impl<R: CpuIdReader> CpuId<R> {
pub fn get_extended_feature_info(&self) -> Option<ExtendedFeatures> {
if self.leaf_is_supported(EAX_STRUCTURED_EXTENDED_FEATURE_INFO) {
let res = self.read.cpuid1(EAX_STRUCTURED_EXTENDED_FEATURE_INFO);
let res1 = self.read.cpuid2(EAX_STRUCTURED_EXTENDED_FEATURE_INFO, 1);
Some(ExtendedFeatures {
_eax: res.eax,
ebx: ExtendedFeaturesEbx::from_bits_truncate(res.ebx),
ecx: ExtendedFeaturesEcx::from_bits_truncate(res.ecx),
edx: ExtendedFeaturesEdx::from_bits_truncate(res.edx),
eax1: ExtendedFeaturesEax1::from_bits_truncate(res1.eax),
_ebx1: res1.ebx,
_ecx1: res1.ecx,
edx1: ExtendedFeaturesEdx1::from_bits_truncate(res1.edx),
})
} else {
None
Expand Down Expand Up @@ -3219,6 +3224,10 @@ pub struct ExtendedFeatures {
ebx: ExtendedFeaturesEbx,
ecx: ExtendedFeaturesEcx,
edx: ExtendedFeaturesEdx,
eax1: ExtendedFeaturesEax1,
_ebx1: u32,
_ecx1: u32,
edx1: ExtendedFeaturesEdx1,
}

impl ExtendedFeatures {
Expand Down Expand Up @@ -3728,6 +3737,69 @@ impl ExtendedFeatures {
pub const fn has_amx_int8(&self) -> bool {
self.edx.contains(ExtendedFeaturesEdx::AMX_INT8)
}

/// Supports AVX_VNNI.
///
/// # Platforms
/// ❌ AMD (reserved) ✅ Intel
#[inline]
pub const fn has_avx_vnni(&self) -> bool {
self.eax1.contains(ExtendedFeaturesEax1::AVX_VNNI)
}

/// Supports AVX512_BF16.
///
/// # Platforms
/// ❌ AMD (reserved) ✅ Intel
#[inline]
pub const fn has_avx512_bf16(&self) -> bool {
self.eax1.contains(ExtendedFeaturesEax1::AVX512_BF16)
}

/// Supports Fast zero-length REP MOVSB
///
/// # Platforms
/// ❌ AMD (reserved) ✅ Intel
#[inline]
pub const fn has_fzrm(&self) -> bool {
self.eax1.contains(ExtendedFeaturesEax1::FZRM)
}

/// Supports Fast Short REP STOSB
///
/// # Platforms
/// ❌ AMD (reserved) ✅ Intel
#[inline]
pub const fn has_fsrs(&self) -> bool {
self.eax1.contains(ExtendedFeaturesEax1::FSRS)
}

/// Supports Fast Short REP CMPSB, REP SCASB
///
/// # Platforms
/// ❌ AMD (reserved) ✅ Intel
#[inline]
pub const fn has_fsrcrs(&self) -> bool {
self.eax1.contains(ExtendedFeaturesEax1::FSRCRS)
}

/// Supports HRESET
///
/// # Platforms
/// ❌ AMD (reserved) ✅ Intel
#[inline]
pub const fn has_hreset(&self) -> bool {
self.eax1.contains(ExtendedFeaturesEax1::HRESET)
}

/// Supports CET_SSS
///
/// # Platforms
/// ❌ AMD (reserved) ✅ Intel
#[inline]
pub const fn has_cet_sss(&self) -> bool {
self.edx1.contains(ExtendedFeaturesEdx1::CET_SSS)
}
}

impl Debug for ExtendedFeatures {
Expand Down Expand Up @@ -3886,6 +3958,36 @@ bitflags! {
}
}

bitflags! {
#[repr(transparent)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct ExtendedFeaturesEax1: u32 {
// Some of the Unimplemented bits are reserved and maybe release in future CPUs, see Intel SDM for future features (Date of comment: 07.17.2024)
/// Bit 04: AVX_VNNI. AVX (VEX-encoded) versions of the Vector Neural Network Instructions.
const AVX_VNNI = 1 << 4;
/// Bit 05: AVX512_BF16. Vector Neural Network Instructions supporting BFLOAT16 inputs and conversion instructions from IEEE single precision.
const AVX512_BF16 = 1 << 5;
/// Bit 10: If 1, supports fast zero-length REP MOVSB.
const FZRM = 1 << 10;
/// Bit 11: If 1, supports fast short REP STOSB.
const FSRS = 1 << 11;
/// Bit 12: If 1, supports fast short REP CMPSB, REP SCASB.
const FSRCRS = 1 << 12;
/// Bit 22: If 1, supports history reset via the HRESET instruction and the IA32_HRESET_ENABLE MSR. When set, indicates that the Processor History Reset Leaf (EAX = 20H) is valid.
const HRESET = 1 << 22;
}
}

bitflags! {
#[repr(transparent)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct ExtendedFeaturesEdx1: u32 {
// Some of the Unimplemented bits are reserved and maybe release in future CPUs, see Intel SDM for future features (Date of comment: 07.17.2024)
/// Bit 18: CET_SSS. If 1, indicates that an operating system can enable supervisor shadow stacks as long as it ensures that a supervisor shadow stack cannot become prematurely busy due to page faults
const CET_SSS = 1 << 18;
}
}

/// Direct cache access info (LEAF=0x09).
///
/// # Platforms
Expand Down
16 changes: 16 additions & 0 deletions src/tests/i5_3337u.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,10 @@ fn extended_features() {
ebx: ExtendedFeaturesEbx::from_bits_truncate(641),
ecx: ExtendedFeaturesEcx::from_bits_truncate(0),
edx: ExtendedFeaturesEdx::from_bits_truncate(0),
eax1: ExtendedFeaturesEax1::from_bits_truncate(0),
_ebx1: 0,
_ecx1: 0,
edx1: ExtendedFeaturesEdx1::from_bits_truncate(0),
};
assert!(tpfeatures._eax == 0);
assert!(tpfeatures.has_fsgsbase());
Expand Down Expand Up @@ -274,6 +278,10 @@ fn extended_features() {
| ExtendedFeaturesEbx::PROCESSOR_TRACE,
ecx: ExtendedFeaturesEcx::from_bits_truncate(0),
edx: ExtendedFeaturesEdx::from_bits_truncate(201326592),
eax1: ExtendedFeaturesEax1::from_bits_truncate(0),
_ebx1: 0,
_ecx1: 0,
edx1: ExtendedFeaturesEdx1::from_bits_truncate(0),
};

assert!(tpfeatures2.has_fsgsbase());
Expand All @@ -299,6 +307,14 @@ fn extended_features() {
assert!(!tpfeatures2.has_avx512_fp16());
assert!(!tpfeatures2.has_amx_tile());
assert!(!tpfeatures2.has_amx_int8());

assert!(!tpfeatures2.has_avx_vnni());
assert!(!tpfeatures2.has_avx512_bf16());
assert!(!tpfeatures2.has_fzrm());
assert!(!tpfeatures2.has_fsrs());
assert!(!tpfeatures2.has_fsrcrs());
assert!(!tpfeatures2.has_hreset());
assert!(!tpfeatures2.has_cet_sss());
}

#[test]
Expand Down
1 change: 1 addition & 0 deletions src/tests/ryzen_matisse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,7 @@ static CPUID_VALUE_MAP: phf::Map<u64, CpuIdResult> = phf_map! {
0x00000005_00000000u64 => CpuIdResult { eax: 0x00000040, ebx: 0x00000040, ecx: 0x00000003, edx: 0x00000011 },
0x00000006_00000000u64 => CpuIdResult { eax: 0x00000004, ebx: 0x00000000, ecx: 0x00000001, edx: 0x00000000 },
0x00000007_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x219c91a9, ecx: 0x00400004, edx: 0x00000000 },
0x00000007_00000001u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 },
0x00000008_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 },
0x00000009_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 },
0x0000000a_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 },
Expand Down
1 change: 1 addition & 0 deletions src/tests/xeon_gold_6252.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ static CPUID_VALUE_MAP: phf::Map<u64, CpuIdResult> = phf_map! {
0x00000005_00000000u64 => CpuIdResult { eax: 0x00000040, ebx: 0x00000040, ecx: 0x00000003, edx: 0x00002020 },
0x00000006_00000000u64 => CpuIdResult { eax: 0x00000077, ebx: 0x00000002, ecx: 0x00000009, edx: 0x00000000 },
0x00000007_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0xd39ff7eb, ecx: 0x00000818, edx: 0xbc000400 },
0x00000007_00000001u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 },
0x00000008_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 },
0x00000009_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 },
0x0000000a_00000000u64 => CpuIdResult { eax: 0x07300404, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000603 },
Expand Down

0 comments on commit 6bd7969

Please sign in to comment.