diff --git a/src/interrupts/mod.rs b/src/interrupts/mod.rs index 02f3d66..3cb1dce 100644 --- a/src/interrupts/mod.rs +++ b/src/interrupts/mod.rs @@ -53,7 +53,41 @@ extern "x86-interrupt" fn breakpoint_handler(stack_frame: InterruptStackFrame) { } extern "x86-interrupt" fn syscall_handler_32(_stack_frame: InterruptStackFrame) { + let rax: u64; + let rbx: u64; + let rcx: u64; + let rdx: u64; + let rsi: u64; + let rdi: u64; + let rbp: u64; + unsafe { + asm!( + "push rax", + "push rbx", + "push rcx", + "push rdx", + "push rsi", + "push rdi", + "push rbp", + + "pop {rbp}", + "pop {rdi}", + "pop {rsi}", + "pop {rdx}", + "pop {rcx}", + "pop {rbx}", + "pop {rax}", + rax = out(reg) rax, + rbx = out(reg) rbx, + rcx = out(reg) rcx, + rdx = out(reg) rdx, + rsi = out(reg) rsi, + rdi = out(reg) rdi, + rbp = out(reg) rbp, + ) + } println!("Received syscall"); + crate::syscalls::syscall_routine(rax); } extern "x86-interrupt" fn page_fault_handler( diff --git a/src/proc/scheduler/mod.rs b/src/proc/scheduler/mod.rs index d3f8b1a..f4d4991 100644 --- a/src/proc/scheduler/mod.rs +++ b/src/proc/scheduler/mod.rs @@ -23,7 +23,7 @@ pub const K_THREAD_ID: ThreadId = ThreadId(0); // Kernel main thread identifier struct ThreadStream { ids: ArrayQueue, - waker: AtomicWaker + waker: AtomicWaker, } impl ThreadStream { @@ -35,9 +35,7 @@ impl ThreadStream { } pub fn register(&mut self, id: ThreadId) { - self.ids - .push(id) - .expect("Thread queue full"); + self.ids.push(id).expect("Thread queue full"); self.waker.wake(); } } @@ -84,12 +82,12 @@ impl Scheduler { res } - pub async fn run(&mut self) { while let Some(id) = self.thread_queue.next().await { - if let Some(thread) = self.get_thread(id) { // Thread still exists + if let Some(thread) = self.get_thread(id) { + // Thread still exists unsafe { - (&mut*thread.as_ptr()).run(); + (&mut *thread.as_ptr()).run(); } self.thread_queue.register(id); } @@ -123,4 +121,4 @@ pub async fn scheduler_run() { let mut scheduler = SCHEDULER.lock().await; SCHEDULER.force_unlock(); scheduler.run().await; -} \ No newline at end of file +} diff --git a/src/proc/thread/mod.rs b/src/proc/thread/mod.rs index e801f5d..53fbdf7 100644 --- a/src/proc/thread/mod.rs +++ b/src/proc/thread/mod.rs @@ -1,7 +1,7 @@ use crate::println; use crate::utils::mutex::AsyncMutex; -use super::scheduler::{SCHEDULER, K_THREAD_ID}; +use super::scheduler::{K_THREAD_ID, SCHEDULER}; use core::arch::asm; use core::sync::atomic::{AtomicU64, Ordering}; @@ -25,34 +25,21 @@ impl ThreadId { } } -pub fn exit() { - println!("Exiting thread"); - { - let mut scheduler = SCHEDULER.try_lock().unwrap(); - scheduler.exit(*RUNNING_THREAD.try_lock().unwrap()); - } // Drop scheduler mutex guard - - resume_k_thread(); -} - -pub fn resume_k_thread() { +pub async fn resume_k_thread() { let k_thread: *mut Thread; { - let mut scheduler = SCHEDULER.try_lock().unwrap(); - k_thread = scheduler - .get_thread(K_THREAD_ID) - .unwrap() - .as_ptr(); + let mut scheduler = SCHEDULER.lock().await; + k_thread = scheduler.get_thread(K_THREAD_ID).unwrap().as_ptr(); } // Drop scheduler mutex guard unsafe { - (&mut* k_thread).run(); + (&mut *k_thread).run(); } } pub fn routine() { println!("Routine executed"); - exit(); + crate::syscalls::syscall_routine(crate::syscalls::EXIT_ID); // Call exit } pub struct Thread { @@ -60,7 +47,7 @@ pub struct Thread { pub entry_point: u64, pub started: bool, pub rsp: u64, - pub base_stack: u64 + pub base_stack: u64, } impl Thread { @@ -79,7 +66,10 @@ impl Thread { pub fn exit(&self) { unsafe { - dealloc(self.base_stack as *mut u8, Layout::new::<[u8; STACK_SIZE]>()); + dealloc( + self.base_stack as *mut u8, + Layout::new::<[u8; STACK_SIZE]>(), + ); } } @@ -98,8 +88,8 @@ impl Thread { out = out(reg) current_rsp, // Save thread rsp ); current_thread.borrow_mut().rsp = current_rsp; - } - else { // Thread does not exists anymore + } else { + // Thread does not exists anymore *current_thread_guard = self.id; // change running thread asm!( // Just switch to new thead without saving registers "push {rsp}", // Set stack pointer to the new thread diff --git a/src/syscalls/ids.rs b/src/syscalls/ids.rs new file mode 100644 index 0000000..3357b38 --- /dev/null +++ b/src/syscalls/ids.rs @@ -0,0 +1,3 @@ +pub type SyscallId = u64; + +pub const EXIT_ID: u64 = 0; diff --git a/src/syscalls/mod.rs b/src/syscalls/mod.rs index a253f3a..be2b42a 100644 --- a/src/syscalls/mod.rs +++ b/src/syscalls/mod.rs @@ -1,5 +1,47 @@ -pub mod io; +use crate::proc::thread::{resume_k_thread, RUNNING_THREAD}; +use crate::task::executor::EXECUTOR; +use crate::task::Task; -pub fn syscall_dispatcher() -> u64 { - 0 -} \ No newline at end of file +pub use ids::*; + +use alloc::sync::Arc; +use core::cell::RefCell; + +pub mod ids; +pub mod io; +pub mod proc; + +pub type SyscallContextT = Arc>; + +pub struct SyscallContext { + id: SyscallId, + res: u64, + thread_id: crate::proc::thread::ThreadId, +} + +pub fn syscall_dispatcher(context: SyscallContextT) -> Task { + match context.borrow().id { + EXIT_ID => Task::new(proc::exit(context.clone())), + _ => Task::new(bad_syscall()), + } +} + +pub fn syscall_routine(syscall_id: SyscallId) -> u64 { + let context: SyscallContextT = Arc::new(RefCell::new(SyscallContext { + id: syscall_id, + res: 0, + thread_id: *RUNNING_THREAD.try_lock().unwrap(), + })); + + EXECUTOR + .try_lock() + .unwrap() + .spawn(syscall_dispatcher(context.clone())); + + resume_k_thread(); + + let res = context.borrow().res; + res +} + +async fn bad_syscall() {} diff --git a/src/syscalls/proc.rs b/src/syscalls/proc.rs new file mode 100644 index 0000000..d8c8f3b --- /dev/null +++ b/src/syscalls/proc.rs @@ -0,0 +1,10 @@ +use crate::println; +use crate::proc::scheduler::SCHEDULER; + +use super::SyscallContextT; + +pub async fn exit(context: SyscallContextT) { + println!("Exiting thread"); + let mut scheduler = SCHEDULER.lock().await; + scheduler.exit(context.borrow().thread_id); +}