2023-05-09 03:36:37 -05:00
|
|
|
use crate::engine::VMPage;
|
2023-04-22 17:17:49 -05:00
|
|
|
|
2023-05-09 03:36:37 -05:00
|
|
|
use {
|
|
|
|
crate::{engine::Page, RuntimeErrors},
|
|
|
|
alloc::vec::Vec,
|
|
|
|
hashbrown::HashMap,
|
|
|
|
log::trace,
|
|
|
|
};
|
2023-04-22 17:17:49 -05:00
|
|
|
|
2023-04-22 16:06:33 -05:00
|
|
|
pub struct Memory {
|
2023-04-22 17:17:49 -05:00
|
|
|
inner: HashMap<u64, Page>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Memory {
|
|
|
|
pub fn new() -> Self {
|
|
|
|
Self {
|
|
|
|
inner: HashMap::new(),
|
|
|
|
}
|
2023-05-09 03:36:37 -05:00
|
|
|
//
|
2023-04-22 17:17:49 -05:00
|
|
|
}
|
|
|
|
|
2023-05-09 03:36:37 -05:00
|
|
|
pub fn map_vec(&mut self, address: u64, vec: Vec<u8>) {
|
|
|
|
panic!("Mapping vectors into pages is not supported yet");
|
|
|
|
}
|
2023-04-22 16:06:33 -05:00
|
|
|
}
|
2023-04-22 17:17:49 -05:00
|
|
|
|
2023-04-22 16:06:33 -05:00
|
|
|
impl Memory {
|
2023-04-22 17:17:49 -05:00
|
|
|
pub fn read_addr8(&mut self, address: u64) -> Result<u8, RuntimeErrors> {
|
|
|
|
let (page, offset) = addr_to_page(address);
|
2023-05-06 07:33:40 -05:00
|
|
|
trace!("page {} offset {}", page, offset);
|
2023-04-22 17:47:01 -05:00
|
|
|
match self.inner.get(&page) {
|
|
|
|
Some(page) => {
|
2023-05-09 03:36:37 -05:00
|
|
|
let val = page.data()[offset as usize];
|
2023-05-06 07:33:40 -05:00
|
|
|
trace!("Value {}", val);
|
2023-04-22 17:47:01 -05:00
|
|
|
Ok(val)
|
|
|
|
}
|
2023-05-06 07:33:40 -05:00
|
|
|
None => {
|
|
|
|
trace!("page not mapped");
|
|
|
|
Err(RuntimeErrors::PageNotMapped(page))
|
|
|
|
}
|
2023-04-22 17:47:01 -05:00
|
|
|
}
|
2023-04-22 16:06:33 -05:00
|
|
|
}
|
|
|
|
pub fn read_addr64(&mut self, address: u64) -> u64 {
|
2023-04-22 17:17:49 -05:00
|
|
|
unimplemented!()
|
2023-04-22 16:06:33 -05:00
|
|
|
}
|
|
|
|
|
2023-04-22 17:47:01 -05:00
|
|
|
pub fn set_addr8(&mut self, address: u64, value: u8) -> Result<(), RuntimeErrors> {
|
|
|
|
let (page, offset) = addr_to_page(address);
|
|
|
|
let ret: Option<(&u64, &mut Page)> = self.inner.get_key_value_mut(&page);
|
|
|
|
match ret {
|
|
|
|
Some((_, page)) => {
|
2023-05-09 03:36:37 -05:00
|
|
|
page.data()[offset as usize] = value;
|
2023-04-22 17:47:01 -05:00
|
|
|
}
|
|
|
|
None => {
|
2023-05-09 03:36:37 -05:00
|
|
|
let mut pg = VMPage::new();
|
2023-04-22 17:47:01 -05:00
|
|
|
pg.data[offset as usize] = value;
|
2023-05-09 03:36:37 -05:00
|
|
|
self.inner.insert(page, Page::VMPage(pg));
|
|
|
|
trace!("Mapped page {}", page);
|
2023-04-22 17:47:01 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
2023-04-22 16:06:33 -05:00
|
|
|
}
|
2023-05-24 08:07:29 -05:00
|
|
|
pub fn set_addr64(&mut self, address: u64, value: u64) -> Result<(), RuntimeErrors> {
|
2023-04-22 17:17:49 -05:00
|
|
|
unimplemented!()
|
2023-04-22 16:06:33 -05:00
|
|
|
}
|
|
|
|
}
|
2023-04-22 17:17:49 -05:00
|
|
|
|
|
|
|
fn addr_to_page(addr: u64) -> (u64, u64) {
|
|
|
|
(addr / 8192, addr % 8192)
|
|
|
|
}
|