2023-10-27 20:26:04 -05:00
|
|
|
//! Environment call handling routines
|
2023-11-18 02:17:54 -06:00
|
|
|
|
2024-09-13 16:41:31 -05:00
|
|
|
use crate::holeybytes::kernel_services::{block_read, service_definition_service::sds_msg_handler};
|
2024-02-15 14:21:00 -06:00
|
|
|
|
2023-10-27 20:26:04 -05:00
|
|
|
use {
|
2024-09-13 16:41:31 -05:00
|
|
|
super::Vm,
|
|
|
|
crate::{arch, ipc::buffer::IpcBuffer, kmain::IPC_BUFFERS},
|
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);
|
2024-08-19 13:13:58 -05:00
|
|
|
//info!("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);
|
2024-08-19 13:13:58 -05:00
|
|
|
info!("Buffer ID: {}", buff_id);
|
2023-10-29 07:27:10 -05:00
|
|
|
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-08-12 08:15:50 -05:00
|
|
|
trace!("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(()) => {}
|
2024-09-04 12:14:30 -05:00
|
|
|
Err(err) => log::error!("Improper sds format: {err:?}"),
|
2024-03-22 03:58:59 -05:00
|
|
|
},
|
2023-11-18 02:17:54 -06:00
|
|
|
1 => match log_msg_handler(vm, mem_addr, length) {
|
|
|
|
Ok(()) => {}
|
2024-09-13 16:41:31 -05:00
|
|
|
Err(_) => log::error!("Improper log format"),
|
2023-11-18 02:17:54 -06:00
|
|
|
},
|
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
|
|
|
}
|
2024-09-13 16:41:31 -05:00
|
|
|
#[cfg(not(target_arch = "x86_64"))]
|
|
|
|
3 => info!("TODO: implement whatever buffer 3 does for no x86_64"),
|
|
|
|
#[cfg(target_arch = "x86_64")]
|
2024-07-15 16:56:46 -05:00
|
|
|
3 => {
|
2024-09-13 16:41:31 -05:00
|
|
|
unsafe fn x86_out<T: x86_64::instructions::port::PortWrite>(
|
|
|
|
address: u16,
|
|
|
|
value: T,
|
|
|
|
) {
|
2024-08-31 09:38:15 -05:00
|
|
|
x86_64::instructions::port::Port::new(address).write(value);
|
|
|
|
}
|
2024-09-13 16:41:31 -05:00
|
|
|
unsafe fn x86_in<T: x86_64::instructions::port::PortRead>(address: u16) -> T {
|
|
|
|
x86_64::instructions::port::Port::new(address).read()
|
2024-08-31 09:38:15 -05:00
|
|
|
}
|
2024-09-13 16:41:31 -05:00
|
|
|
let msg_vec = block_read(mem_addr, length);
|
2024-07-15 16:56:46 -05:00
|
|
|
let msg_type = msg_vec[0];
|
|
|
|
match msg_type {
|
2024-08-31 09:38:15 -05:00
|
|
|
0 => 'wow: {
|
|
|
|
let size = match msg_vec[0] {
|
|
|
|
0 => 1,
|
|
|
|
1 => 2,
|
|
|
|
2 => 4,
|
|
|
|
_ => {
|
|
|
|
error!("Tried to write more than 32 bits");
|
|
|
|
break 'wow;
|
|
|
|
}
|
|
|
|
};
|
2024-09-13 16:41:31 -05:00
|
|
|
let addr = u16::from_le_bytes(msg_vec[1..3].try_into().unwrap());
|
2024-08-31 09:38:15 -05:00
|
|
|
let value = unsafe {
|
|
|
|
match size {
|
2024-09-13 16:41:31 -05:00
|
|
|
1 => x86_in::<u8>(addr) as u64,
|
|
|
|
2 => x86_in::<u16>(addr) as u64,
|
|
|
|
4 => x86_in::<u32>(addr) as u64,
|
2024-08-31 09:38:15 -05:00
|
|
|
_ => panic!("how?"),
|
|
|
|
}
|
|
|
|
};
|
2024-08-12 08:15:50 -05:00
|
|
|
trace!("Read the value {} from address {}", value, addr);
|
2024-08-31 09:38:15 -05:00
|
|
|
vm.registers[1] = hbvm::value::Value(value);
|
2024-07-15 16:56:46 -05:00
|
|
|
}
|
2024-08-31 09:38:15 -05:00
|
|
|
1 => 'wow: {
|
2024-09-13 16:41:31 -05:00
|
|
|
let size = match msg_vec[1] {
|
2024-08-31 09:38:15 -05:00
|
|
|
0 => 1,
|
|
|
|
1 => 2,
|
|
|
|
2 => 4,
|
|
|
|
_ => {
|
|
|
|
error!("Tried to write more than 32 bits");
|
|
|
|
break 'wow;
|
|
|
|
}
|
|
|
|
};
|
2024-09-13 16:41:31 -05:00
|
|
|
let addr = unsafe {
|
|
|
|
u16::from_le_bytes(msg_vec[1..3].try_into().unwrap_unchecked())
|
|
|
|
};
|
2024-08-31 09:38:15 -05:00
|
|
|
trace!("Setting address {}", addr);
|
|
|
|
unsafe {
|
|
|
|
match size {
|
2024-09-13 16:41:31 -05:00
|
|
|
1 => x86_out(addr, msg_vec[3]),
|
|
|
|
2 => x86_out(
|
2024-08-31 09:38:15 -05:00
|
|
|
addr,
|
2024-09-13 16:41:31 -05:00
|
|
|
u16::from_le_bytes(
|
|
|
|
msg_vec[3..5].try_into().unwrap_unchecked(),
|
|
|
|
),
|
2024-08-31 09:38:15 -05:00
|
|
|
),
|
2024-09-13 16:41:31 -05:00
|
|
|
4 => x86_out(
|
2024-08-31 09:38:15 -05:00
|
|
|
addr,
|
2024-09-13 16:41:31 -05:00
|
|
|
u32::from_le_bytes(
|
|
|
|
msg_vec[3..7].try_into().unwrap_unchecked(),
|
|
|
|
),
|
2024-08-31 09:38:15 -05:00
|
|
|
),
|
|
|
|
_ => panic!("How?"),
|
|
|
|
}
|
|
|
|
}
|
2024-07-15 16:56:46 -05:00
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
2024-08-29 15:37:49 -05:00
|
|
|
// source of rng
|
|
|
|
4 => {
|
2024-09-13 16:41:31 -05:00
|
|
|
// limit to last 32 bits
|
|
|
|
vm.registers[1] =
|
|
|
|
hbvm::value::Value(crate::arch::hardware_random_u64() & 0xFFFFFFFF);
|
|
|
|
}
|
|
|
|
// get arch
|
|
|
|
5 => {
|
|
|
|
if cfg!(target_arch = "x86_64") {
|
|
|
|
vm.registers[1] = hbvm::value::Value(0);
|
|
|
|
} else if cfg!(target_arch = "aarch64") {
|
|
|
|
vm.registers[1] = hbvm::value::Value(1);
|
|
|
|
} else {
|
|
|
|
vm.registers[1] = hbvm::value::Value(u64::MAX)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// AbleCode™ (get fb ptr)
|
|
|
|
6 => {
|
|
|
|
use {
|
|
|
|
crate::kmain::FB_REQ,
|
|
|
|
limine::{Framebuffer, NonNullPtr},
|
|
|
|
};
|
|
|
|
let fb1: &NonNullPtr<Framebuffer> =
|
|
|
|
&FB_REQ.get_response().get().unwrap().framebuffers()[0];
|
|
|
|
let msg = block_read(mem_addr, length)[0];
|
|
|
|
if msg == b'p' {
|
|
|
|
// ptr
|
|
|
|
let fb_front = fb1.address.as_ptr().unwrap() as *const u8;
|
|
|
|
log::info!("Graphics front ptr {:?}", fb_front);
|
|
|
|
vm.registers[1] = hbvm::value::Value(fb_front as u64);
|
|
|
|
} else if msg == b'w' {
|
|
|
|
// width
|
|
|
|
log::info!("FB Width: {}", fb1.width);
|
|
|
|
vm.registers[1] = hbvm::value::Value(fb1.width);
|
|
|
|
} else if msg == b'h' {
|
|
|
|
// height
|
|
|
|
log::info!("FB Height: {}", fb1.height);
|
|
|
|
vm.registers[1] = hbvm::value::Value(fb1.height);
|
|
|
|
}
|
2024-08-29 15:37:49 -05:00
|
|
|
}
|
2023-10-27 20:26:04 -05:00
|
|
|
buffer_id => {
|
2023-10-29 07:27:10 -05:00
|
|
|
let mut buffs = IPC_BUFFERS.lock();
|
2023-12-01 08:48:57 -06:00
|
|
|
match buffs.get_mut(&buffer_id) {
|
|
|
|
Some(buff) => {
|
2024-09-13 16:41:31 -05:00
|
|
|
let mut msg_vec = Vec::with_capacity(length);
|
2023-12-01 08:48:57 -06:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2024-08-31 09:38:15 -05:00
|
|
|
debug!(
|
2023-12-01 08:48:57 -06:00
|
|
|
"Message {:?} has been sent to Buffer({})",
|
|
|
|
msg_vec, buffer_id
|
|
|
|
);
|
2024-09-13 16:41:31 -05:00
|
|
|
buff.push(msg_vec);
|
2023-12-01 08:48:57 -06:00
|
|
|
}
|
2023-12-01 09:02:56 -06:00
|
|
|
None => {
|
|
|
|
log::error!("Access of non-existent buffer {}", buffer_id)
|
|
|
|
}
|
2023-10-29 07:27:10 -05:00
|
|
|
}
|
|
|
|
drop(buffs);
|
2023-10-27 20:26:04 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-10-29 07:27:10 -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>();
|
2023-10-29 07:27:10 -05:00
|
|
|
|
|
|
|
let mut buffs = IPC_BUFFERS.lock();
|
2024-09-13 16:41:31 -05:00
|
|
|
let buff: &mut IpcBuffer;
|
2024-08-19 13:13:58 -05:00
|
|
|
|
|
|
|
if buffs.get_mut(&buffer_id).is_some() {
|
|
|
|
buff = buffs.get_mut(&buffer_id).unwrap();
|
|
|
|
} else {
|
2024-08-29 15:37:49 -05:00
|
|
|
// info!("AHHH");
|
2024-08-19 13:13:58 -05:00
|
|
|
vm.registers[1] = hbvm::value::Value(0);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
let pop = buff.pop();
|
|
|
|
if pop.is_err() {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
let msg = pop.unwrap();
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-31 09:38:15 -05:00
|
|
|
debug!("Recieve {:?} from Buffer({})", msg, buffer_id);
|
2024-07-07 08:35:07 -05:00
|
|
|
}
|
2023-10-29 07:27:10 -05:00
|
|
|
}
|
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);
|
|
|
|
}
|
2024-07-16 16:42:49 -05:00
|
|
|
let x = hbvm::value::Value(unsafe { x86_in(r2 as u16) } as u64);
|
|
|
|
info!("Read {:?} from Port {:?}", x, r2);
|
|
|
|
vm.registers[3] = x
|
2023-12-13 04:21:32 -06:00
|
|
|
}
|
2023-12-04 23:56:23 -06:00
|
|
|
}
|
2023-10-27 20:26:04 -05:00
|
|
|
_ => {
|
2024-05-31 09:15:55 -05:00
|
|
|
log::error!("Syscall unknown {:?}{:?}", ecall_number, vm.registers);
|
2023-10-27 20:26:04 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-10-28 08:43:32 -05:00
|
|
|
|
2024-09-13 16:41:31 -05:00
|
|
|
fn log_msg_handler(_vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> {
|
2023-10-28 23:14:36 -05:00
|
|
|
// 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-09-13 16:41:31 -05:00
|
|
|
let msg_vec = block_read(mem_addr, length);
|
2023-10-28 23:14:36 -05:00
|
|
|
|
2024-09-13 16:41:31 -05:00
|
|
|
let log_level = msg_vec.last().unwrap();
|
|
|
|
match core::str::from_utf8(&msg_vec[1..]) {
|
2023-12-13 04:21:32 -06:00
|
|
|
Ok(strr) => {
|
2023-12-04 23:56:23 -06:00
|
|
|
// use LogLevel::*;
|
2024-09-13 16:41:31 -05:00
|
|
|
let _ll = match log_level {
|
2023-12-04 23:56:23 -06:00
|
|
|
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-11-18 02:17:54 -06:00
|
|
|
}
|
2023-12-04 23:56:23 -06:00
|
|
|
Err(e) => {
|
|
|
|
error!("{:?}", e);
|
|
|
|
}
|
|
|
|
}
|
2023-10-28 08:43:32 -05:00
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2023-10-29 07:27:10 -05:00
|
|
|
#[derive(Debug)]
|
2023-10-28 08:43:32 -05:00
|
|
|
pub enum LogError {
|
2024-09-04 12:14:30 -05:00
|
|
|
NoMessages,
|
2023-10-28 08:43:32 -05:00
|
|
|
InvalidLogFormat,
|
|
|
|
}
|
2023-12-01 06:11:33 -06:00
|
|
|
|
2024-09-13 16:41:31 -05:00
|
|
|
// 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(())
|
|
|
|
// }
|