a
This commit is contained in:
parent
498e729c90
commit
ce878c2319
|
@ -1,5 +1,5 @@
|
|||
use hbvm::vm::{
|
||||
mem::{Memory, PageSize},
|
||||
mem::{Memory, MemoryAccessReason, PageSize},
|
||||
trap::HandleTrap,
|
||||
value::Value,
|
||||
};
|
||||
|
@ -33,7 +33,14 @@ pub fn time() -> u32 {
|
|||
|
||||
struct TestTrapHandler;
|
||||
impl HandleTrap for TestTrapHandler {
|
||||
fn page_fault(&mut self, _: &mut Memory, _: u64, _: PageSize, _: *mut u8) -> bool {
|
||||
fn page_fault(
|
||||
&mut self,
|
||||
_: MemoryAccessReason,
|
||||
_: &mut Memory,
|
||||
_: u64,
|
||||
_: PageSize,
|
||||
_: *mut u8,
|
||||
) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ impl Memory {
|
|||
traph: &mut impl HandleTrap,
|
||||
) -> Result<(), LoadError> {
|
||||
self.memory_access(
|
||||
MemoryAccessReason::Load,
|
||||
addr,
|
||||
target,
|
||||
count,
|
||||
|
@ -96,6 +97,7 @@ impl Memory {
|
|||
traph: &mut impl HandleTrap,
|
||||
) -> Result<(), StoreError> {
|
||||
self.memory_access(
|
||||
MemoryAccessReason::Store,
|
||||
addr,
|
||||
source.cast_mut(),
|
||||
count,
|
||||
|
@ -118,7 +120,7 @@ impl Memory {
|
|||
dst: u64,
|
||||
count: usize,
|
||||
traph: &mut impl HandleTrap,
|
||||
) -> Result<(), BlkCopyError> {
|
||||
) -> Result<(), MemoryAccessReason> {
|
||||
// Yea, i know it is possible to do this more efficiently, but I am too lazy.
|
||||
|
||||
const STACK_BUFFER_SIZE: usize = 512;
|
||||
|
@ -144,6 +146,7 @@ impl Memory {
|
|||
let status = (|| {
|
||||
// Load to buffer
|
||||
self.memory_access(
|
||||
MemoryAccessReason::Load,
|
||||
src,
|
||||
buf,
|
||||
count,
|
||||
|
@ -156,10 +159,11 @@ impl Memory {
|
|||
|src, dst, count| core::ptr::copy(src, dst, count),
|
||||
traph,
|
||||
)
|
||||
.map_err(|_| BlkCopyError::Load)?;
|
||||
.map_err(|_| MemoryAccessReason::Load)?;
|
||||
|
||||
// Store from buffer
|
||||
self.memory_access(
|
||||
MemoryAccessReason::Store,
|
||||
dst,
|
||||
buf,
|
||||
count,
|
||||
|
@ -167,9 +171,9 @@ impl Memory {
|
|||
|dst, src, count| core::ptr::copy(src, dst, count),
|
||||
traph,
|
||||
)
|
||||
.map_err(|_| BlkCopyError::Store)?;
|
||||
.map_err(|_| MemoryAccessReason::Store)?;
|
||||
|
||||
Ok::<_, BlkCopyError>(())
|
||||
Ok::<_, MemoryAccessReason>(())
|
||||
})();
|
||||
|
||||
// Deallocate if used heap-allocated array
|
||||
|
@ -187,8 +191,10 @@ impl Memory {
|
|||
/// to a specified function.
|
||||
///
|
||||
/// If page is not found, execute page fault trap handler.
|
||||
#[allow(clippy::too_many_arguments)] // Silence peasant
|
||||
fn memory_access(
|
||||
&mut self,
|
||||
reason: MemoryAccessReason,
|
||||
src: u64,
|
||||
mut dst: *mut u8,
|
||||
len: usize,
|
||||
|
@ -211,7 +217,7 @@ impl Memory {
|
|||
}
|
||||
Some(Err(AddrSplitError { addr, size })) => {
|
||||
// Execute page fault handler
|
||||
if traph.page_fault(self, addr, size, dst) {
|
||||
if traph.page_fault(reason, self, addr, size, dst) {
|
||||
// Shift the splitter address
|
||||
pspl.bump(size);
|
||||
|
||||
|
@ -372,13 +378,21 @@ pub struct LoadError;
|
|||
#[derive(Clone, Copy, Display, Debug, PartialEq, Eq)]
|
||||
pub struct StoreError;
|
||||
|
||||
/// Unhandled block transfer trap
|
||||
#[derive(Clone, Copy, Display, Debug, PartialEq, Eq)]
|
||||
pub enum BlkCopyError {
|
||||
pub enum MemoryAccessReason {
|
||||
Load,
|
||||
Store,
|
||||
}
|
||||
|
||||
impl From<MemoryAccessReason> for VmRunError {
|
||||
fn from(value: MemoryAccessReason) -> Self {
|
||||
match value {
|
||||
MemoryAccessReason::Load => Self::LoadAccessEx,
|
||||
MemoryAccessReason::Store => Self::StoreAccessEx,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<LoadError> for VmRunError {
|
||||
fn from(_: LoadError) -> Self {
|
||||
Self::LoadAccessEx
|
||||
|
@ -390,12 +404,3 @@ impl From<StoreError> for VmRunError {
|
|||
Self::StoreAccessEx
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BlkCopyError> for VmRunError {
|
||||
fn from(value: BlkCopyError) -> Self {
|
||||
match value {
|
||||
BlkCopyError::Load => Self::LoadAccessEx,
|
||||
BlkCopyError::Store => Self::StoreAccessEx,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
use super::{
|
||||
mem::{Memory, PageSize},
|
||||
mem::{Memory, MemoryAccessReason, PageSize},
|
||||
value::Value,
|
||||
};
|
||||
|
||||
/// Handle VM traps
|
||||
pub trait HandleTrap {
|
||||
/// Handle page fault
|
||||
fn page_fault(&mut self, memory: &mut Memory, addr: u64, size: PageSize, dst: *mut u8) -> bool;
|
||||
fn page_fault(
|
||||
&mut self,
|
||||
reason: MemoryAccessReason,
|
||||
memory: &mut Memory,
|
||||
vaddr: u64,
|
||||
size: PageSize,
|
||||
dataptr: *mut u8,
|
||||
) -> bool;
|
||||
|
||||
/// Handle invalid opcode exception
|
||||
fn invalid_op(
|
||||
|
|
Loading…
Reference in a new issue