Skip to main content

spike_sys/
lib.rs

1#[link(name = "spike-interfaces", kind = "static")]
2unsafe extern "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);
14
15impl std::fmt::Display for Error {
16    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17        write!(f, "error({})", self.0)
18    }
19}
20
21impl std::error::Error for Error {}
22
23pub struct Spike {
24    addr: u64,
25}
26
27impl Spike {
28    pub fn new(mem_size: u64) -> Self {
29        unsafe { Self { addr: spike_new_processor(mem_size) } }
30    }
31
32    pub fn execute(&self, instruction: u64) -> Result<(), Error> {
33        let r = unsafe { spike_execute(self.addr, instruction) };
34        if r != 0 { Err(Error(r)) } else { Ok(()) }
35    }
36
37    pub fn get_reg(&self, index: u64) -> Result<u64, Error> {
38        let mut x = 0;
39        let r = unsafe { spike_get_reg(self.addr, index, &mut x) };
40        if r != 0 { Err(Error(r)) } else { Ok(x) }
41    }
42
43    pub fn set_reg(&self, index: u64, content: u64) -> Result<(), Error> {
44        let r = unsafe { spike_set_reg(self.addr, index, content) };
45        if r != 0 { Err(Error(r)) } else { Ok(()) }
46    }
47
48    pub fn ld(&self, addr: u64, len: u64, bytes: *mut u8) -> Result<(), Error> {
49        let r = unsafe { spike_ld(self.addr, addr, len, bytes) };
50        if r != 0 { Err(Error(r)) } else { Ok(()) }
51    }
52
53    pub fn sd(&self, addr: u64, len: u64, bytes: *mut u8) -> Result<(), Error> {
54        let r = unsafe { spike_sd(self.addr, addr, len, bytes) };
55        if r != 0 { Err(Error(r)) } else { Ok(()) }
56    }
57}
58
59impl Drop for Spike {
60    fn drop(&mut self) {
61        unsafe { spike_delete_processor(self.addr) }
62    }
63}