ableos/kernel/src/holeybytes/ecah.rs

207 lines
7.6 KiB
Rust
Raw Normal View History

2023-10-27 20:26:04 -05:00
//! Environment call handling routines
use crate::holeybytes::kernel_services::{
block_read, dt_msg_handler::dt_msg_handler, logging_service::log_msg_handler,
service_definition_service::sds_msg_handler,
2024-03-22 03:58:59 -05:00
};
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},
hbvm::value::Value,
log::{debug, error, info, trace},
2023-10-27 20:26:04 -05:00
};
#[cfg(target_arch = "x86_64")]
2024-10-12 15:39:09 -05:00
#[inline(always)]
unsafe fn x86_out<T: x86_64::instructions::port::PortWrite>(address: u16, value: T) {
x86_64::instructions::port::Port::new(address).write(value);
}
#[cfg(target_arch = "x86_64")]
2024-10-12 15:39:09 -05:00
#[inline(always)]
unsafe fn x86_in<T: x86_64::instructions::port::PortRead>(address: u16) -> T {
x86_64::instructions::port::Port::new(address).read()
}
2024-10-12 15:39:09 -05:00
#[inline(always)]
2023-10-27 20:26:04 -05:00
pub fn handler(vm: &mut Vm) {
let ecall_number = vm.registers[2].cast::<u64>();
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
let bounded = match vm.registers[3] {
Value(0) => false,
Value(1) => true,
2023-10-27 20:26:04 -05:00
_ => {
panic!("Bad");
}
};
let length = vm.registers[4].cast::<u64>();
2023-10-27 20:26:04 -05:00
let mut buffs = IPC_BUFFERS.lock();
let buff_id = arch::hardware_random_u64();
2024-10-12 15:39:09 -05:00
buffs.insert(
buff_id,
match bounded {
false => IpcBuffer::new(false, 0),
true => IpcBuffer::new(true, length),
},
);
2024-08-19 13:13:58 -05:00
info!("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
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;
trace!("IPC address: {:?}", mem_addr);
2023-10-27 20:26:04 -05:00
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
},
1 => match log_msg_handler(vm, mem_addr, length) {
Ok(()) => {}
2024-09-13 16:41:31 -05:00
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
}
2024-09-13 16:41:31 -05:00
#[cfg(target_arch = "x86_64")]
2024-07-15 16:56:46 -05:00
3 => {
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-09-16 14:15:51 -05:00
0 => unsafe {
2024-09-15 11:01:29 -05:00
let size = msg_vec[1];
let addr =
u16::from_le_bytes(msg_vec[2..4].try_into().unwrap_unchecked());
2024-09-16 14:15:51 -05:00
let value = match size {
0 => x86_in::<u8>(addr) as u64,
1 => x86_in::<u16>(addr) as u64,
2 => x86_in::<u32>(addr) as u64,
_ => panic!("Trying to read size other than: 8, 16, 32 from port."),
};
// info!("Read the value {} from address {}", value, addr);
vm.registers[1] = hbvm::value::Value(value);
2024-09-16 14:15:51 -05:00
},
1 => unsafe {
2024-09-15 11:01:29 -05:00
let size = msg_vec[1];
let addr =
u16::from_le_bytes(msg_vec[2..4].try_into().unwrap_unchecked());
// info!("Setting address {}", addr);
2024-09-20 05:06:08 -05:00
2024-09-16 14:15:51 -05:00
match size {
0 => x86_out(addr, msg_vec[4]),
1 => x86_out(
addr,
u16::from_le_bytes(msg_vec[4..6].try_into().unwrap_unchecked()),
),
2 => x86_out(
addr,
u32::from_le_bytes(msg_vec[4..8].try_into().unwrap_unchecked()),
),
_ => panic!("How?"),
}
2024-09-16 14:15:51 -05:00
},
2024-07-15 16:56:46 -05:00
_ => {}
}
}
2024-09-10 14:52:57 -05:00
#[cfg(not(target_arch = "x86_64"))]
3 => unimplemented!("TODO: implement whatever buffer 3 does for no x86_64"),
// 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);
}
2024-09-13 18:11:23 -05:00
5 => match dt_msg_handler(vm, mem_addr, length) {
Ok(()) => {}
Err(_) => log::error!("Improper dt query"),
2024-09-13 18:11:23 -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) => {
2024-10-12 15:39:09 -05:00
let msg_vec = block_read(mem_addr, length);
buff.push(msg_vec.to_vec());
debug!("Sent Message {:?} to Buffer({})", msg_vec, buffer_id);
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-27 20:26:04 -05:00
}
}
}
4 => {
let buffer_id = vm.registers[3].cast::<u64>();
let map_ptr = vm.registers[4].cast::<u64>();
let max_length = vm.registers[5].cast::<u64>();
let mut buffs = IPC_BUFFERS.lock();
let buff: &mut IpcBuffer = match buffs.get_mut(&buffer_id) {
Some(buff) => buff,
None => panic!(
"Failed to get buffer: id={buffer_id}, ptr={map_ptr}, length={max_length}"
),
};
2024-08-19 13:13:58 -05:00
let msg = match buff.pop() {
Ok(msg) => msg,
Err(_) => return,
};
if msg.len() > unsafe { max_length.try_into().unwrap_unchecked() } {
2024-07-07 08:35:07 -05:00
info!("{}", max_length);
error!("Message is too long to map in.");
} else {
unsafe {
let ptr = map_ptr as *mut u8;
ptr.copy_from(msg.as_ptr(), msg.len());
2024-07-07 08:35:07 -05:00
}
debug!("Recieve {:?} from Buffer({})", msg, buffer_id);
2024-07-07 08:35:07 -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>();
let x = hbvm::value::Value(unsafe { x86_in::<u8>(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
}
}
}
#[derive(Debug)]
pub enum LogError {
2024-09-04 12:14:30 -05:00
NoMessages,
InvalidLogFormat,
}