pub trait Memory {
// Required methods
fn load_byte(&self, addr: Addr) -> u8;
fn store_byte(&mut self, addr: Addr, value: u8);
// Provided methods
fn load_halfword(&self, addr: Addr) -> u16 { ... }
fn load_word(&self, addr: Addr) -> u32 { ... }
fn store_halfword(&mut self, addr: Addr, value: u16) { ... }
fn store_word(&mut self, addr: Addr, value: u32) { ... }
fn memcpy(&mut self, base_addr: Addr, buf: &[u8]) { ... }
}
Expand description
A trait representing a generic interface to a device that can be accessed through memory operations.
This can be used to implement several virtual hardware devices including RAMs, ROMs, and memory-mapped devices, like uarts or video buffers.
It is mandatory to implement load_byte
and store_byte
. All other operations are
optional and will default to being defined in terms of these two.
Several hardware-level notions are ignored, including whether the memory is readable, writable, or executable, or whether it is a memory or a device. There is no notion of atomic access.
There are two implementations provided in this library:
NaiveMemory
is an incredibly simple, but inefficient
implementation that uses a hashmap to assign each memory addresses to its current value.
It is here only as an illustration of the Memory
interface.
PagedMemory
is a slightly less naive implementation.
Whenever an address is first accessed, it will allocate a 4KiB page containing that address.
The pages are then at least contiguous in the host machine’s memory.