Kernel - Slight reworks to timer code
[tpg/acess2.git] / Kernel / arch / x86_64 / desctab.asm
index d49dbc4..6e8aa63 100644 (file)
@@ -1,51 +1,17 @@
 ;
 ;
 ;
+%include "arch/x86_64/include/common.inc.asm"
 [BITS 64]
 
+[extern Log]
+[extern gGDTPtr]
+[extern gGDT]
+
 %define NUM_IRQ_CALLBACKS      4
 
 MM_LOCALAPIC   equ     0xFFFFFD0000000000
 
-%macro PUSH_GPR        0
-       mov [rsp-0x60], rsp
-       mov [rsp-0x08], r15
-       mov [rsp-0x10], r14
-       mov [rsp-0x18], r13
-       mov [rsp-0x20], r12
-       mov [rsp-0x28], r11
-       mov [rsp-0x30], r10
-       mov [rsp-0x38], r9
-       mov [rsp-0x40], r8
-       mov [rsp-0x48], rdi
-       mov [rsp-0x50], rsi
-       mov [rsp-0x58], rbp
-       mov [rsp-0x68], rbx
-       mov [rsp-0x70], rdx
-       mov [rsp-0x78], rcx
-       mov [rsp-0x80], rax
-       sub rsp, 0x80
-%endmacro
-%macro POP_GPR 0
-       add rsp, 0x80
-       mov r15, [rsp-0x08]
-       mov r14, [rsp-0x10]
-       mov r13, [rsp-0x18]
-       mov r12, [rsp-0x20]
-       mov r11, [rsp-0x28]
-       mov r10, [rsp-0x30]
-       mov r9,  [rsp-0x38]
-       mov r8,  [rsp-0x40]
-       mov rdi, [rsp-0x48]
-       mov rsi, [rsp-0x50]
-       mov rbp, [rsp-0x58]
-       ;mov rsp, [rsp-0x60]
-       mov rbx, [rsp-0x68]
-       mov rdx, [rsp-0x70]
-       mov rcx, [rsp-0x78]
-       mov rax, [rsp-0x80]
-%endmacro
-
 [section .text]
 [global Desctab_Init]
 Desctab_Init:  
@@ -55,15 +21,15 @@ Desctab_Init:
        ; Set an IDT entry to a callback
        %macro SETIDT 2
        mov rax, %2
-       mov     WORD [rdi + %1*16], ax
+       mov WORD [rdi + %1*16], ax
        shr rax, 16
-       mov     WORD [rdi + %1*16 + 6], ax
+       mov WORD [rdi + %1*16 + 6], ax
        shr rax, 16
        mov DWORD [rdi + %1*16 + 8], eax
        ; Enable
-       mov     ax, WORD [rdi + %1*16 + 4]
-       or ax, 0x8000
-       mov     WORD [rdi + %1*16 + 4], ax
+       mov ax, WORD [rdi + %1*16 + 4]
+       or  ax, 0x8000
+       mov WORD [rdi + %1*16 + 4], ax
        %endmacro
        
        ; Install error handlers
@@ -78,7 +44,7 @@ Desctab_Init:
        %endrep
        
        ; Install IRQs
-       SETIDT  0xF0, Irq0
+       SETIDT  0xF0, PIT_IRQ
        SETIDT  0xF1, Irq1
        SETIDT  0xF2, Irq2
        SETIDT  0xF3, Irq3
@@ -100,27 +66,27 @@ Desctab_Init:
        mov dx, 0x20
        mov al, 0x11
        out dx, al      ;       Init Command
-    mov dx, 0x21
+       mov dx, 0x21
        mov al, 0xF0
        out dx, al      ;       Offset (Start of IDT Range)
-    mov al, 0x04
+       mov al, 0x04
        out dx, al      ;       IRQ connected to Slave (00000100b) = IRQ2
-    mov al, 0x01
+       mov al, 0x01
        out dx, al      ;       Set Mode
-    mov al, 0x00
+       mov al, 0x00
        out dx, al      ;       Set Mode
        
        mov dx, 0xA0
        mov al, 0x11
        out dx, al      ;       Init Command
-    mov dx, 0xA1
+       mov dx, 0xA1
        mov al, 0xF8
        out dx, al      ;       Offset (Start of IDT Range)
-    mov al, 0x02
+       mov al, 0x02
        out dx, al      ;       IRQ Line connected to master
-    mov al, 0x01
+       mov al, 0x01
        out dx, al      ;       Set Mode
-    mov dl, 0x00
+       mov dl, 0x00
        out dx, al      ;       Set Mode
        pop rdx
        
@@ -129,12 +95,34 @@ Desctab_Init:
        mov rax, gIDTPtr
        lidt [rax]
        
+       ; Re-install GDT (in higher address space)
+       mov rax, gGDTPtr
+       mov rcx, gGDT
+       mov QWORD [rax+2], rcx
+       lgdt [rax]
+       
        ; Start interrupts
        sti
+
+       ; 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 | (0x1B << 16)     ; Kernel CS (and Kernel DS/SS - 8), User CS
+       wrmsr
        
        ret
 
-; int IRQ_AddHandler(int IRQ, void (*Handler)(int IRQ))
+; int IRQ_AddHandler(int IRQ, void (*Handler)(int IRQ), void *Ptr)
 ; Return Values:
 ;  0 on Success
 ; -1 on an invalid IRQ Number
@@ -143,7 +131,9 @@ Desctab_Init:
 IRQ_AddHandler:
        ; RDI - IRQ Number
        ; RSI - Callback
+       ; RDX - Ptr
        
+       ; Check for RDI >= 16
        cmp rdi, 16
        jb .numOK
        xor rax, rax
@@ -151,15 +141,15 @@ IRQ_AddHandler:
        jmp .ret
 .numOK:
 
-       mov rax, rdi
-       shr rax, 3+2
+       ; Get handler base into RAX
+       lea rax, [rdi*4]
        mov rcx, gaIRQ_Handlers
-       add rax, rcx
+       lea rax, [rcx+rax*8]
        
        ; Find a free callback slot
        %rep NUM_IRQ_CALLBACKS
-       mov rdx, [rax]
-       test rdx, rdx
+       mov rcx, [rax]
+       test rcx, rcx
        jz .assign
        add rax, 8
        %endrep
@@ -171,11 +161,38 @@ IRQ_AddHandler:
        
        ; Assign the IRQ Callback
 .assign:
+       ; A little bit of debug
+       push rdi
+       push rsi
+       push rax
+       push rdx
+       sub rsp, 8
+       mov rcx, rdi    ; IRQ Number
+       mov rdx, rsi    ; Callback
+       mov rsi, rax    ; Pointer
+       mov rdi, csIRQ_Assigned
+       call Log
+       add rsp, 8
+       pop rdx
+       pop rax
+       pop rsi
+       pop rdi
+
+       ; Assign and return
        mov [rax], rsi
+       add rax, gaIRQ_DataPtrs - gaIRQ_Handlers
+       mov [rax], rdx
        xor rax, rax
 
 .ret:
        ret
+       
+[section .rodata]
+csIRQ_Assigned:
+       db      "IRQ %p := %p (IRQ %i)",0
+csIRQ_Fired:
+       db      "IRQ %i fired",0
+[section .text]
 
 %macro ISR_NOERRNO     1
 Isr%1:
@@ -232,7 +249,7 @@ ErrorCommon:
        ;PUSH_XMM
        
        mov rdi, rsp
-       xchg bx, bx
+;      xchg bx, bx
        call Error_Handler
        
        ;POP_XMM
@@ -259,13 +276,20 @@ DEFIRQ    i
 [global IrqCommon]
 IrqCommon:
        PUSH_GPR
+       push gs
+       push fs
+
+;      mov rdi, csIRQ_Fired
+;      mov rsi, [rsp+(16+2)*8]
+;      call Log
        
-       mov rbx, [rsp+16*8]     ; Calculate address
-       shr rbx, 3+2    ; *8*4
+       mov ebx, [rsp+(16+2)*8] ; Get interrupt number (16 GPRS + 2 SRs)
+       shl ebx, 2      ; *4
        mov rax, gaIRQ_Handlers
-       add rbx, rax
+       lea rbx, [rax+rbx*8]
        
        ; Check all callbacks
+       sub rsp, 8      ; Shadow of argument
        %assign i 0
        %rep NUM_IRQ_CALLBACKS
        ; Get callback address
@@ -273,48 +297,131 @@ IrqCommon:
        test rax, rax   ; Check if it exists
        jz .skip.%[i]
        ; Set RDI to IRQ number
-       mov rdi, [rsp+16*8]     ; Get IRQ number
+       mov rdi, [rsp+(16+2+1)*8]       ; Get IRQ number
+       mov rsi, [rbx-gaIRQ_Handlers+gaIRQ_DataPtrs]
        call rax        ; Call
 .skip.%[i]:
        add rbx, 8      ; Next!
        %assign i i+1
        %endrep
+       add rsp, 8
        
        ; ACK
-       mov rdi, [rsp+16*8]     ; Get IRQ number
-       cmp rdi, 8
        mov al, 0x20
+       mov rdi, [rsp+(16+2)*8] ; Get IRQ number
+       cmp rdi, 8
        jb .skipAckSecondary
-       mov dx, 0x00A0
-       out dx, al
+       out 0xA0, al
 .skipAckSecondary:
-       mov dx, 0x0020
-       out dx, al
+       out 0x20, al
        
+       pop fs
+       pop gs
        POP_GPR
        add rsp, 8*2
-       xchg bx, bx
        iretq
 
-[extern Proc_Scheduler]
-[global SchedulerIRQ]
-SchedulerIRQ:
-       ; TODO: Find Current CPU
+[extern Time_UpdateTimestamp]
+
+%if USE_MP
+[global APIC_Timer_IRQ]
+APIC_Timer_IRQ:
+       PUSH_GPR
+       push gs
+       push fs
+
+       ; TODO: What to do?
+
+       mov eax, DWORD [gpMP_LocalAPIC]
+       mov DWORD [eax+0x0B0], 0
+
+       pop fs
+       pop gs
+       POP_GPR
+       iretq
+%endif
+
+[global PIT_IRQ]
+PIT_IRQ:
        PUSH_GPR
        ;PUSH_FPU
        ;PUSH_XMM
        
-       xor rsi, rsi
-       mov rdi, MM_LOCALAPIC+0x20
-       mov esi, [rdi]
-       call Proc_Scheduler
+       call Time_UpdateTimestamp
+
+       %if 0
+[section .rodata]
+csUserSS:      db      "User SS: 0x%x",0
+[section .text]
+       mov rdi, csUserSS
+       mov rsi, [rsp+0x80+0x20]
+       call Log
+       %endif
+
+       ; Send EOI
+       mov al, 0x20
+       out 0x20, al            ; ACK IRQ
        
        ;POP_XMM
        ;POP_FPU
        POP_GPR
-       add rsp, 8*2
        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 (output only)
+       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
+
+       %if 0
+[section .rodata]
+csSyscallReturn:       db      "Syscall Return: 0x%x",0
+[section .text]
+       mov rdi, csSyscallReturn
+       mov rsi, [rsp+0+8]
+       call Log
+       %endif
+
+       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
+       ; TODO: Determine if user is 64 or 32 bit
+
+       db 0x48 ; REX, nasm doesn't have a sysretq opcode
+       sysret
+
 [section .data]
 gIDT:
        ; 64-bit Interrupt Gate, CS = 0x8, IST0 (Disabled)
@@ -325,3 +432,7 @@ gIDTPtr:
 
 gaIRQ_Handlers:
        times   16*NUM_IRQ_CALLBACKS    dq      0
+gaIRQ_DataPtrs:
+       times   16*NUM_IRQ_CALLBACKS    dq      0
+
+; vim: ft=nasm

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