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