ableos/kernel/src/holeybytes/mod.rs

123 lines
3.3 KiB
Rust
Raw Normal View History

2023-10-27 20:26:04 -05:00
mod ecah;
mod mem;
2023-08-22 08:52:30 -05:00
use {
2023-10-23 09:12:43 -05:00
crate::{arch, ipc::buffer::IpcBuffer, kmain::IPC_BUFFERS},
2023-08-22 08:52:30 -05:00
alloc::boxed::Box,
2023-11-15 12:37:52 -06:00
core::{default, future::Future, marker::PhantomData, ptr::NonNull, task::Poll},
2023-08-22 08:57:57 -05:00
hbvm::{
mem::{
softpaging::{icache::ICache, HandlePageFault, SoftPagedMem},
2023-10-23 09:12:43 -05:00
Address, Memory,
2023-08-22 08:57:57 -05:00
},
2023-10-27 20:26:04 -05:00
VmRunError, VmRunOk,
2023-08-22 08:57:57 -05:00
},
2023-10-25 08:36:12 -05:00
log::{debug, error, info, trace, warn},
2023-08-22 08:52:30 -05:00
};
2023-11-15 12:37:52 -06:00
const STACK_SIZE: usize = 1024 * 1024;
2023-08-22 08:52:30 -05:00
const TIMER_QUOTIENT: usize = 100;
2023-10-27 20:26:04 -05:00
type Vm = hbvm::Vm<mem::Memory, TIMER_QUOTIENT>;
2023-08-22 08:52:30 -05:00
pub struct ExecThread<'p> {
2023-10-27 20:26:04 -05:00
vm: Vm,
2023-11-15 12:33:21 -06:00
stack_top: *mut u8,
2023-10-27 20:26:04 -05:00
_phantom: PhantomData<&'p [u8]>,
2023-08-22 08:52:30 -05:00
}
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);
}
2023-08-22 08:52:30 -05:00
pub unsafe fn new(program: &'p [u8], entrypoint: Address) -> Self {
2023-11-15 12:33:21 -06:00
let mut vm = unsafe {
Vm::new(
mem::Memory,
Address::new(program.as_ptr() as u64 + entrypoint.get()),
)
};
2023-11-15 12:37:52 -06:00
let stack_top = unsafe { allocate_stack().as_ptr().add(STACK_SIZE - 1) };
2023-11-15 12:33:21 -06:00
vm.write_reg(254, stack_top as u64);
2023-08-22 08:52:30 -05:00
ExecThread {
2023-11-15 12:33:21 -06:00
vm,
stack_top,
2023-10-27 20:26:04 -05:00
_phantom: Default::default(),
2023-08-22 08:52:30 -05:00
}
}
}
2023-11-15 12:33:21 -06:00
impl<'p> Drop for ExecThread<'p> {
fn drop(&mut self) {
2023-11-15 12:37:52 -06:00
unsafe { alloc::alloc::dealloc(self.stack_top.sub(STACK_SIZE - 1), stack_layout()) };
2023-11-15 12:33:21 -06:00
}
}
2023-08-22 08:52:30 -05:00
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) => {
2023-10-27 20:26:04 -05:00
log::error!("HBVM Error\r\nRegister dump: {:?}", self.vm.registers,);
return Poll::Ready(Err(err));
}
2023-08-22 08:52:30 -05:00
Ok(VmRunOk::End) => return Poll::Ready(Ok(())),
2023-10-27 20:26:04 -05:00
Ok(VmRunOk::Ecall) => ecah::handler(&mut self.vm),
2023-08-22 08:52:30 -05:00
Ok(VmRunOk::Timer) => (),
2023-10-27 20:26:04 -05:00
Ok(VmRunOk::Breakpoint) => {
log::error!(
"HBVM Debug breakpoint\r\nRegister dump: {:?}",
self.vm.registers,
);
}
2023-08-22 08:52:30 -05:00
}
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
}
}
2023-11-15 12:33:21 -06:00
const fn stack_layout() -> core::alloc::Layout {
2023-11-15 12:37:52 -06:00
unsafe { alloc::alloc::Layout::from_size_align_unchecked(STACK_SIZE, 4096) }
2023-11-15 12:33:21 -06:00
}
fn allocate_stack() -> NonNull<u8> {
let layout = stack_layout();
match NonNull::new(unsafe { alloc::alloc::alloc_zeroed(layout) }) {
Some(ptr) => ptr,
None => alloc::alloc::handle_alloc_error(layout),
}
}