Skip to main content

sbi_testing/
base.rs

1//! RISC-V SBI Base extension test suite.
2
3use sbi::{ExtensionInfo, Version};
4use sbi_spec::base::impl_id;
5
6/// Base extension test cases.
7#[derive(Clone, Debug)]
8pub enum Case {
9    /// Can't proceed test for base extension does not exist.
10    NotExist,
11    /// Test begin.
12    Begin,
13    /// Test process for getting SBI specification version.
14    GetSbiSpecVersion(Version),
15    /// Test process for getting SBI implementation ID.
16    GetSbiImplId(Result<&'static str, usize>),
17    /// Test process for getting version of SBI implementation.
18    GetSbiImplVersion(usize),
19    /// Test process for probe standard SBI extensions.
20    ProbeExtensions(Extensions),
21    /// Test process for getting vendor ID from RISC-V environment.
22    GetMvendorId(usize),
23    /// Test process for getting architecture ID from RISC-V environment.
24    GetMarchId(usize),
25    /// Test process for getting implementation ID from RISC-V environment.
26    GetMimpId(usize),
27    /// All test cases on base module finished.
28    Pass,
29}
30
31/// Information about all SBI standard extensions.
32#[derive(Clone, Debug)]
33pub struct Extensions {
34    /// Timer programmer extension.
35    pub time: ExtensionInfo,
36    /// Inter-processor Interrupt extension.
37    pub spi: ExtensionInfo,
38    /// Remote Fence extension.
39    pub rfnc: ExtensionInfo,
40    /// Hart State Monitor extension.
41    pub hsm: ExtensionInfo,
42    /// System Reset extension.
43    pub srst: ExtensionInfo,
44    /// Performance Monitor Unit extension.
45    pub pmu: ExtensionInfo,
46}
47
48impl core::fmt::Display for Extensions {
49    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
50        write!(f, "[Base")?;
51        if self.time.is_available() {
52            write!(f, ", TIME")?;
53        }
54        if self.spi.is_available() {
55            write!(f, ", sPI")?;
56        }
57        if self.rfnc.is_available() {
58            write!(f, ", RFNC")?;
59        }
60        if self.hsm.is_available() {
61            write!(f, ", HSM")?;
62        }
63        if self.srst.is_available() {
64            write!(f, ", SRST")?;
65        }
66        if self.pmu.is_available() {
67            write!(f, ", PMU")?;
68        }
69        write!(f, "]")
70    }
71}
72
73/// Test base extension.
74///
75/// The test case output would be handled in `f`.
76pub fn test(mut f: impl FnMut(Case)) {
77    if sbi::probe_extension(sbi::Base).is_unavailable() {
78        f(Case::NotExist);
79        return;
80    }
81    f(Case::Begin);
82    f(Case::GetSbiSpecVersion(sbi::get_spec_version()));
83    f(Case::GetSbiImplId(match sbi::get_sbi_impl_id() {
84        impl_id::BBL => Ok("BBL"),
85        impl_id::OPEN_SBI => Ok("OpenSBI"),
86        impl_id::XVISOR => Ok("Xvisor"),
87        impl_id::KVM => Ok("KVM"),
88        impl_id::RUST_SBI => Ok("RustSBI"),
89        impl_id::DIOSIX => Ok("Diosix"),
90        impl_id::COFFER => Ok("Coffer"),
91        impl_id::XEN => Ok("Xen Project"),
92        impl_id::POLARFIRE_HSS => Ok("PolarFire Hart Software Services"),
93        impl_id::COREBOOT => Ok("Coreboot"),
94        impl_id::OREBOOT => Ok("Oreboot"),
95        unknown => Err(unknown),
96    }));
97    f(Case::GetSbiImplVersion(sbi::get_sbi_impl_version()));
98    f(Case::ProbeExtensions(Extensions {
99        time: sbi::probe_extension(sbi::Timer),
100        spi: sbi::probe_extension(sbi::Ipi),
101        rfnc: sbi::probe_extension(sbi::Fence),
102        hsm: sbi::probe_extension(sbi::Hsm),
103        srst: sbi::probe_extension(sbi::Reset),
104        pmu: sbi::probe_extension(sbi::Pmu),
105    }));
106    f(Case::GetMvendorId(sbi::get_mvendorid()));
107    f(Case::GetMarchId(sbi::get_marchid()));
108    f(Case::GetMimpId(sbi::get_mimpid()));
109    f(Case::Pass);
110}