Skip to main content

islet_rmm/rmi/
version.rs

1use crate::event::RmiHandle;
2use crate::listen;
3use crate::rmi::{self, error::Error};
4
5extern crate alloc;
6
7pub fn decode_version(version: usize) -> (usize, usize) {
8    let major = (version & 0x7fff0000) >> 16;
9    let minor = version & 0xffff;
10
11    (major, minor)
12}
13
14fn encode_version() -> usize {
15    (rmi::ABI_MAJOR_VERSION << 16) | rmi::ABI_MINOR_VERSION
16}
17
18pub fn set_event_handler(rmi: &mut RmiHandle) {
19    listen!(rmi, rmi::VERSION, |arg, ret, _| {
20        let req = arg[0];
21
22        let lower = encode_version();
23        let higher = lower;
24
25        ret[1] = lower;
26        ret[2] = higher;
27
28        let (req_major, req_minor) = decode_version(req);
29
30        if req_major != rmi::ABI_MAJOR_VERSION || req_minor != rmi::ABI_MINOR_VERSION {
31            warn!(
32                "Wrong unsupported version requested ({}, {})",
33                req_major, req_minor
34            );
35            return Err(Error::RmiErrorInput);
36        }
37
38        trace!("RMI_ABI_VERSION: {:#X?} {:#X?}", lower, higher);
39
40        Ok(())
41    });
42}
43
44#[cfg(test)]
45mod test {
46    use super::encode_version;
47    use crate::rmi::{ABI_MAJOR_VERSION, ABI_MINOR_VERSION, SUCCESS, VERSION};
48    use crate::test_utils::*;
49
50    // Source: https://github.com/ARM-software/cca-rmm-acs
51    // Test Case: cmd_rmi_version_host
52    #[test]
53    fn rmi_version() {
54        let ret = rmi::<VERSION>(&[encode_version()]);
55
56        assert_eq!(ret[0], SUCCESS);
57
58        // Must Be Zero fields
59        assert_eq!(extract_bits(ret[1], 31, 63), 0);
60        assert_eq!(extract_bits(ret[2], 31, 63), 0);
61
62        // Version Check
63        assert_eq!(extract_bits(ret[1], 0, 15), ABI_MINOR_VERSION);
64        assert_eq!(extract_bits(ret[1], 16, 30), ABI_MAJOR_VERSION);
65    }
66}