squid/
runtime.rs

1//! Contains the [`Runtime`] trait.
2
3use crate::{
4    frontend::VAddr,
5    riscv::register::{
6        CsrRegister,
7        FpRegister,
8        GpRegister,
9    },
10};
11
12/// Snapshots are referred to by IDs of this type
13pub type SnapshotId = usize;
14
15/// This trait contains the minimum behavior that is expected from any runtime.
16pub trait Runtime {
17    /// Each runtime has its corresponding error type
18    type Error: std::error::Error;
19
20    /// The Event is the return value of the [`Runtime::run`] function
21    type Event;
22
23    /* Register I/O */
24    /// Set the program counter to the specified address
25    fn set_pc(&mut self, pc: VAddr);
26    /// Get the program counter of the program
27    fn get_pc(&self) -> VAddr;
28    /// Store a value into a general puporse register
29    fn set_gp_register(&mut self, register: GpRegister, value: u64);
30    /// Retrieve the value of a general purpose register
31    fn get_gp_register(&self, register: GpRegister) -> u64;
32    /// Store a value into a floating point register
33    fn set_fp_register(&mut self, register: FpRegister, value: f64);
34    /// Retrieve the value of a floating point register
35    fn get_fp_register(&self, register: FpRegister) -> f64;
36    /// Store a value into one of the control/status registers
37    fn set_csr_register(&mut self, register: CsrRegister, value: u64);
38    /// Retrieve the value of one of the control/status registers
39    fn get_csr_register(&self, register: CsrRegister) -> u64;
40
41    /* Interact with the code */
42    /// Execute the program starting at the current program counter until an event is thrown
43    fn run(&mut self) -> Result<Self::Event, Self::Error>;
44
45    /* Snapshot handling */
46    /// Check if a snapshot with the given ID is available
47    fn has_snapshot(&self, id: SnapshotId) -> bool;
48    /// Take a snapshot of the current program state and assign it the given ID.
49    /// If a snapshot with the same ID has already been created, it is overwritten.
50    fn take_snapshot(&mut self, id: SnapshotId);
51    /// Given a snapshot ID, restore the corresponding snapshot
52    fn restore_snapshot(&mut self, id: SnapshotId) -> Result<(), Self::Error>;
53    /// Delete the snapshot with the given ID from the snapshot store
54    fn delete_snapshot(&mut self, id: SnapshotId) -> Result<(), Self::Error>;
55
56    /* Event channel I/O */
57    /// Get read-only access to the data in the event channel
58    fn event_channel(&self) -> &[u64];
59    /// Get write-access to the event channel. `size` determines how many elements you want to place into the event channel.
60    fn event_channel_mut(&mut self, size: usize) -> Result<&mut [u64], Self::Error>;
61
62    /* Memory I/O */
63    /// Return the memory contents at the given address as a dword (8 bytes)
64    fn load_dword(&self, address: VAddr) -> Result<u64, Self::Error>;
65    /// Return the memory contents at the given address as a word (4 bytes)
66    fn load_word(&self, address: VAddr) -> Result<u32, Self::Error>;
67    /// Return the memory contents at the given address as an hword (2 bytes)
68    fn load_hword(&self, address: VAddr) -> Result<u16, Self::Error>;
69    /// Return the memory contents at the given address as a byte
70    fn load_byte(&self, address: VAddr) -> Result<u8, Self::Error>;
71    /// Return the memory contents at the given address as an array of bytes with size `size`
72    fn load_slice(&self, address: VAddr, size: usize) -> Result<&[u8], Self::Error>;
73    /// Store the given value at the given address as a byte
74    fn store_byte(&mut self, address: VAddr, value: u8) -> Result<(), Self::Error>;
75    /// Store the given value at the given address as a hword (2 bytes)
76    fn store_hword(&mut self, address: VAddr, value: u16) -> Result<(), Self::Error>;
77    /// Store the given value at the given address as a word (4 bytes)
78    fn store_word(&mut self, address: VAddr, value: u32) -> Result<(), Self::Error>;
79    /// Store the given value at the given address as a dword (8 bytes)
80    fn store_dword(&mut self, address: VAddr, value: u64) -> Result<(), Self::Error>;
81    /// Store the given byte array at the given address
82    fn store_slice<S: AsRef<[u8]>>(&mut self, address: VAddr, value: S) -> Result<(), Self::Error>;
83    /// Retreive a NUL-terminated string at the given address.
84    /// The NUL terminator must not be included in the return value but exists in memory.
85    fn load_string(&self, address: VAddr) -> Result<&[u8], Self::Error>;
86    /// Store the provided string as is at the given address. A NUL-terminator must be added by the implementation.
87    fn store_string<S: AsRef<str>>(&mut self, address: VAddr, value: S) -> Result<(), Self::Error>;
88}