islet_rmm/rmi/
features.rs1use crate::event::RmiHandle;
2use crate::gic;
3use crate::listen;
4use crate::pmu;
5use crate::rec;
6use crate::rmi;
7use crate::simd;
8use armv9a::{define_bitfield, define_bits, define_mask};
9
10extern crate alloc;
11
12define_bits!(
13 FeatureReg0,
14 MAX_RECS_ORDER[41 - 38],
15 GICV3_NUM_LRS[37 - 34],
16 HASH_SHA_512[33 - 33],
17 HASH_SHA_256[32 - 32],
18 PMU_NUM_CTRS[31 - 27],
19 PMU_EN[26 - 26],
20 NUM_WPS[25 - 20],
21 NUM_BPS[19 - 14],
22 SVE_VL[13 - 10],
23 SVE_EN[9 - 9],
24 LPA2[8 - 8],
25 S2SZ[7 - 0]
26);
27
28const S2SZ_VALUE: u64 = 48;
29pub const LPA2_VALUE: u64 = 0;
30const HASH_SHA_256_VALUE: u64 = SUPPORTED;
31const HASH_SHA_512_VALUE: u64 = SUPPORTED;
32
33pub const NOT_SUPPORTED: u64 = 0;
34pub const SUPPORTED: u64 = 1;
35
36const FEATURE_REGISTER_0_INDEX: usize = 0;
37
38pub fn set_event_handler(rmi: &mut RmiHandle) {
39 listen!(rmi, rmi::FEATURES, |arg, ret, _| {
40 if arg[0] != FEATURE_REGISTER_0_INDEX {
41 ret[1] = 0;
42 return Ok(());
43 }
44
45 let mut feat_reg0 = FeatureReg0::new(0);
46 feat_reg0
47 .set_masked_value(FeatureReg0::S2SZ, S2SZ_VALUE)
48 .set_masked_value(FeatureReg0::LPA2, LPA2_VALUE)
49 .set_masked_value(FeatureReg0::HASH_SHA_256, HASH_SHA_256_VALUE)
50 .set_masked_value(FeatureReg0::HASH_SHA_512, HASH_SHA_512_VALUE)
51 .set_masked_value(FeatureReg0::MAX_RECS_ORDER, rec::max_recs_order() as u64);
52
53 #[cfg(not(any(miri, test, fuzzing)))]
54 feat_reg0
55 .set_masked_value(
56 FeatureReg0::SVE_EN,
57 if simd::sve_en() {
58 SUPPORTED
59 } else {
60 NOT_SUPPORTED
61 },
62 )
63 .set_masked_value(FeatureReg0::SVE_VL, simd::max_sve_vl())
64 .set_masked_value(
65 FeatureReg0::PMU_EN,
66 if pmu::pmu_present() {
67 SUPPORTED
68 } else {
69 NOT_SUPPORTED
70 },
71 )
72 .set_masked_value(FeatureReg0::PMU_NUM_CTRS, pmu::pmu_num_ctrs())
73 .set_masked_value(FeatureReg0::GICV3_NUM_LRS, gic::nr_lrs() as u64);
74 #[cfg(any(miri, test, fuzzing))]
75 feat_reg0
76 .set_masked_value(FeatureReg0::SVE_EN, NOT_SUPPORTED)
77 .set_masked_value(FeatureReg0::SVE_VL, 0)
78 .set_masked_value(FeatureReg0::GICV3_NUM_LRS, 0);
79
80 ret[1] = feat_reg0.get() as usize;
81 debug!("rmi::FEATURES ret:{:X}", feat_reg0.get());
82 Ok(())
83 });
84}
85
86pub fn validate(s2sz: usize) -> bool {
88 const MIN_IPA_SIZE: usize = 32;
89 if !(MIN_IPA_SIZE..=S2SZ_VALUE as usize).contains(&s2sz) {
90 return false;
91 }
92
93 true
94}
95
96#[cfg(test)]
97mod test {
98 use crate::rmi::{FEATURES, SUCCESS};
99 use crate::test_utils::*;
100
101 #[test]
104 fn rmi_features() {
105 let ret = rmi::<FEATURES>(&[0]);
106
107 assert_eq!(ret[0], SUCCESS);
108 assert_eq!(extract_bits(ret[1], 42, 63), 0);
109
110 let ret = rmi::<FEATURES>(&[1]);
111 assert_eq!(ret[0], SUCCESS);
112 assert_eq!(ret[1], 0);
113 }
114}