airbender_guest/
transport.rs1pub trait Transport {
5 fn read_word(&mut self) -> u32;
6 fn write_word(&mut self, word: u32);
7}
8
9pub struct CsrTransport;
11
12#[cfg(target_arch = "riscv32")]
13impl Transport for CsrTransport {
14 fn read_word(&mut self) -> u32 {
15 airbender_rt::sys::read_word()
16 }
17
18 fn write_word(&mut self, word: u32) {
19 airbender_rt::sys::write_word(word);
20 }
21}
22
23#[cfg(not(target_arch = "riscv32"))]
24impl Transport for CsrTransport {
25 fn read_word(&mut self) -> u32 {
26 panic!("csr transport is only available on riscv32")
27 }
28
29 fn write_word(&mut self, _word: u32) {
30 panic!("csr transport is only available on riscv32")
31 }
32}
33
34#[derive(Default)]
36pub struct MockTransport {
37 reads: alloc::vec::Vec<u32>,
38 writes: alloc::vec::Vec<u32>,
39 cursor: usize,
40}
41
42impl MockTransport {
43 pub fn new(reads: alloc::vec::Vec<u32>) -> Self {
45 Self {
46 reads,
47 writes: alloc::vec::Vec::new(),
48 cursor: 0,
49 }
50 }
51
52 pub fn push_reads(&mut self, words: impl IntoIterator<Item = u32>) {
54 self.reads.extend(words);
55 }
56
57 pub fn writes(&self) -> &[u32] {
59 &self.writes
60 }
61
62 pub fn into_writes(self) -> alloc::vec::Vec<u32> {
64 self.writes
65 }
66}
67
68impl Transport for MockTransport {
69 fn read_word(&mut self) -> u32 {
70 let Some(word) = self.reads.get(self.cursor) else {
71 panic!("mock transport exhausted");
72 };
73 self.cursor += 1;
74 *word
75 }
76
77 fn write_word(&mut self, word: u32) {
78 self.writes.push(word);
79 }
80}