stores
This commit is contained in:
parent
2e6e6b7939
commit
c873945681
35
Cargo.lock
generated
35
Cargo.lock
generated
|
@ -29,12 +29,6 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
name = "compiler"
|
name = "compiler"
|
||||||
version = "0.1.0"
|
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]]
|
[[package]]
|
||||||
name = "delegate"
|
name = "delegate"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
|
@ -46,19 +40,6 @@ dependencies = [
|
||||||
"syn 1.0.109",
|
"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]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
|
@ -93,7 +74,6 @@ name = "hbvm"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"delegate",
|
"delegate",
|
||||||
"derive_more",
|
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
"hbbytecode",
|
"hbbytecode",
|
||||||
"log",
|
"log",
|
||||||
|
@ -186,21 +166,6 @@ version = "0.6.29"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
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]]
|
[[package]]
|
||||||
name = "static_assertions"
|
name = "static_assertions"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
|
|
@ -8,7 +8,6 @@ lto = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
delegate = "0.9"
|
delegate = "0.9"
|
||||||
derive_more = "0.99"
|
|
||||||
hashbrown = "0.13"
|
hashbrown = "0.13"
|
||||||
hbbytecode.path = "../hbbytecode"
|
hbbytecode.path = "../hbbytecode"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
|
|
@ -57,6 +57,49 @@ impl Memory {
|
||||||
|
|
||||||
/// Load value from an address
|
/// Load value from an address
|
||||||
pub fn load<S: MemAccessSize>(&self, addr: u64) -> Option<Value> {
|
pub fn load<S: MemAccessSize>(&self, addr: u64) -> Option<Value> {
|
||||||
|
let lookup = self.page_lookup(addr)?;
|
||||||
|
match lookup.perm {
|
||||||
|
Permission::Empty | Permission::Node => None,
|
||||||
|
Permission::Readonly | Permission::Write | Permission::Exec => {
|
||||||
|
let mut value = MaybeUninit::<Value>::zeroed();
|
||||||
|
unsafe {
|
||||||
|
core::ptr::copy_nonoverlapping::<u8>(lookup.ptr, value.as_mut_ptr().cast(), 1);
|
||||||
|
Some(value.assume_init())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Store value to an address
|
||||||
|
pub fn store<S: MemAccessSize>(&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::<u8>(
|
||||||
|
(&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<PageLookupResult> {
|
||||||
let mut current_pt = self.root_pt;
|
let mut current_pt = self.root_pt;
|
||||||
for lvl in (0..5).rev() {
|
for lvl in (0..5).rev() {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -69,36 +112,32 @@ impl Memory {
|
||||||
match entry.permission() {
|
match entry.permission() {
|
||||||
Permission::Empty => return None,
|
Permission::Empty => return None,
|
||||||
Permission::Node => current_pt = ptr as _,
|
Permission::Node => current_pt = ptr as _,
|
||||||
Permission::Readonly | Permission::Write | Permission::Exec => {
|
_ if lvl > 2 => return None,
|
||||||
let mut value = MaybeUninit::<Value>::zeroed();
|
perm => {
|
||||||
core::ptr::copy_nonoverlapping::<u8>(
|
return Some(PageLookupResult {
|
||||||
entry.ptr() as _,
|
perm,
|
||||||
value.as_mut_ptr().cast(),
|
ptr: ptr as _,
|
||||||
1,
|
size: match lvl {
|
||||||
);
|
0 => 4096,
|
||||||
return Some(value.assume_init());
|
1 => 1024_usize.pow(2) * 2,
|
||||||
|
2 => 4096_usize.pow(3),
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
|
offset: addr as usize & ((1 << 12) - 1),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Store value to an address
|
struct PageLookupResult {
|
||||||
pub fn store<S: MemAccessSize>(&mut self, addr: u64, value: Value) -> Result<(), ()> {
|
perm: Permission,
|
||||||
Err(())
|
ptr: *mut u8,
|
||||||
}
|
size: usize,
|
||||||
|
offset: usize,
|
||||||
#[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 }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! size_markers {
|
macro_rules! size_markers {
|
||||||
|
|
|
@ -5,7 +5,6 @@ use core::{
|
||||||
slice::SliceIndex,
|
slice::SliceIndex,
|
||||||
};
|
};
|
||||||
use delegate::delegate;
|
use delegate::delegate;
|
||||||
use derive_more::{Deref, DerefMut};
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
||||||
#[repr(u8)]
|
#[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)]
|
#[derive(Clone, Copy)]
|
||||||
#[repr(C)]
|
#[repr(C, align(4096))]
|
||||||
pub union PtPointedData {
|
pub union PtPointedData {
|
||||||
pub pt: PageTable,
|
pub pt: PageTable,
|
||||||
pub page: SpecialByte,
|
pub page: u8,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue