%endrep
; Install IRQs
- SETIDT 0xF0, SchedulerIRQ
+ SETIDT 0xF0, PIT_IRQ
SETIDT 0xF1, Irq1
SETIDT 0xF2, Irq2
SETIDT 0xF3, Irq3
; 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
; Set IA32_FMASK (flags mask)
mov ecx, 0xC0000084
rdmsr
- mov eax, 0x202
+ 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
+ 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
IRQ_AddHandler:
; RDI - IRQ Number
; RSI - Callback
+ ; RDX - Ptr
; Check for RDI >= 16
cmp rdi, 16
; 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
push rdi
push rsi
push rax
+ push rdx
sub rsp, 8
mov rcx, rdi ; IRQ Number
mov rdx, rsi ; Callback
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:
;PUSH_XMM
mov rdi, rsp
- xchg bx, bx
+; xchg bx, bx
call Error_Handler
;POP_XMM
; call Log
mov ebx, [rsp+(16+2)*8] ; Get interrupt number (16 GPRS + 2 SRs)
-; xchg bx, bx ; Bochs Magic break (NOTE: will clear the high-bits of RBX)
shl ebx, 2 ; *4
mov rax, gaIRQ_Handlers
lea rbx, [rax+rbx*8]
jz .skip.%[i]
; Set RDI to 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!
add rsp, 8*2
iretq
-[extern Proc_Scheduler]
-[global SchedulerIRQ]
-;
-; NOTE: Proc_Scheduler makes assumptions about the stack state when called
-;
-SchedulerIRQ:
- push 0 ; Error code
- push 0 ; IRQNum
+[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
- ; Save Thread Pointer
- mov rax, dr0
- push rax
-
- mov rdi, dr1 ; Get the CPU Number
- mov rsi, rsp ; Save stack pointer
- mov rdx, SchedulerIRQ.restoreState
- ; Call the Scheduler
- call Proc_Scheduler
-.restoreState:
-
- ; Restore Thread Pointer
- pop rax
- mov dr0, rax
-
- ; Send EOI (To either the APIC or the PIC)
- %if USE_MP
- test ebx, ebx
- jnz .sendEOI
+ 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
- ; PIC
+
+ ; Send EOI
mov al, 0x20
out 0x20, al ; ACK IRQ
- %if USE_MP
- jmp .ret
- ; APIC
-.sendEOI:
- mov eax, DWORD [gpMP_LocalAPIC]
- mov DWORD [eax+0x0B0], 0
- %endif
-.ret:
;POP_XMM
;POP_FPU
- pop fs
- pop gs
POP_GPR
- add rsp, 2*8 ; Dummy error code and IRQ num
iretq
[extern ci_offsetof_tThread_KernelStack]
; R9
sub rsp, (6+2)*8
mov [rsp+0x00], rax ; Number
-; mov [rsp+0x08], rax ; Errno (don't care really)
+; mov [rsp+0x08], rax ; Errno (output only)
mov [rsp+0x10], rdi ; Arg1
mov [rsp+0x18], rsi ; Arg2
mov [rsp+0x20], rdx ; Arg3
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
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]
gaIRQ_Handlers:
times 16*NUM_IRQ_CALLBACKS dq 0
+gaIRQ_DataPtrs:
+ times 16*NUM_IRQ_CALLBACKS dq 0
+
+; vim: ft=nasm