holey-bytes/hbvm/src/mem/mod.rs

87 lines
2.1 KiB
Rust
Raw Normal View History

2023-08-15 09:32:59 -05:00
//! Memory implementations
pub mod softpaging;
2023-08-17 18:41:05 -05:00
2023-09-26 16:36:27 -05:00
pub(crate) mod addr;
pub use addr::Address;
2023-08-19 16:46:47 -05:00
2023-09-26 16:36:27 -05:00
use {crate::utils::impl_display, hbbytecode::BytecodeItem};
2023-08-17 18:41:05 -05:00
/// Load-store memory access
pub trait Memory {
/// Load data from memory on address
///
/// # Safety
/// - Shall not overrun the buffer
unsafe fn load(
&mut self,
addr: Address,
target: *mut u8,
count: usize,
) -> Result<(), LoadError>;
2023-08-17 18:41:05 -05:00
/// Store data to memory on address
///
/// # Safety
/// - Shall not overrun the buffer
unsafe fn store(
&mut self,
addr: Address,
2023-08-17 18:41:05 -05:00
source: *const u8,
count: usize,
) -> Result<(), StoreError>;
/// Read from program memory to execute
///
/// # Safety
/// - Data read have to be valid
2023-09-26 16:36:27 -05:00
unsafe fn prog_read<T: BytecodeItem>(&mut self, addr: Address) -> Option<T>;
2023-08-17 18:41:05 -05:00
/// Read from program memory to exectue
///
/// # Safety
/// - You have to be really sure that these bytes are there, understand?
2023-09-26 16:36:27 -05:00
unsafe fn prog_read_unchecked<T: BytecodeItem>(&mut self, addr: Address) -> T;
2023-08-17 18:41:05 -05:00
}
/// Unhandled load access trap
2023-08-19 16:46:47 -05:00
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct LoadError(pub Address);
2023-08-19 16:46:47 -05:00
impl_display!(for LoadError =>
|LoadError(a)| "Load access error at address {a}",
);
2023-08-17 18:41:05 -05:00
/// Unhandled store access trap
2023-08-19 16:46:47 -05:00
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct StoreError(pub Address);
2023-08-19 16:46:47 -05:00
impl_display!(for StoreError =>
|StoreError(a)| "Load access error at address {a}",
);
2023-08-17 18:41:05 -05:00
/// Reason to access memory
2023-08-19 16:46:47 -05:00
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
2023-08-17 18:41:05 -05:00
pub enum MemoryAccessReason {
/// Memory was accessed for load (read)
Load,
/// Memory was accessed for store (write)
Store,
}
2023-08-19 16:46:47 -05:00
impl_display!(for MemoryAccessReason => match {
2023-08-19 16:57:48 -05:00
Self::Load => const "Load";
Self::Store => const "Store";
2023-08-19 16:46:47 -05:00
});
2023-08-17 18:41:05 -05:00
impl From<LoadError> for crate::VmRunError {
fn from(value: LoadError) -> Self {
Self::LoadAccessEx(value.0)
}
}
impl From<StoreError> for crate::VmRunError {
fn from(value: StoreError) -> Self {
Self::StoreAccessEx(value.0)
}
}