use { crate::holeybytes::{ ecah::LogError, kernel_services::{block_read, mem_serve}, Vm, }, alloc::alloc::alloc_zeroed, log::{debug, info}, }; pub enum MemoryServiceError { InvalidMemoryFormat, } #[derive(Debug)] pub enum MemoryQuotaType { NoQuota = 0, SoftQuota = 1, HardQuota = 2, KillQuota = 3, } fn alloc_page(vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), MemoryServiceError> { let mut val = alloc::vec::Vec::new(); for _ in 0..4096 { val.push(0); } info!("Block address: {:?}", val.as_ptr()); vm.registers[1] = hbvm::value::Value(val.as_ptr() as u64); vm.registers[2] = hbvm::value::Value(4096); Ok(()) } pub fn memory_msg_handler( vm: &mut Vm, mem_addr: u64, length: usize, ) -> Result<(), MemoryServiceError> { let mut msg_vec = block_read(mem_addr, length); let msg_type = msg_vec[0]; msg_vec.remove(0); match msg_type { 0 => { let page_count = msg_vec[0]; msg_vec.remove(0); let mptr_raw: [u8; 8] = msg_vec[0..8].try_into().unwrap(); let mptr: u64 = u64::from_le_bytes(mptr_raw); log::debug!("Allocating {} pages @ {:x}", page_count, mptr); let mut val = alloc::vec::Vec::new(); for _ in 0..(page_count as isize * 4096) { val.push(0); } vm.registers[1] = hbvm::value::Value(val.as_ptr() as u64); } 1 => { let page_count = msg_vec[0]; msg_vec.remove(0); } 2 => { use MemoryQuotaType::*; let quota_type = match msg_vec[0] { 0 => NoQuota, 1 => SoftQuota, 2 => HardQuota, 3 => KillQuota, _ => NoQuota, }; msg_vec.remove(0); let hid_raw: [u8; 8] = msg_vec[0..8].try_into().unwrap(); let hid: u64 = u64::from_le_bytes(hid_raw); for _ in 0..8 { msg_vec.remove(0); } let pid_raw: [u8; 8] = msg_vec[0..8].try_into().unwrap(); let pid: u64 = u64::from_le_bytes(hid_raw); for _ in 0..8 { msg_vec.remove(0); } debug!( "Setting HID-{:x}:PID-{:x}'s quota type to {:?}", hid, pid, quota_type ) } 3 => { let page_count = msg_vec[0]; log::debug!(" {} pages", page_count); msg_vec.remove(0); } _ => { log::debug!("Unknown memory service message type: {}", msg_type); } } Ok(()) }