Kernel - Bugfixing x86_64 port
[tpg/acess2.git] / Kernel / arch / x86_64 / desctab.asm
1 ;
2 ;
3 ;
4 [BITS 64]
5
6 [extern Log]
7 [extern gGDTPtr]
8 [extern gGDT]
9
10 %define NUM_IRQ_CALLBACKS       4
11
12 MM_LOCALAPIC    equ     0xFFFFFD0000000000
13
14 %macro PUSH_GPR 0
15         mov [rsp-0x60], rsp
16         mov [rsp-0x08], r15
17         mov [rsp-0x10], r14
18         mov [rsp-0x18], r13
19         mov [rsp-0x20], r12
20         mov [rsp-0x28], r11
21         mov [rsp-0x30], r10
22         mov [rsp-0x38], r9
23         mov [rsp-0x40], r8
24         mov [rsp-0x48], rdi
25         mov [rsp-0x50], rsi
26         mov [rsp-0x58], rbp
27         mov [rsp-0x68], rbx
28         mov [rsp-0x70], rdx
29         mov [rsp-0x78], rcx
30         mov [rsp-0x80], rax
31         sub rsp, 0x80
32 %endmacro
33 %macro POP_GPR  0
34         add rsp, 0x80
35         mov r15, [rsp-0x08]
36         mov r14, [rsp-0x10]
37         mov r13, [rsp-0x18]
38         mov r12, [rsp-0x20]
39         mov r11, [rsp-0x28]
40         mov r10, [rsp-0x30]
41         mov r9,  [rsp-0x38]
42         mov r8,  [rsp-0x40]
43         mov rdi, [rsp-0x48]
44         mov rsi, [rsp-0x50]
45         mov rbp, [rsp-0x58]
46         ;mov rsp, [rsp-0x60]
47         mov rbx, [rsp-0x68]
48         mov rdx, [rsp-0x70]
49         mov rcx, [rsp-0x78]
50         mov rax, [rsp-0x80]
51 %endmacro
52
53 [section .text]
54 [global Desctab_Init]
55 Desctab_Init:   
56         ; Save to make following instructions smaller
57         mov rdi, gIDT
58         
59         ; Set an IDT entry to a callback
60         %macro SETIDT 2
61         mov rax, %2
62         mov WORD [rdi + %1*16], ax
63         shr rax, 16
64         mov WORD [rdi + %1*16 + 6], ax
65         shr rax, 16
66         mov DWORD [rdi + %1*16 + 8], eax
67         ; Enable
68         mov ax, WORD [rdi + %1*16 + 4]
69         or  ax, 0x8000
70         mov WORD [rdi + %1*16 + 4], ax
71         %endmacro
72         
73         ; Install error handlers
74         %macro SETISR 1
75         SETIDT %1, Isr%1
76         %endmacro
77         
78         %assign i 0
79         %rep 32
80         SETISR i
81         %assign i i+1
82         %endrep
83         
84         ; Install IRQs
85         SETIDT  0xF0, SchedulerIRQ
86         SETIDT  0xF1, Irq1
87         SETIDT  0xF2, Irq2
88         SETIDT  0xF3, Irq3
89         SETIDT  0xF4, Irq4
90         SETIDT  0xF5, Irq5
91         SETIDT  0xF6, Irq6
92         SETIDT  0xF7, Irq7
93         SETIDT  0xF8, Irq8
94         SETIDT  0xF9, Irq9
95         SETIDT  0xFA, Irq10
96         SETIDT  0xFB, Irq11
97         SETIDT  0xFC, Irq12
98         SETIDT  0xFD, Irq13
99         SETIDT  0xFE, Irq14
100         SETIDT  0xFF, Irq15
101
102         ; Remap PIC
103         push rdx        ; Save RDX
104         mov dx, 0x20
105         mov al, 0x11
106         out dx, al      ;       Init Command
107         mov dx, 0x21
108         mov al, 0xF0
109         out dx, al      ;       Offset (Start of IDT Range)
110         mov al, 0x04
111         out dx, al      ;       IRQ connected to Slave (00000100b) = IRQ2
112         mov al, 0x01
113         out dx, al      ;       Set Mode
114         mov al, 0x00
115         out dx, al      ;       Set Mode
116         
117         mov dx, 0xA0
118         mov al, 0x11
119         out dx, al      ;       Init Command
120         mov dx, 0xA1
121         mov al, 0xF8
122         out dx, al      ;       Offset (Start of IDT Range)
123         mov al, 0x02
124         out dx, al      ;       IRQ Line connected to master
125         mov al, 0x01
126         out dx, al      ;       Set Mode
127         mov dl, 0x00
128         out dx, al      ;       Set Mode
129         pop rdx
130         
131         
132         ; Install IDT
133         mov rax, gIDTPtr
134         lidt [rax]
135         
136         ; Re-install GDT (in higher address space)
137         mov rax, gGDTPtr
138         mov rcx, gGDT
139         mov QWORD [rax+2], rcx
140         lgdt [rax]
141         
142         ; Start interrupts
143         sti
144         
145         ret
146
147 ; int IRQ_AddHandler(int IRQ, void (*Handler)(int IRQ))
148 ; Return Values:
149 ;  0 on Success
150 ; -1 on an invalid IRQ Number
151 ; -2 when no slots are avaliable
152 [global IRQ_AddHandler]
153 IRQ_AddHandler:
154         ; RDI - IRQ Number
155         ; RSI - Callback
156         
157         ; Check for RDI >= 16
158         cmp rdi, 16
159         jb .numOK
160         xor rax, rax
161         dec rax
162         jmp .ret
163 .numOK:
164
165         ; Get handler base into RAX
166         lea rax, [rdi*4]
167         mov rcx, gaIRQ_Handlers
168         lea rax, [rcx+rax*8]
169         
170         ; Find a free callback slot
171         %rep NUM_IRQ_CALLBACKS
172         mov rdx, [rax]
173         test rdx, rdx
174         jz .assign
175         add rax, 8
176         %endrep
177         ; None found, return -2
178         xor rax, rax
179         dec rax
180         dec rax
181         jmp .ret
182         
183         ; Assign the IRQ Callback
184 .assign:
185         ; A little bit of debug
186         push rdi
187         push rsi
188         push rax
189         sub rsp, 8
190         mov rcx, rdi    ; IRQ Number
191         mov rdx, rsi    ; Callback
192         mov rsi, rax    ; Pointer
193         mov rdi, csIRQ_Assigned
194         call Log
195         add rsp, 8
196         pop rax
197         pop rsi
198         pop rdi
199
200         ; Assign and return
201         mov [rax], rsi
202         xor rax, rax
203
204 .ret:
205         ret
206         
207 [section .rodata]
208 csIRQ_Assigned:
209         db      "IRQ %p := %p (IRQ %i)",0
210 [section .text]
211
212 %macro ISR_NOERRNO      1
213 Isr%1:
214         push    QWORD 0
215         push    QWORD %1
216         jmp     ErrorCommon
217 %endmacro
218 %macro ISR_ERRNO        1
219 Isr%1:
220         push    QWORD %1
221         jmp     ErrorCommon
222 %endmacro
223
224 ISR_NOERRNO     0;  0: Divide By Zero Exception
225 ISR_NOERRNO     1;  1: Debug Exception
226 ISR_NOERRNO     2;  2: Non Maskable Interrupt Exception
227 ISR_NOERRNO     3;  3: Int 3 Exception
228 ISR_NOERRNO     4;  4: INTO Exception
229 ISR_NOERRNO     5;  5: Out of Bounds Exception
230 ISR_NOERRNO     6;  6: Invalid Opcode Exception
231 ISR_NOERRNO     7;  7: Coprocessor Not Available Exception
232 ISR_ERRNO       8;  8: Double Fault Exception (With Error Code!)
233 ISR_NOERRNO     9;  9: Coprocessor Segment Overrun Exception
234 ISR_ERRNO       10; 10: Bad TSS Exception (With Error Code!)
235 ISR_ERRNO       11; 11: Segment Not Present Exception (With Error Code!)
236 ISR_ERRNO       12; 12: Stack Fault Exception (With Error Code!)
237 ISR_ERRNO       13; 13: General Protection Fault Exception (With Error Code!)
238 ISR_ERRNO       14; 14: Page Fault Exception (With Error Code!)
239 ISR_NOERRNO     15; 15: Reserved Exception
240 ISR_NOERRNO     16; 16: Floating Point Exception
241 ISR_NOERRNO     17; 17: Alignment Check Exception
242 ISR_NOERRNO     18; 18: Machine Check Exception
243 ISR_NOERRNO     19; 19: Reserved
244 ISR_NOERRNO     20; 20: Reserved
245 ISR_NOERRNO     21; 21: Reserved
246 ISR_NOERRNO     22; 22: Reserved
247 ISR_NOERRNO     23; 23: Reserved
248 ISR_NOERRNO     24; 24: Reserved
249 ISR_NOERRNO     25; 25: Reserved
250 ISR_NOERRNO     26; 26: Reserved
251 ISR_NOERRNO     27; 27: Reserved
252 ISR_NOERRNO     28; 28: Reserved
253 ISR_NOERRNO     29; 29: Reserved
254 ISR_NOERRNO     30; 30: Reserved
255 ISR_NOERRNO     31; 31: Reserved
256
257 [extern Error_Handler]
258 [global ErrorCommon]
259 ErrorCommon:
260         PUSH_GPR
261         push gs
262         push fs
263         ;PUSH_FPU
264         ;PUSH_XMM
265         
266         mov rdi, rsp
267         xchg bx, bx
268         call Error_Handler
269         
270         ;POP_XMM
271         ;POP_FPU
272         pop fs
273         pop gs
274         POP_GPR
275         add rsp, 2*8
276         iretq
277
278 %macro DEFIRQ   1
279 Irq%1:
280         push    0
281         push    %1
282         jmp     IrqCommon
283 %endmacro
284
285 %assign i 0
286 %rep 16
287 DEFIRQ  i
288 %assign i i+1
289 %endrep
290
291 [global IrqCommon]
292 IrqCommon:
293         PUSH_GPR
294         push gs
295         push fs
296         
297         mov rbx, [rsp+(16+2)*8] ; Get interrupt number (16 GPRS + 2 SRs)
298 ;       xchg bx, bx     ; Bochs Magic break (NOTE: will clear the high-bits of RBX)
299         shl rbx, 2      ; *8*4
300         mov rax, gaIRQ_Handlers
301         lea rbx, [rax+rbx*8]
302         
303         ; Check all callbacks
304         sub rsp, 8      ; Shadow of argument
305         %assign i 0
306         %rep NUM_IRQ_CALLBACKS
307         ; Get callback address
308         mov rax, [rbx]
309         test rax, rax   ; Check if it exists
310         jz .skip.%[i]
311         ; Set RDI to IRQ number
312         mov rdi, [rsp+(16+2+1)*8]       ; Get IRQ number
313         call rax        ; Call
314 .skip.%[i]:
315         add rbx, 8      ; Next!
316         %assign i i+1
317         %endrep
318         add rsp, 8
319         
320         ; ACK
321         mov al, 0x20
322         mov rdi, [rsp+16*8]     ; Get IRQ number
323         cmp rdi, 8
324         jb .skipAckSecondary
325         mov dx, 0x00A0
326         out dx, al
327 .skipAckSecondary:
328         mov dx, 0x0020
329         out dx, al
330         
331         pop fs
332         pop gs
333         POP_GPR
334         add rsp, 8*2
335         ;xchg bx, bx
336         iretq
337
338 [extern Proc_Scheduler]
339 [global SchedulerIRQ]
340 ;
341 ; NOTE: Proc_Scheduler makes assumptions about the stack state when called 
342 ;
343 SchedulerIRQ:
344         push 0  ; Error code
345         push 0  ; IRQNum
346         PUSH_GPR
347         push gs
348         push fs
349         ;PUSH_FPU
350         ;PUSH_XMM
351         
352         ; Save Thread Pointer
353         mov rax, dr0
354         push rax
355         
356         ; Get the CPU Number
357         mov rdi, dr1
358         ; Call the Scheduler
359         call Proc_Scheduler
360         
361         ; Restore Thread Pointer
362         pop rax
363         mov dr0, rax
364         
365         ; Send EOI (To either the APIC or the PIC)
366         %if USE_MP
367         test ebx, ebx
368         jnz .sendEOI
369         %endif
370         ; PIC
371         mov al, 0x20
372         out 0x20, al            ; ACK IRQ
373         %if USE_MP
374         jmp .ret
375         ; APIC
376 .sendEOI:
377         mov eax, DWORD [gpMP_LocalAPIC]
378         mov DWORD [eax+0x0B0], 0
379         %endif
380 .ret:
381         
382         ;POP_XMM
383         ;POP_FPU
384         pop fs
385         pop gs
386         POP_GPR
387         add rsp, 2*8    ; Dummy error code and IRQ num
388         iretq
389
390 [section .data]
391 gIDT:
392         ; 64-bit Interrupt Gate, CS = 0x8, IST0 (Disabled)
393         times 256       dd      0x00080000, 0x00000E00, 0, 0
394 gIDTPtr:
395         dw      256*16-1
396         dq      gIDT
397
398 gaIRQ_Handlers:
399         times   16*NUM_IRQ_CALLBACKS    dq      0

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