1
0
Fork 0
forked from AbleOS/ableos
ableos/kernel/src/holeybytes/ecah.rs

203 lines
6.5 KiB
Rust
Raw Normal View History

2023-10-27 20:26:04 -05:00
//! Environment call handling routines
2024-03-22 03:58:59 -05:00
use core::borrow::Borrow;
use crate::{
allocator,
holeybytes::kernel_services::{
block_read,
service_definition_service::{sds_msg_handler, SERVICES},
},
};
2024-02-15 14:21:00 -06:00
2023-10-27 20:26:04 -05:00
use {
super::{mem::Memory, Vm},
crate::{arch, holeybytes::mem, ipc::buffer::IpcBuffer, kmain::IPC_BUFFERS},
alloc::string::String,
2023-10-27 20:26:04 -05:00
log::{debug, error, info, trace, warn},
};
pub fn handler(vm: &mut Vm) {
2024-05-31 09:15:55 -05:00
let ecall_number = vm.registers[2].cast::<u64>();
2023-10-27 20:26:04 -05:00
2024-05-31 09:15:55 -05:00
// debug!("Ecall number {:?}", ecall_number);
// trace!("Register dump: {:?}", vm.registers);
2023-10-27 20:26:04 -05:00
2024-05-31 09:15:55 -05:00
match ecall_number {
2023-10-27 20:26:04 -05:00
0 => {
// TODO: explode computer
// hello world ecall
for x in 0u64..=255 {
vm.registers[x as usize] = x.into();
}
}
1 => {
// Make buffer
2024-05-31 09:15:55 -05:00
let bounded = match vm.registers[3].cast::<u64>() {
2023-10-27 20:26:04 -05:00
0 => false,
1 => true,
_ => {
panic!("Bad");
}
};
2024-05-31 09:15:55 -05:00
let length = vm.registers[4].cast::<u64>();
2023-10-27 20:26:04 -05:00
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);
2023-10-27 20:26:04 -05:00
}
2 => {
// Delete buffer
}
3 => {
// Send a message to a buffer
2024-05-31 09:15:55 -05:00
let buffer_id = vm.registers[3].cast::<u64>();
let mem_addr = vm.registers[4].cast::<u64>();
let length = vm.registers[5].cast::<u64>() as usize;
2024-07-06 09:24:23 -05:00
// debug!("IPC address: {:?}", mem_addr);
2023-10-27 20:26:04 -05:00
use alloc::vec::Vec;
match buffer_id {
2024-03-22 03:58:59 -05:00
0 => match sds_msg_handler(vm, mem_addr, length) {
Ok(()) => {}
Err(err) => log::error!("Improper sds format"),
},
1 => match log_msg_handler(vm, mem_addr, length) {
Ok(()) => {}
Err(err) => log::error!("Improper log format"),
},
2024-03-11 09:48:56 -05:00
2 => {
use crate::holeybytes::kernel_services::mem_serve::memory_msg_handler;
match memory_msg_handler(vm, mem_addr, length) {
Ok(_) => {}
Err(_) => {}
2024-02-15 14:21:00 -06:00
}
2024-03-11 09:48:56 -05:00
//
}
2023-10-27 20:26:04 -05:00
buffer_id => {
let mut buffs = IPC_BUFFERS.lock();
2023-12-01 08:48:57 -06:00
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
);
}
2023-12-01 09:02:56 -06:00
None => {
log::error!("Access of non-existent buffer {}", buffer_id)
}
}
drop(buffs);
2023-10-27 20:26:04 -05:00
}
}
}
4 => {
2024-05-31 09:15:55 -05:00
let buffer_id = vm.registers[3].cast::<u64>();
2024-07-07 08:35:07 -05:00
let mut map_ptr = vm.registers[4].cast::<u64>();
let max_length = vm.registers[5].cast::<u64>();
let mut buffs = IPC_BUFFERS.lock();
2024-05-31 09:15:55 -05:00
let mut buff = buffs.get_mut(&buffer_id).unwrap();
let msg = buff.pop();
2024-07-07 08:35:07 -05:00
if msg.len() > max_length.try_into().unwrap() {
info!("{}", max_length);
error!("Message is too long to map in.");
} else {
unsafe {
let ptr: *mut u64 = &mut map_ptr;
for (index, byte) in msg.iter().enumerate() {
ptr.offset(index.try_into().unwrap()).write_bytes(*byte, 1);
}
}
info!("Recieve {:?} from Buffer({})", msg, buffer_id);
}
}
2023-12-04 23:56:23 -06:00
5 => {
2023-12-13 04:21:32 -06:00
#[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);
}
2023-12-04 23:56:23 -06:00
}
2023-10-27 20:26:04 -05:00
// 5
_ => {
2024-05-31 09:15:55 -05:00
log::error!("Syscall unknown {:?}{:?}", ecall_number, vm.registers);
2023-10-27 20:26:04 -05:00
}
}
}
fn log_msg_handler(vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> {
// let message_length = 8 + 8 + 8;
2023-11-19 18:15:03 -06:00
// log::info!("Mem Addr 0x{:x?} length {}", mem_addr, length);
2024-03-22 03:58:59 -05:00
let mut msg_vec = block_read(mem_addr, length);
let log_level = msg_vec.pop().unwrap();
2023-12-04 23:56:23 -06:00
match String::from_utf8(msg_vec) {
2023-12-13 04:21:32 -06:00
Ok(strr) => {
2023-12-04 23:56:23 -06:00
// 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);
}
};
}
2023-12-04 23:56:23 -06:00
Err(e) => {
error!("{:?}", e);
}
}
Ok(())
}
#[derive(Debug)]
pub enum LogError {
InvalidLogFormat,
}
use {alloc::vec, log::Record};
2024-03-11 09:48:56 -05:00
// 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(())
// }