ableos/kernel/src/holeybytes/mod.rs

167 lines
5.2 KiB
Rust

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, error, info, trace, warn},
};
const TIMER_QUOTIENT: usize = 100;
pub struct ExecThread<'p> {
vm: Vm<SoftPagedMem<'p, PageFaultHandler, true>, 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<Self::Output> {
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];
debug!("Ecall number {:?}", r255);
trace!("Register dump: {:?}", self.vm.registers);
match r255.cast::<u64>() {
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!("IPC address: {:?}", mem_addr);
use alloc::vec::Vec;
match buffer_id {
1 => {
error!("Logging via IPC isn't quite ready")
}
buffer_id => {
info!("Message has been sent to {}", buffer_id)
}
}
}
// 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
}
}