ableos/kernel/src/holeybytes/ecah.rs

134 lines
3.8 KiB
Rust

//! Environment call handling routines
use {
super::{mem::Memory, Vm},
crate::{arch, ipc::buffer::IpcBuffer, kmain::IPC_BUFFERS},
alloc::string::String,
log::{debug, error, info, trace, warn},
};
pub fn handler(vm: &mut Vm) {
let r1 = vm.registers[1].cast::<u64>();
// debug!("Ecall number {:?}", r1);
// trace!("Register dump: {:?}", vm.registers);
match r1 {
0 => {
// TODO: explode computer
// hello world ecall
for x in 0u64..=255 {
vm.registers[x as usize] = x.into();
}
}
1 => {
// Make buffer
let bounded = match vm.registers[2].cast::<u64>() {
0 => false,
1 => true,
_ => {
panic!("Bad");
}
};
let length = vm.registers[3].cast::<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);
vm.registers[1] = hbvm::value::Value(buff_id);
}
2 => {
// Delete buffer
}
3 => {
// Send a message to a buffer
let r2 = vm.registers[2].cast::<u64>();
let r3 = vm.registers[3].cast::<u64>();
let r4 = vm.registers[4].cast::<u64>();
let buffer_id = r2;
let mem_addr = r3;
let length = r4 as usize;
trace!("IPC address: {:?}", mem_addr);
use alloc::vec::Vec;
match buffer_id {
1 => {
log_msg_handler(vm, mem_addr, length);
}
buffer_id => {
let mut buffs = IPC_BUFFERS.lock();
let mut buff = buffs.get_mut(&buffer_id).unwrap();
let mut msg_vec = vec![];
for x in 0..(length as isize) {
let xyz = mem_addr as *const u8;
let value = unsafe { xyz.offset(x).read() };
msg_vec.push(value);
}
buff.push(msg_vec.clone());
info!("Message {:?} has been sent to {}", msg_vec, buffer_id);
drop(buffs);
}
}
}
4 => {
let r2 = vm.registers[2].cast::<u64>();
let mut buffs = IPC_BUFFERS.lock();
let mut buff = buffs.get_mut(&r2).unwrap();
let msg = buff.pop();
info!("Recieve {:?} from Buffer({})", msg, r2);
}
// 5
_ => {
log::error!("Syscall unknown {:?}", r1);
}
}
}
fn log_msg_handler(vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> {
// let message_length = 8 + 8 + 8;
let mut msg_vec = vec![];
for x in 0..(length as isize) {
let xyz = mem_addr as *const u8;
let value = unsafe { xyz.offset(x).read() };
// info!("{} - {:x?} - {}", value, value, value as char);
msg_vec.push(value);
}
let log_level = msg_vec.pop().unwrap();
let strr = String::from_utf8(msg_vec).unwrap();
// info!("{}", strr);
// use LogLevel::*;
let ll = match log_level {
48 => error!("{}", strr),
49 => warn!("{}", strr),
50 => info!("{}", strr),
51 => debug!("{}", strr),
52 => trace!("{}", strr),
_ => return Err(LogError::InvalidLogFormat),
};
Ok(())
}
#[derive(Debug)]
pub enum LogError {
InvalidLogFormat,
}
use {alloc::vec, log::Record};