Add correct framebuffer mapping, so Doom works again, remove unneded

code, add cooperative scheduling on syscalls determined by the
reschedule flag, make serial console automatically clear and be a single
render, make process_scancodes push to all processes, add a user-facing
framebuffer to be mapped, automatically swap buffers inside timer
interrupt, update all submodules
This commit is contained in:
csd4ni3l
2026-05-11 19:09:20 +02:00
parent 925b2bc8d2
commit 85e0d45d3c
25 changed files with 695 additions and 466 deletions
+108 -35
View File
@@ -2,7 +2,10 @@ use core::arch::asm;
use x86_64::instructions::tlb::flush_all;
use crate::arch::x86_64::gdt::{GDT, TSS};
use crate::{
arch::x86_64::gdt::{GDT, TSS},
task::scheduler::{SCHEDULER, current_pid},
};
const IA32_EFER: u32 = 0xC0000080;
const IA32_EFER_SCE: u64 = 1; // system call enable bit
@@ -10,6 +13,7 @@ const IA32_STAR: u32 = 0xC0000081;
const IA32_LSTAR: u32 = 0xC0000082;
const IA32_FMASK: u32 = 0xC0000084;
const IA32_KERNEL_GS_BASE: u32 = 0xC0000102;
const IA32_GS_BASE: u32 = 0xC0000101;
#[repr(C)]
pub struct PerCpuData {
@@ -69,6 +73,8 @@ pub fn init_syscalls() {
wrmsr(IA32_FMASK, 1 << 9); // Mask interupts during syscalls
wrmsr(IA32_GS_BASE, 0);
let kernel_cs = (GDT.1.0.0 & !0b11) as u64;
let user_ds = (GDT.1.3.0 & !0b11) as u64;
@@ -79,57 +85,124 @@ pub fn init_syscalls() {
}
}
#[unsafe(no_mangle)]
unsafe extern "C" fn check_and_reschedule() -> usize {
let pid = current_pid().unwrap_or(0);
if pid == 0 {
return 0;
}
let should = SCHEDULER
.with_process(pid, |process| process.should_reschedule)
.unwrap_or(false);
if !should {
return 0;
}
let next_task = SCHEDULER.next_task();
if next_task == pid {
return 0;
}
SCHEDULER.switch_to(next_task, false);
1
}
#[unsafe(naked)]
#[unsafe(no_mangle)]
unsafe extern "C" fn syscall_entry() {
core::arch::naked_asm!(
r#"
.intel_syntax noprefix
swapgs
// save user stack
mov gs:[0], rsp
// use kernel stack
mov rsp, gs:[8]
push r11
push rcx
push rax
push rdi
push rsi
push rdx
push r10
push r8
push r9
sub rsp, 128
mov rdi, rax
mov rsi, [rsp + 40]
mov rdx, [rsp + 32]
mov rcx, [rsp + 24]
mov r8, [rsp + 16]
mov r9, [rsp + 8]
push qword ptr [rsp]
mov qword ptr [rsp + 0], r15
mov qword ptr [rsp + 8], r14
mov qword ptr [rsp + 16], r13
mov qword ptr [rsp + 24], r12
mov qword ptr [rsp + 32], r11
mov qword ptr [rsp + 40], r10
mov qword ptr [rsp + 48], r9
mov qword ptr [rsp + 56], r8
mov qword ptr [rsp + 64], rsi
mov qword ptr [rsp + 72], rdi
mov qword ptr [rsp + 80], rbp
mov qword ptr [rsp + 88], rdx
mov qword ptr [rsp + 96], rcx
mov qword ptr [rsp + 104], rbx
mov qword ptr [rsp + 112], rax
mov rax, qword ptr gs:[0]
mov qword ptr [rsp + 120], rax
mov rbx, rsp // rbx = frame base
// ctx_save(frame)
mov rdi, rbx
lea rsp, [rbx - 8]
call ctx_save
mov rsp, rbx
// syscall_dispatch(num,arg0..arg5)
mov rdi, qword ptr [rbx + 112]
mov rsi, qword ptr [rbx + 72]
mov rdx, qword ptr [rbx + 64]
mov rcx, qword ptr [rbx + 88]
mov r8, qword ptr [rbx + 40]
mov r9, qword ptr [rbx + 56]
lea rsp, [rbx - 24] // rsp%16==8 before call
mov rax, qword ptr [rbx + 48]
mov qword ptr [rsp + 0], rax
call syscall_dispatch
mov rsp, rbx
add rsp, 8 // fix alignment
// save return value into frame (so normal restore uses it)
mov qword ptr [rbx + 112], rax
pop r9
pop r8
pop r10
pop rdx
pop rsi
pop rdi
add rsp, 8
// ctx_save(frame) again so saved_ctx.rax reflects return value
mov rdi, rbx
lea rsp, [rbx - 8]
call ctx_save
mov rsp, rbx
pop rcx
pop r11
// maybe switch tasks (this should not return if it switches)
lea rsp, [rbx - 8]
call check_and_reschedule
mov rsp, rbx
mov rsp, gs:[0]
test rax, rax
jnz .done
// restore registers from frame
mov rax, qword ptr [rsp + 112]
mov rbx, qword ptr [rsp + 104]
mov rcx, qword ptr [rsp + 96]
mov rdx, qword ptr [rsp + 88]
mov rbp, qword ptr [rsp + 80]
mov rdi, qword ptr [rsp + 72]
mov rsi, qword ptr [rsp + 64]
mov r8, qword ptr [rsp + 56]
mov r9, qword ptr [rsp + 48]
mov r10, qword ptr [rsp + 40]
mov r11, qword ptr [rsp + 32] // rflags — sysretq loads RFLAGS from r11
mov r12, qword ptr [rsp + 24]
mov r13, qword ptr [rsp + 16]
mov r14, qword ptr [rsp + 8]
mov r15, qword ptr [rsp + 0]
// don't restore rsp from frame — use the user rsp we saved in gs:[0]
mov rsp, qword ptr gs:[0]
swapgs
sysretq"#,
sysretq
.done:
ud2
"#,
);
}