use { crate::{arch, ipc::buffer::IpcBuffer, kmain::IPC_BUFFERS}, alloc::boxed::Box, core::{default, future::Future, task::Poll}, hbvm::{ mem::{ softpaging::{icache::ICache, HandlePageFault, SoftPagedMem}, Address, Memory, }, Vm, VmRunError, VmRunOk, }, log::{debug, info, trace, warn}, }; 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 let r255 = self.vm.registers[255]; let r254 = self.vm.registers[254]; let r253 = self.vm.registers[253]; let bounded = match unsafe { r254.u64 } { 0 => false, 1 => true, _ => { panic!("Bad"); } }; let length = unsafe { r254.u64 }; let mut buffs = IPC_BUFFERS.lock(); let abc; match bounded { false => { abc = IpcBuffer::new(false, 0); } true => { abc = IpcBuffer::new(true, length); } }; let buff_id = arch::hardware_random_u64(); buffs.insert(buff_id, abc); debug!("Buffer ID: {}", buff_id); } 2 => { // Delete buffer } 3 => { // Send a message to a buffer let r254 = self.vm.registers[254]; let r253 = self.vm.registers[253]; let r252 = self.vm.registers[252]; let buffer_id = unsafe { r254.u64 }; let mem_addr = unsafe { r253.u64 }; let length = unsafe { r252.u64 as usize }; trace!("{:?}", mem_addr); use alloc::vec::Vec; if buffer_id == 1 { info!("Logging") } } // 4 // 5 _ => { 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 } }