Kernel/x86_64 - Implemented SYSCALL in x86_64 port
authorJohn Hodge <[email protected]>
Thu, 8 Sep 2011 15:01:54 +0000 (23:01 +0800)
committerJohn Hodge <[email protected]>
Thu, 8 Sep 2011 15:01:54 +0000 (23:01 +0800)
- Seems to work
- I just love this code

Kernel/arch/x86_64/desctab.asm
Kernel/arch/x86_64/include/arch.h
Kernel/arch/x86_64/main.c
Kernel/arch/x86_64/proc.c

index 8212773..411cea3 100644 (file)
@@ -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)
index d8b1124..a0b3ba9 100644 (file)
@@ -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;
 
 /**
index 044330a..77df362 100644 (file)
@@ -27,7 +27,7 @@ void kmain(Uint MbMagic, void *MbInfoPtr)
        tMBoot_Info     *mbInfo;
        
        Desctab_Init();
-       
+
        MM_InitVirt();
        *(Uint16*)(KERNEL_BASE|0xB8000) = 0x1F00|'C';
        
index 15c60b4..f7d6f92 100644 (file)
@@ -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;

UCC git Repository :: git.ucc.asn.au