[USER] System calls
This commit is contained in:
65
kernel/syscall/syscall.c
Normal file
65
kernel/syscall/syscall.c
Normal file
@@ -0,0 +1,65 @@
|
||||
#include <syscall.h>
|
||||
#include <debug.h>
|
||||
#include <int.h>
|
||||
#include <msr.h>
|
||||
#include <gdt.h>
|
||||
#include <registers.h>
|
||||
|
||||
extern void syscall_entry();
|
||||
|
||||
syscall_handler_t syscall_handlers[1024];
|
||||
|
||||
SYSCALL_DECL(debug);
|
||||
|
||||
registers_t *syscall_handler(registers_t *r)
|
||||
{
|
||||
// Syscall number: RAX
|
||||
// Order of arguments:
|
||||
// RDI
|
||||
// RSI
|
||||
// RDX
|
||||
// R10
|
||||
// R8
|
||||
// R9
|
||||
// stack
|
||||
//
|
||||
// Return value:
|
||||
// RAX
|
||||
|
||||
if(syscall_handlers[r->rax])
|
||||
{
|
||||
r->rax = syscall_handlers[r->rax](r->rax, r->rdi, r->rsi, r->rdx, r->r10, r->r8, r->r9);
|
||||
return r;
|
||||
}
|
||||
|
||||
debug_error("Unknown syscall, No:%d\n", r->rax);
|
||||
debug("syscall_%d(%x, %x, %x, %x, %x, %x)\n", r->rax, r->rdi, r->rsi, r->rdx, r->r10, r->r8, r->r9);
|
||||
for(;;);
|
||||
}
|
||||
|
||||
int syscall_installed = 0;
|
||||
|
||||
void syscall_init()
|
||||
{
|
||||
msr_write(MSR_REG_STAR, (((uint64_t)SEG_KDATA | 0x3)<<48 | ((uint64_t)SEG_KCODE)<<32));
|
||||
msr_write(MSR_REG_LSTAR, (uint64_t)syscall_entry);
|
||||
msr_write(MSR_REG_EFER, msr_read(MSR_REG_EFER)| 1);
|
||||
msr_write(MSR_REG_FMASK, RFLAGS_IF);
|
||||
|
||||
if(!syscall_installed)
|
||||
{
|
||||
register_int_handler(INT_SYSCALL, syscall_handler);
|
||||
syscall_installed = 1;
|
||||
memset(syscall_handlers, 0, 1024*sizeof(syscall_handler_t));
|
||||
|
||||
SYSCALL_REGISTER(debug, 0x3FF);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SYSCALL_DEF(debug)
|
||||
{
|
||||
SYSCALL_INIT(char*, message);
|
||||
debug_puts(message);
|
||||
return 0;
|
||||
}
|
||||
38
kernel/syscall/syscall_entry.S
Normal file
38
kernel/syscall/syscall_entry.S
Normal file
@@ -0,0 +1,38 @@
|
||||
#include <mem.h>
|
||||
#include <gdt.h>
|
||||
#include <int.h>
|
||||
#include <cpu.h>
|
||||
.intel_syntax noprefix
|
||||
|
||||
|
||||
.global syscall_entry
|
||||
.global syscall_return
|
||||
.extern syscall_handler
|
||||
|
||||
syscall_entry:
|
||||
|
||||
swapgs
|
||||
mov [gs:GS_OFFSET_SCTEMP], rsp
|
||||
mov rsp, [gs:GS_OFFSET_STACK]
|
||||
|
||||
// Prepare a fake interrupt stack
|
||||
pushq SEG_UDATA // SS
|
||||
push [gs:GS_OFFSET_SCTEMP] // RSP
|
||||
push r11 // RFLAGS
|
||||
pushq SEG_UCODE // CS
|
||||
push rcx // RIP
|
||||
pushq 0 // Error code
|
||||
pushq INT_SYSCALL // Interrupt id
|
||||
swapgs
|
||||
|
||||
jmp isr_common
|
||||
syscall_return:
|
||||
|
||||
pop rax
|
||||
add rsp, 16
|
||||
pop rcx
|
||||
add rsp, 8
|
||||
pop r11
|
||||
pop rsp
|
||||
|
||||
sysretq
|
||||
Reference in New Issue
Block a user