use crate::kmain::IPC_BUFFERS; use { alloc::boxed::Box, core::{default, future::Future, task::Poll}, hbvm::{ mem::{ softpaging::{icache::ICache, HandlePageFault, SoftPagedMem}, Address, }, Vm, VmRunError, VmRunOk, }, }; mod ecalls; 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 ecalls::make_ipc_buffer(self.vm.registers); } 2 => { // Delete buffer ecalls::delete_ipc_buffer(self.vm.registers); } _ => { 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 } }