//! 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::(); 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::() { 0 => false, 1 => true, _ => { panic!("Bad"); } }; let length = vm.registers[3].cast::(); 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 r2 = vm.registers[2].cast::(); let r3 = vm.registers[3].cast::(); let r4 = vm.registers[4].cast::(); 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); error!("Logging via IPC isn't quite ready") } buffer_id => { info!("Message has been sent to {}", buffer_id) } } } // 4 // 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..(message_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); } // use LogLevel::*; // let log_level = match bytes[0] { // 0 => Error, // 2 => Info, // _ => return Err(LogError::InvalidLogFormat), // }; // println!("Log Level {:?}", log_level); // let mut msg_ptr_arr = [0u8; 8]; // msg_ptr_arr.copy_from_slice(&bytes[8..=15]); // let msg_ptr = u64::from_le_bytes(msg_ptr_arr) as *const u8; // info!("bytes ptr: {:?}", msg_ptr); // let mut msg_len_arr = [0u8; 8]; // msg_len_arr.copy_from_slice(&bytes[16..=23]); // let msg_len = usize::from_le_bytes(msg_len_arr); // info!("MSG Len: {}", msg_len); // let mut str_vec = vec![]; // for offset in 0..(msg_len as isize) { // let value = unsafe { msg_ptr.offset(offset).read() }; // info!("{} - {}", value, value as char); // str_vec.push(value); // } // let log_message = String::from_utf8(str_vec).unwrap(); // info!("{}", log_message); Ok(()) } pub enum LogError { InvalidLogFormat, } use alloc::vec;