Misc changes
[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         cmp rdi, 16
158         jb .numOK
159         xor rax, rax
160         dec rax
161         jmp .ret
162 .numOK:
163
164         mov rax, rdi
165         shr rax, 3+2
166         mov rcx, gaIRQ_Handlers
167         add rax, rcx
168         
169         ; Find a free callback slot
170         %rep NUM_IRQ_CALLBACKS
171         mov rdx, [rax]
172         test rdx, rdx
173         jz .assign
174         add rax, 8
175         %endrep
176         ; None found, return -2
177         xor rax, rax
178         dec rax
179         dec rax
180         jmp .ret
181         
182         ; Assign the IRQ Callback
183 .assign:
184         ; A little bit of debug
185         push rdi
186         push rsi
187         push rax
188         sub rsp, 8
189         mov rcx, rdi    ; IRQ Number
190         mov rdx, rsi    ; Callback
191         mov rsi, rax    ; Pointer
192         mov rdi, csIRQ_Assigned
193         call Log
194         add rsp, 8
195         pop rax
196         pop rsi
197         pop rdi
198
199         mov [rax], rsi
200         xor rax, rax
201
202 .ret:
203         ret
204         
205 [section .rodata]
206 csIRQ_Assigned:
207         db      "IRQ %p := %p (IRQ %i)",0
208 [section .text]
209
210 %macro ISR_NOERRNO      1
211 Isr%1:
212         push    QWORD 0
213         push    QWORD %1
214         jmp     ErrorCommon
215 %endmacro
216 %macro ISR_ERRNO        1
217 Isr%1:
218         push    QWORD %1
219         jmp     ErrorCommon
220 %endmacro
221
222 ISR_NOERRNO     0;  0: Divide By Zero Exception
223 ISR_NOERRNO     1;  1: Debug Exception
224 ISR_NOERRNO     2;  2: Non Maskable Interrupt Exception
225 ISR_NOERRNO     3;  3: Int 3 Exception
226 ISR_NOERRNO     4;  4: INTO Exception
227 ISR_NOERRNO     5;  5: Out of Bounds Exception
228 ISR_NOERRNO     6;  6: Invalid Opcode Exception
229 ISR_NOERRNO     7;  7: Coprocessor Not Available Exception
230 ISR_ERRNO       8;  8: Double Fault Exception (With Error Code!)
231 ISR_NOERRNO     9;  9: Coprocessor Segment Overrun Exception
232 ISR_ERRNO       10; 10: Bad TSS Exception (With Error Code!)
233 ISR_ERRNO       11; 11: Segment Not Present Exception (With Error Code!)
234 ISR_ERRNO       12; 12: Stack Fault Exception (With Error Code!)
235 ISR_ERRNO       13; 13: General Protection Fault Exception (With Error Code!)
236 ISR_ERRNO       14; 14: Page Fault Exception (With Error Code!)
237 ISR_NOERRNO     15; 15: Reserved Exception
238 ISR_NOERRNO     16; 16: Floating Point Exception
239 ISR_NOERRNO     17; 17: Alignment Check Exception
240 ISR_NOERRNO     18; 18: Machine Check Exception
241 ISR_NOERRNO     19; 19: Reserved
242 ISR_NOERRNO     20; 20: Reserved
243 ISR_NOERRNO     21; 21: Reserved
244 ISR_NOERRNO     22; 22: Reserved
245 ISR_NOERRNO     23; 23: Reserved
246 ISR_NOERRNO     24; 24: Reserved
247 ISR_NOERRNO     25; 25: Reserved
248 ISR_NOERRNO     26; 26: Reserved
249 ISR_NOERRNO     27; 27: Reserved
250 ISR_NOERRNO     28; 28: Reserved
251 ISR_NOERRNO     29; 29: Reserved
252 ISR_NOERRNO     30; 30: Reserved
253 ISR_NOERRNO     31; 31: Reserved
254
255 [extern Error_Handler]
256 [global ErrorCommon]
257 ErrorCommon:
258         PUSH_GPR
259         push gs
260         push fs
261         ;PUSH_FPU
262         ;PUSH_XMM
263         
264         mov rdi, rsp
265         xchg bx, bx
266         call Error_Handler
267         
268         ;POP_XMM
269         ;POP_FPU
270         pop fs
271         pop gs
272         POP_GPR
273         add rsp, 2*8
274         iretq
275
276 %macro DEFIRQ   1
277 Irq%1:
278         push    0
279         push    %1
280         jmp     IrqCommon
281 %endmacro
282
283 %assign i 0
284 %rep 16
285 DEFIRQ  i
286 %assign i i+1
287 %endrep
288
289 [global IrqCommon]
290 IrqCommon:
291         PUSH_GPR
292         
293         mov rbx, [rsp+16*8]     ; Calculate address
294         shr rbx, 3+2    ; *8*4
295         mov rax, gaIRQ_Handlers
296         add rbx, rax
297         
298         ; Check all callbacks
299         %assign i 0
300         %rep NUM_IRQ_CALLBACKS
301         ; Get callback address
302         mov rax, [rbx]
303         test rax, rax   ; Check if it exists
304         jz .skip.%[i]
305         ; Set RDI to IRQ number
306         mov rdi, [rsp+16*8]     ; Get IRQ number
307         call rax        ; Call
308 .skip.%[i]:
309         add rbx, 8      ; Next!
310         %assign i i+1
311         %endrep
312         
313         ; ACK
314         mov rdi, [rsp+16*8]     ; Get IRQ number
315         cmp rdi, 8
316         mov al, 0x20
317         jb .skipAckSecondary
318         mov dx, 0x00A0
319         out dx, al
320 .skipAckSecondary:
321         mov dx, 0x0020
322         out dx, al
323         
324         POP_GPR
325         add rsp, 8*2
326         ;xchg bx, bx
327         iretq
328
329 [extern Proc_Scheduler]
330 [global SchedulerIRQ]
331 SchedulerIRQ:
332         PUSH_GPR
333         ;PUSH_FPU
334         ;PUSH_XMM
335         
336         ; Save Thread Pointer
337         mov rax, dr0
338         push rax
339         
340         ; Get the CPU Number
341         mov rdi, dr1
342         ; Call the Scheduler
343         call Proc_Scheduler
344         
345         ; Restore Thread Pointer
346         pop rax
347         mov dr0, rax
348         
349         ; Send EOI (To either the APIC or the PIC)
350         %if USE_MP
351         test ebx, ebx
352         jnz .sendEOI
353         %endif
354         ; PIC
355         mov al, 0x20
356         out 0x20, al            ; ACK IRQ
357         %if USE_MP
358         jmp .ret
359         ; APIC
360 .sendEOI:
361         mov eax, DWORD [gpMP_LocalAPIC]
362         mov DWORD [eax+0x0B0], 0
363         %endif
364 .ret:
365         
366         ;POP_XMM
367         ;POP_FPU
368         POP_GPR
369         iretq
370
371 [section .data]
372 gIDT:
373         ; 64-bit Interrupt Gate, CS = 0x8, IST0 (Disabled)
374         times 256       dd      0x00080000, 0x00000E00, 0, 0
375 gIDTPtr:
376         dw      256*16-1
377         dq      gIDT
378
379 gaIRQ_Handlers:
380         times   16*NUM_IRQ_CALLBACKS    dq      0

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