[USER] System calls

This commit is contained in:
2016-12-06 15:50:35 +01:00
parent 63b3c3f2c0
commit a7d2b24a79
9 changed files with 166 additions and 2 deletions

65
kernel/syscall/syscall.c Normal file
View 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;
}

View 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