mod ecah; mod mem; use { crate::{arch, ipc::buffer::IpcBuffer, kmain::IPC_BUFFERS}, alloc::boxed::Box, core::{default, future::Future, marker::PhantomData, task::Poll}, hbvm::{ mem::{ softpaging::{icache::ICache, HandlePageFault, SoftPagedMem}, Address, Memory, }, VmRunError, VmRunOk, }, log::{debug, error, info, trace, warn}, }; const TIMER_QUOTIENT: usize = 100; type Vm = hbvm::Vm; pub struct ExecThread<'p> { vm: Vm, _phantom: PhantomData<&'p [u8]>, } unsafe impl<'p> Send for ExecThread<'p> {} impl<'p> ExecThread<'p> { pub fn set_arguments(&mut self, ptr: u64, length: u64) { self.vm.registers[1] = hbvm::value::Value(ptr); self.vm.registers[2] = hbvm::value::Value(length); } pub unsafe fn new(program: &'p [u8], entrypoint: Address) -> Self { ExecThread { vm: unsafe { Vm::new( mem::Memory, Address::new(program.as_ptr() as u64 + entrypoint.get()), ) }, _phantom: Default::default(), } } } impl<'p> Future for ExecThread<'p> { type Output = Result<(), VmRunError>; fn poll( mut self: core::pin::Pin<&mut Self>, cx: &mut core::task::Context<'_>, ) -> Poll { match self.vm.run() { Err(err) => { log::error!("HBVM Error\r\nRegister dump: {:?}", self.vm.registers,); return Poll::Ready(Err(err)); } Ok(VmRunOk::End) => return Poll::Ready(Ok(())), Ok(VmRunOk::Ecall) => ecah::handler(&mut self.vm), Ok(VmRunOk::Timer) => (), Ok(VmRunOk::Breakpoint) => { log::error!( "HBVM Debug breakpoint\r\nRegister dump: {:?}", self.vm.registers, ); } } cx.waker().wake_by_ref(); Poll::Pending } } struct PageFaultHandler; impl HandlePageFault for PageFaultHandler { fn page_fault( &mut self, reason: hbvm::mem::MemoryAccessReason, pagetable: &mut hbvm::mem::softpaging::paging::PageTable, vaddr: hbvm::mem::Address, size: hbvm::mem::softpaging::PageSize, dataptr: *mut u8, ) -> bool where Self: Sized, { log::error!( "REASON: {reason} \ vaddr: {vaddr} \ size: {size:?} \ Dataptr {dataptr:p}", ); false } }