Add syscall handler
All checks were successful
Build / build (push) Successful in 2m52s

This commit is contained in:
Mathieu Strypsteen 2024-12-23 21:07:06 +01:00
parent 1cccf16bfe
commit 76e31b5e42
8 changed files with 48 additions and 2 deletions

View file

@ -22,6 +22,7 @@ global_asm!(include_str!("isr.s"), options(att_syntax));
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct ISRState { pub struct ISRState {
pub ds: u64,
pub rax: u64, pub rax: u64,
pub rbx: u64, pub rbx: u64,
pub rcx: u64, pub rcx: u64,

View file

@ -31,10 +31,17 @@ isr_common:
push %rcx push %rcx
push %rbx push %rbx
push %rax push %rax
mov %ds, %rax
push %rax
mov %rsp, %rdi mov %rsp, %rdi
call isr_handler call isr_handler
pop %rax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
pop %rax pop %rax
pop %rbx pop %rbx
pop %rcx pop %rcx

View file

@ -6,4 +6,30 @@ syscall:
mov %rsp, %gs:8 mov %rsp, %gs:8
mov %gs:0, %rsp mov %gs:0, %rsp
swapgs swapgs
jmp . sti
push %r11
push %r10
push %r9
push %r8
push %rsi
push %rdi
push %rdx
push %rcx
push %rax
call syscall_handler
pop %rax
pop %rcx
pop %rdx
pop %rdi
pop %rsi
pop %r8
pop %r9
pop %r10
pop %r11
cli
swapgs
mov %gs:8, %rsp
swapgs
sysretq

View file

@ -2,11 +2,13 @@
.global jump_usermode .global jump_usermode
jump_usermode: jump_usermode:
cli // Ensure consistency in segment registers
mov $0x1b, %ax mov $0x1b, %ax
mov %ax, %ds mov %ax, %ds
mov %ax, %es mov %ax, %es
mov %ax, %fs mov %ax, %fs
mov %ax, %gs mov %ax, %gs
sti
push $0x1b push $0x1b
push $0 push $0
pushf pushf

View file

@ -41,6 +41,7 @@ pub fn send_eoi() {
address.add(REGISTER_EOI).write_volatile(0); address.add(REGISTER_EOI).write_volatile(0);
} }
} }
// It's unsafe to get the LAPIC ID if interrupts are enabled, because the task can have migrated to a different core.
pub fn get_current_lapic_id() -> usize { pub fn get_current_lapic_id() -> usize {
let address = ADDRESS.load(Ordering::SeqCst); let address = ADDRESS.load(Ordering::SeqCst);
let lapic_id = unsafe { address.add(REGISTER_ID).read_volatile() as usize >> 24 }; let lapic_id = unsafe { address.add(REGISTER_ID).read_volatile() as usize >> 24 };

View file

@ -10,4 +10,5 @@ pub mod process;
pub mod scheduler; pub mod scheduler;
pub mod smp; pub mod smp;
pub mod sync; pub mod sync;
mod syscall;
pub mod task; pub mod task;

View file

@ -0,0 +1,2 @@
#[no_mangle]
extern "C" fn syscall_handler() {}

View file

@ -40,6 +40,7 @@ pub struct Task {
pub sleep_until_us: usize, pub sleep_until_us: usize,
pub block_on_semaphore: Option<Arc<RawSemaphore>>, pub block_on_semaphore: Option<Arc<RawSemaphore>>,
pub semaphore_requested_count: usize, pub semaphore_requested_count: usize,
user_stack: u64,
} }
#[repr(C)] #[repr(C)]
@ -64,8 +65,10 @@ pub fn allocate_stack() -> u64 {
pub fn switch_task(current_state: &mut ISRState, new_task: Task) { pub fn switch_task(current_state: &mut ISRState, new_task: Task) {
let lapic_id = get_current_lapic_id(); let lapic_id = get_current_lapic_id();
let mut current_tasks = CURRENT_TASKS.lock(); let mut current_tasks = CURRENT_TASKS.lock();
let cpu_data = &mut CPUDATA.lock()[lapic_id];
if let Some(mut current_task) = current_tasks[lapic_id].take() { if let Some(mut current_task) = current_tasks[lapic_id].take() {
current_task.state = *current_state; current_task.state = *current_state;
current_task.user_stack = cpu_data.user_stack;
if current_task.task_state == TaskState::Terminated { if current_task.task_state == TaskState::Terminated {
unsafe { unsafe {
get_kernel_process().lock().address_space.switch(); get_kernel_process().lock().address_space.switch();
@ -90,7 +93,8 @@ pub fn switch_task(current_state: &mut ISRState, new_task: Task) {
} }
} }
let kernel_stack = new_task.kernel_stack.as_ptr() as u64 + STACK_SIZE as u64; let kernel_stack = new_task.kernel_stack.as_ptr() as u64 + STACK_SIZE as u64;
CPUDATA.lock()[lapic_id].kernel_stack = kernel_stack; cpu_data.kernel_stack = kernel_stack;
cpu_data.user_stack = new_task.user_stack;
current_tasks[get_current_lapic_id()] = Some(new_task); current_tasks[get_current_lapic_id()] = Some(new_task);
schedule_timer_interrupt(); schedule_timer_interrupt();
} }
@ -100,6 +104,7 @@ pub fn create_task(process: Arc<Spinlock<Process>>, func: fn()) -> Task {
id: NEXT_TASK_ID.fetch_add(1, Ordering::SeqCst), id: NEXT_TASK_ID.fetch_add(1, Ordering::SeqCst),
process, process,
state: ISRState { state: ISRState {
ds: 0x10,
rax: 0, rax: 0,
rbx: 0, rbx: 0,
rcx: 0, rcx: 0,
@ -129,6 +134,7 @@ pub fn create_task(process: Arc<Spinlock<Process>>, func: fn()) -> Task {
sleep_until_us: 0, sleep_until_us: 0,
block_on_semaphore: None, block_on_semaphore: None,
semaphore_requested_count: 0, semaphore_requested_count: 0,
user_stack: 0,
} }
} }
fn create_idle_task() { fn create_idle_task() {