Implement syscalls, hello world from userspace

This commit is contained in:
2025-09-02 23:51:14 +02:00
parent 920de10025
commit 8a12f23b69
24 changed files with 313 additions and 44 deletions

View File

@ -1,14 +1,28 @@
#include <stdint.h>
#include <stddef.h>
#include "cpu.h"
#include "vmm.h"
#include "pmm/pmm.h"
#include "hal/hal.h"
#include "bootinfo/bootinfo.h"
LocalCpuData HAL_CPUS[HAL_CPUS_MAX];
uint64_t hal_cpu_rdmsr(uint32_t id) {
uint32_t lo, hi;
asm volatile("rdmsr" : "=m"(lo), "=d"(hi) : "c"(id));
asm volatile("rdmsr" : "=a"(lo), "=d"(hi) : "c"(id));
return ((uint64_t)lo) | ((uint64_t)hi << 32);
}
uint64_t hal_cpu_wrmsr(uint32_t id, uint64_t val) {
uint32_t lo = val & 0xffffffff, hi = (val >> 32) & 0xffffffff;
asm volatile("wrmsr" :: "a"(lo), "d"(hi), "c"(id) : "memory");
uint32_t lo = val & 0xFFFFFFFF;
uint32_t hi = val >> 32;
asm volatile("wrmsr" :: "c"(id), "a"(lo), "d"(hi));
return val;
}
void hal_cpu_init(uint32_t cpu) {
void *addr = pmm_alloc(16) + (16 * HAL_PAGE_SIZE);
HAL_CPUS[cpu].syscall_kstack = (uint64_t *)VIRT(addr);
HAL_CPUS[cpu].kcr3 = hal_vmm_current_cr3();
}

View File

@ -1,11 +1,36 @@
#ifndef HAL_CPU_H_
#define HAL_CPU_H_
#include <stdint.h>
#include "compiler/attr.h"
#include "vmm.h"
#include "intr.h"
#define HAL_CPUS_MAX 0xff
#define HAL_CPU_EFER 0xC0000080
#define HAL_CPU_STAR 0xC0000081
#define HAL_CPU_LSTAR 0xC0000082
#define HAL_CPU_CSTAR 0xC0000083
#define HAL_CPU_SFMASK 0xC0000084
#define HAL_CPU_FSBASE 0xC0000100
#define HAL_CPU_GSBASE 0xC0000101
#define HAL_CPU_KGSBASE 0xC0000102
typedef struct {
uint64_t *syscall_kstack;
uint64_t *syscall_ustack;
PgTable *kcr3;
PgTable *pcr3;
IntrStackFrame *frame;
} PACKED LocalCpuData;
uint64_t hal_cpu_rdmsr(uint32_t id);
uint64_t hal_cpu_wrmsr(uint32_t id, uint64_t val);
void hal_cpu_init(uint32_t cpu);
extern LocalCpuData HAL_CPUS[HAL_CPUS_MAX];
#endif // HAL_CPU_H_

View File

@ -9,6 +9,7 @@
#include "pic.h"
#include "apic.h"
#include "pit.h"
#include "syscall.h"
void hal_init(void) {
if (!serial_init()) {
@ -32,6 +33,7 @@ void hal_init_withmalloc(void) {
pit_init();
ioapic_setentry(IOAPIC, acpi_remapirq(0x00), INTR_TIMER);
hal_intr_disable();
hal_syscall_init();
}
void hal_wait(uint32_t ms) {

View File

@ -133,7 +133,7 @@ void intr_dumpframe(IntrStackFrame *frame) {
asm volatile("mov %%cr3, %0" : "=r"(cr3));
uint64_t cr4;
asm volatile("mov %%cr4, %0" : "=r"(cr4));
kprintf_unsafe("rax=%016lx rcx=%016lx rdx=%016lx\n"
kprintf("rax=%016lx rcx=%016lx rdx=%016lx\n"
"rsi=%016lx rdi=%016lx r8 =%016lx\n"
"r9 =%016lx r10=%016lx r11=%016lx\n"
"rip=%016lx rfl=%016lx rsp=%016lx\n"
@ -150,11 +150,14 @@ void intr_dumpframe(IntrStackFrame *frame) {
}
void intr_handleintr(IntrStackFrame *frame) {
if (frame->trapnum >= 0 && frame->trapnum <= 31) {
// EXCEPTION
kprintf_unsafe("ERROR %s, 0x%lX\n", exceptions[frame->trapnum], frame->errnum);
if (frame->trapnum <= 31) {
if (frame->trapnum == 14 && frame->errnum & 0x4) {
proc_killself();
proc_sched((void *)frame);
}
kprintf("ERROR %s, 0x%lX\n", exceptions[frame->trapnum], frame->errnum);
intr_dumpframe(frame);
hal_hang();
hal_hang();
} else if (frame->trapnum >= 32 && frame->trapnum <= 47) {
if (frame->trapnum == INTR_TIMER) {
io_out8(PIC2_CMD, 0x20);

View File

@ -17,6 +17,7 @@ typedef struct {
uint64_t r10;
uint64_t r9;
uint64_t r8;
uint64_t rbp;
uint64_t rdi;
uint64_t rsi;
uint64_t rdx;

View File

@ -215,4 +215,3 @@ intr_vec46:
intr_vec47:
_vecintr_plain_save 47
_vecintr_bodygen

View File

@ -4,6 +4,7 @@
push %rdx
push %rsi
push %rdi
push %rbp
push %r8
push %r9
push %r10
@ -23,6 +24,7 @@
pop %r10
pop %r9
pop %r8
pop %rbp
pop %rdi
pop %rsi
pop %rdx

View File

@ -0,0 +1,43 @@
#include <stdint.h>
#include "syscall.h"
#include "cpu.h"
#include "intr.h"
#include "syscall/syscall.h"
#include "proc/proc.h"
#include "kprintf.h"
#include "errors.h"
extern void hal_enable_syscallentry(void);
extern void hal_syscallentry(void);
void hal_syscalldispatch(IntrStackFrame *frame) {
uint64_t sysnum = frame->regs.rax;
if (sysnum < SYSCALLS_MAX) {
SyscallFn fn = SYSCALL_TABLE[sysnum];
if (fn == NULL) {
frame->regs.rax = E_BADSYSCALL;
return;
}
int32_t ret = fn(frame->regs.rdi, frame->regs.rsi, frame->regs.rdx,
frame->regs.r10, frame->regs.r8, frame->regs.r9);
if (sysnum == SYS_QUITPROC) {
proc_sched((void *)frame);
}
frame->regs.rax = *(uint64_t *)&ret;
}
}
void hal_syscall_init(void) {
hal_cpu_init(0);
LocalCpuData *lcd = &HAL_CPUS[0];
hal_cpu_wrmsr(HAL_CPU_EFER, hal_cpu_rdmsr(HAL_CPU_EFER) | 0x1);
hal_enable_syscallentry();
hal_cpu_wrmsr(HAL_CPU_GSBASE, (uint64_t)lcd);
hal_cpu_wrmsr(HAL_CPU_KGSBASE, (uint64_t)lcd);
hal_cpu_wrmsr(HAL_CPU_SFMASK, (uint64_t)0);
hal_cpu_wrmsr(HAL_CPU_LSTAR, (uint64_t)&hal_syscallentry);
}

View File

@ -0,0 +1,6 @@
#ifndef HAL_SYSCALL_H_
#define HAL_SYSCALL_H_
void hal_syscall_init(void);
#endif // HAL_SYSCALL_H_

View File

@ -0,0 +1,48 @@
#include "regs.S"
.extern hal_syscalldispatch
.global hal_enable_syscallentry
hal_enable_syscallentry:
movq $0xC0000080, %rcx
rdmsr
or $0x1, %eax
wrmsr
movq $0xC0000081, %rcx
rdmsr
movl $0x180008, %edx
wrmsr
ret
.global hal_syscallentry
hal_syscallentry:
cli
swapgs
movq %rsp, %gs:0x8
movq %gs:0x0, %rsp
pushq $0x23
pushq %gs:0x8
swapgs
pushq %r11
pushq $0x1b
pushq %rcx
_push_regs
mov %rsp, %rdi
mov $0x0, %rbp
call hal_syscalldispatch
cli
_pop_regs
popq %rcx
add $0x8, %rsp
popq %r11
popq %rsp
sysret