diff -Nru distinst-0.3.2~1650402197~21.10~52e2e8d~dev/Cargo.lock distinst-0.3.2~1652283129~21.10~4af925c~dev/Cargo.lock --- distinst-0.3.2~1650402197~21.10~52e2e8d~dev/Cargo.lock 2022-04-19 21:03:17.000000000 +0000 +++ distinst-0.3.2~1652283129~21.10~4af925c~dev/Cargo.lock 2022-05-11 15:32:09.000000000 +0000 @@ -1278,9 +1278,9 @@ [[package]] name = "raw-cpuid" -version = "9.0.0" +version = "9.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c27cb5785b85bd05d4eb171556c9a1a514552e26123aeae6bb7d811353148026" +checksum = "1733f6f80c9c24268736a501cd00d41a9849b4faa7a9f9334c096e5d10553206" dependencies = [ "bitflags", ] diff -Nru distinst-0.3.2~1650402197~21.10~52e2e8d~dev/crates/disks/src/config/partitions/mod.rs distinst-0.3.2~1652283129~21.10~4af925c~dev/crates/disks/src/config/partitions/mod.rs --- distinst-0.3.2~1650402197~21.10~52e2e8d~dev/crates/disks/src/config/partitions/mod.rs 2022-04-19 21:03:17.000000000 +0000 +++ distinst-0.3.2~1652283129~21.10~4af925c~dev/crates/disks/src/config/partitions/mod.rs 2022-05-11 15:32:09.000000000 +0000 @@ -24,6 +24,7 @@ FileSystem::Fat16 | FileSystem::Fat32 => "umask=0077", FileSystem::Ext4 => "noatime,errors=remount-ro", FileSystem::Swap => "sw", + FileSystem::F2fs => "defaults,compress_algorithm=lz4,compress_chksum,atgc,gc_merge,lazytime,nodiscard", _ => "defaults", } } diff -Nru distinst-0.3.2~1650402197~21.10~52e2e8d~dev/crates/external/src/block.rs distinst-0.3.2~1652283129~21.10~4af925c~dev/crates/external/src/block.rs --- distinst-0.3.2~1650402197~21.10~52e2e8d~dev/crates/external/src/block.rs 2022-04-19 21:03:17.000000000 +0000 +++ distinst-0.3.2~1652283129~21.10~4af925c~dev/crates/external/src/block.rs 2022-05-11 15:32:09.000000000 +0000 @@ -71,7 +71,7 @@ Ext2 => ("mkfs.ext2", &["-F", "-q"]), Ext3 => ("mkfs.ext3", &["-F", "-q"]), Ext4 => ("mkfs.ext4", &["-F", "-q", "-E", "lazy_itable_init"]), - F2fs => ("mkfs.f2fs", &["-q"]), + F2fs => ("mkfs.f2fs", &["-f", "-q", "-O", "extra_attr,inode_checksum,sb_checksum,compression"]), Fat16 => ("mkfs.fat", &["-F", "16"]), Fat32 => ("mkfs.fat", &["-F", "32"]), Ntfs => ("mkfs.ntfs", &["-FQ", "-q"]), @@ -124,18 +124,16 @@ } fn get_label_cmd(kind: FileSystem) -> Option<(&'static str, &'static [&'static str])> { - let cmd: (&'static str, &'static [&'static str]) = match kind { - Btrfs => ("btrfs", &["filesystem", "label"]), - // Exfat => ("exfatlabel", &[]), - Exfat => unimplemented!("exfat is not supported, yet"), - Ext2 | Ext3 | Ext4 => ("e2label", &[]), - F2fs => unimplemented!(), - Fat16 | Fat32 => ("dosfslabel", &[]), - Ntfs => ("ntfslabel", &[]), - Xfs => ("xfs_admin", &["-l"]), + let cmd = match kind { + Btrfs => ("btrfs", &["filesystem", "label"][..]), + Ext2 | Ext3 | Ext4 => ("e2label", &[][..]), + Fat16 | Fat32 => ("dosfslabel", &[][..]), + Ntfs => ("ntfslabel", &[][..]), + Xfs => ("xfs_admin", &["-l"][..]), Swap | Luks | Lvm => { return None; } + _ => ("blkid", &["-s", "LABEL", "-o", "value"][..]), }; Some(cmd) diff -Nru distinst-0.3.2~1650402197~21.10~52e2e8d~dev/crates/hardware/Cargo.toml distinst-0.3.2~1652283129~21.10~4af925c~dev/crates/hardware/Cargo.toml --- distinst-0.3.2~1650402197~21.10~52e2e8d~dev/crates/hardware/Cargo.toml 2022-04-19 21:03:17.000000000 +0000 +++ distinst-0.3.2~1652283129~21.10~4af925c~dev/crates/hardware/Cargo.toml 2022-05-11 15:32:09.000000000 +0000 @@ -1,7 +1,10 @@ [package] name = "distinst-hardware-support" version = "0.1.0" -authors = ["Jeremy Soller ", "Michael Aaron Murphy "] +authors = [ + "Jeremy Soller ", + "Michael Aaron Murphy ", +] description = "Linux hardware detection and package recommendation" repository = "https://github.com/pop-os/distinst" readme = "README.md" @@ -15,5 +18,7 @@ dbus = "0.9" os-release = "0.1.0" proc-modules = "0.1.0" -raw-cpuid = "9.0" log = "0.4.8" + +[target.'cfg(any(target_arch = "x86", target_arch = "x86_64"))'.dependencies] +raw-cpuid = "9.0" diff -Nru distinst-0.3.2~1650402197~21.10~52e2e8d~dev/crates/hardware/src/lib.rs distinst-0.3.2~1652283129~21.10~4af925c~dev/crates/hardware/src/lib.rs --- distinst-0.3.2~1650402197~21.10~52e2e8d~dev/crates/hardware/src/lib.rs 2022-04-19 21:03:17.000000000 +0000 +++ distinst-0.3.2~1652283129~21.10~4af925c~dev/crates/hardware/src/lib.rs 2022-05-11 15:32:09.000000000 +0000 @@ -3,9 +3,11 @@ extern crate log; extern crate os_release; extern crate proc_modules; +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] extern crate raw_cpuid; use os_release::OsRelease; +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] use raw_cpuid::CpuId; use std::io::Read; @@ -16,7 +18,7 @@ use proc_modules::Module; // NOTE: Distributions should provide their distro ID and associated packages here, if applicable. - +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] fn amd_microcode(os_release: &OsRelease) -> Option<&'static str> { if &os_release.id_like == "debian" { Some("amd64-microcode") @@ -25,6 +27,7 @@ } } +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] fn intel_microcode(os_release: &OsRelease) -> Option<&'static str> { if &os_release.id_like == "debian" { Some("intel-microcode") @@ -68,6 +71,7 @@ } /// Microcode packages for specific processor vendors. +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] fn processor_support(os_release: &OsRelease) -> Option<&'static str> { if let Some(vf) = CpuId::new().get_vendor_info() { return match vf.as_string() { @@ -80,6 +84,11 @@ None } +#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] +fn processor_support(_os_release: &OsRelease) -> Option<&'static str> { + None +} + /// Hardware enablement packages for hardware from specific vendors. fn vendor_support(os_release: &OsRelease) -> Option<&'static str> { if let Some(vendor) = vendor() { diff -Nru distinst-0.3.2~1650402197~21.10~52e2e8d~dev/debian/changelog distinst-0.3.2~1652283129~21.10~4af925c~dev/debian/changelog --- distinst-0.3.2~1650402197~21.10~52e2e8d~dev/debian/changelog 2022-04-19 21:03:17.000000000 +0000 +++ distinst-0.3.2~1652283129~21.10~4af925c~dev/debian/changelog 2022-05-11 15:32:09.000000000 +0000 @@ -1,10 +1,10 @@ -distinst (0.3.2~1650402197~21.10~52e2e8d~dev) impish; urgency=medium +distinst (0.3.2~1652283129~21.10~4af925c~dev) impish; urgency=medium * Auto Build * Fix bug with C API disks constructor - -- Pop OS (ISO Signing Key) Tue, 19 Apr 2022 15:03:17 -0600 + -- Pop OS (ISO Signing Key) Wed, 11 May 2022 17:32:09 +0200 distinst (0.3.1-1) bionic; urgency=medium diff -Nru distinst-0.3.2~1650402197~21.10~52e2e8d~dev/debian/control distinst-0.3.2~1652283129~21.10~4af925c~dev/debian/control --- distinst-0.3.2~1650402197~21.10~52e2e8d~dev/debian/control 2022-04-19 21:03:17.000000000 +0000 +++ distinst-0.3.2~1652283129~21.10~4af925c~dev/debian/control 2022-05-11 15:32:09.000000000 +0000 @@ -14,7 +14,7 @@ Homepage: https://github.com/pop-os/distinst Package: distinst -Architecture: amd64 +Architecture: linux-any Depends: libdistinst (= ${binary:Version}), ${misc:Depends}, @@ -22,7 +22,7 @@ Description: Distribution Installer CLI Package: libdistinst -Architecture: amd64 +Architecture: linux-any Depends: apt, btrfs-progs, @@ -55,7 +55,7 @@ Description: Distribution Installer Library Package: libdistinst-dev -Architecture: amd64 +Architecture: linux-any Depends: libdistinst (= ${binary:Version}), ${misc:Depends} diff -Nru distinst-0.3.2~1650402197~21.10~52e2e8d~dev/ffi/src/installer.rs distinst-0.3.2~1652283129~21.10~4af925c~dev/ffi/src/installer.rs --- distinst-0.3.2~1650402197~21.10~52e2e8d~dev/ffi/src/installer.rs 2022-04-19 21:03:17.000000000 +0000 +++ distinst-0.3.2~1652283129~21.10~4af925c~dev/ffi/src/installer.rs 2022-05-11 15:32:09.000000000 +0000 @@ -1,6 +1,6 @@ use libc; -use std::io; +use std::{io, mem}; use crate::config::DistinstConfig; use crate::disk::DistinstDisks; @@ -79,7 +79,7 @@ /// Installer user account creation callback pub type DistinstUserAccountCallback = - extern "C" fn(user_data: *mut libc::c_void) -> DistinstUserAccountCreate; + extern "C" fn(user_account_create: *mut DistinstUserAccountCreate, user_data: *mut libc::c_void); /// An installer object #[repr(C)] @@ -164,7 +164,9 @@ user_data: *mut libc::c_void, ) { (*(installer as *mut Installer)).set_user_callback(move || { - (callback(user_data)).as_config().expect("user callback invalid") + let mut user_account_create = mem::zeroed(); + callback(&mut user_account_create, user_data); + user_account_create.as_config().expect("user callback invalid") }); } diff -Nru distinst-0.3.2~1650402197~21.10~52e2e8d~dev/src/distribution/debian.rs distinst-0.3.2~1652283129~21.10~4af925c~dev/src/distribution/debian.rs --- distinst-0.3.2~1650402197~21.10~52e2e8d~dev/src/distribution/debian.rs 2022-04-19 21:03:17.000000000 +0000 +++ distinst-0.3.2~1652283129~21.10~4af925c~dev/src/distribution/debian.rs 2022-05-11 15:32:09.000000000 +0000 @@ -123,11 +123,12 @@ Bootloader::Efi => &[ "grub-efi", "grub-efi-amd64", + "grub-efi-amd64-bin", "grub-efi-amd64-signed", "shim-signed", "mokutil", - "fwupdate-signed", - "linux-signed-generic", + "fwupd-signed", + "linux-image-generic", ], } } diff -Nru distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/AUTHORS distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/AUTHORS --- distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/AUTHORS 2022-04-19 21:33:04.000000000 +0000 +++ distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/AUTHORS 2022-05-11 16:26:11.000000000 +0000 @@ -4,3 +4,4 @@ Stefan Lankes Mingshen Sun Niklas Fiekas +Philipp Schuster \ No newline at end of file diff -Nru distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/.cargo-checksum.json distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/.cargo-checksum.json --- distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/.cargo-checksum.json 2022-04-19 21:33:04.000000000 +0000 +++ distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/.cargo-checksum.json 2022-05-11 16:26:11.000000000 +0000 @@ -1 +1 @@ -{"files":{"AUTHORS":"d471c3d15d7a32d82d4e44e50d244063027d330f4a5446b1f1e087a8f8ea2d0f","Cargo.lock":"62babcc7e83c170b8184989424d823fb5cf5d0f3e9d350d2df366868559a7610","Cargo.toml":"6e62adf321a10949a69e1758b9ce58e53662ec6c6006be8e50fa1507dfbafe68","LICENSE.md":"cdd45f4d0c552c3a51725728215919e0dedb1e1af250f130e7c2d60eef6721fe","README.md":"0eb82fa97cceb17f63e2d089258fd2db3581d226dd214951f335a88c1450684f","examples/cache.rs":"c8fc57159c15a67aaf64cba3f68405357e99c55607c4f8c5ff2cb7d88fb56c30","examples/cpu.rs":"f7e11fef1a268f3bda08a1f534cf7f8ee7ce23131df2bc6b18872b40872d9dea","examples/topology.rs":"494b0f18eec7a250a87079f6eb70a1d1d778a8e097b16407bdcfd69e95fb4757","examples/tsc_frequency.rs":"f15db8b37f7b875bdbb6ec45d57eaf048afa78dcb99c853d99d7821c9f5a5d89","src/bin/cpuid.rs":"10f50c6e5d2917cea59c273b2bad439646c5ca53b8224a44c80ca30c7b378408","src/lib.rs":"5f33b8bda7c5a4f9aa959c7a42851aa9e531e3606ebc23be21bef2b9a4022c11","src/tests.rs":"69db928394d441c4e8a02e40d3c18affe1e988d8b47be41fc64d11f84d255b73"},"package":"c27cb5785b85bd05d4eb171556c9a1a514552e26123aeae6bb7d811353148026"} \ No newline at end of file +{"files":{"AUTHORS":"e3b10b41409586bd2f09d3c6cabaa44d65ccc50153793b70bbd3ba5ec66be054","CHANGELOG.md":"ca7c73741e5891b206bb3d9cbcbb965f6855978662eb483fd2a1dd9a22ed9ece","Cargo.lock":"c75b965dcba89a8157304fef4e9b94ad96b7ec2559177d25c8469a7b878b1701","Cargo.toml":"7f960f060b178eddbd73e29989a7f24de8f8605ef832960cfadbacbba1eca5a2","LICENSE.md":"cdd45f4d0c552c3a51725728215919e0dedb1e1af250f130e7c2d60eef6721fe","README.md":"b22ef0ff10235a56f0f1f5969661e49cff70975ca70825f280886820f38aaaf4","examples/cache.rs":"145dbbb2ec70a14c8b6ecb495f24f6000332e5ffaea94ea179d864818315b428","examples/cpu.rs":"b6f5c0a0052db8c3db715f8e9eafe715ad282477a37ee80a729d3024c07b35a5","examples/topology.rs":"6f9dff78249293f5f09f464ac794a686b15c356cc19aa22a973a7e7c0088811d","examples/tsc_frequency.rs":"f15db8b37f7b875bdbb6ec45d57eaf048afa78dcb99c853d99d7821c9f5a5d89","src/bin/cpuid.rs":"7b1ccf87b63a931ccd3fd0f62b5bc9a025e37991c7d03390f1792256abc1c6ee","src/lib.rs":"2a47478070f8262fac85306334231980dd73dc3c52569ff76959f06a32bf6c29","src/tests/i5_3337u.rs":"2d91b7e38adb1562da2ec7f48dad86e432256791a645d70c8d5163e9360a1f88","src/tests/mod.rs":"56ac154a0a31175b51f3b66eea8bf3d5ef96c789853fca82b438effcdfe300ce","src/tests/ryzen_matisse.rs":"efca8007318bdc3ba9938106f4167e790ed54c9da4c8228f879c8a75d879b372"},"package":"1733f6f80c9c24268736a501cd00d41a9849b4faa7a9f9334c096e5d10553206"} \ No newline at end of file diff -Nru distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/Cargo.lock distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/Cargo.lock --- distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/Cargo.lock 2022-04-19 21:33:04.000000000 +0000 +++ distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/Cargo.lock 2022-05-11 16:26:11.000000000 +0000 @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "bitflags" version = "1.2.1" @@ -7,6 +9,12 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] name = "core_affinity" version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -19,10 +27,21 @@ ] [[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] name = "hermit-abi" -version = "0.1.12" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61565ff7aaace3525556587bd2dc31d4a07071957be715e63ce7b1eccf51a8f4" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] @@ -39,9 +58,9 @@ [[package]] name = "libc" -version = "0.2.69" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005" +checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6" [[package]] name = "num_cpus" @@ -54,30 +73,127 @@ ] [[package]] +name = "phf" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ac8b67553a7ca9457ce0e526948cad581819238f4a9d1ea74545851fa24f37" +dependencies = [ + "phf_macros", + "phf_shared", + "proc-macro-hack", +] + +[[package]] +name = "phf_generator" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc1437ada0f3a97d538f0bb608137bf53c53969028cab74c89893e1e9a12f0e" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b706f5936eb50ed880ae3009395b43ed19db5bff2ebd459c95e7bf013a89ab86" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_shared" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a68318426de33640f02be62b4ae8eb1261be2efbc337b60c54d845bf4484e0d9" +dependencies = [ + "siphasher", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] name = "proc-macro2" -version = "1.0.10" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3" +checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.3" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" dependencies = [ "proc-macro2", ] [[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core", +] + +[[package]] name = "raw-cpuid" -version = "9.0.0" +version = "9.1.1" dependencies = [ "bitflags", "core_affinity", "libc", + "phf", "rustversion", "serde", "serde_derive", @@ -85,21 +201,21 @@ [[package]] name = "rustversion" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb5d2a036dc6d2d8fd16fde3498b04306e29bd193bf306a57427019b823d5acd" +checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088" [[package]] name = "serde" -version = "1.0.106" +version = "1.0.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399" +checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" [[package]] name = "serde_derive" -version = "1.0.106" +version = "1.0.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c" +checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" dependencies = [ "proc-macro2", "quote", @@ -107,10 +223,16 @@ ] [[package]] +name = "siphasher" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbce6d4507c7e4a3962091436e56e95290cb71fa302d0d270e32130b75fbff27" + +[[package]] name = "syn" -version = "1.0.18" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "410a7488c0a728c7ceb4ad59b9567eb4053d02e8cc7f5c0e0eeeb39518369213" +checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7" dependencies = [ "proc-macro2", "quote", @@ -119,9 +241,15 @@ [[package]] name = "unicode-xid" -version = "0.2.0" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "winapi" diff -Nru distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/Cargo.toml distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/Cargo.toml --- distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/Cargo.toml 2022-04-19 21:33:04.000000000 +0000 +++ distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/Cargo.toml 2022-05-11 16:26:11.000000000 +0000 @@ -13,7 +13,7 @@ [package] edition = "2018" name = "raw-cpuid" -version = "9.0.0" +version = "9.1.1" authors = ["Gerd Zellweger "] exclude = ["/ci"] description = "A library to parse the x86 CPUID instruction, written in rust with no external dependencies. The implementation closely resembles the Intel CPUID manual description. The library does only depend on libcore." @@ -48,5 +48,9 @@ version = "0.2" default-features = false +[target."cfg(unix)".dev-dependencies.phf] +version = "0.9" +features = ["macros"] + [target."cfg(unix)".dev-dependencies.rustversion] version = "1.0" diff -Nru distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/CHANGELOG.md distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/CHANGELOG.md --- distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/CHANGELOG.md 1970-01-01 00:00:00.000000000 +0000 +++ distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/CHANGELOG.md 2022-05-11 16:26:11.000000000 +0000 @@ -0,0 +1,27 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +- Use more idiomatic rust code in readme/doc.rs example. +- Use `str::from_utf8` instead of `str::from_utf8_unchecked` to avoid potential + panics with the Deserialize trait ([#43](https://github.com/gz/rust-cpuid/issues/43)). +- More extensive Debug trait implementation ([#49](https://github.com/gz/rust-cpuid/pull/49)) + +## [9.1.0] - 2021-07-03 + +### Added + +- A `CpuId::with_cpuid_fn` that allows to override the default cpuid function. + +### Changed + +- Fixed `RdtAllocationInfo.has_memory_bandwidth_allocation`: was using the wrong bit +- Fixed `capacity_mask_length` in `L3CatInfo` and `L2CatInfo`: add +1 to returned value +- Fixed `MemBwAllocationInfo.max_hba_throttling`: add +1 to returned value +- Refactored tests into a module. +- Started to add tests for Ryzen/AMD. diff -Nru distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/examples/cache.rs distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/examples/cache.rs --- distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/examples/cache.rs 2022-04-19 21:33:04.000000000 +0000 +++ distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/examples/cache.rs 2022-05-11 16:26:11.000000000 +0000 @@ -21,7 +21,7 @@ }; let associativity = if cache.is_fully_associative() { - format!("fully associative") + "fully associative".to_string() } else { format!("{}-way associativity", cache.associativity()) }; diff -Nru distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/examples/cpu.rs distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/examples/cpu.rs --- distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/examples/cpu.rs 2022-04-19 21:33:04.000000000 +0000 +++ distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/examples/cpu.rs 2022-05-11 16:26:11.000000000 +0000 @@ -38,7 +38,7 @@ ); cpuid.get_feature_info().as_ref().map_or_else( - || println!("Family: {}\nExtended Family: {}\nModel: {}\nExtended Model: {}\nStepping: {}\nBrand Index: {}", "n/a", "n/a", "n/a", "n/a", "n/a", "n/a"), + || println!("Family: n/a\nExtended Family: n/a\nModel: n/a\nExtended Model: n/a\nStepping: n/a\nBrand Index: n/a"), |finfo| { println!( "Family: {}\nExtended Family: {}\nModel: {}\nExtended Model: {}\nStepping: {}\nBrand Index: {}", diff -Nru distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/examples/topology.rs distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/examples/topology.rs --- distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/examples/topology.rs 2022-04-19 21:33:04.000000000 +0000 +++ distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/examples/topology.rs 2022-05-11 16:26:11.000000000 +0000 @@ -88,7 +88,7 @@ println!("Enumeration of all cores in the system (with x2APIC IDs):"); let mut all_x2apic_ids: Vec = gather_all_x2apic_ids(); - all_x2apic_ids.sort(); + all_x2apic_ids.sort_unstable(); for x2apic_id in all_x2apic_ids { let smt_select_mask = !(u32::max_value() << smt_x2apic_shift); let core_select_mask = (!((u32::max_value()) << core_x2apic_shift)) ^ smt_select_mask; @@ -146,7 +146,7 @@ println!("Enumeration of all cores in the system (with APIC IDs):"); let mut all_xapic_ids: Vec = gather_all_xapic_ids(); - all_xapic_ids.sort(); + all_xapic_ids.sort_unstable(); for xapic_id in all_xapic_ids { let smt_id = xapic_id & smt_select_mask; @@ -195,9 +195,9 @@ }, ); - println!(""); + println!(); enumerate_with_legacy_leaf_1_4(); - println!(""); + println!(); enumerate_with_extended_topology_info(); } diff -Nru distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/README.md distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/README.md --- distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/README.md 2022-04-19 21:33:04.000000000 +0000 +++ distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/README.md 2022-05-11 16:26:11.000000000 +0000 @@ -1,38 +1,35 @@ -# cpuid [![Build Status](https://travis-ci.org/gz/rust-cpuid.svg)](https://travis-ci.org/gz/rust-cpuid) [![Crates.io](https://img.shields.io/crates/v/raw_cpuid.svg)](https://crates.io/crates/raw-cpuid) +# cpuid [![Crates.io](https://img.shields.io/crates/v/raw_cpuid.svg)](https://crates.io/crates/raw-cpuid) [![Standard checks](https://github.com/gz/rust-cpuid/actions/workflows/standard.yml/badge.svg)](https://github.com/gz/rust-cpuid/actions/workflows/standard.yml) A library to parse the x86 CPUID instruction, written in rust with no external dependencies. The implementation closely resembles the Intel CPUID manual description. The library does only depend on libcore. The code should be in sync with the latest March 2018 revision of the Intel Architectures Software Developer’s Manual. ## Library usage + ```rust +use raw_cpuid::CpuId; let cpuid = CpuId::new(); -match cpuid.get_vendor_info() { - Some(vf) => assert!(vf.as_string() == "GenuineIntel"), - None => () +if let Some(vf) = cpuid.get_vendor_info() { + assert!(vf.as_string() == "GenuineIntel" || vf.as_string() == "AuthenticAMD"); } -let has_sse = match cpuid.get_feature_info() { - Some(finfo) => finfo.has_sse(), - None => false -}; - +let has_sse = cpuid.get_feature_info().map_or(false, |finfo| finfo.has_sse()); if has_sse { println!("CPU supports SSE!"); } -match cpuid.get_cache_parameters() { - Some(cparams) => { - for cache in cparams { - let size = cache.associativity() * cache.physical_line_partitions() * cache.coherency_line_size() * cache.sets(); - println!("L{}-Cache size is {}", cache.level(), size); - } - }, - None => println!("No cache parameter information available"), +if let Some(cparams) = cpuid.get_cache_parameters() { + for cache in cparams { + let size = cache.associativity() * cache.physical_line_partitions() * cache.coherency_line_size() * cache.sets(); + println!("L{}-Cache size is {}", cache.level(), size); + } +} else { + println!("No cache parameter information available") } ``` ## Documentation + * [API Documentation](https://docs.rs/raw-cpuid/) * [Examples](https://github.com/gz/rust-cpuid/tree/master/examples) diff -Nru distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/src/bin/cpuid.rs distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/src/bin/cpuid.rs --- distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/src/bin/cpuid.rs 2022-04-19 21:33:04.000000000 +0000 +++ distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/src/bin/cpuid.rs 2022-05-11 16:26:11.000000000 +0000 @@ -5,94 +5,94 @@ fn main() { let cpuid = CpuId::new(); // Implement Display for each of those structs - cpuid.get_vendor_info().map(|info| { + if let Some(info) = cpuid.get_vendor_info() { println!("Vendor"); println!("{}", info); - }); - cpuid.get_feature_info().map(|info| { + }; + if let Some(info) = cpuid.get_feature_info() { println!("Feature"); println!("{:?}", info); - }); - cpuid.get_cache_info().map(|info| { + } + if let Some(info) = cpuid.get_cache_info() { println!("Cache"); println!("{:?}", info); - }); - cpuid.get_processor_serial().map(|info| { + } + if let Some(info) = cpuid.get_processor_serial() { println!("Processor Serial"); println!("{:?}", info); - }); - cpuid.get_cache_parameters().map(|info| { + } + if let Some(info) = cpuid.get_cache_parameters() { println!("Cache Parameters"); println!("{:?}", info); - }); - cpuid.get_monitor_mwait_info().map(|info| { + } + if let Some(info) = cpuid.get_monitor_mwait_info() { println!("Monitor/MWait"); println!("{:?}", info); - }); - cpuid.get_thermal_power_info().map(|info| { + } + if let Some(info) = cpuid.get_thermal_power_info() { println!("Thermal Power"); println!("{:?}", info); - }); - cpuid.get_extended_feature_info().map(|info| { + } + if let Some(info) = cpuid.get_extended_feature_info() { println!("Extended Features"); println!("{:?}", info); - }); - cpuid.get_direct_cache_access_info().map(|info| { + } + if let Some(info) = cpuid.get_direct_cache_access_info() { println!("Direct Cache Access"); println!("{:?}", info); - }); - cpuid.get_performance_monitoring_info().map(|info| { + } + if let Some(info) = cpuid.get_performance_monitoring_info() { println!("Performance Monitoring"); println!("{:?}", info); - }); - cpuid.get_extended_topology_info().map(|info| { + } + if let Some(info) = cpuid.get_extended_topology_info() { println!("Extended Topology"); println!("{:?}", info); - }); - cpuid.get_extended_state_info().map(|info| { + } + if let Some(info) = cpuid.get_extended_state_info() { println!("Extended State"); println!("{:?}", info); - }); - cpuid.get_rdt_monitoring_info().map(|info| { + } + if let Some(info) = cpuid.get_rdt_monitoring_info() { println!("RDT Monitoring"); println!("{:?}", info); - }); - cpuid.get_rdt_allocation_info().map(|info| { + } + if let Some(info) = cpuid.get_rdt_allocation_info() { println!("RDT Allocation"); println!("{:?}", info); - }); - cpuid.get_sgx_info().map(|info| { + } + if let Some(info) = cpuid.get_sgx_info() { println!("Software Guard Extensions"); println!("{:?}", info); - }); - cpuid.get_processor_trace_info().map(|info| { + } + if let Some(info) = cpuid.get_processor_trace_info() { println!("Processor Trace"); println!("{:?}", info); - }); - cpuid.get_tsc_info().map(|info| { + } + if let Some(info) = cpuid.get_tsc_info() { println!("TSC"); println!("{:?}", info); - }); - cpuid.get_processor_frequency_info().map(|info| { + } + if let Some(info) = cpuid.get_processor_frequency_info() { println!("Processor Frequency"); println!("{:?}", info); - }); - cpuid.deterministic_address_translation_info().map(|dats| { + } + if let Some(dats) = cpuid.deterministic_address_translation_info() { println!("Deterministic Address Translation"); for dat in dats { println!("{:?}", dat); } - }); - cpuid.get_soc_vendor_info().map(|info| { + } + if let Some(info) = cpuid.get_soc_vendor_info() { println!("SoC Vendor Info"); println!("{:?}", info); - }); - cpuid.get_extended_function_info().map(|info| { + } + if let Some(info) = cpuid.get_extended_function_info() { println!("Extended Function Info"); println!("{:?}", info); - }); - cpuid.get_memory_encryption_info().map(|info| { + } + if let Some(info) = cpuid.get_memory_encryption_info() { println!("Memory Encryption Info"); println!("{:?}", info); - }); + } } diff -Nru distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/src/lib.rs distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/src/lib.rs --- distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/src/lib.rs 2022-04-19 21:33:04.000000000 +0000 +++ distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/src/lib.rs 2022-05-11 16:26:11.000000000 +0000 @@ -1,3 +1,34 @@ +//! A library to parse the x86 CPUID instruction, written in rust with no external dependencies. +//! The implementation closely resembles the Intel CPUID manual description. The library does only +//! depend on libcore. +//! +//! The code should be in sync with the latest March 2018 revision of the Intel Architectures +//! Software Developer’s Manual. +//! +//! ## Example +//! ```rust +//! use raw_cpuid::CpuId; +//! let cpuid = CpuId::new(); +//! +//! if let Some(vf) = cpuid.get_vendor_info() { +//! assert!(vf.as_string() == "GenuineIntel" || vf.as_string() == "AuthenticAMD"); +//! } +//! +//! let has_sse = cpuid.get_feature_info().map_or(false, |finfo| finfo.has_sse()); +//! if has_sse { +//! println!("CPU supports SSE!"); +//! } +//! +//! if let Some(cparams) = cpuid.get_cache_parameters() { +//! for cache in cparams { +//! let size = cache.associativity() * cache.physical_line_partitions() * cache.coherency_line_size() * cache.sets(); +//! println!("L{}-Cache size is {}", cache.level(), size); +//! } +//! } else { +//! println!("No cache parameter information available") +//! } +//! ``` + #![no_std] #![crate_name = "raw_cpuid"] #![crate_type = "lib"] @@ -12,6 +43,9 @@ #[macro_use] extern crate serde_derive; +#[cfg(feature = "serialize")] +extern crate serde; + #[macro_use] extern crate bitflags; @@ -40,6 +74,7 @@ use core::cmp::min; use core::fmt; +use core::fmt::{Debug, Formatter}; use core::mem::size_of; use core::slice; use core::str; @@ -102,15 +137,77 @@ }; } +/// Implements function to read/write cpuid. +/// This allows to conveniently swap out the underlying cpuid implementation +/// with one that returns data that is deterministic (for unit-testing). +#[derive(Debug, Clone, Copy)] +struct CpuIdReader { + cpuid_fn: fn(u32, u32) -> CpuIdResult, +} + +impl CpuIdReader { + fn new(cpuid_fn: fn(u32, u32) -> CpuIdResult) -> Self { + Self { cpuid_fn } + } + + fn cpuid1(&self, eax: u32) -> CpuIdResult { + (self.cpuid_fn)(eax, 0) + } + + fn cpuid2(&self, eax: u32, ecx: u32) -> CpuIdResult { + (self.cpuid_fn)(eax, ecx) + } +} + +impl Default for CpuIdReader { + fn default() -> Self { + Self { + cpuid_fn: native_cpuid::cpuid_count, + } + } +} + +#[derive(Debug, Eq, PartialEq, Clone, Copy)] +#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] +enum Vendor { + Intel, + Amd, + Unknown(u32, u32, u32), +} + +impl Vendor { + fn from_vendor_leaf(res: CpuIdResult) -> Self { + let vi = VendorInfo { + ebx: res.ebx, + ecx: res.ecx, + edx: res.edx, + }; + + match vi.as_string() { + "GenuineIntel" => Vendor::Intel, + "AuthenticAMD" => Vendor::Amd, + _ => Vendor::Unknown(res.ebx, res.ecx, res.edx), + } + } +} + /// Main type used to query for information about the CPU we're running on. -#[derive(Debug, Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct CpuId { - max_eax_value: u32, + #[cfg_attr(feature = "serialize", serde(skip))] + read: CpuIdReader, + vendor: Vendor, + supported_leafs: u32, +} + +impl Default for CpuId { + fn default() -> CpuId { + CpuId::with_cpuid_fn(native_cpuid::cpuid_count) + } } /// Low-level data-structure to store result of cpuid instruction. -#[derive(Copy, Clone, Debug, Default)] +#[derive(Copy, Clone, Default, Eq, PartialEq)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] #[repr(C)] pub struct CpuIdResult { @@ -124,6 +221,23 @@ pub edx: u32, } +impl CpuIdResult { + pub fn all_zero(&self) -> bool { + self.eax == 0 && self.ebx == 0 && self.ecx == 0 && self.edx == 0 + } +} + +impl Debug for CpuIdResult { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_struct("CpuIdResult") + .field("eax", &(self.eax as *const u32)) + .field("ebx", &(self.ebx as *const u32)) + .field("ecx", &(self.ecx as *const u32)) + .field("edx", &(self.edx as *const u32)) + .finish() + } +} + const EAX_VENDOR_INFO: u32 = 0x0; const EAX_FEATURE_INFO: u32 = 0x1; const EAX_CACHE_INFO: u32 = 0x2; @@ -150,15 +264,29 @@ impl CpuId { /// Return new CPUID struct. - pub fn new() -> CpuId { - let res = cpuid!(EAX_VENDOR_INFO); + pub fn new() -> Self { + Self::default() + } + + pub fn with_cpuid_fn(cpuid_fn: fn(u32, u32) -> CpuIdResult) -> Self { + let read = CpuIdReader::new(cpuid_fn); + let vendor_leaf = read.cpuid1(EAX_VENDOR_INFO); CpuId { - max_eax_value: res.eax, + supported_leafs: vendor_leaf.eax, + vendor: Vendor::from_vendor_leaf(vendor_leaf), + read, } } + /// Check if a non extended leaf (`val`) is supported. fn leaf_is_supported(&self, val: u32) -> bool { - val <= self.max_eax_value + // Exclude reserved functions/leafs on AMD + if self.vendor == Vendor::Amd && ((0x2..=0x4).contains(&val) || (0x8..=0xa).contains(&val)) + { + return false; + } + + val <= self.supported_leafs } /// Return information about vendor. @@ -166,7 +294,7 @@ /// GenuineIntel for Intel CPUs or AuthenticAMD for AMD CPUs. pub fn get_vendor_info(&self) -> Option { if self.leaf_is_supported(EAX_VENDOR_INFO) { - let res = cpuid!(EAX_VENDOR_INFO); + let res = self.read.cpuid1(EAX_VENDOR_INFO); Some(VendorInfo { ebx: res.ebx, ecx: res.ecx, @@ -180,7 +308,7 @@ /// Query a set of features that are available on this CPU. pub fn get_feature_info(&self) -> Option { if self.leaf_is_supported(EAX_FEATURE_INFO) { - let res = cpuid!(EAX_FEATURE_INFO); + let res = self.read.cpuid1(EAX_FEATURE_INFO); Some(FeatureInfo { eax: res.eax, ebx: res.ebx, @@ -197,7 +325,7 @@ /// into a static table of cache descriptions (see `CACHE_INFO_TABLE`). pub fn get_cache_info(&self) -> Option { if self.leaf_is_supported(EAX_CACHE_INFO) { - let res = cpuid!(EAX_CACHE_INFO); + let res = self.read.cpuid1(EAX_CACHE_INFO); Some(CacheInfoIter { current: 1, eax: res.eax, @@ -213,7 +341,7 @@ /// Retrieve serial number of processor. pub fn get_processor_serial(&self) -> Option { if self.leaf_is_supported(EAX_PROCESSOR_SERIAL) { - let res = cpuid!(EAX_PROCESSOR_SERIAL); + let res = self.read.cpuid1(EAX_PROCESSOR_SERIAL); Some(ProcessorSerial { ecx: res.ecx, edx: res.edx, @@ -228,7 +356,10 @@ /// set size, line size etc. for each level of the cache hierarchy. pub fn get_cache_parameters(&self) -> Option { if self.leaf_is_supported(EAX_CACHE_PARAMETERS) { - Some(CacheParametersIter { current: 0 }) + Some(CacheParametersIter { + read: self.read, + current: 0, + }) } else { None } @@ -237,7 +368,7 @@ /// Information about how monitor/mwait works on this CPU. pub fn get_monitor_mwait_info(&self) -> Option { if self.leaf_is_supported(EAX_MONITOR_MWAIT_INFO) { - let res = cpuid!(EAX_MONITOR_MWAIT_INFO); + let res = self.read.cpuid1(EAX_MONITOR_MWAIT_INFO); Some(MonitorMwaitInfo { eax: res.eax, ebx: res.ebx, @@ -252,12 +383,12 @@ /// Query information about thermal and power management features of the CPU. pub fn get_thermal_power_info(&self) -> Option { if self.leaf_is_supported(EAX_THERMAL_POWER_INFO) { - let res = cpuid!(EAX_THERMAL_POWER_INFO); + let res = self.read.cpuid1(EAX_THERMAL_POWER_INFO); Some(ThermalPowerInfo { eax: ThermalPowerFeaturesEax { bits: res.eax }, ebx: res.ebx, ecx: ThermalPowerFeaturesEcx { bits: res.ecx }, - edx: res.edx, + _edx: res.edx, }) } else { None @@ -267,13 +398,12 @@ /// Find out about more features supported by this CPU. pub fn get_extended_feature_info(&self) -> Option { if self.leaf_is_supported(EAX_STRUCTURED_EXTENDED_FEATURE_INFO) { - let res = cpuid!(EAX_STRUCTURED_EXTENDED_FEATURE_INFO); - assert!(res.eax == 0); + let res = self.read.cpuid1(EAX_STRUCTURED_EXTENDED_FEATURE_INFO); Some(ExtendedFeatures { - eax: res.eax, + _eax: res.eax, ebx: ExtendedFeaturesEbx { bits: res.ebx }, ecx: ExtendedFeaturesEcx { bits: res.ecx }, - edx: res.edx, + _edx: res.edx, }) } else { None @@ -283,7 +413,7 @@ /// Direct cache access info. pub fn get_direct_cache_access_info(&self) -> Option { if self.leaf_is_supported(EAX_DIRECT_CACHE_ACCESS_INFO) { - let res = cpuid!(EAX_DIRECT_CACHE_ACCESS_INFO); + let res = self.read.cpuid1(EAX_DIRECT_CACHE_ACCESS_INFO); Some(DirectCacheAccessInfo { eax: res.eax }) } else { None @@ -293,11 +423,11 @@ /// Info about performance monitoring (how many counters etc.). pub fn get_performance_monitoring_info(&self) -> Option { if self.leaf_is_supported(EAX_PERFORMANCE_MONITOR_INFO) { - let res = cpuid!(EAX_PERFORMANCE_MONITOR_INFO); + let res = self.read.cpuid1(EAX_PERFORMANCE_MONITOR_INFO); Some(PerformanceMonitoringInfo { eax: res.eax, ebx: PerformanceMonitoringFeaturesEbx { bits: res.ebx }, - ecx: res.ecx, + _ecx: res.ecx, edx: res.edx, }) } else { @@ -308,7 +438,10 @@ /// Information about topology (how many cores and what kind of cores). pub fn get_extended_topology_info(&self) -> Option { if self.leaf_is_supported(EAX_EXTENDED_TOPOLOGY_INFO) { - Some(ExtendedTopologyIter { level: 0 }) + Some(ExtendedTopologyIter { + read: self.read, + level: 0, + }) } else { None } @@ -317,17 +450,18 @@ /// Information for saving/restoring extended register state. pub fn get_extended_state_info(&self) -> Option { if self.leaf_is_supported(EAX_EXTENDED_STATE_INFO) { - let res = cpuid!(EAX_EXTENDED_STATE_INFO, 0); - let res1 = cpuid!(EAX_EXTENDED_STATE_INFO, 1); + let res = self.read.cpuid2(EAX_EXTENDED_STATE_INFO, 0); + let res1 = self.read.cpuid2(EAX_EXTENDED_STATE_INFO, 1); Some(ExtendedStateInfo { + read: self.read, eax: ExtendedStateInfoXCR0Flags { bits: res.eax }, ebx: res.ebx, ecx: res.ecx, - edx: res.edx, + _edx: res.edx, eax1: res1.eax, ebx1: res1.ebx, ecx1: ExtendedStateInfoXSSFlags { bits: res1.ecx }, - edx1: res1.edx, + _edx1: res1.edx, }) } else { None @@ -336,10 +470,11 @@ /// Quality of service informations. pub fn get_rdt_monitoring_info(&self) -> Option { - let res = cpuid!(EAX_RDT_MONITORING, 0); + let res = self.read.cpuid1(EAX_RDT_MONITORING); if self.leaf_is_supported(EAX_RDT_MONITORING) { Some(RdtMonitoringInfo { + read: self.read, ebx: res.ebx, edx: res.edx, }) @@ -350,10 +485,13 @@ /// Quality of service enforcement information. pub fn get_rdt_allocation_info(&self) -> Option { - let res = cpuid!(EAX_RDT_ALLOCATION, 0); + let res = self.read.cpuid1(EAX_RDT_ALLOCATION); if self.leaf_is_supported(EAX_RDT_ALLOCATION) { - Some(RdtAllocationInfo { ebx: res.ebx }) + Some(RdtAllocationInfo { + read: self.read, + ebx: res.ebx, + }) } else { None } @@ -363,12 +501,13 @@ // Leaf 12H sub-leaf 0 (ECX = 0) is supported if CPUID.(EAX=07H, ECX=0H):EBX[SGX] = 1. self.get_extended_feature_info().and_then(|info| { if self.leaf_is_supported(EAX_SGX) && info.has_sgx() { - let res = cpuid!(EAX_SGX, 0); - let res1 = cpuid!(EAX_SGX, 1); + let res = self.read.cpuid2(EAX_SGX, 0); + let res1 = self.read.cpuid2(EAX_SGX, 1); Some(SgxInfo { + read: self.read, eax: res.eax, ebx: res.ebx, - ecx: res.ecx, + _ecx: res.ecx, edx: res.edx, eax1: res1.eax, ebx1: res1.ebx, @@ -383,19 +522,19 @@ /// Intel Processor Trace Enumeration Information. pub fn get_processor_trace_info(&self) -> Option { - let res = cpuid!(EAX_TRACE_INFO, 0); if self.leaf_is_supported(EAX_TRACE_INFO) { + let res = self.read.cpuid2(EAX_TRACE_INFO, 0); let res1 = if res.eax >= 1 { - Some(cpuid!(EAX_TRACE_INFO, 1)) + Some(self.read.cpuid2(EAX_TRACE_INFO, 1)) } else { None }; Some(ProcessorTraceInfo { - eax: res.eax, + _eax: res.eax, ebx: res.ebx, ecx: res.ecx, - edx: res.edx, + _edx: res.edx, leaf1: res1, }) } else { @@ -405,8 +544,8 @@ /// Time Stamp Counter/Core Crystal Clock Information. pub fn get_tsc_info(&self) -> Option { - let res = cpuid!(EAX_TIME_STAMP_COUNTER_INFO, 0); if self.leaf_is_supported(EAX_TIME_STAMP_COUNTER_INFO) { + let res = self.read.cpuid2(EAX_TIME_STAMP_COUNTER_INFO, 0); Some(TscInfo { eax: res.eax, ebx: res.ebx, @@ -419,8 +558,8 @@ /// Processor Frequency Information. pub fn get_processor_frequency_info(&self) -> Option { - let res = cpuid!(EAX_FREQUENCY_INFO, 0); if self.leaf_is_supported(EAX_FREQUENCY_INFO) { + let res = self.read.cpuid1(EAX_FREQUENCY_INFO); Some(ProcessorFrequencyInfo { eax: res.eax, ebx: res.ebx, @@ -433,8 +572,11 @@ pub fn deterministic_address_translation_info(&self) -> Option { if self.leaf_is_supported(EAX_DETERMINISTIC_ADDRESS_TRANSLATION_INFO) { - let res = cpuid!(EAX_DETERMINISTIC_ADDRESS_TRANSLATION_INFO, 0); + let res = self + .read + .cpuid2(EAX_DETERMINISTIC_ADDRESS_TRANSLATION_INFO, 0); Some(DatIter { + read: self.read, current: 0, count: res.eax, }) @@ -444,9 +586,10 @@ } pub fn get_soc_vendor_info(&self) -> Option { - let res = cpuid!(EAX_SOC_VENDOR_INFO, 0); if self.leaf_is_supported(EAX_SOC_VENDOR_INFO) { + let res = self.read.cpuid1(EAX_SOC_VENDOR_INFO); Some(SoCVendorInfo { + read: self.read, eax: res.eax, ebx: res.ebx, ecx: res.ecx, @@ -458,9 +601,12 @@ } pub fn get_hypervisor_info(&self) -> Option { - let res = cpuid!(EAX_HYPERVISOR_INFO); + let res = self.read.cpuid1(EAX_HYPERVISOR_INFO); if res.eax > 0 { - Some(HypervisorInfo { res: res }) + Some(HypervisorInfo { + read: self.read, + res, + }) } else { None } @@ -469,7 +615,7 @@ /// Extended functionality of CPU described here (including more supported features). /// This also contains a more detailed CPU model identifier. pub fn get_extended_function_info(&self) -> Option { - let res = cpuid!(EAX_EXTENDED_FUNCTION_INFO); + let res = self.read.cpuid1(EAX_EXTENDED_FUNCTION_INFO); if res.eax == 0 { return None; @@ -537,19 +683,19 @@ let max_eax_value = min(ef.max_eax_value + 1, ef.data.len() as u32); for i in 1..max_eax_value { - ef.data[i as usize] = cpuid!(EAX_EXTENDED_FUNCTION_INFO + i); + ef.data[i as usize] = self.read.cpuid1(EAX_EXTENDED_FUNCTION_INFO + i); } Some(ef) } pub fn get_memory_encryption_info(&self) -> Option { - let res = cpuid!(EAX_EXTENDED_FUNCTION_INFO); + let res = self.read.cpuid1(EAX_EXTENDED_FUNCTION_INFO); if res.eax < EAX_MEMORY_ENCRYPTION_INFO { return None; } - let res = cpuid!(EAX_MEMORY_ENCRYPTION_INFO); + let res = self.read.cpuid1(EAX_MEMORY_ENCRYPTION_INFO); Some(MemoryEncryptionInfo { eax: MemoryEncryptionInfoEax { bits: res.eax }, ebx: res.ebx, @@ -559,7 +705,56 @@ } } -#[derive(Debug, Default)] +/// Vendor Info String, that can be for example "AuthenticAMD" or "GenuineIntel". +/// +/// ## Technical Background +/// The vendor info is a 12-byte (96 bit) long string stored in `ebx`, `edx` and `ecx` by +/// the corresponding `cpuid` instruction. +impl Debug for CpuId { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_struct("CpuId") + .field("vendor", &self.vendor) + // .field("supported_leafs", &(self.supported_leafs as *const u32)) + .field("vendor_info", &self.get_vendor_info()) + .field("feature_info", &self.get_feature_info()) + .field("cache_info", &self.get_cache_info()) + .field("processor_serial", &self.get_processor_serial()) + .field("cache_parameters", &self.get_cache_parameters()) + .field("monitor_mwait_info", &self.get_monitor_mwait_info()) + .field("thermal_power_info", &self.get_thermal_power_info()) + .field("extended_feature_info", &self.get_extended_feature_info()) + .field( + "direct_cache_access_info", + &self.get_direct_cache_access_info(), + ) + .field( + "performance_monitoring_info", + &self.get_performance_monitoring_info(), + ) + .field("extended_topology_info", &self.get_extended_topology_info()) + .field("extended_state_info", &self.get_extended_state_info()) + .field("rdt_monitoring_info", &self.get_rdt_monitoring_info()) + .field("rdt_allocation_info", &self.get_rdt_allocation_info()) + .field("sgx_info", &self.get_sgx_info()) + .field("processor_trace_info", &self.get_processor_trace_info()) + .field("tsc_info", &self.get_tsc_info()) + .field( + "processor_frequency_info", + &self.get_processor_frequency_info(), + ) + .field( + "deterministic_address_translation_info", + &self.deterministic_address_translation_info(), + ) + .field("soc_vendor_info", &self.get_soc_vendor_info()) + .field("hypervisor_info", &self.get_hypervisor_info()) + .field("extended_function_info", &self.get_extended_function_info()) + .field("memory_encryption_info", &self.get_memory_encryption_info()) + .finish() + } +} + +#[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] #[repr(C)] pub struct VendorInfo { @@ -570,21 +765,28 @@ impl VendorInfo { /// Return vendor identification as human readable string. - pub fn as_string<'a>(&'a self) -> &'a str { + pub fn as_string(&self) -> &str { let brand_string_start = self as *const VendorInfo as *const u8; - unsafe { - // Safety: VendorInfo is laid out with repr(C). - let slice: &'a [u8] = slice::from_raw_parts(brand_string_start, size_of::()); - // Safety: The field is specified to be ASCII, and the only safe - // way to construct VendorInfo is from real CPUID data or the - // Default implementation. - str::from_utf8_unchecked(slice) - } + let slice = unsafe { + // Safety: VendorInfo is laid out with repr(C) and exactly + // 12 byte long without any padding. + slice::from_raw_parts(brand_string_start, size_of::()) + }; + + str::from_utf8(slice).unwrap_or("InvalidVendorString") + } +} + +impl Debug for VendorInfo { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_struct("VendorInfo") + .field("brand_string", &self.as_string()) + .finish() } } /// Used to iterate over cache information contained in cpuid instruction. -#[derive(Debug, Default)] +#[derive(Default, Clone)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct CacheInfoIter { current: u32, @@ -640,6 +842,16 @@ } } +impl Debug for CacheInfoIter { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + let mut debug = f.debug_list(); + self.clone().for_each(|ref item| { + debug.entry(item); + }); + debug.finish() + } +} + /// What type of cache are we dealing with? #[derive(Copy, Clone, Debug)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] @@ -659,7 +871,7 @@ } /// Describes any kind of cache (TLB, Data and Instruction caches plus prefetchers). -#[derive(Copy, Clone, Debug, Default)] +#[derive(Copy, Clone, Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct CacheInfo { /// Number as retrieved from cpuid @@ -790,6 +1002,15 @@ } } +impl Debug for CacheInfo { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.debug_struct("CacheInfo") + .field("typ", &self.typ) + .field("desc", &self.desc()) + .finish() + } +} + impl fmt::Display for CacheInfo { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let typ = match self.typ { @@ -1247,7 +1468,7 @@ } } -#[derive(Debug, Default)] +#[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct ProcessorSerial { ecx: u32, @@ -1272,7 +1493,17 @@ } } -#[derive(Debug, Default)] +impl Debug for ProcessorSerial { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_struct("ProcessorSerial") + .field("serial_lower", &self.serial_lower()) + .field("serial_middle", &self.serial_middle()) + .field("serial_middle", &self.serial_middle()) + .finish() + } +} + +#[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct FeatureInfo { eax: u32, @@ -1825,6 +2056,26 @@ ); } +impl Debug for FeatureInfo { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_struct("FeatureInfo") + .field("extended_family_id", &self.extended_family_id()) + .field("extended_model_id", &self.extended_model_id()) + .field("family_id", &self.family_id()) + .field("model_id", &self.model_id()) + .field("stepping_id", &self.stepping_id()) + .field("brand_index", &self.brand_index()) + .field("cflush_cache_line_size", &self.cflush_cache_line_size()) + .field("initial_local_apic_id", &self.initial_local_apic_id()) + .field( + "max_logical_processor_ids", + &self.max_logical_processor_ids(), + ) + .field("edx_ecx", &self.edx_ecx) + .finish() + } +} + bitflags! { #[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] @@ -1895,7 +2146,7 @@ // EDX flags /// Floating Point Unit On-Chip. The processor contains an x87 FPU. - const FPU = 1 << (32 + 0); + const FPU = 1 << 32; /// Virtual 8086 Mode Enhancements. Virtual 8086 mode enhancements, including CR4.VME for controlling the feature, CR4.PVI for protected mode virtual interrupts, software interrupt indirection, expansion of the TSS with the software indirection bitmap, and EFLAGS.VIF and EFLAGS.VIP flags. const VME = 1 << (32 + 1); /// Debugging Extensions. Support for I/O breakpoints, including CR4.DE for controlling the feature, and optional trapping of accesses to DR4 and DR5. @@ -1955,9 +2206,11 @@ } } -#[derive(Debug, Default)] +#[derive(Default, Clone)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct CacheParametersIter { + #[cfg_attr(feature = "serialize", serde(skip))] + read: CpuIdReader, current: u32, } @@ -1968,7 +2221,7 @@ /// Note: cpuid is called every-time we this function to get information /// about next cache. fn next(&mut self) -> Option { - let res = cpuid!(EAX_CACHE_PARAMETERS, self.current); + let res = self.read.cpuid2(EAX_CACHE_PARAMETERS, self.current); let cp = CacheParameter { eax: res.eax, ebx: res.ebx, @@ -1987,7 +2240,17 @@ } } -#[derive(Copy, Clone, Debug, Default)] +impl Debug for CacheParametersIter { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + let mut debug = f.debug_list(); + self.clone().for_each(|ref item| { + debug.entry(item); + }); + debug.finish() + } +} + +#[derive(Copy, Clone, Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct CacheParameter { eax: u32, @@ -2097,7 +2360,27 @@ } } -#[derive(Debug, Default)] +impl Debug for CacheParameter { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_struct("CacheParameter") + .field("cache_type", &self.cache_type()) + .field("level", &self.level()) + .field("is_self_initializing", &self.is_self_initializing()) + .field("is_fully_associative", &self.is_fully_associative()) + .field("max_cores_for_cache", &self.max_cores_for_cache()) + .field("max_cores_for_package", &self.max_cores_for_package()) + .field("coherency_line_size", &self.coherency_line_size()) + .field("physical_line_partitions", &self.physical_line_partitions()) + .field("associativity", &self.associativity()) + .field("sets", &self.sets()) + .field("is_write_back_invalidate", &self.is_write_back_invalidate()) + .field("is_inclusive", &self.is_inclusive()) + .field("has_complex_indexing", &self.has_complex_indexing()) + .finish() + } +} + +#[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct MonitorMwaitInfo { eax: u32, @@ -2168,13 +2451,35 @@ } } -#[derive(Debug, Default)] +impl Debug for MonitorMwaitInfo { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_struct("MonitorMwaitInfo") + .field("smallest_monitor_line", &self.smallest_monitor_line()) + .field("largest_monitor_line", &self.largest_monitor_line()) + .field("extensions_supported", &self.extensions_supported()) + .field( + "interrupts_as_break_event", + &self.interrupts_as_break_event(), + ) + .field("supported_c0_states", &self.supported_c0_states()) + .field("supported_c1_states", &self.supported_c1_states()) + .field("supported_c2_states", &self.supported_c2_states()) + .field("supported_c3_states", &self.supported_c3_states()) + .field("supported_c4_states", &self.supported_c4_states()) + .field("supported_c5_states", &self.supported_c5_states()) + .field("supported_c6_states", &self.supported_c6_states()) + .field("supported_c7_states", &self.supported_c7_states()) + .finish() + } +} + +#[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct ThermalPowerInfo { eax: ThermalPowerFeaturesEax, ebx: u32, ecx: ThermalPowerFeaturesEcx, - edx: u32, + _edx: u32, } impl ThermalPowerInfo { @@ -2334,6 +2639,42 @@ ); } +impl Debug for ThermalPowerInfo { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_struct("ThermalPowerInfo") + .field("dts_irq_threshold", &self.dts_irq_threshold()) + .field("has_dts", &self.has_dts()) + .field("has_arat", &self.has_arat()) + .field("has_pln", &self.has_pln()) + .field("has_ecmd", &self.has_ecmd()) + .field("has_ptm", &self.has_ptm()) + .field("has_hwp", &self.has_hwp()) + .field("has_hwp_notification", &self.has_hwp_notification()) + .field("has_hwp_activity_window", &self.has_hwp_activity_window()) + .field( + "has_hwp_energy_performance_preference", + &self.has_hwp_energy_performance_preference(), + ) + .field( + "has_hwp_package_level_request", + &self.has_hwp_package_level_request(), + ) + .field("has_hdc", &self.has_hdc()) + .field("has_turbo_boost3", &self.has_turbo_boost3()) + .field("has_hwp_capabilities", &self.has_hwp_capabilities()) + .field("has_hwp_peci_override", &self.has_hwp_peci_override()) + .field("has_flexible_hwp", &self.has_flexible_hwp()) + .field("has_hwp_fast_access_mode", &self.has_hwp_fast_access_mode()) + .field( + "has_ignore_idle_processor_hwp_request", + &self.has_ignore_idle_processor_hwp_request(), + ) + .field("has_hw_coord_feedback", &self.has_hw_coord_feedback()) + .field("has_energy_bias_pref", &self.has_energy_bias_pref()) + .finish() + } +} + bitflags! { #[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] @@ -2396,13 +2737,13 @@ } } -#[derive(Debug, Default)] +#[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct ExtendedFeatures { - eax: u32, + _eax: u32, ebx: ExtendedFeaturesEbx, ecx: ExtendedFeaturesEcx, - edx: u32, + _edx: u32, } impl ExtendedFeatures { @@ -2650,6 +2991,16 @@ } } +impl Debug for ExtendedFeatures { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_struct("ExtendedFeatures") + .field("ebx", &self.ebx) + .field("ecx", &self.ecx) + .field("mawau_value", &self.mawau_value()) + .finish() + } +} + bitflags! { #[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] @@ -2753,7 +3104,7 @@ } } -#[derive(Debug, Default)] +#[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct DirectCacheAccessInfo { eax: u32, @@ -2766,12 +3117,20 @@ } } -#[derive(Debug, Default)] +impl Debug for DirectCacheAccessInfo { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_struct("DirectCacheAccessInfo") + .field("dca_cap_value", &self.get_dca_cap_value()) + .finish() + } +} + +#[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct PerformanceMonitoringInfo { eax: u32, ebx: PerformanceMonitoringFeaturesEbx, - ecx: u32, + _ecx: u32, edx: u32, } @@ -2863,6 +3222,22 @@ ); } +impl Debug for PerformanceMonitoringInfo { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_struct("PerformanceMonitoringInfo") + .field("version_id", &self.version_id()) + .field("number_of_counters", &self.number_of_counters()) + .field("counter_bit_width", &self.counter_bit_width()) + .field("ebx_length", &self.ebx_length()) + .field("fixed_function_counters", &self.fixed_function_counters()) + .field( + "fixed_function_counters_bit_width", + &self.fixed_function_counters_bit_width(), + ) + .finish() + } +} + bitflags! { #[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] @@ -2886,9 +3261,11 @@ /// Iterates over the system topology in order to retrieve more /// system information at each level of the topology. -#[derive(Debug, Default)] +#[derive(Default, Clone)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct ExtendedTopologyIter { + #[cfg_attr(feature = "serialize", serde(skip))] + read: CpuIdReader, level: u32, } @@ -2969,7 +3346,7 @@ type Item = ExtendedTopologyLevel; fn next(&mut self) -> Option { - let res = cpuid!(EAX_EXTENDED_TOPOLOGY_INFO, self.level); + let res = self.read.cpuid2(EAX_EXTENDED_TOPOLOGY_INFO, self.level); self.level += 1; let et = ExtendedTopologyLevel { @@ -2986,6 +3363,16 @@ } } +impl Debug for ExtendedTopologyIter { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + let mut debug = f.debug_list(); + self.clone().for_each(|ref item| { + debug.entry(item); + }); + debug.finish() + } +} + bitflags! { #[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] @@ -3034,17 +3421,19 @@ } } -#[derive(Debug, Default)] +#[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct ExtendedStateInfo { + #[cfg_attr(feature = "serialize", serde(skip))] + read: CpuIdReader, eax: ExtendedStateInfoXCR0Flags, ebx: u32, ecx: u32, - edx: u32, + _edx: u32, eax1: u32, ebx1: u32, ecx1: ExtendedStateInfoXSSFlags, - edx1: u32, + _edx1: u32, } impl ExtendedStateInfo { @@ -3167,6 +3556,7 @@ /// Iterator over extended state enumeration levels >= 2. pub fn iter(&self) -> ExtendedStateIter { ExtendedStateIter { + read: self.read, level: 1, supported_xcr0: self.eax.bits(), supported_xss: self.ecx1.bits(), @@ -3174,9 +3564,34 @@ } } -#[derive(Debug, Default)] +impl Debug for ExtendedStateInfo { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_struct("ExtendedStateInfo") + .field("eax", &self.eax) + .field("ecx1", &self.ecx1) + .field( + "xsave_area_size_enabled_features", + &self.xsave_area_size_enabled_features(), + ) + .field( + "xsave_area_size_supported_features", + &self.xsave_area_size_supported_features(), + ) + .field("has_xsaveopt", &self.has_xsaveopt()) + .field("has_xsavec", &self.has_xsavec()) + .field("has_xgetbv", &self.has_xgetbv()) + .field("has_xsaves_xrstors", &self.has_xsaves_xrstors()) + .field("xsave_size", &self.xsave_size()) + .field("extended_state_iter", &self.iter()) + .finish() + } +} + +#[derive(Default, Clone)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct ExtendedStateIter { + #[cfg_attr(feature = "serialize", serde(skip))] + read: CpuIdReader, level: u32, supported_xcr0: u32, supported_xss: u32, @@ -3204,7 +3619,7 @@ let bit = 1 << self.level; if (self.supported_xcr0 & bit > 0) || (self.supported_xss & bit > 0) { - let res = cpuid!(EAX_EXTENDED_STATE_INFO, self.level); + let res = self.read.cpuid2(EAX_EXTENDED_STATE_INFO, self.level); return Some(ExtendedState { subleaf: self.level, eax: res.eax, @@ -3217,7 +3632,17 @@ } } -#[derive(Debug, Default)] +impl Debug for ExtendedStateIter { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + let mut debug = f.debug_list(); + self.clone().for_each(|ref item| { + debug.entry(item); + }); + debug.finish() + } +} + +#[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct ExtendedState { pub subleaf: u32, @@ -3260,9 +3685,23 @@ } } -#[derive(Debug, Default)] +impl Debug for ExtendedState { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.debug_struct("ExtendedState") + .field("size", &self.size()) + .field("offset", &self.offset()) + .field("is_in_ia32_xss", &self.is_in_ia32_xss()) + .field("is_in_xcr0", &self.is_in_xcr0()) + .field("is_compacted_format", &self.is_compacted_format()) + .finish() + } +} + +#[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct RdtMonitoringInfo { + #[cfg_attr(feature = "serialize", serde(skip))] + read: CpuIdReader, ebx: u32, edx: u32, } @@ -3284,19 +3723,28 @@ /// L3 Cache Monitoring. pub fn l3_monitoring(&self) -> Option { if self.has_l3_monitoring() { - let res = cpuid!(EAX_RDT_MONITORING, 1); - return Some(L3MonitoringInfo { + let res = self.read.cpuid2(EAX_RDT_MONITORING, 1); + Some(L3MonitoringInfo { ebx: res.ebx, ecx: res.ecx, edx: res.edx, - }); + }) } else { - return None; + None } } } -#[derive(Debug, Default)] +impl Debug for RdtMonitoringInfo { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_struct("RdtMonitoringInfo") + .field("rmid_range", &self.rmid_range()) + .field("l3_monitoring", &self.l3_monitoring()) + .finish() + } +} + +#[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct L3MonitoringInfo { ebx: u32, @@ -3337,9 +3785,20 @@ ); } -#[derive(Debug, Default)] +impl Debug for L3MonitoringInfo { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_struct("L3MonitoringInfo") + .field("conversion_factor", &self.conversion_factor()) + .field("maximum_rmid_range", &self.maximum_rmid_range()) + .finish() + } +} + +#[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct RdtAllocationInfo { + #[cfg_attr(feature = "serialize", serde(skip))] + read: CpuIdReader, ebx: u32, } @@ -3352,55 +3811,68 @@ doc = "Supports Memory Bandwidth Allocation.", has_memory_bandwidth_allocation, ebx, - 1 + 3 ); /// L3 Cache Allocation Information. pub fn l3_cat(&self) -> Option { if self.has_l3_cat() { - let res = cpuid!(EAX_RDT_ALLOCATION, 1); - return Some(L3CatInfo { + let res = self.read.cpuid2(EAX_RDT_ALLOCATION, 1); + Some(L3CatInfo { eax: res.eax, ebx: res.ebx, ecx: res.ecx, edx: res.edx, - }); + }) } else { - return None; + None } } /// L2 Cache Allocation Information. pub fn l2_cat(&self) -> Option { if self.has_l2_cat() { - let res = cpuid!(EAX_RDT_ALLOCATION, 2); - return Some(L2CatInfo { + let res = self.read.cpuid2(EAX_RDT_ALLOCATION, 2); + Some(L2CatInfo { eax: res.eax, ebx: res.ebx, edx: res.edx, - }); + }) } else { - return None; + None } } /// Memory Bandwidth Allocation Information. pub fn memory_bandwidth_allocation(&self) -> Option { if self.has_l2_cat() { - let res = cpuid!(EAX_RDT_ALLOCATION, 3); - return Some(MemBwAllocationInfo { + let res = self.read.cpuid2(EAX_RDT_ALLOCATION, 3); + Some(MemBwAllocationInfo { eax: res.eax, ecx: res.ecx, edx: res.edx, - }); + }) } else { - return None; + None } } } +impl Debug for RdtAllocationInfo { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_struct("RdtAllocationInfo") + .field("l3_cat", &self.l3_cat()) + .field("l2_cat", &self.l2_cat()) + .field( + "memory_bandwidth_allocation", + &self.memory_bandwidth_allocation(), + ) + .finish() + } +} + /// L3 Cache Allocation Technology Enumeration Sub-leaf (EAX = 10H, ECX = ResID = 1). -#[derive(Debug, Default)] +#[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct L3CatInfo { eax: u32, @@ -3410,9 +3882,9 @@ } impl L3CatInfo { - /// Length of the capacity bit mask using minus-one notation. + /// Length of the capacity bit mask. pub fn capacity_mask_length(&self) -> u8 { - get_bits(self.eax, 0, 4) as u8 + (get_bits(self.eax, 0, 4) + 1) as u8 } /// Bit-granular map of isolation/contention of allocation units. @@ -3433,8 +3905,18 @@ ); } +impl Debug for L3CatInfo { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_struct("L3CatInfo") + .field("capacity_mask_length", &self.capacity_mask_length()) + .field("isolation_bitmap", &self.isolation_bitmap()) + .field("highest_cos", &self.highest_cos()) + .finish() + } +} + /// L2 Cache Allocation Technology Enumeration Sub-leaf (EAX = 10H, ECX = ResID = 2). -#[derive(Debug, Default)] +#[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct L2CatInfo { eax: u32, @@ -3443,9 +3925,9 @@ } impl L2CatInfo { - /// Length of the capacity bit mask using minus-one notation. + /// Length of the capacity bit mask. pub fn capacity_mask_length(&self) -> u8 { - get_bits(self.eax, 0, 4) as u8 + (get_bits(self.eax, 0, 4) + 1) as u8 } /// Bit-granular map of isolation/contention of allocation units. @@ -3459,8 +3941,18 @@ } } +impl Debug for L2CatInfo { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_struct("L2CatInfo") + .field("capacity_mask_length", &self.capacity_mask_length()) + .field("isolation_bitmap", &self.isolation_bitmap()) + .field("highest_cos", &self.highest_cos()) + .finish() + } +} + /// Memory Bandwidth Allocation Enumeration Sub-leaf (EAX = 10H, ECX = ResID = 3). -#[derive(Debug, Default)] +#[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct MemBwAllocationInfo { eax: u32, @@ -3469,9 +3961,9 @@ } impl MemBwAllocationInfo { - /// Reports the maximum MBA throttling value supported for the corresponding ResID using minus-one notation. + /// Reports the maximum MBA throttling value supported for the corresponding ResID. pub fn max_hba_throttling(&self) -> u16 { - get_bits(self.eax, 0, 11) as u16 + (get_bits(self.eax, 0, 11) + 1) as u16 } /// Highest COS number supported for this Leaf. @@ -3487,13 +3979,28 @@ ); } +impl Debug for MemBwAllocationInfo { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_struct("MemBwAllocationInfo") + .field("max_hba_throttling", &self.max_hba_throttling()) + .field("highest_cos", &self.highest_cos()) + .field( + "has_linear_response_delay", + &self.has_linear_response_delay(), + ) + .finish() + } +} + /// Intel SGX Capability Enumeration Leaf, sub-leaf 0 (EAX = 12H, ECX = 0 and ECX = 1) -#[derive(Debug, Default)] +#[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct SgxInfo { + #[cfg_attr(feature = "serialize", serde(skip))] + read: CpuIdReader, eax: u32, ebx: u32, - ecx: u32, + _ecx: u32, edx: u32, eax1: u32, ebx1: u32, @@ -3542,14 +4049,43 @@ } /// Iterator over SGX sub-leafs. pub fn iter(&self) -> SgxSectionIter { - SgxSectionIter { current: 2 } + SgxSectionIter { + read: self.read, + current: 2, + } + } +} + +impl Debug for SgxInfo { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_struct("SgxInfo") + .field("has_sgx1", &self.has_sgx1()) + .field("has_sgx2", &self.has_sgx2()) + .field("miscselect", &self.miscselect()) + .field( + "max_enclave_size_non_64bit", + &self.max_enclave_size_non_64bit(), + ) + .field("max_enclave_size_64bit", &self.max_enclave_size_64bit()) + .field( + "has_encls_leaves_etrackc_erdinfo_eldbc_elduc", + &self.has_encls_leaves_etrackc_erdinfo_eldbc_elduc(), + ) + .field( + "has_enclv_leaves_einvirtchild_edecvirtchild_esetcontext", + &self.has_enclv_leaves_einvirtchild_edecvirtchild_esetcontext(), + ) + .field("sgx_section_iter", &self.iter()) + .finish() } } /// Iterator over the SGX sub-leafs (ECX >= 2). -#[derive(Debug, Default)] +#[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct SgxSectionIter { + #[cfg_attr(feature = "serialize", serde(skip))] + read: CpuIdReader, current: u32, } @@ -3557,7 +4093,7 @@ type Item = SgxSectionInfo; fn next(&mut self) -> Option { - let res = cpuid!(EAX_SGX, self.current); + let res = self.read.cpuid2(EAX_SGX, self.current); self.current += 1; match get_bits(res.eax, 0, 3) { 0b0001 => Some(SgxSectionInfo::Epc(EpcSection { @@ -3571,6 +4107,14 @@ } } +impl Debug for SgxSectionIter { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_struct("SgxSectionIter") + // TODO find way to include all elements here nicely + .finish() + } +} + /// Intel SGX EPC Enumeration Leaf, sub-leaves (EAX = 12H, ECX = 2 or higher) #[derive(Debug)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] @@ -3611,13 +4155,13 @@ } } -#[derive(Debug, Default)] +#[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct ProcessorTraceInfo { - eax: u32, + _eax: u32, ebx: u32, ecx: u32, - edx: u32, + _edx: u32, leaf1: Option, } @@ -3725,6 +4269,29 @@ } } +impl Debug for ProcessorTraceInfo { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_struct("ProcessorTraceInfo") + .field( + "configurable_address_ranges", + &self.configurable_address_ranges(), + ) + .field( + "supported_mtc_period_encodings", + &self.supported_mtc_period_encodings(), + ) + .field( + "supported_cycle_threshold_value_encodings", + &self.supported_cycle_threshold_value_encodings(), + ) + .field( + "supported_psb_frequency_encodings", + &self.supported_psb_frequency_encodings(), + ) + .finish() + } +} + /// Time Stamp Counter and Nominal Core Crystal Clock Information Leaf. #[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] @@ -3737,9 +4304,10 @@ impl fmt::Debug for TscInfo { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("TscInfo") - .field("denominator/eax", &self.denominator()) - .field("numerator/ebx", &self.numerator()) - .field("nominal_frequency/ecx", &self.nominal_frequency()) + .field("denominator", &self.denominator()) + .field("numerator", &self.numerator()) + .field("nominal_frequency", &self.nominal_frequency()) + .field("tsc_frequency", &self.tsc_frequency()) .finish() } } @@ -3777,7 +4345,7 @@ } /// Processor Frequency Information -#[derive(Debug, Default)] +#[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct ProcessorFrequencyInfo { eax: u32, @@ -3802,10 +4370,22 @@ } } +impl fmt::Debug for ProcessorFrequencyInfo { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("ProcessorFrequencyInfo") + .field("processor_base_frequency", &self.processor_base_frequency()) + .field("processor_max_frequency", &self.processor_max_frequency()) + .field("bus_frequency", &self.bus_frequency()) + .finish() + } +} + /// Deterministic Address Translation Structure Iterator -#[derive(Debug, Default)] +#[derive(Default, Clone)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct DatIter { + #[cfg_attr(feature = "serialize", serde(skip))] + read: CpuIdReader, current: u32, count: u32, } @@ -3821,7 +4401,9 @@ return None; } - let res = cpuid!(EAX_DETERMINISTIC_ADDRESS_TRANSLATION_INFO, self.current); + let res = self + .read + .cpuid2(EAX_DETERMINISTIC_ADDRESS_TRANSLATION_INFO, self.current); self.current += 1; // A sub-leaf index is also invalid if EDX[4:0] returns 0. @@ -3833,7 +4415,7 @@ } return Some(DatInfo { - eax: res.eax, + _eax: res.eax, ebx: res.ebx, ecx: res.ecx, edx: res.edx, @@ -3842,11 +4424,21 @@ } } +impl Debug for DatIter { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + let mut debug = f.debug_list(); + self.clone().for_each(|ref item| { + debug.entry(item); + }); + debug.finish() + } +} + /// Deterministic Address Translation Structure -#[derive(Debug, Default)] +#[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct DatInfo { - eax: u32, + _eax: u32, ebx: u32, ecx: u32, edx: u32, @@ -3926,6 +4518,18 @@ } } +impl Debug for DatInfo { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.debug_struct("DatInfo") + .field("has_4k_entries", &self.has_4k_entries()) + .field("has_2mb_entries", &self.has_2mb_entries()) + .field("has_4mb_entries", &self.has_4mb_entries()) + .field("has_1gb_entries", &self.has_1gb_entries()) + .field("is_fully_associative", &self.is_fully_associative()) + .finish() + } +} + /// Deterministic Address Translation cache type (EDX bits 04 -- 00) #[derive(Debug)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] @@ -3949,9 +4553,11 @@ } } -#[derive(Debug, Default)] +#[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct SoCVendorInfo { + #[cfg_attr(feature = "serialize", serde(skip))] + read: CpuIdReader, /// MaxSOCID_Index eax: u32, ebx: u32, @@ -3972,17 +4578,22 @@ self.edx } - pub fn get_vendor_brand(&self) -> SoCVendorBrand { - assert!(self.eax >= 3); // Leaf 17H is valid if MaxSOCID_Index >= 3. - let r1 = cpuid!(EAX_SOC_VENDOR_INFO, 1); - let r2 = cpuid!(EAX_SOC_VENDOR_INFO, 2); - let r3 = cpuid!(EAX_SOC_VENDOR_INFO, 3); - SoCVendorBrand { data: [r1, r2, r3] } + pub fn get_vendor_brand(&self) -> Option { + // Leaf 17H is valid if MaxSOCID_Index >= 3. + if self.eax >= 3 { + let r1 = cpuid!(EAX_SOC_VENDOR_INFO, 1); + let r2 = cpuid!(EAX_SOC_VENDOR_INFO, 2); + let r3 = cpuid!(EAX_SOC_VENDOR_INFO, 3); + Some(SoCVendorBrand { data: [r1, r2, r3] }) + } else { + None + } } pub fn get_vendor_attributes(&self) -> Option { if self.eax > 3 { Some(SoCVendorAttributesIter { + read: self.read, count: self.eax, current: 3, }) @@ -3992,9 +4603,23 @@ } } +impl fmt::Debug for SoCVendorInfo { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("SoCVendorInfo") + .field("soc_vendor_id", &self.get_soc_vendor_id()) + .field("project_id", &self.get_project_id()) + .field("stepping_id", &self.get_stepping_id()) + .field("vendor_brand", &self.get_vendor_brand()) + .field("vendor_attributes", &self.get_vendor_attributes()) + .finish() + } +} + #[derive(Debug, Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct SoCVendorAttributesIter { + #[cfg_attr(feature = "serialize", serde(skip))] + read: CpuIdReader, count: u32, current: u32, } @@ -4008,7 +4633,7 @@ return None; } self.count += 1; - Some(cpuid!(EAX_SOC_VENDOR_INFO, self.count)) + Some(self.read.cpuid2(EAX_SOC_VENDOR_INFO, self.count)) } } @@ -4020,16 +4645,13 @@ } impl SoCVendorBrand { - pub fn as_string<'a>(&'a self) -> &'a str { + pub fn as_string(&self) -> &str { let brand_string_start = self as *const SoCVendorBrand as *const u8; - unsafe { + let slice = unsafe { // Safety: SoCVendorBrand is laid out with repr(C). - let slice: &'a [u8] = slice::from_raw_parts(brand_string_start, size_of::()); - // Safety: The field is specified to be ASCII, and the only safe - // way to construct SoCVendorBrand is from real CPUID data or the - // Default implementation. - str::from_utf8_unchecked(slice) - } + slice::from_raw_parts(brand_string_start, size_of::()) + }; + str::from_utf8(slice).unwrap_or("InvalidSoCVendorString") } } @@ -4039,15 +4661,23 @@ } } -/// Information about Hypervisor (https://lwn.net/Articles/301888/) +/// Information about Hypervisor +/// +/// More information about this semi-official leaf can be found here +/// +#[derive(Default)] +#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct HypervisorInfo { + #[cfg_attr(feature = "serialize", serde(skip))] + read: CpuIdReader, res: CpuIdResult, } impl fmt::Debug for HypervisorInfo { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("HypervisorInfo") - .field("type", &self.identify()) + .field("res", &self.res) + .field("identify", &self.identify()) .field("tsc_frequency", &self.tsc_frequency()) .field("apic_frequency", &self.apic_frequency()) .finish() @@ -4084,7 +4714,7 @@ // vm aware tsc frequency retrieval: // # EAX: (Virtual) TSC frequency in kHz. if self.res.eax >= 0x40000010 { - let virt_tinfo = cpuid!(0x40000010, 0); + let virt_tinfo = self.read.cpuid2(0x40000010, 0); Some(virt_tinfo.eax) } else { None @@ -4095,7 +4725,7 @@ pub fn apic_frequency(&self) -> Option { // # EBX: (Virtual) Bus (local apic timer) frequency in kHz. if self.res.eax >= 0x40000010 { - let virt_tinfo = cpuid!(0x40000010, 0); + let virt_tinfo = self.read.cpuid2(0x40000010, 0); Some(virt_tinfo.ebx) } else { None @@ -4103,7 +4733,7 @@ } } -#[derive(Debug, Default)] +#[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] pub struct ExtendedFunctionInfo { max_eax_value: u32, @@ -4138,21 +4768,20 @@ val <= self.max_eax_value } - /// Retrieve processor brand string. + /// Retrieve processor brand string. For example + /// "11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz". pub fn processor_brand_string<'a>(&'a self) -> Option<&'a str> { if self.leaf_is_supported(EAX_EXTENDED_BRAND_STRING) { let brand_string_start = &self.data[2] as *const CpuIdResult as *const u8; // Safety: CpuIdResult is laid out with repr(C), and the array // self.data contains 9 continguous elements. - let slice: &'a [u8] = unsafe { slice::from_raw_parts(brand_string_start, 3 * size_of::()) }; + let slice: &'a [u8] = + unsafe { slice::from_raw_parts(brand_string_start, 3 * size_of::()) }; // Brand terminated at nul byte or end, whichever comes first. let slice = slice.split(|&x| x == 0).next().unwrap(); - // Safety: Field is specified to be ASCII, and the only safe way - // to construct ExtendedFunctionInfo is from real CPUID data - // or the Default implementation. - Some(unsafe { str::from_utf8_unchecked(slice) }) + str::from_utf8(slice).ok() } else { None } @@ -4299,6 +4928,29 @@ } } +impl Debug for ExtendedFunctionInfo { + fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { + f.debug_struct("ExtendedFunctionInfo") + .field("processor_brand_string", &self.processor_brand_string()) + .field("extended_signature", &self.extended_signature()) + .field("cache_line_size", &self.cache_line_size()) + .field("l2_associativity", &self.l2_associativity()) + .field("cache_size", &self.cache_size()) + .field("physical_address_bits", &self.physical_address_bits()) + .field("linear_address_bits", &self.linear_address_bits()) + .field("has_invariant_tsc", &self.has_invariant_tsc()) + .field("has_lahf_sahf", &self.has_lahf_sahf()) + .field("has_lzcnt", &self.has_lzcnt()) + .field("has_prefetchw", &self.has_prefetchw()) + .field("has_syscall_sysret", &self.has_syscall_sysret()) + .field("has_execute_disable", &self.has_execute_disable()) + .field("has_1gib_pages", &self.has_1gib_pages()) + .field("has_rdtscp", &self.has_rdtscp()) + .field("has_64bit_mode", &self.has_64bit_mode()) + .finish() + } +} + bitflags! { #[derive(Default)] #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))] @@ -4398,3 +5050,15 @@ const SEV_ES = 1 << 3; } } + +#[cfg(doctest)] +mod test_readme { + macro_rules! external_doc_test { + ($x:expr) => { + #[doc = $x] + extern "C" {} + }; + } + + external_doc_test!(include_str!("../README.md")); +} diff -Nru distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/src/tests/i5_3337u.rs distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/src/tests/i5_3337u.rs --- distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/src/tests/i5_3337u.rs 1970-01-01 00:00:00.000000000 +0000 +++ distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/src/tests/i5_3337u.rs 2022-05-11 16:26:11.000000000 +0000 @@ -0,0 +1,749 @@ +use crate::*; + +#[test] +fn genuine_intel() { + let vf = VendorInfo { + ebx: 1970169159, + edx: 1231384169, + ecx: 1818588270, + }; + assert!(vf.as_string() == "GenuineIntel"); +} + +#[test] +fn feature_info() { + let finfo = FeatureInfo { + eax: 198313, + ebx: 34605056, + edx_ecx: FeatureInfoFlags { + bits: 2109399999 | 3219913727 << 32, + }, + }; + + assert!(finfo.model_id() == 10); + assert!(finfo.extended_model_id() == 3); + assert!(finfo.stepping_id() == 9); + assert!(finfo.extended_family_id() == 0); + assert!(finfo.family_id() == 6); + assert!(finfo.stepping_id() == 9); + assert!(finfo.brand_index() == 0); + + assert!(finfo.edx_ecx.contains(FeatureInfoFlags::SSE2)); + assert!(finfo.edx_ecx.contains(FeatureInfoFlags::SSE41)); +} + +#[test] +fn cache_info() { + let cinfos = CacheInfoIter { + current: 1, + eax: 1979931137, + ebx: 15774463, + ecx: 0, + edx: 13238272, + }; + for (idx, cache) in cinfos.enumerate() { + match idx { + 0 => assert!(cache.num == 0xff), + 1 => assert!(cache.num == 0x5a), + 2 => assert!(cache.num == 0xb2), + 3 => assert!(cache.num == 0x03), + 4 => assert!(cache.num == 0xf0), + 5 => assert!(cache.num == 0xca), + 6 => assert!(cache.num == 0x76), + _ => unreachable!(), + } + } +} + +#[test] +fn cache_parameters() { + let caches: [CacheParameter; 4] = [ + CacheParameter { + eax: 469778721, + ebx: 29360191, + ecx: 63, + edx: 0, + }, + CacheParameter { + eax: 469778722, + ebx: 29360191, + ecx: 63, + edx: 0, + }, + CacheParameter { + eax: 469778755, + ebx: 29360191, + ecx: 511, + edx: 0, + }, + CacheParameter { + eax: 470008163, + ebx: 46137407, + ecx: 4095, + edx: 6, + }, + ]; + + for (idx, cache) in caches.iter().enumerate() { + match idx { + 0 => { + assert!(cache.cache_type() == CacheType::Data); + assert!(cache.level() == 1); + assert!(cache.is_self_initializing()); + assert!(!cache.is_fully_associative()); + assert!(cache.max_cores_for_cache() == 2); + assert!(cache.max_cores_for_package() == 8); + assert!(cache.coherency_line_size() == 64); + assert!(cache.physical_line_partitions() == 1); + assert!(cache.associativity() == 8); + assert!(!cache.is_write_back_invalidate()); + assert!(!cache.is_inclusive()); + assert!(!cache.has_complex_indexing()); + assert!(cache.sets() == 64); + } + 1 => { + assert!(cache.cache_type() == CacheType::Instruction); + assert!(cache.level() == 1); + assert!(cache.is_self_initializing()); + assert!(!cache.is_fully_associative()); + assert!(cache.max_cores_for_cache() == 2); + assert!(cache.max_cores_for_package() == 8); + assert!(cache.coherency_line_size() == 64); + assert!(cache.physical_line_partitions() == 1); + assert!(cache.associativity() == 8); + assert!(!cache.is_write_back_invalidate()); + assert!(!cache.is_inclusive()); + assert!(!cache.has_complex_indexing()); + assert!(cache.sets() == 64); + } + 2 => { + assert!(cache.cache_type() == CacheType::Unified); + assert!(cache.level() == 2); + assert!(cache.is_self_initializing()); + assert!(!cache.is_fully_associative()); + assert!(cache.max_cores_for_cache() == 2); + assert!(cache.max_cores_for_package() == 8); + assert!(cache.coherency_line_size() == 64); + assert!(cache.physical_line_partitions() == 1); + assert!(cache.associativity() == 8); + assert!(!cache.is_write_back_invalidate()); + assert!(!cache.is_inclusive()); + assert!(!cache.has_complex_indexing()); + assert!(cache.sets() == 512); + } + 3 => { + assert!(cache.cache_type() == CacheType::Unified); + assert!(cache.level() == 3); + assert!(cache.is_self_initializing()); + assert!(!cache.is_fully_associative()); + assert!(cache.max_cores_for_cache() == 16); + assert!(cache.max_cores_for_package() == 8); + assert!(cache.coherency_line_size() == 64); + assert!(cache.physical_line_partitions() == 1); + assert!(cache.associativity() == 12); + assert!(!cache.is_write_back_invalidate()); + assert!(cache.is_inclusive()); + assert!(cache.has_complex_indexing()); + assert!(cache.sets() == 4096); + } + _ => unreachable!(), + } + } +} + +#[test] +fn monitor_mwait_features() { + let mmfeatures = MonitorMwaitInfo { + eax: 64, + ebx: 64, + ecx: 3, + edx: 135456, + }; + assert!(mmfeatures.smallest_monitor_line() == 64); + assert!(mmfeatures.largest_monitor_line() == 64); + assert!(mmfeatures.extensions_supported()); + assert!(mmfeatures.interrupts_as_break_event()); + assert!(mmfeatures.supported_c0_states() == 0); + assert!(mmfeatures.supported_c1_states() == 2); + assert!(mmfeatures.supported_c2_states() == 1); + assert!(mmfeatures.supported_c3_states() == 1); + assert!(mmfeatures.supported_c4_states() == 2); + assert!(mmfeatures.supported_c5_states() == 0); + assert!(mmfeatures.supported_c6_states() == 0); + assert!(mmfeatures.supported_c7_states() == 0); +} + +#[test] +fn thermal_power_features() { + let tpfeatures = ThermalPowerInfo { + eax: ThermalPowerFeaturesEax { bits: 119 }, + ebx: 2, + ecx: ThermalPowerFeaturesEcx { bits: 9 }, + _edx: 0, + }; + + assert!(tpfeatures.eax.contains(ThermalPowerFeaturesEax::DTS)); + assert!(tpfeatures + .eax + .contains(ThermalPowerFeaturesEax::TURBO_BOOST)); + assert!(tpfeatures.eax.contains(ThermalPowerFeaturesEax::ARAT)); + assert!(tpfeatures.eax.contains(ThermalPowerFeaturesEax::PLN)); + assert!(tpfeatures.eax.contains(ThermalPowerFeaturesEax::ECMD)); + assert!(tpfeatures.eax.contains(ThermalPowerFeaturesEax::PTM)); + + assert!(tpfeatures + .ecx + .contains(ThermalPowerFeaturesEcx::HW_COORD_FEEDBACK)); + assert!(tpfeatures + .ecx + .contains(ThermalPowerFeaturesEcx::ENERGY_BIAS_PREF)); + + assert!(tpfeatures.dts_irq_threshold() == 0x2); + let tpfeatures = ThermalPowerInfo { + eax: ThermalPowerFeaturesEax::DTS + | ThermalPowerFeaturesEax::TURBO_BOOST + | ThermalPowerFeaturesEax::ARAT + | ThermalPowerFeaturesEax::PLN + | ThermalPowerFeaturesEax::ECMD + | ThermalPowerFeaturesEax::PTM + | ThermalPowerFeaturesEax::HWP + | ThermalPowerFeaturesEax::HWP_NOTIFICATION + | ThermalPowerFeaturesEax::HWP_ACTIVITY_WINDOW + | ThermalPowerFeaturesEax::HWP_ENERGY_PERFORMANCE_PREFERENCE + | ThermalPowerFeaturesEax::HDC, + ebx: 2, + ecx: ThermalPowerFeaturesEcx::HW_COORD_FEEDBACK | ThermalPowerFeaturesEcx::ENERGY_BIAS_PREF, + _edx: 0, + }; + + assert!(tpfeatures.has_dts()); + assert!(!tpfeatures.has_turbo_boost3()); + assert!(tpfeatures.has_turbo_boost()); + assert!(tpfeatures.has_arat()); + assert!(tpfeatures.has_pln()); + assert!(tpfeatures.has_ecmd()); + assert!(tpfeatures.has_ptm()); + assert!(tpfeatures.has_hwp()); + assert!(tpfeatures.has_hwp_notification()); + assert!(tpfeatures.has_hwp_activity_window()); + assert!(tpfeatures.has_hwp_energy_performance_preference()); + assert!(!tpfeatures.has_hwp_package_level_request()); + assert!(tpfeatures.has_hdc()); + assert!(tpfeatures.has_hw_coord_feedback()); + assert!(tpfeatures.has_energy_bias_pref()); + assert!(tpfeatures.dts_irq_threshold() == 0x2); +} + +#[test] +fn extended_features() { + let tpfeatures = ExtendedFeatures { + _eax: 0, + ebx: ExtendedFeaturesEbx { bits: 641 }, + ecx: ExtendedFeaturesEcx { bits: 0 }, + _edx: 0, + }; + assert!(tpfeatures._eax == 0); + assert!(tpfeatures.has_fsgsbase()); + assert!(!tpfeatures.has_tsc_adjust_msr()); + assert!(!tpfeatures.has_bmi1()); + assert!(!tpfeatures.has_hle()); + assert!(!tpfeatures.has_avx2()); + assert!(tpfeatures.has_smep()); + assert!(!tpfeatures.has_bmi2()); + assert!(tpfeatures.has_rep_movsb_stosb()); + assert!(!tpfeatures.has_invpcid()); + assert!(!tpfeatures.has_rtm()); + assert!(!tpfeatures.has_rdtm()); + assert!(!tpfeatures.has_fpu_cs_ds_deprecated()); + + let tpfeatures2 = ExtendedFeatures { + _eax: 0, + ebx: ExtendedFeaturesEbx::FSGSBASE + | ExtendedFeaturesEbx::ADJUST_MSR + | ExtendedFeaturesEbx::BMI1 + | ExtendedFeaturesEbx::AVX2 + | ExtendedFeaturesEbx::SMEP + | ExtendedFeaturesEbx::BMI2 + | ExtendedFeaturesEbx::REP_MOVSB_STOSB + | ExtendedFeaturesEbx::INVPCID + | ExtendedFeaturesEbx::DEPRECATE_FPU_CS_DS + | ExtendedFeaturesEbx::MPX + | ExtendedFeaturesEbx::RDSEED + | ExtendedFeaturesEbx::ADX + | ExtendedFeaturesEbx::SMAP + | ExtendedFeaturesEbx::CLFLUSHOPT + | ExtendedFeaturesEbx::PROCESSOR_TRACE, + ecx: ExtendedFeaturesEcx { bits: 0 }, + _edx: 201326592, + }; + + assert!(tpfeatures2.has_fsgsbase()); + assert!(tpfeatures2.has_tsc_adjust_msr()); + assert!(tpfeatures2.has_bmi1()); + assert!(tpfeatures2.has_avx2()); + assert!(tpfeatures2.has_smep()); + assert!(tpfeatures2.has_bmi2()); + assert!(tpfeatures2.has_rep_movsb_stosb()); + assert!(tpfeatures2.has_invpcid()); + assert!(tpfeatures2.has_fpu_cs_ds_deprecated()); + assert!(tpfeatures2.has_mpx()); + assert!(tpfeatures2.has_rdseed()); + assert!(tpfeatures2.has_adx()); + assert!(tpfeatures2.has_smap()); + assert!(tpfeatures2.has_clflushopt()); + assert!(tpfeatures2.has_processor_trace()); +} + +#[test] +fn direct_cache_access_info() { + let dca = DirectCacheAccessInfo { eax: 0x1 }; + assert!(dca.get_dca_cap_value() == 0x1); +} + +#[test] +fn performance_monitoring_info() { + let pm = PerformanceMonitoringInfo { + eax: 120587267, + ebx: PerformanceMonitoringFeaturesEbx { bits: 0 }, + _ecx: 0, + edx: 1539, + }; + + assert!(pm.version_id() == 3); + assert!(pm.number_of_counters() == 4); + assert!(pm.counter_bit_width() == 48); + assert!(pm.ebx_length() == 7); + assert!(pm.fixed_function_counters() == 3); + assert!(pm.fixed_function_counters_bit_width() == 48); + + assert!(!pm + .ebx + .contains(PerformanceMonitoringFeaturesEbx::CORE_CYC_EV_UNAVAILABLE)); + assert!(!pm + .ebx + .contains(PerformanceMonitoringFeaturesEbx::INST_RET_EV_UNAVAILABLE)); + assert!(!pm + .ebx + .contains(PerformanceMonitoringFeaturesEbx::REF_CYC_EV_UNAVAILABLE)); + assert!(!pm + .ebx + .contains(PerformanceMonitoringFeaturesEbx::CACHE_REF_EV_UNAVAILABLE)); + assert!(!pm + .ebx + .contains(PerformanceMonitoringFeaturesEbx::LL_CACHE_MISS_EV_UNAVAILABLE)); + assert!(!pm + .ebx + .contains(PerformanceMonitoringFeaturesEbx::BRANCH_INST_RET_EV_UNAVAILABLE)); + assert!(!pm + .ebx + .contains(PerformanceMonitoringFeaturesEbx::BRANCH_MISPRED_EV_UNAVAILABLE)); +} + +#[cfg(test)] +#[test] +fn extended_topology_info() { + let l1 = ExtendedTopologyLevel { + eax: 1, + ebx: 2, + ecx: 256, + edx: 3, + }; + let l2 = ExtendedTopologyLevel { + eax: 4, + ebx: 4, + ecx: 513, + edx: 3, + }; + + assert!(l1.processors() == 2); + assert!(l1.level_number() == 0); + assert!(l1.level_type() == TopologyType::SMT); + assert!(l1.x2apic_id() == 3); + assert!(l1.shift_right_for_next_apic_id() == 1); + + assert!(l2.processors() == 4); + assert!(l2.level_number() == 1); + assert!(l2.level_type() == TopologyType::Core); + assert!(l2.x2apic_id() == 3); + assert!(l2.shift_right_for_next_apic_id() == 4); +} + +#[test] +fn extended_state_info() { + let es = ExtendedStateInfo { + read: Default::default(), + eax: ExtendedStateInfoXCR0Flags { bits: 7 }, + ebx: 832, + ecx: 832, + _edx: 0, + eax1: 1, + ebx1: 0, + ecx1: ExtendedStateInfoXSSFlags { bits: 0 }, + _edx1: 0, + }; + + assert!(es.xsave_area_size_enabled_features() == 832); + assert!(es.xsave_area_size_supported_features() == 832); + assert!(es.has_xsaveopt()); +} + +#[test] +fn extended_state_info3() { + /*let cpuid = CpuId::new(); + cpuid.get_extended_state_info().map(|info| { + println!("{:?}", info); + use std::vec::Vec; + let es: Vec = info.iter().collect(); + println!("{:?}", es); + });*/ + + let esi = ExtendedStateInfo { + read: Default::default(), + eax: ExtendedStateInfoXCR0Flags::LEGACY_X87 + | ExtendedStateInfoXCR0Flags::SSE128 + | ExtendedStateInfoXCR0Flags::AVX256 + | ExtendedStateInfoXCR0Flags::MPX_BNDREGS + | ExtendedStateInfoXCR0Flags::MPX_BNDCSR + | ExtendedStateInfoXCR0Flags::AVX512_OPMASK + | ExtendedStateInfoXCR0Flags::AVX512_ZMM_HI256 + | ExtendedStateInfoXCR0Flags::AVX512_ZMM_HI16 + | ExtendedStateInfoXCR0Flags::PKRU, + ebx: 2688, + ecx: 2696, + _edx: 0, + eax1: 15, + ebx1: 2560, + ecx1: ExtendedStateInfoXSSFlags::PT, + _edx1: 0, + }; + + assert!(esi.xcr0_supports_legacy_x87()); + assert!(esi.xcr0_supports_sse_128()); + assert!(esi.xcr0_supports_avx_256()); + assert!(esi.xcr0_supports_mpx_bndregs()); + assert!(esi.xcr0_supports_mpx_bndcsr()); + assert!(esi.xcr0_supports_avx512_opmask()); + assert!(esi.xcr0_supports_avx512_zmm_hi256()); + assert!(esi.xcr0_supports_avx512_zmm_hi16()); + assert!(esi.xcr0_supports_pkru()); + assert!(esi.ia32_xss_supports_pt()); + assert!(!esi.ia32_xss_supports_hdc()); + + assert!(esi.xsave_area_size_enabled_features() == 2688); + assert!(esi.xsave_area_size_supported_features() == 2696); + + assert!(esi.has_xsaveopt()); + assert!(esi.has_xsavec()); + assert!(esi.has_xgetbv()); + assert!(esi.has_xsaves_xrstors()); + assert!(esi.xsave_size() == 2560); + + let es = [ + ExtendedState { + subleaf: 2, + eax: 256, + ebx: 576, + ecx: 0, + }, + ExtendedState { + subleaf: 3, + eax: 64, + ebx: 960, + ecx: 0, + }, + ExtendedState { + subleaf: 4, + eax: 64, + ebx: 1024, + ecx: 0, + }, + ExtendedState { + subleaf: 5, + eax: 64, + ebx: 1088, + ecx: 0, + }, + ExtendedState { + subleaf: 6, + eax: 512, + ebx: 1152, + ecx: 0, + }, + ExtendedState { + subleaf: 7, + eax: 1024, + ebx: 1664, + ecx: 0, + }, + ExtendedState { + subleaf: 8, + eax: 128, + ebx: 0, + ecx: 1, + }, + ExtendedState { + subleaf: 9, + eax: 8, + ebx: 2688, + ecx: 0, + }, + ]; + + let e = &es[0]; + assert!(e.subleaf == 2); + assert!(e.size() == 256); + assert!(e.offset() == 576); + assert!(e.is_in_xcr0()); + assert!(!e.is_in_ia32_xss()); + assert!(!e.is_compacted_format()); + + let e = &es[1]; + assert!(e.subleaf == 3); + assert!(e.size() == 64); + assert!(e.offset() == 960); + assert!(e.is_in_xcr0()); + assert!(!e.is_in_ia32_xss()); + assert!(!e.is_compacted_format()); + + let e = &es[2]; + assert!(e.subleaf == 4); + assert!(e.size() == 64); + assert!(e.offset() == 1024); + assert!(e.is_in_xcr0()); + assert!(!e.is_in_ia32_xss()); + assert!(!e.is_compacted_format()); + + let e = &es[3]; + assert!(e.subleaf == 5); + assert!(e.size() == 64); + assert!(e.offset() == 1088); + assert!(e.is_in_xcr0()); + assert!(!e.is_in_ia32_xss()); + assert!(!e.is_compacted_format()); + + let e = &es[4]; + assert!(e.subleaf == 6); + assert!(e.size() == 512); + assert!(e.offset() == 1152); + assert!(e.is_in_xcr0()); + assert!(!e.is_in_ia32_xss()); + assert!(!e.is_compacted_format()); + + let e = &es[5]; + assert!(e.subleaf == 7); + assert!(e.size() == 1024); + assert!(e.offset() == 1664); + assert!(e.is_in_xcr0()); + assert!(!e.is_in_ia32_xss()); + assert!(!e.is_compacted_format()); + + let e = &es[6]; + assert!(e.subleaf == 8); + assert!(e.size() == 128); + assert!(e.offset() == 0); + assert!(!e.is_in_xcr0()); + assert!(e.is_in_ia32_xss()); + assert!(!e.is_compacted_format()); + + let e = &es[7]; + assert!(e.subleaf == 9); + assert!(e.size() == 8); + assert!(e.offset() == 2688); + assert!(e.is_in_xcr0()); + assert!(!e.is_in_ia32_xss()); + assert!(!e.is_compacted_format()); +} + +#[test] +fn extended_state_info2() { + let es = ExtendedStateInfo { + read: Default::default(), + eax: ExtendedStateInfoXCR0Flags { bits: 31 }, + ebx: 1088, + ecx: 1088, + _edx: 0, + eax1: 15, + ebx1: 960, + ecx1: ExtendedStateInfoXSSFlags { bits: 256 }, + _edx1: 0, + }; + + assert!(es.xcr0_supports_legacy_x87()); + assert!(es.xcr0_supports_sse_128()); + assert!(es.xcr0_supports_avx_256()); + assert!(es.xcr0_supports_mpx_bndregs()); + assert!(es.xcr0_supports_mpx_bndcsr()); + assert!(!es.xcr0_supports_avx512_opmask()); + assert!(!es.xcr0_supports_pkru()); + assert!(es.ia32_xss_supports_pt()); + + assert!(es.xsave_area_size_enabled_features() == 0x440); + assert!(es.xsave_area_size_supported_features() == 0x440); + + assert!(es.has_xsaveopt()); + assert!(es.has_xsavec()); + assert!(es.has_xgetbv()); + assert!(es.has_xsaves_xrstors()); + assert!(es.xsave_size() == 0x3c0); + + let esiter: [ExtendedState; 3] = [ + ExtendedState { + subleaf: 2, + eax: 256, + ebx: 576, + ecx: 0, + }, + ExtendedState { + subleaf: 3, + eax: 64, + ebx: 960, + ecx: 0, + }, + ExtendedState { + subleaf: 4, + eax: 64, + ebx: 1024, + ecx: 0, + }, + ]; + + let e = &esiter[0]; + assert!(e.subleaf == 2); + assert!(e.size() == 256); + assert!(e.offset() == 576); + assert!(e.is_in_xcr0()); + assert!(!e.is_in_ia32_xss()); + + let e = &esiter[1]; + assert!(e.subleaf == 3); + assert!(e.size() == 64); + assert!(e.offset() == 960); + assert!(e.is_in_xcr0()); + assert!(!e.is_in_ia32_xss()); + + let e = &esiter[2]; + assert!(e.subleaf == 4); + assert!(e.size() == 64); + assert!(e.offset() == 1024); + assert!(e.is_in_xcr0()); + assert!(!e.is_in_ia32_xss()); +} + +#[test] +fn quality_of_service_info() { + let qos = RdtMonitoringInfo { + read: Default::default(), + ebx: 832, + edx: 0, + }; + + assert!(qos.rmid_range() == 832); + assert!(!qos.has_l3_monitoring()); +} + +#[test] +fn extended_functions() { + let ef = ExtendedFunctionInfo { + max_eax_value: 8, + data: [ + CpuIdResult { + eax: 2147483656, + ebx: 0, + ecx: 0, + edx: 0, + }, + CpuIdResult { + eax: 0, + ebx: 0, + ecx: 1, + edx: 672139264, + }, + CpuIdResult { + eax: 538976288, + ebx: 1226842144, + ecx: 1818588270, + edx: 539578920, + }, + CpuIdResult { + eax: 1701998403, + ebx: 692933672, + ecx: 758475040, + edx: 926102323, + }, + CpuIdResult { + eax: 1346576469, + ebx: 541073493, + ecx: 808988209, + edx: 8013895, + }, + CpuIdResult { + eax: 0, + ebx: 0, + ecx: 0, + edx: 0, + }, + CpuIdResult { + eax: 0, + ebx: 0, + ecx: 16801856, + edx: 0, + }, + CpuIdResult { + eax: 0, + ebx: 0, + ecx: 0, + edx: 256, + }, + CpuIdResult { + eax: 12324, + ebx: 0, + ecx: 0, + edx: 0, + }, + ], + }; + + assert_eq!( + ef.processor_brand_string().unwrap(), + " Intel(R) Core(TM) i5-3337U CPU @ 1.80GHz" + ); + assert!(ef.has_lahf_sahf()); + assert!(!ef.has_lzcnt()); + assert!(!ef.has_prefetchw()); + assert!(ef.has_syscall_sysret()); + assert!(ef.has_execute_disable()); + assert!(!ef.has_1gib_pages()); + assert!(ef.has_rdtscp()); + assert!(ef.has_64bit_mode()); + assert!(ef.has_invariant_tsc()); + + assert!(ef.extended_signature().unwrap() == 0x0); + assert!(ef.cache_line_size().unwrap() == 64); + assert!(ef.l2_associativity().unwrap() == L2Associativity::EightWay); + assert!(ef.cache_size().unwrap() == 256); + assert!(ef.physical_address_bits().unwrap() == 36); + assert!(ef.linear_address_bits().unwrap() == 48); +} + +#[cfg(test)] +#[test] +fn sgx_test() { + let sgx = SgxInfo { + read: Default::default(), + eax: 1, + ebx: 0, + _ecx: 0, + edx: 9247, + eax1: 54, + ebx1: 0, + ecx1: 31, + edx1: 0, + }; + + assert!(sgx.max_enclave_size_64bit() == 0x24); + assert!(sgx.max_enclave_size_non_64bit() == 0x1f); + assert!(sgx.has_sgx1()); + assert!(!sgx.has_sgx2()); + assert!(sgx.miscselect() == 0x0); + assert!(sgx.secs_attributes() == (0x0000000000000036, 0x000000000000001f)); +} diff -Nru distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/src/tests/mod.rs distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/src/tests/mod.rs --- distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/src/tests/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/src/tests/mod.rs 2022-05-11 16:26:11.000000000 +0000 @@ -0,0 +1,2 @@ +mod i5_3337u; +mod ryzen_matisse; diff -Nru distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/src/tests/ryzen_matisse.rs distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/src/tests/ryzen_matisse.rs --- distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/src/tests/ryzen_matisse.rs 1970-01-01 00:00:00.000000000 +0000 +++ distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/src/tests/ryzen_matisse.rs 2022-05-11 16:26:11.000000000 +0000 @@ -0,0 +1,386 @@ +use crate::{CpuId, CpuIdResult, TopologyType}; +use phf::phf_map; + +/// Raw dump of ryzen mantisse cpuid values. +/// +// Key format is (eax << 32 | ecx) e.g., two 32 bit values packed in one 64 bit value +static CPUID_VALUE_MAP: phf::Map = phf_map! { + 0x00000000_00000000u64 => CpuIdResult { eax: 0x00000010, ebx: 0x68747541, ecx: 0x444d4163, edx: 0x69746e65 }, + 0x00000001_00000000u64 => CpuIdResult { eax: 0x00870f10, ebx: 0x000c0800, ecx: 0x7ed8320b, edx: 0x178bfbff }, + 0x00000002_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, + 0x00000003_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, + 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 }, + 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 }, + 0x0000000b_00000000u64 => CpuIdResult { eax: 0x00000001, ebx: 0x00000002, ecx: 0x00000100, edx: 0x00000000 }, + 0x0000000b_00000001u64 => CpuIdResult { eax: 0x00000007, ebx: 0x0000000c, ecx: 0x00000201, edx: 0x00000000 }, + 0x0000000c_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, + 0x0000000d_00000000u64 => CpuIdResult { eax: 0x00000207, ebx: 0x00000340, ecx: 0x00000380, edx: 0x00000000 }, + 0x0000000d_00000001u64 => CpuIdResult { eax: 0x0000000f, ebx: 0x00000340, ecx: 0x00000000, edx: 0x00000000 }, + 0x0000000d_00000002u64 => CpuIdResult { eax: 0x00000100, ebx: 0x00000240, ecx: 0x00000000, edx: 0x00000000 }, + 0x0000000d_00000009u64 => CpuIdResult { eax: 0x00000040, ebx: 0x00000340, ecx: 0x00000000, edx: 0x00000000 }, + 0x0000000e_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, + 0x0000000f_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x000000ff, ecx: 0x00000000, edx: 0x00000002 }, + 0x0000000f_00000001u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000040, ecx: 0x000000ff, edx: 0x00000007 }, + 0x00000010_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000002, ecx: 0x00000000, edx: 0x00000000 }, + 0x00000010_00000001u64 => CpuIdResult { eax: 0x0000000f, ebx: 0x00000000, ecx: 0x00000004, edx: 0x0000000f }, + 0x20000000_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, + 0x80000000_00000000u64 => CpuIdResult { eax: 0x80000020, ebx: 0x68747541, ecx: 0x444d4163, edx: 0x69746e65 }, + 0x80000001_00000000u64 => CpuIdResult { eax: 0x00870f10, ebx: 0x20000000, ecx: 0x75c237ff, edx: 0x2fd3fbff }, + 0x80000002_00000000u64 => CpuIdResult { eax: 0x20444d41, ebx: 0x657a7952, ecx: 0x2035206e, edx: 0x30303633 }, + 0x80000003_00000000u64 => CpuIdResult { eax: 0x2d362058, ebx: 0x65726f43, ecx: 0x6f725020, edx: 0x73736563 }, + 0x80000004_00000000u64 => CpuIdResult { eax: 0x2020726f, ebx: 0x20202020, ecx: 0x20202020, edx: 0x00202020 }, + 0x80000005_00000000u64 => CpuIdResult { eax: 0xff40ff40, ebx: 0xff40ff40, ecx: 0x20080140, edx: 0x20080140 }, + 0x80000006_00000000u64 => CpuIdResult { eax: 0x48006400, ebx: 0x68006400, ecx: 0x02006140, edx: 0x01009140 }, + 0x80000007_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x0000001b, ecx: 0x00000000, edx: 0x00006799 }, + 0x80000008_00000000u64 => CpuIdResult { eax: 0x00003030, ebx: 0x010eb757, ecx: 0x0000700b, edx: 0x00010000 }, + 0x80000009_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, + 0x8000000a_00000000u64 => CpuIdResult { eax: 0x00000001, ebx: 0x00008000, ecx: 0x00000000, edx: 0x0013bcff }, + 0x8000000b_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, + 0x8000000c_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, + 0x8000000d_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, + 0x8000000e_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, + 0x8000000f_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, + 0x80000010_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, + 0x80000011_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, + 0x80000012_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, + 0x80000013_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, + 0x80000014_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, + 0x80000015_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, + 0x80000016_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, + 0x80000017_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, + 0x80000018_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, + 0x80000019_00000000u64 => CpuIdResult { eax: 0xf040f040, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, + 0x8000001a_00000000u64 => CpuIdResult { eax: 0x00000006, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, + 0x8000001b_00000000u64 => CpuIdResult { eax: 0x000003ff, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, + 0x8000001c_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, + 0x8000001d_00000000u64 => CpuIdResult { eax: 0x00004121, ebx: 0x01c0003f, ecx: 0x0000003f, edx: 0x00000000 }, + 0x8000001d_00000001u64 => CpuIdResult { eax: 0x00004122, ebx: 0x01c0003f, ecx: 0x0000003f, edx: 0x00000000 }, + 0x8000001d_00000002u64 => CpuIdResult { eax: 0x00004143, ebx: 0x01c0003f, ecx: 0x000003ff, edx: 0x00000002 }, + 0x8000001d_00000003u64 => CpuIdResult { eax: 0x00014163, ebx: 0x03c0003f, ecx: 0x00003fff, edx: 0x00000001 }, + 0x8000001e_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000100, ecx: 0x00000000, edx: 0x00000000 }, + 0x8000001f_00000000u64 => CpuIdResult { eax: 0x0001000f, ebx: 0x0000016f, ecx: 0x000001fd, edx: 0x00000001 }, + 0x80000020_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000002, ecx: 0x00000000, edx: 0x00000000 }, + 0x80000020_00000001u64 => CpuIdResult { eax: 0x0000000b, ebx: 0x00000000, ecx: 0x00000000, edx: 0x0000000f }, + 0x80860000_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, + 0xc0000000_00000000u64 => CpuIdResult { eax: 0x00000000, ebx: 0x00000000, ecx: 0x00000000, edx: 0x00000000 }, +}; + +fn cpuid_reader(eax: u32, ecx: u32) -> CpuIdResult { + let key = (eax as u64) << u32::BITS | ecx as u64; + CPUID_VALUE_MAP[&key] +} + +/// Check that vendor is AuthenticAMD. +#[test] +fn vendor_check() { + let cpuid = CpuId::with_cpuid_fn(cpuid_reader); + let v = cpuid.get_vendor_info().expect("Need to find vendor info"); + assert_eq!(v.as_string(), "AuthenticAMD"); +} + +/// Check feature info gives correct values for CPU +#[test] +fn version_info() { + let cpuid = CpuId::with_cpuid_fn(cpuid_reader); + let f = cpuid.get_feature_info().expect("Need to find feature info"); + + assert_eq!(f.family_id(), 0xf); + assert_eq!(f.model_id(), 0x1); + assert_eq!(f.stepping_id(), 0x0); + assert_eq!(f.extended_family_id(), 0x8); + assert_eq!(f.extended_model_id(), 0x7); + assert_eq!(f.brand_index(), 0x0); + assert_eq!(f.cflush_cache_line_size(), 0x8); + assert_eq!(f.max_logical_processor_ids(), 0xc); + + assert!(f.has_fpu()); + assert!(f.has_vme()); + assert!(f.has_de()); + assert!(f.has_pse()); + assert!(f.has_tsc()); + assert!(f.has_msr()); + assert!(f.has_pae()); + assert!(f.has_mce()); + assert!(f.has_cmpxchg8b()); + assert!(f.has_apic()); + assert!(f.has_sysenter_sysexit()); + assert!(f.has_mtrr()); + assert!(f.has_pge()); + assert!(f.has_mca()); + assert!(f.has_cmov()); + assert!(f.has_pat()); + assert!(f.has_pse36()); + assert!(!f.has_psn()); + assert!(f.has_clflush()); + assert!(!f.has_ds()); + assert!(!f.has_acpi()); + assert!(f.has_mmx()); + assert!(f.has_fxsave_fxstor()); + assert!(f.has_sse()); + assert!(f.has_sse2()); + assert!(!f.has_ss()); + assert!(f.has_htt()); + assert!(!f.has_tm()); + assert!(!f.has_pbe()); + + assert!(f.has_sse3()); + assert!(f.has_pclmulqdq()); + assert!(!f.has_ds_area()); + assert!(f.has_monitor_mwait()); + assert!(!f.has_cpl()); + assert!(!f.has_vmx()); + assert!(!f.has_smx()); + assert!(!f.has_eist()); + assert!(!f.has_tm2()); + assert!(f.has_ssse3()); + assert!(!f.has_cnxtid()); + // has_SDBG + assert!(f.has_fma()); + assert!(f.has_cmpxchg16b()); + // xTPR + assert!(!f.has_pdcm()); + assert!(!f.has_pcid()); + assert!(!f.has_dca()); + assert!(f.has_sse41()); + assert!(f.has_sse42()); + assert!(!f.has_x2apic()); + assert!(f.has_movbe()); + assert!(f.has_popcnt()); + assert!(!f.has_tsc_deadline()); + assert!(f.has_aesni()); + assert!(f.has_xsave()); + assert!(f.has_oxsave()); + assert!(f.has_avx()); + assert!(f.has_f16c()); + assert!(f.has_rdrand()); + assert!(!f.has_hypervisor()); +} + +#[test] +fn cache_info() { + let cpuid = CpuId::with_cpuid_fn(cpuid_reader); + assert!(cpuid.get_cache_info().is_none(), "Not supported by AMD"); +} + +#[test] +fn processor_serial() { + let cpuid = CpuId::with_cpuid_fn(cpuid_reader); + assert!( + cpuid.get_processor_serial().is_none(), + "Not supported by AMD" + ); +} + +#[test] +fn monitor_mwait() { + let cpuid = CpuId::with_cpuid_fn(cpuid_reader); + let mw = cpuid.get_monitor_mwait_info().expect("Leaf is supported"); + assert_eq!(mw.largest_monitor_line(), 64); + assert_eq!(mw.smallest_monitor_line(), 64); + assert!(mw.interrupts_as_break_event()); + assert!(mw.extensions_supported()); + // supported_cX_states functions are not supported according to the manual +} + +#[test] +fn thermal_power() { + let cpuid = CpuId::with_cpuid_fn(cpuid_reader); + let mw = cpuid.get_thermal_power_info().expect("Leaf is supported"); + + assert_eq!(mw.dts_irq_threshold(), 0x0); + assert!(!mw.has_dts()); + assert!(mw.has_arat()); + assert!(!mw.has_turbo_boost()); + assert!(!mw.has_pln()); + assert!(!mw.has_ecmd()); + assert!(!mw.has_ptm()); + assert!(!mw.has_hwp()); + assert!(!mw.has_hwp_notification()); + assert!(!mw.has_hwp_activity_window()); + assert!(!mw.has_hwp_energy_performance_preference()); + assert!(!mw.has_hwp_package_level_request()); + assert!(!mw.has_hdc()); + assert!(!mw.has_turbo_boost3()); + assert!(!mw.has_hwp_capabilities()); + assert!(!mw.has_hwp_peci_override()); + assert!(!mw.has_flexible_hwp()); + assert!(!mw.has_hwp_fast_access_mode()); + assert!(!mw.has_ignore_idle_processor_hwp_request()); + assert!(mw.has_hw_coord_feedback()); + assert!(!mw.has_energy_bias_pref()); +} + +#[test] +fn extended_features() { + let cpuid = CpuId::with_cpuid_fn(cpuid_reader); + let e = cpuid + .get_extended_feature_info() + .expect("Leaf is supported"); + + assert!(e.has_fsgsbase()); + assert!(!e.has_tsc_adjust_msr()); + assert!(e.has_bmi1()); + assert!(!e.has_hle()); + assert!(e.has_avx2()); + assert!(!e.has_fdp()); + assert!(e.has_smep()); + assert!(e.has_bmi2()); + assert!(!e.has_rep_movsb_stosb()); + assert!(!e.has_invpcid()); + assert!(!e.has_rtm()); + assert!(e.has_rdtm()); + assert!(!e.has_fpu_cs_ds_deprecated()); + assert!(!e.has_mpx()); + assert!(e.has_rdta()); + assert!(e.has_rdseed()); + assert!(e.has_adx()); + assert!(e.has_smap()); + assert!(e.has_clflushopt()); + assert!(!e.has_processor_trace()); + assert!(e.has_sha()); + assert!(!e.has_sgx()); + assert!(!e.has_avx512f()); + assert!(!e.has_avx512dq()); + assert!(!e.has_avx512_ifma()); + assert!(!e.has_avx512pf()); + assert!(!e.has_avx512er()); + assert!(!e.has_avx512cd()); + assert!(!e.has_avx512bw()); + assert!(!e.has_avx512vl()); + assert!(e.has_clwb()); + assert!(!e.has_prefetchwt1()); + assert!(e.has_umip()); + assert!(!e.has_pku()); + assert!(!e.has_ospke()); + assert!(e.has_rdpid()); + assert!(!e.has_sgx_lc()); + assert_eq!(e.mawau_value(), 0x0); +} + +#[test] +fn direct_cache_access() { + let cpuid = CpuId::with_cpuid_fn(cpuid_reader); + assert!( + cpuid.get_direct_cache_access_info().is_none(), + "Not supported by AMD" + ); +} + +#[test] +fn perfmon_info() { + let cpuid = CpuId::with_cpuid_fn(cpuid_reader); + assert!( + cpuid.get_performance_monitoring_info().is_none(), + "Not supported by AMD" + ); +} + +#[test] +fn extended_topology_info() { + let cpuid = CpuId::with_cpuid_fn(cpuid_reader); + let mut e = cpuid + .get_extended_topology_info() + .expect("Leaf is supported"); + + let t = e.next().expect("Have level 0"); + assert_eq!(t.processors(), 2); + assert_eq!(t.level_number(), 0); + assert_eq!(t.level_type(), TopologyType::SMT); + assert_eq!(t.x2apic_id(), 0x0); + assert_eq!(t.shift_right_for_next_apic_id(), 0x1); + + let t = e.next().expect("Have level 1"); + assert_eq!(t.processors(), 12); + assert_eq!(t.level_number(), 1); + assert_eq!(t.level_type(), TopologyType::Core); + assert_eq!(t.x2apic_id(), 0x0); + assert_eq!(t.shift_right_for_next_apic_id(), 0x7); +} + +#[test] +fn extended_state_info() { + let cpuid = CpuId::with_cpuid_fn(cpuid_reader); + let e = cpuid.get_extended_state_info().expect("Leaf is supported"); + + assert!(e.xcr0_supports_legacy_x87()); + assert!(e.xcr0_supports_sse_128()); + assert!(e.xcr0_supports_avx_256()); + assert!(!e.xcr0_supports_mpx_bndregs()); + assert!(!e.xcr0_supports_mpx_bndcsr()); + assert!(!e.xcr0_supports_avx512_opmask()); + assert!(!e.xcr0_supports_avx512_zmm_hi256()); + assert!(!e.xcr0_supports_avx512_zmm_hi16()); + assert!(e.xcr0_supports_pkru()); + assert!(!e.ia32_xss_supports_pt()); + assert!(!e.ia32_xss_supports_hdc()); + assert_eq!(e.xsave_area_size_enabled_features(), 0x00000340); + assert_eq!(e.xsave_area_size_supported_features(), 0x00000380); + assert!(e.has_xsaveopt()); + assert!(e.has_xsavec()); + assert!(e.has_xgetbv()); + assert!(e.has_xsaves_xrstors()); + assert_eq!(e.xsave_size(), 0x00000340); + + let mut e = e.iter(); + let ee = e.next().expect("Has level 2"); + assert_eq!(ee.size(), 256); + assert_eq!(ee.offset(), 576); + assert!(ee.is_in_xcr0()); + assert!(!ee.is_compacted_format()); + + let ee = e.next().expect("Has level 9"); + assert_eq!(ee.size(), 64); + assert_eq!(ee.offset(), 832); + assert!(ee.is_in_xcr0()); + assert!(!ee.is_compacted_format()); +} + +#[test] +fn rdt_monitoring_info() { + let cpuid = CpuId::with_cpuid_fn(cpuid_reader); + let e = cpuid.get_rdt_monitoring_info().expect("Leaf is supported"); + + assert!(e.has_l3_monitoring()); + assert_eq!(e.rmid_range(), 255); + + let l3m = e.l3_monitoring().expect("Leaf is available"); + assert_eq!(l3m.conversion_factor(), 64); + assert_eq!(l3m.maximum_rmid_range(), 255); + assert!(l3m.has_occupancy_monitoring()); + assert!(l3m.has_total_bandwidth_monitoring()); + assert!(l3m.has_local_bandwidth_monitoring()); +} + +#[test] +fn rdt_allocation_info() { + let cpuid = CpuId::with_cpuid_fn(cpuid_reader); + let e = cpuid.get_rdt_allocation_info().expect("Leaf is supported"); + + assert!(e.has_l3_cat()); + assert!(!e.has_l2_cat()); + assert!(!e.has_memory_bandwidth_allocation()); + assert!(e.l2_cat().is_none()); + assert!(e.memory_bandwidth_allocation().is_none()); + + let l3c = e.l3_cat().expect("Leaf is available"); + assert_eq!(l3c.capacity_mask_length(), 0x10); + assert_eq!(l3c.isolation_bitmap(), 0x0); + assert_eq!(l3c.highest_cos(), 15); + assert!(l3c.has_code_data_prioritization()); +} + +#[test] +fn remaining_unsupported_leafs() { + let cpuid = CpuId::with_cpuid_fn(cpuid_reader); + + assert!(cpuid.get_sgx_info().is_none()); + assert!(cpuid.get_processor_trace_info().is_none()); + assert!(cpuid.get_tsc_info().is_none()); + assert!(cpuid.get_processor_frequency_info().is_none()); + assert!(cpuid.deterministic_address_translation_info().is_none()); + assert!(cpuid.get_soc_vendor_info().is_none()); +} diff -Nru distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/src/tests.rs distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/src/tests.rs --- distinst-0.3.2~1650402197~21.10~52e2e8d~dev/=unpacked-tar1=/raw-cpuid/src/tests.rs 2022-04-19 21:33:04.000000000 +0000 +++ distinst-0.3.2~1652283129~21.10~4af925c~dev/=unpacked-tar1=/raw-cpuid/src/tests.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,828 +0,0 @@ -use crate::*; - -#[test] -fn genuine_intel() { - let vf = VendorInfo { - ebx: 1970169159, - edx: 1231384169, - ecx: 1818588270, - }; - assert!(vf.as_string() == "GenuineIntel"); -} - -#[test] -fn feature_info() { - let finfo = FeatureInfo { - eax: 198313, - ebx: 34605056, - edx_ecx: FeatureInfoFlags { - bits: 2109399999 | 3219913727 << 32, - }, - }; - - assert!(finfo.model_id() == 10); - assert!(finfo.extended_model_id() == 3); - assert!(finfo.stepping_id() == 9); - assert!(finfo.extended_family_id() == 0); - assert!(finfo.family_id() == 6); - assert!(finfo.stepping_id() == 9); - assert!(finfo.brand_index() == 0); - - assert!(finfo.edx_ecx.contains(FeatureInfoFlags::SSE2)); - assert!(finfo.edx_ecx.contains(FeatureInfoFlags::SSE41)); -} - -#[test] -fn cache_info() { - let cinfos = CacheInfoIter { - current: 1, - eax: 1979931137, - ebx: 15774463, - ecx: 0, - edx: 13238272, - }; - for (idx, cache) in cinfos.enumerate() { - match idx { - 0 => assert!(cache.num == 0xff), - 1 => assert!(cache.num == 0x5a), - 2 => assert!(cache.num == 0xb2), - 3 => assert!(cache.num == 0x03), - 4 => assert!(cache.num == 0xf0), - 5 => assert!(cache.num == 0xca), - 6 => assert!(cache.num == 0x76), - _ => unreachable!(), - } - } -} - -#[test] -fn cache_parameters() { - let caches: [CacheParameter; 4] = [ - CacheParameter { - eax: 469778721, - ebx: 29360191, - ecx: 63, - edx: 0, - }, - CacheParameter { - eax: 469778722, - ebx: 29360191, - ecx: 63, - edx: 0, - }, - CacheParameter { - eax: 469778755, - ebx: 29360191, - ecx: 511, - edx: 0, - }, - CacheParameter { - eax: 470008163, - ebx: 46137407, - ecx: 4095, - edx: 6, - }, - ]; - - for (idx, cache) in caches.iter().enumerate() { - match idx { - 0 => { - assert!(cache.cache_type() == CacheType::Data); - assert!(cache.level() == 1); - assert!(cache.is_self_initializing()); - assert!(!cache.is_fully_associative()); - assert!(cache.max_cores_for_cache() == 2); - assert!(cache.max_cores_for_package() == 8); - assert!(cache.coherency_line_size() == 64); - assert!(cache.physical_line_partitions() == 1); - assert!(cache.associativity() == 8); - assert!(!cache.is_write_back_invalidate()); - assert!(!cache.is_inclusive()); - assert!(!cache.has_complex_indexing()); - assert!(cache.sets() == 64); - } - 1 => { - assert!(cache.cache_type() == CacheType::Instruction); - assert!(cache.level() == 1); - assert!(cache.is_self_initializing()); - assert!(!cache.is_fully_associative()); - assert!(cache.max_cores_for_cache() == 2); - assert!(cache.max_cores_for_package() == 8); - assert!(cache.coherency_line_size() == 64); - assert!(cache.physical_line_partitions() == 1); - assert!(cache.associativity() == 8); - assert!(!cache.is_write_back_invalidate()); - assert!(!cache.is_inclusive()); - assert!(!cache.has_complex_indexing()); - assert!(cache.sets() == 64); - } - 2 => { - assert!(cache.cache_type() == CacheType::Unified); - assert!(cache.level() == 2); - assert!(cache.is_self_initializing()); - assert!(!cache.is_fully_associative()); - assert!(cache.max_cores_for_cache() == 2); - assert!(cache.max_cores_for_package() == 8); - assert!(cache.coherency_line_size() == 64); - assert!(cache.physical_line_partitions() == 1); - assert!(cache.associativity() == 8); - assert!(!cache.is_write_back_invalidate()); - assert!(!cache.is_inclusive()); - assert!(!cache.has_complex_indexing()); - assert!(cache.sets() == 512); - } - 3 => { - assert!(cache.cache_type() == CacheType::Unified); - assert!(cache.level() == 3); - assert!(cache.is_self_initializing()); - assert!(!cache.is_fully_associative()); - assert!(cache.max_cores_for_cache() == 16); - assert!(cache.max_cores_for_package() == 8); - assert!(cache.coherency_line_size() == 64); - assert!(cache.physical_line_partitions() == 1); - assert!(cache.associativity() == 12); - assert!(!cache.is_write_back_invalidate()); - assert!(cache.is_inclusive()); - assert!(cache.has_complex_indexing()); - assert!(cache.sets() == 4096); - } - _ => unreachable!(), - } - } -} - -#[test] -fn monitor_mwait_features() { - let mmfeatures = MonitorMwaitInfo { - eax: 64, - ebx: 64, - ecx: 3, - edx: 135456, - }; - assert!(mmfeatures.smallest_monitor_line() == 64); - assert!(mmfeatures.largest_monitor_line() == 64); - assert!(mmfeatures.extensions_supported()); - assert!(mmfeatures.interrupts_as_break_event()); - assert!(mmfeatures.supported_c0_states() == 0); - assert!(mmfeatures.supported_c1_states() == 2); - assert!(mmfeatures.supported_c2_states() == 1); - assert!(mmfeatures.supported_c3_states() == 1); - assert!(mmfeatures.supported_c4_states() == 2); - assert!(mmfeatures.supported_c5_states() == 0); - assert!(mmfeatures.supported_c6_states() == 0); - assert!(mmfeatures.supported_c7_states() == 0); -} - -#[test] -fn thermal_power_features() { - let tpfeatures = ThermalPowerInfo { - eax: ThermalPowerFeaturesEax { bits: 119 }, - ebx: 2, - ecx: ThermalPowerFeaturesEcx { bits: 9 }, - edx: 0, - }; - - assert!(tpfeatures.eax.contains(ThermalPowerFeaturesEax::DTS)); - assert!(tpfeatures - .eax - .contains(ThermalPowerFeaturesEax::TURBO_BOOST)); - assert!(tpfeatures.eax.contains(ThermalPowerFeaturesEax::ARAT)); - assert!(tpfeatures.eax.contains(ThermalPowerFeaturesEax::PLN)); - assert!(tpfeatures.eax.contains(ThermalPowerFeaturesEax::ECMD)); - assert!(tpfeatures.eax.contains(ThermalPowerFeaturesEax::PTM)); - - assert!(tpfeatures - .ecx - .contains(ThermalPowerFeaturesEcx::HW_COORD_FEEDBACK)); - assert!(tpfeatures - .ecx - .contains(ThermalPowerFeaturesEcx::ENERGY_BIAS_PREF)); - - assert!(tpfeatures.dts_irq_threshold() == 0x2); - let tpfeatures = ThermalPowerInfo { - eax: ThermalPowerFeaturesEax::DTS - | ThermalPowerFeaturesEax::TURBO_BOOST - | ThermalPowerFeaturesEax::ARAT - | ThermalPowerFeaturesEax::PLN - | ThermalPowerFeaturesEax::ECMD - | ThermalPowerFeaturesEax::PTM - | ThermalPowerFeaturesEax::HWP - | ThermalPowerFeaturesEax::HWP_NOTIFICATION - | ThermalPowerFeaturesEax::HWP_ACTIVITY_WINDOW - | ThermalPowerFeaturesEax::HWP_ENERGY_PERFORMANCE_PREFERENCE - | ThermalPowerFeaturesEax::HDC, - ebx: 2, - ecx: ThermalPowerFeaturesEcx::HW_COORD_FEEDBACK | ThermalPowerFeaturesEcx::ENERGY_BIAS_PREF, - edx: 0, - }; - - assert!(tpfeatures.has_dts()); - assert!(!tpfeatures.has_turbo_boost3()); - assert!(tpfeatures.has_turbo_boost()); - assert!(tpfeatures.has_arat()); - assert!(tpfeatures.has_pln()); - assert!(tpfeatures.has_ecmd()); - assert!(tpfeatures.has_ptm()); - assert!(tpfeatures.has_hwp()); - assert!(tpfeatures.has_hwp_notification()); - assert!(tpfeatures.has_hwp_activity_window()); - assert!(tpfeatures.has_hwp_energy_performance_preference()); - assert!(!tpfeatures.has_hwp_package_level_request()); - assert!(tpfeatures.has_hdc()); - assert!(tpfeatures.has_hw_coord_feedback()); - assert!(tpfeatures.has_energy_bias_pref()); - assert!(tpfeatures.dts_irq_threshold() == 0x2); -} - -#[test] -fn extended_features() { - let tpfeatures = ExtendedFeatures { - eax: 0, - ebx: ExtendedFeaturesEbx { bits: 641 }, - ecx: ExtendedFeaturesEcx { bits: 0 }, - edx: 0, - }; - assert!(tpfeatures.eax == 0); - assert!(tpfeatures.has_fsgsbase()); - assert!(!tpfeatures.has_tsc_adjust_msr()); - assert!(!tpfeatures.has_bmi1()); - assert!(!tpfeatures.has_hle()); - assert!(!tpfeatures.has_avx2()); - assert!(tpfeatures.has_smep()); - assert!(!tpfeatures.has_bmi2()); - assert!(tpfeatures.has_rep_movsb_stosb()); - assert!(!tpfeatures.has_invpcid()); - assert!(!tpfeatures.has_rtm()); - assert!(!tpfeatures.has_rdtm()); - assert!(!tpfeatures.has_fpu_cs_ds_deprecated()); - - let tpfeatures2 = ExtendedFeatures { - eax: 0, - ebx: ExtendedFeaturesEbx::FSGSBASE - | ExtendedFeaturesEbx::ADJUST_MSR - | ExtendedFeaturesEbx::BMI1 - | ExtendedFeaturesEbx::AVX2 - | ExtendedFeaturesEbx::SMEP - | ExtendedFeaturesEbx::BMI2 - | ExtendedFeaturesEbx::REP_MOVSB_STOSB - | ExtendedFeaturesEbx::INVPCID - | ExtendedFeaturesEbx::DEPRECATE_FPU_CS_DS - | ExtendedFeaturesEbx::MPX - | ExtendedFeaturesEbx::RDSEED - | ExtendedFeaturesEbx::ADX - | ExtendedFeaturesEbx::SMAP - | ExtendedFeaturesEbx::CLFLUSHOPT - | ExtendedFeaturesEbx::PROCESSOR_TRACE, - ecx: ExtendedFeaturesEcx { bits: 0 }, - edx: 201326592, - }; - - assert!(tpfeatures2.has_fsgsbase()); - assert!(tpfeatures2.has_tsc_adjust_msr()); - assert!(tpfeatures2.has_bmi1()); - assert!(tpfeatures2.has_avx2()); - assert!(tpfeatures2.has_smep()); - assert!(tpfeatures2.has_bmi2()); - assert!(tpfeatures2.has_rep_movsb_stosb()); - assert!(tpfeatures2.has_invpcid()); - assert!(tpfeatures2.has_fpu_cs_ds_deprecated()); - assert!(tpfeatures2.has_mpx()); - assert!(tpfeatures2.has_rdseed()); - assert!(tpfeatures2.has_adx()); - assert!(tpfeatures2.has_smap()); - assert!(tpfeatures2.has_clflushopt()); - assert!(tpfeatures2.has_processor_trace()); -} - -#[test] -fn direct_cache_access_info() { - let dca = DirectCacheAccessInfo { eax: 0x1 }; - assert!(dca.get_dca_cap_value() == 0x1); -} - -#[test] -fn performance_monitoring_info() { - let pm = PerformanceMonitoringInfo { - eax: 120587267, - ebx: PerformanceMonitoringFeaturesEbx { bits: 0 }, - ecx: 0, - edx: 1539, - }; - - assert!(pm.version_id() == 3); - assert!(pm.number_of_counters() == 4); - assert!(pm.counter_bit_width() == 48); - assert!(pm.ebx_length() == 7); - assert!(pm.fixed_function_counters() == 3); - assert!(pm.fixed_function_counters_bit_width() == 48); - - assert!(!pm - .ebx - .contains(PerformanceMonitoringFeaturesEbx::CORE_CYC_EV_UNAVAILABLE)); - assert!(!pm - .ebx - .contains(PerformanceMonitoringFeaturesEbx::INST_RET_EV_UNAVAILABLE)); - assert!(!pm - .ebx - .contains(PerformanceMonitoringFeaturesEbx::REF_CYC_EV_UNAVAILABLE)); - assert!(!pm - .ebx - .contains(PerformanceMonitoringFeaturesEbx::CACHE_REF_EV_UNAVAILABLE)); - assert!(!pm - .ebx - .contains(PerformanceMonitoringFeaturesEbx::LL_CACHE_MISS_EV_UNAVAILABLE)); - assert!(!pm - .ebx - .contains(PerformanceMonitoringFeaturesEbx::BRANCH_INST_RET_EV_UNAVAILABLE)); - assert!(!pm - .ebx - .contains(PerformanceMonitoringFeaturesEbx::BRANCH_MISPRED_EV_UNAVAILABLE)); -} - -#[cfg(test)] -#[test] -fn extended_topology_info() { - let l1 = ExtendedTopologyLevel { - eax: 1, - ebx: 2, - ecx: 256, - edx: 3, - }; - let l2 = ExtendedTopologyLevel { - eax: 4, - ebx: 4, - ecx: 513, - edx: 3, - }; - - assert!(l1.processors() == 2); - assert!(l1.level_number() == 0); - assert!(l1.level_type() == TopologyType::SMT); - assert!(l1.x2apic_id() == 3); - assert!(l1.shift_right_for_next_apic_id() == 1); - - assert!(l2.processors() == 4); - assert!(l2.level_number() == 1); - assert!(l2.level_type() == TopologyType::Core); - assert!(l2.x2apic_id() == 3); - assert!(l2.shift_right_for_next_apic_id() == 4); -} - -#[test] -fn extended_state_info() { - let es = ExtendedStateInfo { - eax: ExtendedStateInfoXCR0Flags { bits: 7 }, - ebx: 832, - ecx: 832, - edx: 0, - eax1: 1, - ebx1: 0, - ecx1: ExtendedStateInfoXSSFlags { bits: 0 }, - edx1: 0, - }; - - assert!(es.xsave_area_size_enabled_features() == 832); - assert!(es.xsave_area_size_supported_features() == 832); - assert!(es.has_xsaveopt()); -} - -#[test] -fn extended_state_info3() { - /*let cpuid = CpuId::new(); - cpuid.get_extended_state_info().map(|info| { - println!("{:?}", info); - use std::vec::Vec; - let es: Vec = info.iter().collect(); - println!("{:?}", es); - });*/ - - let esi = ExtendedStateInfo { - eax: ExtendedStateInfoXCR0Flags::LEGACY_X87 - | ExtendedStateInfoXCR0Flags::SSE128 - | ExtendedStateInfoXCR0Flags::AVX256 - | ExtendedStateInfoXCR0Flags::MPX_BNDREGS - | ExtendedStateInfoXCR0Flags::MPX_BNDCSR - | ExtendedStateInfoXCR0Flags::AVX512_OPMASK - | ExtendedStateInfoXCR0Flags::AVX512_ZMM_HI256 - | ExtendedStateInfoXCR0Flags::AVX512_ZMM_HI16 - | ExtendedStateInfoXCR0Flags::PKRU, - ebx: 2688, - ecx: 2696, - edx: 0, - eax1: 15, - ebx1: 2560, - ecx1: ExtendedStateInfoXSSFlags::PT, - edx1: 0, - }; - - assert!(esi.xcr0_supports_legacy_x87()); - assert!(esi.xcr0_supports_sse_128()); - assert!(esi.xcr0_supports_avx_256()); - assert!(esi.xcr0_supports_mpx_bndregs()); - assert!(esi.xcr0_supports_mpx_bndcsr()); - assert!(esi.xcr0_supports_avx512_opmask()); - assert!(esi.xcr0_supports_avx512_zmm_hi256()); - assert!(esi.xcr0_supports_avx512_zmm_hi16()); - assert!(esi.xcr0_supports_pkru()); - assert!(esi.ia32_xss_supports_pt()); - assert!(!esi.ia32_xss_supports_hdc()); - - assert!(esi.xsave_area_size_enabled_features() == 2688); - assert!(esi.xsave_area_size_supported_features() == 2696); - - assert!(esi.has_xsaveopt()); - assert!(esi.has_xsavec()); - assert!(esi.has_xgetbv()); - assert!(esi.has_xsaves_xrstors()); - assert!(esi.xsave_size() == 2560); - - let es = [ - ExtendedState { - subleaf: 2, - eax: 256, - ebx: 576, - ecx: 0, - }, - ExtendedState { - subleaf: 3, - eax: 64, - ebx: 960, - ecx: 0, - }, - ExtendedState { - subleaf: 4, - eax: 64, - ebx: 1024, - ecx: 0, - }, - ExtendedState { - subleaf: 5, - eax: 64, - ebx: 1088, - ecx: 0, - }, - ExtendedState { - subleaf: 6, - eax: 512, - ebx: 1152, - ecx: 0, - }, - ExtendedState { - subleaf: 7, - eax: 1024, - ebx: 1664, - ecx: 0, - }, - ExtendedState { - subleaf: 8, - eax: 128, - ebx: 0, - ecx: 1, - }, - ExtendedState { - subleaf: 9, - eax: 8, - ebx: 2688, - ecx: 0, - }, - ]; - - let e = &es[0]; - assert!(e.subleaf == 2); - assert!(e.size() == 256); - assert!(e.offset() == 576); - assert!(e.is_in_xcr0()); - assert!(!e.is_in_ia32_xss()); - assert!(!e.is_compacted_format()); - - let e = &es[1]; - assert!(e.subleaf == 3); - assert!(e.size() == 64); - assert!(e.offset() == 960); - assert!(e.is_in_xcr0()); - assert!(!e.is_in_ia32_xss()); - assert!(!e.is_compacted_format()); - - let e = &es[2]; - assert!(e.subleaf == 4); - assert!(e.size() == 64); - assert!(e.offset() == 1024); - assert!(e.is_in_xcr0()); - assert!(!e.is_in_ia32_xss()); - assert!(!e.is_compacted_format()); - - let e = &es[3]; - assert!(e.subleaf == 5); - assert!(e.size() == 64); - assert!(e.offset() == 1088); - assert!(e.is_in_xcr0()); - assert!(!e.is_in_ia32_xss()); - assert!(!e.is_compacted_format()); - - let e = &es[4]; - assert!(e.subleaf == 6); - assert!(e.size() == 512); - assert!(e.offset() == 1152); - assert!(e.is_in_xcr0()); - assert!(!e.is_in_ia32_xss()); - assert!(!e.is_compacted_format()); - - let e = &es[5]; - assert!(e.subleaf == 7); - assert!(e.size() == 1024); - assert!(e.offset() == 1664); - assert!(e.is_in_xcr0()); - assert!(!e.is_in_ia32_xss()); - assert!(!e.is_compacted_format()); - - let e = &es[6]; - assert!(e.subleaf == 8); - assert!(e.size() == 128); - assert!(e.offset() == 0); - assert!(!e.is_in_xcr0()); - assert!(e.is_in_ia32_xss()); - assert!(!e.is_compacted_format()); - - let e = &es[7]; - assert!(e.subleaf == 9); - assert!(e.size() == 8); - assert!(e.offset() == 2688); - assert!(e.is_in_xcr0()); - assert!(!e.is_in_ia32_xss()); - assert!(!e.is_compacted_format()); -} - -#[test] -fn extended_state_info2() { - let es = ExtendedStateInfo { - eax: ExtendedStateInfoXCR0Flags { bits: 31 }, - ebx: 1088, - ecx: 1088, - edx: 0, - eax1: 15, - ebx1: 960, - ecx1: ExtendedStateInfoXSSFlags { bits: 256 }, - edx1: 0, - }; - - assert!(es.xcr0_supports_legacy_x87()); - assert!(es.xcr0_supports_sse_128()); - assert!(es.xcr0_supports_avx_256()); - assert!(es.xcr0_supports_mpx_bndregs()); - assert!(es.xcr0_supports_mpx_bndcsr()); - assert!(!es.xcr0_supports_avx512_opmask()); - assert!(!es.xcr0_supports_pkru()); - assert!(es.ia32_xss_supports_pt()); - - assert!(es.xsave_area_size_enabled_features() == 0x440); - assert!(es.xsave_area_size_supported_features() == 0x440); - - assert!(es.has_xsaveopt()); - assert!(es.has_xsavec()); - assert!(es.has_xgetbv()); - assert!(es.has_xsaves_xrstors()); - assert!(es.xsave_size() == 0x3c0); - - let esiter: [ExtendedState; 3] = [ - ExtendedState { - subleaf: 2, - eax: 256, - ebx: 576, - ecx: 0, - }, - ExtendedState { - subleaf: 3, - eax: 64, - ebx: 960, - ecx: 0, - }, - ExtendedState { - subleaf: 4, - eax: 64, - ebx: 1024, - ecx: 0, - }, - ]; - - let e = &esiter[0]; - assert!(e.subleaf == 2); - assert!(e.size() == 256); - assert!(e.offset() == 576); - assert!(e.is_in_xcr0()); - assert!(!e.is_in_ia32_xss()); - - let e = &esiter[1]; - assert!(e.subleaf == 3); - assert!(e.size() == 64); - assert!(e.offset() == 960); - assert!(e.is_in_xcr0()); - assert!(!e.is_in_ia32_xss()); - - let e = &esiter[2]; - assert!(e.subleaf == 4); - assert!(e.size() == 64); - assert!(e.offset() == 1024); - assert!(e.is_in_xcr0()); - assert!(!e.is_in_ia32_xss()); -} - -#[test] -fn quality_of_service_info() { - let qos = RdtMonitoringInfo { ebx: 832, edx: 0 }; - - assert!(qos.rmid_range() == 832); - assert!(!qos.has_l3_monitoring()); -} - -#[test] -fn extended_functions() { - let ef = ExtendedFunctionInfo { - max_eax_value: 8, - data: [ - CpuIdResult { - eax: 2147483656, - ebx: 0, - ecx: 0, - edx: 0, - }, - CpuIdResult { - eax: 0, - ebx: 0, - ecx: 1, - edx: 672139264, - }, - CpuIdResult { - eax: 538976288, - ebx: 1226842144, - ecx: 1818588270, - edx: 539578920, - }, - CpuIdResult { - eax: 1701998403, - ebx: 692933672, - ecx: 758475040, - edx: 926102323, - }, - CpuIdResult { - eax: 1346576469, - ebx: 541073493, - ecx: 808988209, - edx: 8013895, - }, - CpuIdResult { - eax: 0, - ebx: 0, - ecx: 0, - edx: 0, - }, - CpuIdResult { - eax: 0, - ebx: 0, - ecx: 16801856, - edx: 0, - }, - CpuIdResult { - eax: 0, - ebx: 0, - ecx: 0, - edx: 256, - }, - CpuIdResult { - eax: 12324, - ebx: 0, - ecx: 0, - edx: 0, - }, - ], - }; - - assert_eq!( - ef.processor_brand_string().unwrap(), - " Intel(R) Core(TM) i5-3337U CPU @ 1.80GHz" - ); - assert!(ef.has_lahf_sahf()); - assert!(!ef.has_lzcnt()); - assert!(!ef.has_prefetchw()); - assert!(ef.has_syscall_sysret()); - assert!(ef.has_execute_disable()); - assert!(!ef.has_1gib_pages()); - assert!(ef.has_rdtscp()); - assert!(ef.has_64bit_mode()); - assert!(ef.has_invariant_tsc()); - - assert!(ef.extended_signature().unwrap() == 0x0); - assert!(ef.cache_line_size().unwrap() == 64); - assert!(ef.l2_associativity().unwrap() == L2Associativity::EightWay); - assert!(ef.cache_size().unwrap() == 256); - assert!(ef.physical_address_bits().unwrap() == 36); - assert!(ef.linear_address_bits().unwrap() == 48); -} - -#[cfg(test)] -#[test] -fn sgx_test() { - let sgx = SgxInfo { - eax: 1, - ebx: 0, - ecx: 0, - edx: 9247, - eax1: 54, - ebx1: 0, - ecx1: 31, - edx1: 0, - }; - - assert!(sgx.max_enclave_size_64bit() == 0x24); - assert!(sgx.max_enclave_size_non_64bit() == 0x1f); - assert!(sgx.has_sgx1()); - assert!(!sgx.has_sgx2()); - assert!(sgx.miscselect() == 0x0); - assert!(sgx.secs_attributes() == (0x0000000000000036, 0x000000000000001f)); -} - -#[cfg(test)] -#[test] -fn readme_test() { - // let cpuid = CpuId::new(); - // - // match cpuid.get_vendor_info() { - // Some(vf) => assert!(vf.as_string() == "GenuineIntel"), - // None => () - // } - // - // let has_sse = match cpuid.get_feature_info() { - // Some(finfo) => finfo.has_sse(), - // None => false - // }; - // - // if has_sse { - // println!("CPU supports SSE!"); - // } - // - // match cpuid.get_cache_parameters() { - // Some(cparams) => { - // for cache in cparams { - // let size = cache.associativity() * cache.physical_line_partitions() * cache.coherency_line_size() * cache.sets(); - // println!("L{}-Cache size is {}", cache.level(), size); - // } - // }, - // None => println!("No cache parameter information available"), - // } - // -} - -/* -extern crate serde_json; - -#[cfg(test)] -#[test] -fn test_serializability() { - #[derive(Debug, Default, Serialize, Deserialize)] - struct SerializeDeserializeTest { - _x1: CpuId, - _x2: CpuIdResult, - _x3: VendorInfo, - _x4: CacheInfoIter, - _x5: CacheInfo, - _x6: ProcessorSerial, - _x7: FeatureInfo, - _x8: CacheParametersIter, - _x9: CacheParameter, - _x10: MonitorMwaitInfo, - _x11: ThermalPowerInfo, - _x12: ExtendedFeatures, - _x13: DirectCacheAccessInfo, - _x14: PerformanceMonitoringInfo, - _x15: ExtendedTopologyIter, - _x16: ExtendedTopologyLevel, - _x17: ExtendedStateInfo, - _x18: ExtendedStateIter, - _x19: ExtendedState, - _x20: RdtAllocationInfo, - _x21: RdtMonitoringInfo, - _x22: L3CatInfo, - _x23: L2CatInfo, - _x24: ProcessorTraceInfo, - _x25: ProcessorTraceIter, - _x26: ProcessorTrace, - _x27: TscInfo, - _x28: ProcessorFrequencyInfo, - _x29: SoCVendorInfo, - _x30: SoCVendorAttributesIter, - _x31: SoCVendorBrand, - _x32: ExtendedFunctionInfo, - _x33: MemBwAllocationInfo, - _x34: L3MonitoringInfo, - _x35: SgxSectionInfo, - _x36: EpcSection, - _x37: SgxInfo, - _x38: SgxSectionIter, - _x39: DatInfo, - _x40: DatIter, - _x41: DatType, - } - - let st: SerializeDeserializeTest = Default::default(); - let test = serde_json::to_string(&st).unwrap(); - let _st: SerializeDeserializeTest = serde_json::from_str(&test).unwrap(); -}*/ Binary files /tmp/tmpnpcei9wp/JSWhcYBMya/distinst-0.3.2~1650402197~21.10~52e2e8d~dev/vendor.tar.xz and /tmp/tmpnpcei9wp/YUDUkXWJc_/distinst-0.3.2~1652283129~21.10~4af925c~dev/vendor.tar.xz differ