/kernel/trunk/arch/amd64/src/syscall.c |
---|
34,6 → 34,7 |
#include <arch/asm.h> |
#include <print.h> |
#include <arch/cpu.h> |
extern void syscall_entry(void); |
54,17 → 55,19 |
| ((__u64)(gdtselector(KTEXT_DES) | PL_KERNEL)<<32)); |
write_msr(AMD_MSR_LSTAR, (__u64)syscall_entry); |
/* Mask RFLAGS on syscall |
* - we do not care what is in the flags field |
* - disable interrupts, until we exchange the stack register |
* (mask the IE bit) |
*/ |
write_msr(AMD_MSR_SFMASK, 0); |
write_msr(AMD_MSR_SFMASK, 0x200); |
} |
/** Dispatch system call */ |
__native syscall_handler(__native id, __native a1, __native a2, __native a3) |
{ |
interrupts_enable(); |
if (id < SYSCALL_END) |
return syscall_table[id](a1,a2,a3); |
else |
panic("Undefined syscall %d", id); |
interrupts_disable(); |
} |
/kernel/trunk/arch/amd64/src/asm_utils.S |
---|
192,10 → 192,29 |
syscall_entry: |
# TODO: Switch to kernel stack |
# Switch to hidden gs |
swapgs |
# TODO: I would like LEA instead of thes 2 instrs, |
# why does not it work??? |
mov %gs:0, %r10 # We have a stack in r10 |
addq $0x0ff0, %r10 |
movq %rsp, 0(%r10) # Save old stack pointer to stack |
movq %r10, %rsp # Change to new stack |
pushq %rcx # Return address |
pushq %r11 # Save flags |
# Switch back to remain consistent |
swapgs |
movq %r9, %rcx # Exchange last parameter as a third |
call syscall_handler |
# Switch back |
sysret |
popq %r11 |
popq %rcx |
movq 0(%rsp), %rsp |
sysretq |
.data |
.global interrupt_handler_size |
/kernel/trunk/arch/amd64/src/proc/scheduler.c |
---|
31,8 → 31,15 |
#include <proc/thread.h> |
#include <arch.h> |
#include <arch/context.h> /* SP_DELTA */ |
#include <arch/asm.h> |
void before_thread_runs_arch(void) |
{ |
CPU->arch.tss->rsp0 = (__address) &THREAD->kstack[THREAD_STACK_SIZE-SP_DELTA]; |
/* Syscall support - write thread address to hidden part of gs */ |
swapgs(); |
write_msr(AMD_MSR_GS, |
(__u64)&THREAD->kstack); |
swapgs(); |
} |