Skip to main content

sbi_testing/
dbcn.rs

1//! Debug console extension test suite.
2
3use sbi::SbiRet;
4use sbi_spec::binary::Physical;
5
6/// Debug console extension test cases.
7#[derive(Clone, Debug)]
8pub enum Case {
9    /// Can't proceed test for debug console extension does not exist.
10    NotExist,
11    /// Test begin.
12    Begin,
13    /// Test process for write a byte to console.
14    WriteByte,
15    /// Test failed for can't write byte.
16    WritingByteFailed(SbiRet),
17    /// Test process for write complete slice.
18    WriteSlice,
19    /// Test process for write partial slice.
20    WritingPartialSlice(usize),
21    /// Test failed for can't write slice.
22    WritingSliceFailed(SbiRet),
23    /// Test process for read some bytes from console.
24    Read(usize),
25    /// Test failed for can't read to buffer.
26    ReadingFailed(SbiRet),
27    /// Test process for rejecting a write with a non-zero upper address half.
28    NonzeroUpperWriteRejected(SbiRet),
29    /// Test failed because a write with a non-zero upper address half was accepted.
30    NonzeroUpperWriteAccepted(usize),
31    /// Test process for rejecting a read with a non-zero upper address half.
32    NonzeroUpperReadRejected(SbiRet),
33    /// Test failed because a read with a non-zero upper address half was accepted.
34    NonzeroUpperReadAccepted(usize),
35    /// All test cases on debug console extension has passed.
36    Pass,
37}
38
39/// Test debug console extension.
40pub fn test(mut f: impl FnMut(Case)) {
41    if sbi::probe_extension(sbi::Console).is_unavailable() {
42        f(Case::NotExist);
43        return;
44    }
45
46    f(Case::Begin);
47
48    let ret = sbi::console_write_byte(b'H');
49    if ret.is_ok() {
50        f(Case::WriteByte);
51    } else {
52        f(Case::WritingByteFailed(ret));
53    }
54    let words = b"ello, world!\r\n";
55    let ret = sbi::console_write(Physical::new(words.len(), words.as_ptr() as _, 0));
56    if let Some(len) = ret.ok() {
57        f(if len == words.len() {
58            Case::WriteSlice
59        } else {
60            Case::WritingPartialSlice(len)
61        });
62    } else {
63        f(Case::WritingSliceFailed(ret));
64    }
65    let mut buffer = [0u8; 16];
66    let ret = sbi::console_read(Physical::new(buffer.len(), buffer.as_mut_ptr() as _, 0));
67    if let Some(len) = ret.ok() {
68        f(Case::Read(len));
69    } else {
70        f(Case::ReadingFailed(ret));
71    }
72
73    #[cfg(target_pointer_width = "64")]
74    {
75        let nonzero_upper = 1usize << 32;
76
77        let ret = sbi::console_write(Physical::new(
78            words.len(),
79            words.as_ptr() as _,
80            nonzero_upper,
81        ));
82        if let Some(len) = ret.ok() {
83            f(Case::NonzeroUpperWriteAccepted(len));
84        } else {
85            f(Case::NonzeroUpperWriteRejected(ret));
86        }
87
88        let ret = sbi::console_read(Physical::new(
89            buffer.len(),
90            buffer.as_mut_ptr() as _,
91            nonzero_upper,
92        ));
93        if let Some(len) = ret.ok() {
94            f(Case::NonzeroUpperReadAccepted(len));
95        } else {
96            f(Case::NonzeroUpperReadRejected(ret));
97        }
98    }
99
100    f(Case::Pass);
101}