From cfcbb03e9b8d5f24069a212330075540161c8be0 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 8 Sep 2011 23:01:54 +0800 Subject: [PATCH] Kernel/x86_64 - Implemented SYSCALL in x86_64 port - Seems to work - I just love this code --- Kernel/arch/x86_64/desctab.asm | 64 +++++++++++++++++++++++++++++++ Kernel/arch/x86_64/include/arch.h | 15 +++----- Kernel/arch/x86_64/main.c | 2 +- Kernel/arch/x86_64/proc.c | 2 + 4 files changed, 73 insertions(+), 10 deletions(-) diff --git a/Kernel/arch/x86_64/desctab.asm b/Kernel/arch/x86_64/desctab.asm index 8212773b..411cea3e 100644 --- a/Kernel/arch/x86_64/desctab.asm +++ b/Kernel/arch/x86_64/desctab.asm @@ -141,6 +141,28 @@ Desctab_Init: ; Start interrupts sti + + ; Initialise System Calls (SYSCALL/SYSRET) + ; Set IA32_EFER.SCE + mov ecx, 0xC0000080 + rdmsr + or eax, 1 + wrmsr + ; Set IA32_LSTAR (RIP of handler) + mov ecx, 0xC0000082 ; IA32_LSTAR + mov eax, SyscallStub - 0xFFFFFFFF00000000 + mov edx, 0xFFFFFFFF + wrmsr + ; Set IA32_FMASK (flags mask) + mov ecx, 0xC0000084 + rdmsr + mov eax, 0x202 + wrmsr + ; Set IA32_STAR (Kernel/User CS) + mov ecx, 0xC0000081 + rdmsr + mov edx, 0x8 | (0x18 << 16) ; Kernel CS (and Kernel DS/SS - 8), User CS + wrmsr ret @@ -387,6 +409,48 @@ SchedulerIRQ: add rsp, 2*8 ; Dummy error code and IRQ num iretq +[extern ci_offsetof_tThread_KernelStack] +[extern SyscallHandler] +[global SyscallStub] +SyscallStub: + mov rbp, dr0 + mov ebx, [rel ci_offsetof_tThread_KernelStack] + mov rbp, [rbp+rbx] ; Get kernel stack + xchg rbp, rsp ; Swap stacks + + push rbp ; Save User RSP + push rcx ; RIP + push r11 ; RFLAGS + + ; RDI + ; RSI + ; RDX + ; R10 (RCX for non syscall) + ; R8 + ; R9 + sub rsp, (6+2)*8 + mov [rsp+0x00], rax ; Number +; mov [rsp+0x08], rax ; Errno (don't care really) + mov [rsp+0x10], rdi ; Arg1 + mov [rsp+0x18], rsi ; Arg2 + mov [rsp+0x20], rdx ; Arg3 + mov [rsp+0x28], r10 ; Arg4 + mov [rsp+0x30], r8 ; Arg5 + mov [rsp+0x38], r9 ; Arg6 + + mov rdi, rsp + sub rsp, 8 + call SyscallHandler + add rsp, 8 + mov ebx, [rsp+8] ; Get errno + mov rax, [rsp+0] ; Get return + add rsp, (6+2)*8 + + pop r11 + pop rcx + pop rsp ; Change back to user stack + sysret + [section .data] gIDT: ; 64-bit Interrupt Gate, CS = 0x8, IST0 (Disabled) diff --git a/Kernel/arch/x86_64/include/arch.h b/Kernel/arch/x86_64/include/arch.h index d8b1124d..a0b3ba99 100644 --- a/Kernel/arch/x86_64/include/arch.h +++ b/Kernel/arch/x86_64/include/arch.h @@ -61,20 +61,17 @@ typedef struct sSyscallRegs Uint Num; Uint Return; }; // RAX - Uint Arg4; // RCX - Uint Arg3; // RDX Uint Error; // RBX - Uint Resvd1[2]; // Kernel RSP, RBP - Uint Arg2; // RSI Uint Arg1; // RDI + Uint Arg2; // RSI + Uint Arg3; // RDX + Uint Arg4; // RCX Uint Arg5; // R8 Uint Arg6; // R9 - Uint Resvd2[6]; // R10 - R15 - Uint Resvd3[5]; // IntNum, ErrCode, RIP, CS, RFLAGS - - Uint Resvd4[5]; // Int, Err, rip, CS, ... + Uint _Flags; + Uint _IP; Uint StackPointer; // RSP - Uint Resvd5[1]; // SS + } tSyscallRegs; /** diff --git a/Kernel/arch/x86_64/main.c b/Kernel/arch/x86_64/main.c index 044330a0..77df3628 100644 --- a/Kernel/arch/x86_64/main.c +++ b/Kernel/arch/x86_64/main.c @@ -27,7 +27,7 @@ void kmain(Uint MbMagic, void *MbInfoPtr) tMBoot_Info *mbInfo; Desctab_Init(); - + MM_InitVirt(); *(Uint16*)(KERNEL_BASE|0xB8000) = 0x1F00|'C'; diff --git a/Kernel/arch/x86_64/proc.c b/Kernel/arch/x86_64/proc.c index 15c60b46..f7d6f92c 100644 --- a/Kernel/arch/x86_64/proc.c +++ b/Kernel/arch/x86_64/proc.c @@ -68,6 +68,8 @@ void Proc_StartProcess(Uint16 SS, Uint Stack, Uint Flags, Uint16 CS, Uint IP); void Proc_Scheduler(int CPU); // === GLOBALS === +//!\brief Used by desctab.asm in SyscallStub +const int ci_offsetof_tThread_KernelStack = offsetof(tThread, KernelStack); // --- Multiprocessing --- #if USE_MP volatile int giNumInitingCPUs = 0; -- 2.20.1