From ca80c22f50aa9b2219d33d64042f0c3f0be95061 Mon Sep 17 00:00:00 2001 From: Matheus Date: Sun, 7 May 2023 19:31:36 -0300 Subject: [PATCH] x86_64 cpu: syscall instruction --- kernel-src/arch/x86-64/cpu.c | 32 ++++++++++++++++++++++++++++ kernel-src/include/x86-64/arch/cpu.h | 4 +++- 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 kernel-src/arch/x86-64/cpu.c diff --git a/kernel-src/arch/x86-64/cpu.c b/kernel-src/arch/x86-64/cpu.c new file mode 100644 index 00000000..aff4bd7c --- /dev/null +++ b/kernel-src/arch/x86-64/cpu.c @@ -0,0 +1,32 @@ +#include +#include +#include +#include + +#define CPUID_SYSCALL (1 << 11) +#define EFER_SYSCALLENABLE 1 + +void arch_syscall_entry(); + +void cpu_initstate() { + arch_apic_initap(); + + // syscall instruction + unsigned int eax = 0,ebx = 0,ecx = 0,edx = 0; + __get_cpuid(0x80000001, &eax, &ebx, &ecx, &edx); + + // TODO in the future, have an alternative way of handling syscalls + __assert(edx & CPUID_SYSCALL); + uint64_t efer = rdmsr(MSR_EFER); + efer |= EFER_SYSCALLENABLE; + wrmsr(MSR_EFER, efer); + + uint64_t star = 0; + star |= (uint64_t)0x13 << 48; + star |= (uint64_t)0x08 << 32; + + wrmsr(MSR_STAR, star); + wrmsr(MSR_LSTAR, (uint64_t)arch_syscall_entry); + wrmsr(MSR_CSTAR, 0); // no compatibility mode syscall handler + wrmsr(MSR_FMASK, 0x200); // disable interrupts on syscall +} diff --git a/kernel-src/include/x86-64/arch/cpu.h b/kernel-src/include/x86-64/arch/cpu.h index 0c9cbeb5..ca5e4d0b 100644 --- a/kernel-src/include/x86-64/arch/cpu.h +++ b/kernel-src/include/x86-64/arch/cpu.h @@ -12,6 +12,7 @@ #include typedef struct cpu_t { + thread_t *thread; uint64_t gdt[7]; ist_t ist; long id; @@ -21,7 +22,6 @@ typedef struct cpu_t { timer_t *timer; bool intstatus; long ipl; - thread_t *thread; thread_t *idlethread; timerentry_t schedtimerentry; void *schedulerstack; @@ -37,4 +37,6 @@ static inline void cpu_set(cpu_t *ptr) { wrmsr(MSR_GSBASE, (uint64_t)ptr); } +void cpu_initstate(); + #endif