diff --git a/src/interrupts.rs b/src/interrupts.rs index 6ddddb1..40c3bc0 100644 --- a/src/interrupts.rs +++ b/src/interrupts.rs @@ -1,7 +1,7 @@ use crate::{ bootinfo::BOOTINFO, print, println, - tasking::{InvalidPid, SleepReason}, + tasking::{InvalidPid, IpcMessage, SleepReason}, virtual_memory::{ASpaceMutex, AddressSpace, PagingError, ACTIVE_SPACE, KERNEL_SPACE}, TASKING, }; @@ -163,7 +163,13 @@ pub fn send_ipc_to( pid: usize, buffer: Box<[u8], &'static ASpaceMutex>, len: usize, + from_kernel: bool, ) -> Result<(), SendIpcError> { + let from = if from_kernel { + usize::MAX + } else { + TASKING.current_pid().unwrap() + }; #[cfg(feature = "log-rpc")] { #[expect( @@ -185,13 +191,14 @@ pub fn send_ipc_to( clippy::arithmetic_side_effects, reason = "Can't overflow, as padded_len is no more than 4096 and 4096+24 < u32::MAX" )] - let total_len = padded_len + 8 + (4 * 4); + let total_len = padded_len + 16 + (4 * 4); SECOND_PORT.write_u32s(&[ 0x3, // SPB type total_len, // Total block length - len.saturating_cast::().saturating_add(8), // Packet length + len.saturating_cast::().saturating_add(16), // Packet length ]); SECOND_PORT.write_bytes(&pid.to_ne_bytes()); + SECOND_PORT.write_bytes(&from.to_ne_bytes()); #[expect( clippy::indexing_slicing, reason = "The truncated length is always <= the buffer's length" @@ -225,7 +232,12 @@ pub fn send_ipc_to( buffer }; let new_buffer_key = process.data_buffers().lock().insert(dest_buffer); - process.message_queue().lock().push((new_buffer_key, len)); + let message = IpcMessage { + buffer_idx: new_buffer_key, + len, + from, + }; + process.message_queue().lock().push(message); Ok::<_, PagingError>(()) })??; #[expect( @@ -251,15 +263,13 @@ fn irq_handler(_stack_frame: InterruptStackFrame, index: u8, _error_code: Option handler(irq_num, eoi_guard); } else if let Some(handler_task) = IRQ_TASKS.read()[usize(irq_num)] { let pid = handler_task; - let len: usize = 11; - let rounded_size = len.next_multiple_of(4096); - let mut buffer = Vec::with_capacity_in(rounded_size, &*ACTIVE_SPACE); - buffer.resize(rounded_size, 0); - let mut buffer = buffer.into_boxed_slice(); - buffer[0..8].copy_from_slice(&u64::MAX.to_le_bytes()); - buffer[8..10].copy_from_slice(&2u16.to_le_bytes()); - buffer[10] = irq_num; - match send_ipc_to(pid, buffer, len) { + let mut buffer = Vec::new_in(&*ACTIVE_SPACE); + buffer.extend_from_slice(&2u16.to_le_bytes()); + buffer.push(irq_num); + let len = buffer.len(); + buffer.resize(len.next_multiple_of(4096), 0); + let buffer = buffer.into_boxed_slice(); + match send_ipc_to(pid, buffer, len, true) { Ok(()) => (), Err(SendIpcError::InvalidPid) => { IRQ_TASKS.write()[usize(irq_num)] = None; @@ -394,6 +404,7 @@ extern "C" fn syscall_handler() { let mut retval = 0; let mut retval2 = regs.rcx; let mut retval3 = regs.rdx; + let mut retval4 = regs.rsi; match regs.rax { 0 => { let rval = if let Some(chr) = char::from_u32(regs.rcx.wrapping_cast()) { @@ -535,7 +546,7 @@ extern "C" fn syscall_handler() { if let Some(buffer) = get_buffer(regs.rdx) { let len = usize(regs.rsi); assert!(len <= buffer.len()); - match send_ipc_to(pid, buffer, len) { + match send_ipc_to(pid, buffer, len, false) { Ok(()) => retval = 0, Err(e) => { println!("ipc_send: Error {e:?}"); @@ -556,11 +567,12 @@ extern "C" fn syscall_handler() { reason = "The message queue only contains valid buffer IDs" )] let buffer_addr = u64(TASKING - .current_process(|process| *process.data_buffers().lock().get(msg.0).unwrap()) + .current_process(|process| *process.data_buffers().lock().get(msg.buffer_idx).unwrap()) .expose_provenance()); - retval2 = u64(msg.1); + retval2 = u64(msg.len); retval = buffer_addr; - retval3 = u64(msg.0); + retval3 = u64(msg.buffer_idx); + retval4 = u64(msg.from); } else { retval = 0; } @@ -759,7 +771,6 @@ extern "C" fn syscall_handler() { unsafe { asm!( "mov rbx, [rip+SYSCALL_REGS+8]", - "mov rsi, [rip+SYSCALL_REGS+32]", "mov rdi, [rip+SYSCALL_REGS+40]", "mov rsp, [rip+SYSCALL_REGS+48]", "mov rbp, [rip+SYSCALL_REGS+56]", @@ -772,7 +783,7 @@ extern "C" fn syscall_handler() { "mov r14, [rip+SYSCALL_REGS+112]", "mov r15, [rip+SYSCALL_REGS+120]", "iretq", - in("rax") retval, in("rcx") retval2, in("rdx") retval3, options(noreturn) + in("rax") retval, in("rcx") retval2, in("rdx") retval3, in("rsi") retval4, options(noreturn) ) } } diff --git a/src/tasking.rs b/src/tasking.rs index ed8ec90..9e595bd 100644 --- a/src/tasking.rs +++ b/src/tasking.rs @@ -92,10 +92,16 @@ pub struct Process { kernel_esp_top: VirtAddr, address_spaces: Mutex>, data_buffers: Mutex>, - message_queue: Mutex>, + message_queue: Mutex>, sleeping: RwLock>, } +pub struct IpcMessage { + pub buffer_idx: usize, + pub len: usize, + pub from: usize, +} + impl Process { pub fn address_spaces(&self) -> &Mutex> { &self.address_spaces @@ -105,7 +111,7 @@ impl Process { &self.data_buffers } - pub fn message_queue(&self) -> &Mutex> { + pub fn message_queue(&self) -> &Mutex> { &self.message_queue } @@ -184,7 +190,6 @@ impl Tasking { if let Some(&proc_man_pid) = REGISTERD_PIDS.read().get(&3) { let mut varint_buf = unsigned_varint::encode::u64_buffer(); let mut buffer = Vec::new_in(&*ACTIVE_SPACE); - buffer.extend_from_slice(&u64::MAX.to_le_bytes()); buffer.extend_from_slice(&0u16.to_le_bytes()); buffer.push(0); buffer.extend_from_slice(&0u64.to_le_bytes()); @@ -207,7 +212,7 @@ impl Tasking { clippy::expect_used, reason = "The tasking code in the kernel and proc_man CANNOT lose sync. Failure to communicate is fatal." )] - send_ipc_to(usize(proc_man_pid), buffer, len) + send_ipc_to(usize(proc_man_pid), buffer, len, true) .expect("Failed to send exit message to proc_man"); } else { println!("[TASKING] No process manager when creating PID {pid}"); @@ -289,7 +294,6 @@ impl Tasking { if let Some(&proc_man_pid) = REGISTERD_PIDS.read().get(&3) { let mut varint_buf = unsigned_varint::encode::u64_buffer(); let mut buffer = Vec::new_in(&*ACTIVE_SPACE); - buffer.extend_from_slice(&u64::MAX.to_le_bytes()); buffer.extend_from_slice(&0u16.to_le_bytes()); buffer.push(0); buffer.extend_from_slice(&0u64.to_le_bytes()); @@ -307,7 +311,7 @@ impl Tasking { clippy::expect_used, reason = "The tasking code in the kernel and proc_man CANNOT lose sync. Failure to communicate is fatal." )] - send_ipc_to(usize(proc_man_pid), buffer, len) + send_ipc_to(usize(proc_man_pid), buffer, len, true) .expect("Failed to send exit message to proc_man"); } else { println!(