diff --git a/Cargo.lock b/Cargo.lock index 9657079..0c1a10d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,12 +29,6 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" name = "compiler" version = "0.1.0" -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - [[package]] name = "delegate" version = "0.9.0" @@ -46,19 +40,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "derive_more" -version = "0.99.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn 1.0.109", -] - [[package]] name = "fnv" version = "1.0.7" @@ -93,7 +74,6 @@ name = "hbvm" version = "0.1.0" dependencies = [ "delegate", - "derive_more", "hashbrown", "hbbytecode", "log", @@ -186,21 +166,6 @@ version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] - -[[package]] -name = "semver" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" - [[package]] name = "static_assertions" version = "1.1.0" diff --git a/hbvm/Cargo.toml b/hbvm/Cargo.toml index 48e932f..e4deec3 100644 --- a/hbvm/Cargo.toml +++ b/hbvm/Cargo.toml @@ -8,7 +8,6 @@ lto = true [dependencies] delegate = "0.9" -derive_more = "0.99" hashbrown = "0.13" hbbytecode.path = "../hbbytecode" log = "0.4" diff --git a/hbvm/src/vm/mem/mod.rs b/hbvm/src/vm/mem/mod.rs index afb3d71..3b91add 100644 --- a/hbvm/src/vm/mem/mod.rs +++ b/hbvm/src/vm/mem/mod.rs @@ -57,6 +57,49 @@ impl Memory { /// Load value from an address pub fn load(&self, addr: u64) -> Option { + let lookup = self.page_lookup(addr)?; + match lookup.perm { + Permission::Empty | Permission::Node => None, + Permission::Readonly | Permission::Write | Permission::Exec => { + let mut value = MaybeUninit::::zeroed(); + unsafe { + core::ptr::copy_nonoverlapping::(lookup.ptr, value.as_mut_ptr().cast(), 1); + Some(value.assume_init()) + } + } + } + } + + /// Store value to an address + pub fn store(&mut self, addr: u64, value: Value) -> Result<(), ()> { + let lookup = self.page_lookup(addr).ok_or(())?; + match lookup.perm { + Permission::Write => { + unsafe { + core::ptr::copy_nonoverlapping::( + (&value as *const Value).cast(), + lookup.ptr, + 1, + ) + }; + Ok(()) + } + _ => Err(()), + } + } + + #[inline] + pub fn root_pt(&self) -> &PageTable { + unsafe { &*self.root_pt } + } + + #[inline] + pub fn root_pt_mut(&mut self) -> &mut PageTable { + unsafe { &mut *self.root_pt } + } + + /// Resolve page and offset from the page + fn page_lookup(&self, addr: u64) -> Option { let mut current_pt = self.root_pt; for lvl in (0..5).rev() { unsafe { @@ -69,36 +112,32 @@ impl Memory { match entry.permission() { Permission::Empty => return None, Permission::Node => current_pt = ptr as _, - Permission::Readonly | Permission::Write | Permission::Exec => { - let mut value = MaybeUninit::::zeroed(); - core::ptr::copy_nonoverlapping::( - entry.ptr() as _, - value.as_mut_ptr().cast(), - 1, - ); - return Some(value.assume_init()); + _ if lvl > 2 => return None, + perm => { + return Some(PageLookupResult { + perm, + ptr: ptr as _, + size: match lvl { + 0 => 4096, + 1 => 1024_usize.pow(2) * 2, + 2 => 4096_usize.pow(3), + _ => unreachable!(), + }, + offset: addr as usize & ((1 << 12) - 1), + }) } } } } - None } +} - /// Store value to an address - pub fn store(&mut self, addr: u64, value: Value) -> Result<(), ()> { - Err(()) - } - - #[inline] - pub fn root_pt(&self) -> &PageTable { - unsafe { &*self.root_pt } - } - - #[inline] - pub fn root_pt_mut(&mut self) -> &mut PageTable { - unsafe { &mut *self.root_pt } - } +struct PageLookupResult { + perm: Permission, + ptr: *mut u8, + size: usize, + offset: usize, } macro_rules! size_markers { diff --git a/hbvm/src/vm/mem/paging.rs b/hbvm/src/vm/mem/paging.rs index 05fffce..ae9c0bf 100644 --- a/hbvm/src/vm/mem/paging.rs +++ b/hbvm/src/vm/mem/paging.rs @@ -5,7 +5,6 @@ use core::{ slice::SliceIndex, }; use delegate::delegate; -use derive_more::{Deref, DerefMut}; #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] #[repr(u8)] @@ -94,14 +93,9 @@ impl Default for PageTable { } } -/// This byte is special. It has a whole page reserved just for it. -#[derive(Clone, Copy, PartialEq, Eq, Deref, DerefMut)] -#[repr(align(4096))] -pub struct SpecialByte(u8); - #[derive(Clone, Copy)] -#[repr(C)] +#[repr(C, align(4096))] pub union PtPointedData { pub pt: PageTable, - pub page: SpecialByte, + pub page: u8, }