spike_rs/
lib.rs

1#[link(name = "spike-interfaces", kind = "static")]
2extern "C" {
3    pub fn spike_new_processor(mem_size: u64) -> u64;
4    pub fn spike_delete_processor(processor: u64);
5    pub fn spike_execute(processor: u64, instruction: u64) -> i32;
6    pub fn spike_get_reg(processor: u64, index: u64, content: *mut u64) -> i32;
7    pub fn spike_set_reg(processor: u64, index: u64, content: u64) -> i32;
8    pub fn spike_ld(processor: u64, addr: u64, len: u64, bytes: *mut u8) -> i32;
9    pub fn spike_sd(processor: u64, addr: u64, len: u64, bytes: *mut u8) -> i32;
10}
11
12#[derive(Debug)]
13pub struct Error(i32);
14impl std::fmt::Display for Error {
15    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16        write!(f, "error({})", self.0)
17    }
18}
19impl std::error::Error for Error {}
20
21pub struct Spike {
22    addr: u64,
23}
24
25impl Spike {
26    pub fn new(mem_size: u64) -> Self {
27        unsafe {
28            Self {
29                addr: spike_new_processor(mem_size),
30            }
31        }
32    }
33
34    pub fn execute(&self, instruction: u64) -> Result<(), Error> {
35        let r = unsafe { spike_execute(self.addr, instruction) };
36        if r != 0 {
37            Err(Error(r))
38        } else {
39            Ok(())
40        }
41    }
42
43    pub fn get_reg(&self, index: u64) -> Result<u64, Error> {
44        let mut x = 0;
45        let r = unsafe { spike_get_reg(self.addr, index, &mut x) };
46        if r != 0 {
47            Err(Error(r))
48        } else {
49            Ok(x)
50        }
51    }
52
53    pub fn set_reg(&self, index: u64, content: u64) -> Result<(), Error> {
54        let r = unsafe { spike_set_reg(self.addr, index, content) };
55        if r != 0 {
56            Err(Error(r))
57        } else {
58            Ok(())
59        }
60    }
61
62    pub fn ld(&self, addr: u64, len: u64, bytes: *mut u8) -> Result<(), Error> {
63        let r = unsafe { spike_ld(self.addr, addr, len, bytes) };
64        if r != 0 {
65            Err(Error(r))
66        } else {
67            Ok(())
68        }
69    }
70
71    pub fn sd(&self, addr: u64, len: u64, bytes: *mut u8) -> Result<(), Error> {
72        let r = unsafe { spike_sd(self.addr, addr, len, bytes) };
73        if r != 0 {
74            Err(Error(r))
75        } else {
76            Ok(())
77        }
78    }
79}
80
81impl Drop for Spike {
82    fn drop(&mut self) {
83        unsafe { spike_delete_processor(self.addr) }
84    }
85}