RISC-V: Linux 6.15 riscv_hwprobe support
This commit adds support for `riscv_hwprobe` on the Linux kernel 6.15. It adds feature detection of 8 extensions (4 of them are new in this). Existing RISC-V Extensions: 1. "Zicntr" 2. "Zihpm" 3. "Zalrsc" 4. "Zaamo" New RISC-V Extensions: 5. "Zicbom" 6. "Zfbfmin" 7. "Zvfbfmin" 8. "Zvfbfwma"
This commit is contained in:
parent
52115419a3
commit
bc4333545a
4 changed files with 39 additions and 3 deletions
|
|
@ -63,6 +63,7 @@ features! {
|
|||
/// * Zve64x: `"zve64x"`
|
||||
/// * Zve64f: `"zve64f"`
|
||||
/// * Zve64d: `"zve64d"`
|
||||
/// * Zicbom: `"zicbom"`
|
||||
/// * Zicboz: `"zicboz"`
|
||||
/// * Zicntr: `"zicntr"`
|
||||
/// * Zicond: `"zicond"`
|
||||
|
|
@ -75,6 +76,7 @@ features! {
|
|||
/// * Zacas: `"zacas"`
|
||||
/// * Zawrs: `"zawrs"`
|
||||
/// * Zfa: `"zfa"`
|
||||
/// * Zfbfmin: `"zfbfmin"`
|
||||
/// * Zfh: `"zfh"`
|
||||
/// * Zfhmin: `"zfhmin"`
|
||||
/// * Zfinx: `"zfinx"`
|
||||
|
|
@ -99,6 +101,8 @@ features! {
|
|||
/// * Zkt: `"zkt"`
|
||||
/// * Zvbb: `"zvbb"`
|
||||
/// * Zvbc: `"zvbc"`
|
||||
/// * Zvfbfmin: `"zvfbfmin"`
|
||||
/// * Zvfbfwma: `"zvfbfwma"`
|
||||
/// * Zvfh: `"zvfh"`
|
||||
/// * Zvfhmin: `"zvfhmin"`
|
||||
/// * Zvkb: `"zvkb"`
|
||||
|
|
@ -173,6 +177,8 @@ features! {
|
|||
/// "Zihintpause" Extension for Pause Hint
|
||||
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zimop: "zimop";
|
||||
/// "Zimop" Extension for May-Be-Operations
|
||||
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zicbom: "zicbom";
|
||||
/// "Zicbom" Extension for Cache-Block Management Instructions
|
||||
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zicboz: "zicboz";
|
||||
/// "Zicboz" Extension for Cache-Block Zero Instruction
|
||||
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zicond: "zicond";
|
||||
|
|
@ -210,6 +216,8 @@ features! {
|
|||
/// "Zfhmin" Extension for Minimal Half-Precision Floating-Point
|
||||
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zfa: "zfa";
|
||||
/// "Zfa" Extension for Additional Floating-Point Instructions
|
||||
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zfbfmin: "zfbfmin";
|
||||
/// "Zfbfmin" Extension for Scalar BF16 Converts
|
||||
|
||||
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zfinx: "zfinx";
|
||||
/// "Zfinx" Extension for Single-Precision Floating-Point in Integer Registers
|
||||
|
|
@ -289,6 +297,10 @@ features! {
|
|||
/// "Zvfh" Vector Extension for Half-Precision Floating-Point
|
||||
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvfhmin: "zvfhmin";
|
||||
/// "Zvfhmin" Vector Extension for Minimal Half-Precision Floating-Point
|
||||
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvfbfmin: "zvfbfmin";
|
||||
/// "Zvfbfmin" Vector Extension for BF16 Converts
|
||||
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvfbfwma: "zvfbfwma";
|
||||
/// "Zvfbfwma" Vector Extension for BF16 Widening Multiply-Add
|
||||
|
||||
@FEATURE: #[unstable(feature = "stdarch_riscv_feature_detection", issue = "111192")] zvbb: "zvbb";
|
||||
/// "Zvbb" Extension for Vector Basic Bit-Manipulation
|
||||
|
|
|
|||
|
|
@ -10,13 +10,13 @@ use super::super::riscv::imply_features;
|
|||
use super::auxvec;
|
||||
use crate::detect::{Feature, bit, cache};
|
||||
|
||||
// See <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/prctl.h?h=v6.14>
|
||||
// See <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/linux/prctl.h?h=v6.15>
|
||||
// for runtime status query constants.
|
||||
const PR_RISCV_V_GET_CONTROL: libc::c_int = 70;
|
||||
const PR_RISCV_V_VSTATE_CTRL_ON: libc::c_int = 2;
|
||||
const PR_RISCV_V_VSTATE_CTRL_CUR_MASK: libc::c_int = 3;
|
||||
|
||||
// See <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/riscv/include/uapi/asm/hwprobe.h?h=v6.14>
|
||||
// See <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/riscv/include/uapi/asm/hwprobe.h?h=v6.15>
|
||||
// for riscv_hwprobe struct and hardware probing constants.
|
||||
|
||||
#[repr(C)]
|
||||
|
|
@ -83,6 +83,14 @@ const RISCV_HWPROBE_EXT_ZCMOP: u64 = 1 << 47;
|
|||
const RISCV_HWPROBE_EXT_ZAWRS: u64 = 1 << 48;
|
||||
// Excluded because it only reports the existence of `prctl`-based pointer masking control.
|
||||
// const RISCV_HWPROBE_EXT_SUPM: u64 = 1 << 49;
|
||||
const RISCV_HWPROBE_EXT_ZICNTR: u64 = 1 << 50;
|
||||
const RISCV_HWPROBE_EXT_ZIHPM: u64 = 1 << 51;
|
||||
const RISCV_HWPROBE_EXT_ZFBFMIN: u64 = 1 << 52;
|
||||
const RISCV_HWPROBE_EXT_ZVFBFMIN: u64 = 1 << 53;
|
||||
const RISCV_HWPROBE_EXT_ZVFBFWMA: u64 = 1 << 54;
|
||||
const RISCV_HWPROBE_EXT_ZICBOM: u64 = 1 << 55;
|
||||
const RISCV_HWPROBE_EXT_ZAAMO: u64 = 1 << 56;
|
||||
const RISCV_HWPROBE_EXT_ZALRSC: u64 = 1 << 57;
|
||||
|
||||
const RISCV_HWPROBE_KEY_CPUPERF_0: i64 = 5;
|
||||
const RISCV_HWPROBE_MISALIGNED_FAST: u64 = 3;
|
||||
|
|
@ -133,7 +141,7 @@ pub(crate) fn detect_features() -> cache::Initializer {
|
|||
// Use auxiliary vector to enable single-letter ISA extensions.
|
||||
// The values are part of the platform-specific [asm/hwcap.h][hwcap]
|
||||
//
|
||||
// [hwcap]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/riscv/include/uapi/asm/hwcap.h?h=v6.14
|
||||
// [hwcap]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/riscv/include/uapi/asm/hwcap.h?h=v6.15
|
||||
let auxv = auxvec::auxv().expect("read auxvec"); // should not fail on RISC-V platform
|
||||
let mut has_i = bit::test(auxv.hwcap, (b'i' - b'a').into());
|
||||
#[allow(clippy::eq_op)]
|
||||
|
|
@ -221,12 +229,18 @@ pub(crate) fn detect_features() -> cache::Initializer {
|
|||
enable_feature(Feature::d, test(RISCV_HWPROBE_IMA_FD)); // F is implied.
|
||||
enable_feature(Feature::c, test(RISCV_HWPROBE_IMA_C));
|
||||
|
||||
enable_feature(Feature::zicntr, test(RISCV_HWPROBE_EXT_ZICNTR));
|
||||
enable_feature(Feature::zihpm, test(RISCV_HWPROBE_EXT_ZIHPM));
|
||||
|
||||
enable_feature(Feature::zihintntl, test(RISCV_HWPROBE_EXT_ZIHINTNTL));
|
||||
enable_feature(Feature::zihintpause, test(RISCV_HWPROBE_EXT_ZIHINTPAUSE));
|
||||
enable_feature(Feature::zimop, test(RISCV_HWPROBE_EXT_ZIMOP));
|
||||
enable_feature(Feature::zicbom, test(RISCV_HWPROBE_EXT_ZICBOM));
|
||||
enable_feature(Feature::zicboz, test(RISCV_HWPROBE_EXT_ZICBOZ));
|
||||
enable_feature(Feature::zicond, test(RISCV_HWPROBE_EXT_ZICOND));
|
||||
|
||||
enable_feature(Feature::zalrsc, test(RISCV_HWPROBE_EXT_ZALRSC));
|
||||
enable_feature(Feature::zaamo, test(RISCV_HWPROBE_EXT_ZAAMO));
|
||||
enable_feature(Feature::zawrs, test(RISCV_HWPROBE_EXT_ZAWRS));
|
||||
enable_feature(Feature::zacas, test(RISCV_HWPROBE_EXT_ZACAS));
|
||||
enable_feature(Feature::ztso, test(RISCV_HWPROBE_EXT_ZTSO));
|
||||
|
|
@ -255,6 +269,7 @@ pub(crate) fn detect_features() -> cache::Initializer {
|
|||
enable_feature(Feature::zfh, test(RISCV_HWPROBE_EXT_ZFH));
|
||||
enable_feature(Feature::zfhmin, test(RISCV_HWPROBE_EXT_ZFHMIN));
|
||||
enable_feature(Feature::zfa, test(RISCV_HWPROBE_EXT_ZFA));
|
||||
enable_feature(Feature::zfbfmin, test(RISCV_HWPROBE_EXT_ZFBFMIN));
|
||||
|
||||
// Use prctl (if any) to determine whether the vector extension
|
||||
// is enabled on the current thread (assuming the entire process
|
||||
|
|
@ -290,6 +305,8 @@ pub(crate) fn detect_features() -> cache::Initializer {
|
|||
|
||||
enable_feature(Feature::zvfh, test(RISCV_HWPROBE_EXT_ZVFH));
|
||||
enable_feature(Feature::zvfhmin, test(RISCV_HWPROBE_EXT_ZVFHMIN));
|
||||
enable_feature(Feature::zvfbfmin, test(RISCV_HWPROBE_EXT_ZVFBFMIN));
|
||||
enable_feature(Feature::zvfbfwma, test(RISCV_HWPROBE_EXT_ZVFBFWMA));
|
||||
}
|
||||
is_v_set = true;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -105,6 +105,8 @@ pub(crate) fn imply_features(mut value: cache::Initializer) -> cache::Initialize
|
|||
imply!(zvfh => zvfhmin); // functional
|
||||
imply!(zvfh => zve32f & zfhmin);
|
||||
imply!(zvfhmin => zve32f);
|
||||
imply!(zvfbfwma => zvfbfmin & zfbfmin);
|
||||
imply!(zvfbfmin => zve32f);
|
||||
|
||||
imply!(v => zve64d);
|
||||
imply!(zve64d => zve64f & d);
|
||||
|
|
@ -115,6 +117,7 @@ pub(crate) fn imply_features(mut value: cache::Initializer) -> cache::Initialize
|
|||
imply!(zfh => zfhmin);
|
||||
imply!(q => d);
|
||||
imply!(d | zfhmin | zfa => f);
|
||||
imply!(zfbfmin => f); // and some of (not all) "Zfh" instructions.
|
||||
|
||||
// Relatively complex implication rules from the "C" extension.
|
||||
imply!(c => zca);
|
||||
|
|
|
|||
|
|
@ -251,6 +251,7 @@ fn riscv_linux() {
|
|||
println!("zihintntl: {}", is_riscv_feature_detected!("zihintntl"));
|
||||
println!("zihintpause: {}", is_riscv_feature_detected!("zihintpause"));
|
||||
println!("zimop: {}", is_riscv_feature_detected!("zimop"));
|
||||
println!("zicbom: {}", is_riscv_feature_detected!("zicbom"));
|
||||
println!("zicboz: {}", is_riscv_feature_detected!("zicboz"));
|
||||
println!("zicond: {}", is_riscv_feature_detected!("zicond"));
|
||||
println!("m: {}", is_riscv_feature_detected!("m"));
|
||||
|
|
@ -267,6 +268,7 @@ fn riscv_linux() {
|
|||
println!("zfh: {}", is_riscv_feature_detected!("zfh"));
|
||||
println!("zfhmin: {}", is_riscv_feature_detected!("zfhmin"));
|
||||
println!("zfa: {}", is_riscv_feature_detected!("zfa"));
|
||||
println!("zfbfmin: {}", is_riscv_feature_detected!("zfbfmin"));
|
||||
println!("zfinx: {}", is_riscv_feature_detected!("zfinx"));
|
||||
println!("zdinx: {}", is_riscv_feature_detected!("zdinx"));
|
||||
println!("zhinx: {}", is_riscv_feature_detected!("zhinx"));
|
||||
|
|
@ -303,6 +305,8 @@ fn riscv_linux() {
|
|||
println!("zve64d: {}", is_riscv_feature_detected!("zve64d"));
|
||||
println!("zvfh: {}", is_riscv_feature_detected!("zvfh"));
|
||||
println!("zvfhmin: {}", is_riscv_feature_detected!("zvfhmin"));
|
||||
println!("zvfbfmin: {}", is_riscv_feature_detected!("zvfbfmin"));
|
||||
println!("zvfbfwma: {}", is_riscv_feature_detected!("zvfbfwma"));
|
||||
println!("zvbb: {}", is_riscv_feature_detected!("zvbb"));
|
||||
println!("zvbc: {}", is_riscv_feature_detected!("zvbc"));
|
||||
println!("zvkb: {}", is_riscv_feature_detected!("zvkb"));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue