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

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