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}