use { alloc::boxed::Box, core::{default, future::Future, task::Poll}, hbvm::{ mem::{ softpaging::{icache::ICache, HandlePageFault, SoftPagedMem}, Address, }, Vm, VmRunError, VmRunOk, }, }; const TIMER_QUOTIENT: usize = 100; pub struct ExecThread<'p> { vm: Vm, TIMER_QUOTIENT>, } unsafe impl<'p> Send for ExecThread<'p> {} impl<'p> ExecThread<'p> { pub unsafe fn new(program: &'p [u8], entrypoint: Address) -> Self { ExecThread { vm: unsafe { Vm::new( SoftPagedMem { root_pt: Box::into_raw(Box::default()), pf_handler: PageFaultHandler, program, icache: ICache::default(), }, entrypoint, ) }, } } } 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 Register dump: {:?}", self.vm.registers ); return Poll::Ready(Err(err)); } Ok(VmRunOk::End) => return Poll::Ready(Ok(())), Ok(VmRunOk::Ecall) => { let r255 = self.vm.registers[255]; let r254 = self.vm.registers[254]; let r253 = self.vm.registers[253]; log::debug!("Ecall number {:?}", r255); log::trace!("Register dump: {:?}", self.vm.registers); match r255.cast::() { 0 => { // TODO: explode computer // hello world ecall for x in 0u64..=255 { self.vm.registers[x as usize] = x.into(); } } 1 => { // Make buffer log::trace!( "bounded: {}\n\r length: {:?}", match unsafe { r254.u64 } { 0 => { false } 1 => { true } _ => { // TODO: throw this back to the runtime panic!("Bad"); } }, r253 ) } 2 => { // Delete buffer log::warn!("Syscall 2"); } 3 => { log::warn!("Syscall 3"); } 4 => { log::warn!("Syscall 4"); } _ => { log::error!("Syscall unknown {:?}", r255) } } } Ok(VmRunOk::Timer) => (), } 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 } }