forked from AbleOS/ableos
186 lines
5.9 KiB
Rust
186 lines
5.9 KiB
Rust
//! Environment call handling routines
|
|
|
|
use crate::allocator;
|
|
|
|
use {
|
|
super::{mem::Memory, Vm},
|
|
crate::{arch, holeybytes::mem, 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 => match log_msg_handler(vm, mem_addr, length) {
|
|
Ok(()) => {}
|
|
Err(err) => log::error!("Improper log format"),
|
|
},
|
|
2 => match memory_msg_handler(vm, mem_addr, length) {
|
|
Ok(()) => {
|
|
let free_chunks = allocator::get_free_chunks_count();
|
|
debug!("Free chunk count: {}", free_chunks);
|
|
}
|
|
Err(err) => log::error!("Improper log format"),
|
|
},
|
|
buffer_id => {
|
|
let mut buffs = IPC_BUFFERS.lock();
|
|
|
|
match buffs.get_mut(&buffer_id) {
|
|
Some(buff) => {
|
|
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 Buffer({})",
|
|
msg_vec, buffer_id
|
|
);
|
|
}
|
|
None => {
|
|
log::error!("Access of non-existent buffer {}", 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 => {
|
|
#[cfg(target_arch = "x86_64")]
|
|
{
|
|
let r2 = vm.registers[2].cast::<u64>();
|
|
unsafe fn x86_in(address: u16) -> u32 {
|
|
x86_64::instructions::port::Port::new(address).read()
|
|
}
|
|
unsafe fn x86_out(address: u16, value: u32) {
|
|
x86_64::instructions::port::Port::new(address).write(value);
|
|
}
|
|
vm.registers[3] = hbvm::value::Value(unsafe { x86_in(r2 as u16) } as u64);
|
|
}
|
|
}
|
|
// 5
|
|
_ => {
|
|
log::error!("Syscall unknown {:?}{:?}", r1, vm.registers);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn log_msg_handler(vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> {
|
|
// let message_length = 8 + 8 + 8;
|
|
// log::info!("Mem Addr 0x{:x?} length {}", mem_addr, length);
|
|
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!("{} - 0x{:x?} - {}", value, value, value as char);
|
|
msg_vec.push(value);
|
|
}
|
|
let log_level = msg_vec.pop().unwrap();
|
|
match String::from_utf8(msg_vec) {
|
|
Ok(strr) => {
|
|
// use LogLevel::*;
|
|
let ll = match log_level {
|
|
0 | 48 => error!("{}", strr),
|
|
1 | 49 => warn!("{}", strr),
|
|
2 | 50 => info!("{}", strr),
|
|
3 | 51 => debug!("{}", strr),
|
|
4 | 52 => trace!("{}", strr),
|
|
_ => {
|
|
return Err(LogError::InvalidLogFormat);
|
|
}
|
|
};
|
|
}
|
|
Err(e) => {
|
|
error!("{:?}", e);
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum LogError {
|
|
InvalidLogFormat,
|
|
}
|
|
use {alloc::vec, log::Record};
|
|
|
|
fn memory_msg_handler(vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> {
|
|
let mut val = alloc::vec::Vec::new();
|
|
for _ in 0..4096 {
|
|
val.push(0);
|
|
}
|
|
info!("Block address: {:?}", val.as_ptr());
|
|
vm.registers[1] = hbvm::value::Value(val.as_ptr() as u64);
|
|
vm.registers[2] = hbvm::value::Value(4096);
|
|
Ok(())
|
|
}
|