Updated PCI IDs to latest snapshot.
[tangerine.git] / arch / x86_64-pc / kernel / intr.c
bloba7763da4e3ba22bab1246ce08c74c3bb5d51b572
1 #include <inttypes.h>
2 #define DEBUG 0
3 #include <aros/debug.h>
5 #include <stdio.h>
6 #include <asm/cpu.h>
7 #include <asm/io.h>
8 #include <asm/segments.h>
9 #include <aros/libcall.h>
10 #include <aros/asmcall.h>
11 #include <exec/execbase.h>
12 #include <hardware/intbits.h>
14 #include <proto/exec.h>
16 #include "kernel_intern.h"
18 static void core_XTPIC_DisableIRQ(uint8_t irqnum);
19 static void core_XTPIC_EnableIRQ(uint8_t irqnum);
21 AROS_LH4(void *, KrnAddIRQHandler,
22 AROS_LHA(uint8_t, irq, D0),
23 AROS_LHA(void *, handler, A0),
24 AROS_LHA(void *, handlerData, A1),
25 AROS_LHA(void *, handlerData2, A2),
26 struct KernelBase *, KernelBase, 7, Kernel)
28 AROS_LIBFUNC_INIT
30 struct ExecBase *SysBase = TLS_GET(SysBase);
31 struct IntrNode *handle = NULL;
32 D(bug("[Kernel] KrnAddIRQHandler(%02x, %012p, %012p, %012p):\n", irq, handler, handlerData, handlerData2));
34 if (irq >=0 && irq <= 0xff)
37 handle = AllocVecPooled(KernelBase->kb_MemPool, sizeof(struct IntrNode));
39 #warning TODO: Add IP range checking
41 D(bug("[Kernel] handle=%012p\n", handle));
43 if (handle)
45 handle->in_Handler = handler;
46 handle->in_HandlerData = handlerData;
47 handle->in_HandlerData2 = handlerData2;
49 Disable();
50 ADDHEAD(&KernelBase->kb_Intr[irq], &handle->in_Node);
51 Enable();
53 if (KernelBase->kb_Intr[irq].lh_Type == KBL_XTPIC)
54 core_XTPIC_EnableIRQ(irq);
57 return handle;
59 AROS_LIBFUNC_EXIT
62 AROS_LH1(void, KrnRemIRQHandler,
63 AROS_LHA(void *, handle, A0),
64 struct KernelBase *, KernelBase, 8, Kernel)
66 AROS_LIBFUNC_INIT
68 struct IntrNode *h = handle;
70 Disable();
71 REMOVE(h);
72 Enable();
74 FreeVecPooled(KernelBase->kb_MemPool, h);
76 AROS_LIBFUNC_EXIT
79 AROS_LH0I(void, KrnCli,
80 struct KernelBase *, KernelBase, 9, Kernel)
82 AROS_LIBFUNC_INIT
84 asm volatile("cli");
86 AROS_LIBFUNC_EXIT
89 AROS_LH0I(void, KrnSti,
90 struct KernelBase *, KernelBase, 10, Kernel)
92 AROS_LIBFUNC_INIT
94 asm volatile("sti");
96 AROS_LIBFUNC_EXIT
100 static struct int_gate_64bit IGATES[256] __attribute__((used,aligned(256)));
101 const struct
103 uint16_t size __attribute__((packed));
104 uint64_t base __attribute__((packed));
105 } IDT_sel = {sizeof(IGATES)-1, (uint64_t)IGATES};
107 #define STR_(x) #x
108 #define STR(x) STR_(x)
110 #define IRQ_NAME_(nr) nr##_intr(void)
111 #define IRQ_NAME(nr) IRQ_NAME_(IRQ##nr)
113 #define BUILD_IRQ(nr) \
114 void IRQ_NAME(nr); \
115 asm(".balign 8 ,0x90\n\t" \
116 ".globl IRQ" STR(nr) "_intr\n\t" \
117 ".type IRQ" STR(nr) "_intr,@function\n" \
118 "IRQ" STR(nr) "_intr: pushq $0; pushq $" #nr "\n\t" \
119 "jmp core_EnterInterrupt\n\t" \
120 ".size IRQ" STR(nr) "_intr, . - IRQ" STR(nr) "_intr" \
123 #define BUILD_IRQ_ERR(nr) \
124 void IRQ_NAME(nr); \
125 asm(".balign 8 ,0x90\n\t" \
126 ".globl IRQ" STR(nr) "_intr\n\t" \
127 ".type IRQ" STR(nr) "_intr,@function\n" \
128 "IRQ" STR(nr) "_intr: pushq $" #nr "\n\t" \
129 "jmp core_EnterInterrupt\n\t" \
130 ".size IRQ" STR(nr) "_intr, . - IRQ" STR(nr) "_intr" \
133 BUILD_IRQ(0x00) // Divide-By-Zero Exception
134 BUILD_IRQ(0x01) // Debug Exception
135 BUILD_IRQ(0x02) // NMI Exception
136 BUILD_IRQ(0x03) // Breakpoint Exception
137 BUILD_IRQ(0x04) // Overflow Exception
138 BUILD_IRQ(0x05) // Bound-Range Exception
139 BUILD_IRQ(0x06) // Invalid-Opcode Exception
140 BUILD_IRQ(0x07) // Device-Not-Available Exception
141 BUILD_IRQ_ERR(0x08) // Double-Fault Exception
142 BUILD_IRQ(0x09) // Unused (used to be Coprocesor-Segment-Overrun)
143 BUILD_IRQ_ERR(0x0a) // Invalid-TSS Exception
144 BUILD_IRQ_ERR(0x0b) // Segment-Not-Present Exception
145 BUILD_IRQ_ERR(0x0c) // Stack Exception
146 BUILD_IRQ_ERR(0x0d) // General-Protection Exception
147 BUILD_IRQ_ERR(0x0e) // Page-Fault Exception
148 BUILD_IRQ(0x0f) // Reserved
149 BUILD_IRQ(0x10) // Floating-Point Exception
150 BUILD_IRQ_ERR(0x11) // Alignment-Check Exception
151 BUILD_IRQ(0x12) // Machine-Check Exception
152 BUILD_IRQ(0x13) // SIMD-Floating-Point Exception
153 BUILD_IRQ(0x14) BUILD_IRQ(0x15) BUILD_IRQ(0x16) BUILD_IRQ(0x17)
154 BUILD_IRQ(0x18) BUILD_IRQ(0x19) BUILD_IRQ(0x1a) BUILD_IRQ(0x1b)
155 BUILD_IRQ(0x1c) BUILD_IRQ(0x1d) BUILD_IRQ(0x1e) BUILD_IRQ(0x1f)
157 #define B(x,y) BUILD_IRQ(x##y)
158 #define B16(x) \
159 B(x,0) B(x,1) B(x,2) B(x,3) B(x,4) B(x,5) B(x,6) B(x,7) \
160 B(x,8) B(x,9) B(x,a) B(x,b) B(x,c) B(x,d) B(x,e) B(x,f)
162 B16(0x2)
163 BUILD_IRQ(0x80)
164 BUILD_IRQ(0xfe) // APIC timer
166 #define SAVE_REGS \
167 "pushq %rax; pushq %rbp; pushq %rbx; pushq %rdi; pushq %rsi; pushq %rdx;" \
168 "pushq %rcx; pushq %r8; pushq %r9; pushq %r10; pushq %r11; pushq %r12;" \
169 "pushq %r13; pushq %r14; pushq %r15; mov %ds,%eax; pushq %rax;"
171 #define RESTORE_REGS \
172 "popq %rax; mov %ax,%ds; mov %ax,%es; popq %r15; popq %r14; popq %r13;" \
173 "popq %r12; popq %r11; popq %r10; popq %r9; popq %r8; popq %rcx;" \
174 "popq %rdx; popq %rsi; popq %rdi; popq %rbx; popq %rbp; popq %rax"
176 asm(
177 " .balign 32,0x90 \n"
178 " .globl core_EnterInterrupt \n"
179 " .type core_EnterInterrupt,@function \n"
180 "core_EnterInterrupt: \n\t" SAVE_REGS "\n"
181 " movl $" STR(KERNEL_DS) ",%eax \n"
182 " mov %ax,%ds \n"
183 " mov %ax,%es \n"
184 " movq %rsp,%rdi \n"
185 " call core_IRQHandle \n"
186 " movq %rsp,%rdi \n"
187 " jmp core_ExitInterrupt \n"
188 " .size core_EnterInterrupt, .-core_EnterInterrupt"
191 asm(
192 " .balign 32,0x90 \n"
193 " .globl core_LeaveInterrupt \n"
194 " .type core_LeaveInterrupt,@function \n"
195 "core_LeaveInterrupt: movq %rdi,%rsp \n\t" RESTORE_REGS "\n"
196 " addq $16,%rsp \n"
197 " iretq \n"
198 " .size core_LeaveInterrupt, .-core_LeaveInterrupt"
201 #define IRQ(x,y) \
202 (const void (*)(void))IRQ##x##y##_intr
204 #define IRQLIST_16(x) \
205 IRQ(x,0), IRQ(x,1), IRQ(x,2), IRQ(x,3), \
206 IRQ(x,4), IRQ(x,5), IRQ(x,6), IRQ(x,7), \
207 IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \
208 IRQ(x,c), IRQ(x,d), IRQ(x,e), IRQ(x,f)
210 const void __attribute__((section(".text"))) (*interrupt[256])(void) = {
211 IRQLIST_16(0x0), IRQLIST_16(0x1), IRQLIST_16(0x2)
214 void core_SetupIDT(struct KernBootPrivate *__KernBootPrivate)
216 IPTR _APICBase;
217 UBYTE _APICID;
218 int i;
219 uintptr_t off;
221 _APICBase = AROS_UFC0(IPTR,
222 ((struct GenericAPIC *)__KernBootPrivate->kbp_APIC_Drivers[__KernBootPrivate->kbp_APIC_DriverID])->getbase);
224 _APICID = AROS_UFC1(UBYTE,
225 ((struct GenericAPIC *)__KernBootPrivate->kbp_APIC_Drivers[__KernBootPrivate->kbp_APIC_DriverID])->getid,
226 AROS_UFCA(IPTR, _APICBase, A0));
228 if (_APICID == __KernBootPrivate->kbp_APIC_BSPID)
230 rkprintf("[Kernel] core_SetupIDT[%d] Setting all interrupt handlers to default value\n", _APICID);
232 for (i=0; i < 256; i++)
234 if (interrupt[i])
235 off = (uintptr_t)interrupt[i];
236 else if (i == 0x80)
237 off = (uintptr_t)&IRQ0x80_intr;
238 else if (i == 0xfe)
239 off = (uintptr_t)&IRQ0xfe_intr;
240 else
241 off = (uintptr_t)&core_DefaultIRETQ;
243 IGATES[i].offset_low = off & 0xffff;
244 IGATES[i].offset_mid = (off >> 16) & 0xffff;
245 IGATES[i].offset_high = (off >> 32) & 0xffffffff;
246 IGATES[i].type = 0x0e;
247 IGATES[i].dpl = 3;
248 IGATES[i].p = 1;
249 IGATES[i].selector = KERNEL_CS;
250 IGATES[i].ist = 0;
253 rkprintf("[Kernel] core_SetupIDT[%d] Registering interrupt handlers ..\n", _APICID);
254 asm volatile ("lidt %0"::"m"(IDT_sel));
258 void core_Cause(struct ExecBase *SysBase)
260 struct IntVector *iv = &SysBase->IntVects[INTB_SOFTINT];
262 /* If the SoftInt vector in SysBase is set, call it. It will do the rest for us */
263 if (iv->iv_Code)
265 AROS_UFC5(void, iv->iv_Code,
266 AROS_UFCA(ULONG, 0, D1),
267 AROS_UFCA(ULONG, 0, A0),
268 AROS_UFCA(APTR, 0, A1),
269 AROS_UFCA(APTR, iv->iv_Code, A5),
270 AROS_UFCA(struct ExecBase *, SysBase, A6)
275 static void core_APIC_AckIntr(uint8_t intnum)
277 struct KernelBase *KernelBase = TLS_GET(KernelBase);
278 asm volatile ("movl %0,(%1)"::"r"(0),"r"(KernelBase->kb_APIC_BaseMap[0] + 0xb0));
281 static void core_XTPIC_DisableIRQ(uint8_t irqnum)
283 struct KernelBase *KernelBase = TLS_GET(KernelBase);
284 irqnum &= 15;
285 KernelBase->kb_XTPIC_Mask |= 1 << irqnum;
287 if (irqnum >= 8)
289 outb((KernelBase->kb_XTPIC_Mask >> 8) & 0xff, 0xA1);
291 else
293 outb(KernelBase->kb_XTPIC_Mask & 0xff, 0x21);
297 static void core_XTPIC_EnableIRQ(uint8_t irqnum)
299 struct KernelBase *KernelBase = TLS_GET(KernelBase);
300 irqnum &= 15;
301 KernelBase->kb_XTPIC_Mask &= ~(1 << irqnum);
303 if (irqnum >= 8)
305 outb((KernelBase->kb_XTPIC_Mask >> 8) & 0xff, 0xA1);
307 else
309 outb(KernelBase->kb_XTPIC_Mask & 0xff, 0x21);
313 static void core_XTPIC_AckIntr(uint8_t intnum)
315 struct KernelBase *KernelBase = TLS_GET(KernelBase);
316 intnum &= 15;
317 KernelBase->kb_XTPIC_Mask |= 1 << intnum;
319 if (intnum >= 8)
321 outb((KernelBase->kb_XTPIC_Mask >> 8) & 0xff, 0xA1);
322 outb(0x62, 0x20);
323 outb(0x20, 0xa0);
325 else
327 outb(KernelBase->kb_XTPIC_Mask & 0xff, 0x21);
328 outb(0x20, 0x20);
332 void core_IRQHandle(regs_t regs)
334 struct ExecBase *SysBase = TLS_GET(SysBase); // *(struct ExecBase **)4;
335 struct KernelBase *KernelBase = TLS_GET(KernelBase);
336 struct Task *t = NULL;
337 int die = 0;
339 if (SysBase)
340 t = SysBase->ThisTask;
342 if ((regs.irq_number < 0x20) && regs.irq_number != 0x0e)
343 rkprintf("IRQ %02x:", regs.irq_number);
345 if (regs.irq_number == 0x03) /* Debug */
347 rkprintf("[Kernel] INT3 debug fault!\n");
349 if (t)
351 rkprintf("[Kernel] %s %p '%s'\n",
352 t->tc_Node.ln_Type == NT_TASK?"task":"process", t, t->tc_Node.ln_Name);
353 rkprintf("[Kernel] SPLower=%016lx SPUpper=%016lx\n", t->tc_SPLower, t->tc_SPUpper);
355 if (((uint64_t *)regs.return_rsp < t->tc_SPLower)||((uint64_t *)regs.return_rsp > t->tc_SPUpper))
356 rkprintf("[Kernel] Stack out of Bounds!\n");
359 rkprintf("[Kernel] stack=%04x:%012x rflags=%016x ip=%04x:%012x err=%08x\n",
360 regs.return_ss, regs.return_rsp, regs.return_rflags,
361 regs.return_cs, regs.return_rip, regs.error_code);
363 rkprintf("[Kernel] rax=%016lx rbx=%016lx rcx=%016lx rdx=%016lx\n", regs.rax, regs.rbx, regs.rcx, regs.rdx);
364 rkprintf("[Kernel] rsi=%016lx rdi=%016lx rbp=%016lx rsp=%016lx\n", regs.rsi, regs.rdi, regs.rbp, regs.return_rsp);
365 rkprintf("[Kernel] r08=%016lx r09=%016lx r10=%016lx r11=%016lx\n", regs.r8, regs.r9, regs.r10, regs.r11);
366 rkprintf("[Kernel] r12=%016lx r13=%016lx r14=%016lx r15=%016lx\n", regs.r12, regs.r13, regs.r14, regs.r15);
367 rkprintf("[Kernel] *rsp=%016lx\n", *(uint64_t *)regs.return_rsp);
370 rkprintf("[Kenrel] Stack:\n");
371 int i;
372 uint64_t *ptr = (void*)regs.return_rsp;
373 for (i=0; i < 10; i++)
375 rkprintf("[Kernel] %02x: %016p\n", i*8, ptr[i]);
378 else if (regs.irq_number == 0x06) /* GPF */
380 rkprintf("[Kernel] UNDEFINED INSTRUCTION!\n");
382 if (t)
384 rkprintf("[Kernel] %s %p '%s'\n",
385 t->tc_Node.ln_Type == NT_TASK?"task":"process", t, t->tc_Node.ln_Name);
386 rkprintf("[Kernel] SPLower=%016lx SPUpper=%016lx\n", t->tc_SPLower, t->tc_SPUpper);
388 if (((uint64_t *)regs.return_rsp < t->tc_SPLower)||((uint64_t *)regs.return_rsp > t->tc_SPUpper))
389 rkprintf("[Kernel] Stack out of Bounds!\n");
392 rkprintf("[Kernel] stack=%04x:%012x rflags=%016x ip=%04x:%012x err=%08x\n",
393 regs.return_ss, regs.return_rsp, regs.return_rflags,
394 regs.return_cs, regs.return_rip, regs.error_code);
396 rkprintf("[Kernel] rax=%016lx rbx=%016lx rcx=%016lx rdx=%016lx\n", regs.rax, regs.rbx, regs.rcx, regs.rdx);
397 rkprintf("[Kernel] rsi=%016lx rdi=%016lx rbp=%016lx rsp=%016lx\n", regs.rsi, regs.rdi, regs.rbp, regs.return_rsp);
398 rkprintf("[Kernel] r08=%016lx r09=%016lx r10=%016lx r11=%016lx\n", regs.r8, regs.r9, regs.r10, regs.r11);
399 rkprintf("[Kernel] r12=%016lx r13=%016lx r14=%016lx r15=%016lx\n", regs.r12, regs.r13, regs.r14, regs.r15);
400 die = 1;
402 int i;
403 uint8_t *ptr = (uint8_t *)regs.return_rip;
405 rkprintf("[Kernel] ");
407 for (i=0; i < 16; i++)
408 rkprintf("%02x ", ptr[i]);
410 rkprintf("\n");
412 else if (regs.irq_number == 0x07) /* GPF */
414 rkprintf("[Kernel] Device Not Available!\n");
416 if (t)
418 rkprintf("[Kernel] %s %p '%s'\n",
419 t->tc_Node.ln_Type == NT_TASK?"task":"process", t, t->tc_Node.ln_Name);
420 rkprintf("[Kernel] SPLower=%016lx SPUpper=%016lx\n", t->tc_SPLower, t->tc_SPUpper);
422 if (((uint64_t *)regs.return_rsp < t->tc_SPLower)||((uint64_t *)regs.return_rsp > t->tc_SPUpper))
423 rkprintf("[Kernel] Stack out of Bounds!\n");
426 rkprintf("[Kernel] stack=%04x:%012x rflags=%016x ip=%04x:%012x err=%08x\n",
427 regs.return_ss, regs.return_rsp, regs.return_rflags,
428 regs.return_cs, regs.return_rip, regs.error_code);
430 rkprintf("[Kernel] rax=%016lx rbx=%016lx rcx=%016lx rdx=%016lx\n", regs.rax, regs.rbx, regs.rcx, regs.rdx);
431 rkprintf("[Kernel] rsi=%016lx rdi=%016lx rbp=%016lx rsp=%016lx\n", regs.rsi, regs.rdi, regs.rbp, regs.return_rsp);
432 rkprintf("[Kernel] r08=%016lx r09=%016lx r10=%016lx r11=%016lx\n", regs.r8, regs.r9, regs.r10, regs.r11);
433 rkprintf("[Kernel] r12=%016lx r13=%016lx r14=%016lx r15=%016lx\n", regs.r12, regs.r13, regs.r14, regs.r15);
434 die = 1;
436 else if (regs.irq_number == 0x0D) /* GPF */
438 rkprintf("[Kernel] GENERAL PROTECTION FAULT!\n");
440 if (t)
442 rkprintf("[Kernel] %s %p '%s'\n",
443 t->tc_Node.ln_Type == NT_TASK?"task":"process", t, t->tc_Node.ln_Name);
444 rkprintf("[Kernel] SPLower=%016lx SPUpper=%016lx\n", t->tc_SPLower, t->tc_SPUpper);
446 if (((uint64_t *)regs.return_rsp < t->tc_SPLower)||((uint64_t *)regs.return_rsp > t->tc_SPUpper))
447 rkprintf("[Kernel] Stack out of Bounds!\n");
450 rkprintf("[Kernel] stack=%04x:%012x rflags=%016x ip=%04x:%012x err=%08x\n",
451 regs.return_ss, regs.return_rsp, regs.return_rflags,
452 regs.return_cs, regs.return_rip, regs.error_code);
454 rkprintf("[Kernel] rax=%016lx rbx=%016lx rcx=%016lx rdx=%016lx\n", regs.rax, regs.rbx, regs.rcx, regs.rdx);
455 rkprintf("[Kernel] rsi=%016lx rdi=%016lx rbp=%016lx rsp=%016lx\n", regs.rsi, regs.rdi, regs.rbp, regs.return_rsp);
456 rkprintf("[Kernel] r08=%016lx r09=%016lx r10=%016lx r11=%016lx\n", regs.r8, regs.r9, regs.r10, regs.r11);
457 rkprintf("[Kernel] r12=%016lx r13=%016lx r14=%016lx r15=%016lx\n", regs.r12, regs.r13, regs.r14, regs.r15);
458 rkprintf("[Kernel] *rsp=%016lx\n", *(uint64_t *)regs.return_rsp);
461 die = 1;
463 else if (regs.irq_number == 0x0e) /* Page fault */
465 void *ptr = rdcr(cr2);
466 unsigned char *ip = regs.return_rip;
467 int i;
469 die = 1;
471 if (ptr == (void*)4)
473 // rkprintf("[Kernel] ** Code at %012lx is trying to access the SysBase at 4UL.\n", regs.return_rip);
475 if ( (ip[0] & 0xfb) == 0x48 &&
476 ip[1] == 0x8b &&
477 (ip[2] & 0xc7) == 0x04 &&
478 ip[3] == 0x25
481 int reg = ((ip[2] >> 3) & 0x07) | ((ip[0] & 0x04) << 1);
483 switch(reg)
485 case 0:
486 regs.rax = SysBase;
487 break;
488 case 1:
489 regs.rcx = SysBase;
490 break;
491 case 2:
492 regs.rdx = SysBase;
493 break;
494 case 3:
495 regs.rbx = SysBase;
496 break;
497 // case 4: /* Cannot put SysBase into rSP register */
498 // regs.return_rsp = SysBase;
499 // break;
500 case 5:
501 regs.rbp = SysBase;
502 break;
503 case 6:
504 regs.rsi = SysBase;
505 break;
506 case 7:
507 regs.rdi = SysBase;
508 break;
509 case 8:
510 regs.r8 = SysBase;
511 break;
512 case 9:
513 regs.r9 = SysBase;
514 break;
515 case 10:
516 regs.r10 = SysBase;
517 break;
518 case 11:
519 regs.r11 = SysBase;
520 break;
521 case 12:
522 regs.r12 = SysBase;
523 break;
524 case 13:
525 regs.r13 = SysBase;
526 break;
527 case 14:
528 regs.r14 = SysBase;
529 break;
530 case 15:
531 regs.r15 = SysBase;
532 break;
535 regs.return_rip += 8;
537 die = 0;
539 else if ( (ip[0] & 0xfb) == 0x48 &&
540 ip[1] == 0x8b &&
541 (ip[2] & 0xc7) == 0x05
544 int reg = ((ip[2] >> 3) & 0x07) | ((ip[0] & 0x04) << 1);
546 switch(reg)
548 case 0:
549 regs.rax = SysBase;
550 break;
551 case 1:
552 regs.rcx = SysBase;
553 break;
554 case 2:
555 regs.rdx = SysBase;
556 break;
557 case 3:
558 regs.rbx = SysBase;
559 break;
560 // case 4: /* Cannot put SysBase into rSP register */
561 // regs.return_rsp = SysBase;
562 // break;
563 case 5:
564 regs.rbp = SysBase;
565 break;
566 case 6:
567 regs.rsi = SysBase;
568 break;
569 case 7:
570 regs.rdi = SysBase;
571 break;
572 case 8:
573 regs.r8 = SysBase;
574 break;
575 case 9:
576 regs.r9 = SysBase;
577 break;
578 case 10:
579 regs.r10 = SysBase;
580 break;
581 case 11:
582 regs.r11 = SysBase;
583 break;
584 case 12:
585 regs.r12 = SysBase;
586 break;
587 case 13:
588 regs.r13 = SysBase;
589 break;
590 case 14:
591 regs.r14 = SysBase;
592 break;
593 case 15:
594 regs.r15 = SysBase;
595 break;
598 regs.return_rip += 7;
600 die = 0;
604 if (die)
606 rkprintf("IRQ %02x:", regs.irq_number);
607 rkprintf("[Kernel] PAGE FAULT EXCEPTION! %016p\n",ptr);
609 if (t)
611 rkprintf("[Kernel] %s %p '%s'\n",
612 t->tc_Node.ln_Type == NT_TASK?"task":"process", t, t->tc_Node.ln_Name);
613 rkprintf("[Kernel] SPLower=%016lx SPUpper=%016lx\n", t->tc_SPLower, t->tc_SPUpper);
615 if (((uint64_t *)regs.return_rsp < t->tc_SPLower)||((uint64_t *)regs.return_rsp > t->tc_SPUpper))
616 rkprintf("[Kernel] Stack out of Bounds!\n");
619 rkprintf("[Kernel] stack=%04x:%012x rflags=%016x ip=%04x:%012x err=%08x\n",
620 regs.return_ss, regs.return_rsp, regs.return_rflags,
621 regs.return_cs, regs.return_rip, regs.error_code);
623 rkprintf("[Kernel] rax=%016lx rbx=%016lx rcx=%016lx rdx=%016lx\n", regs.rax, regs.rbx, regs.rcx, regs.rdx);
624 rkprintf("[Kernel] rsi=%016lx rdi=%016lx rbp=%016lx rsp=%016lx\n", regs.rsi, regs.rdi, regs.rbp, regs.return_rsp);
625 rkprintf("[Kernel] r08=%016lx r09=%016lx r10=%016lx r11=%016lx\n", regs.r8, regs.r9, regs.r10, regs.r11);
626 rkprintf("[Kernel] r12=%016lx r13=%016lx r14=%016lx r15=%016lx\n", regs.r12, regs.r13, regs.r14, regs.r15);
627 rkprintf("[Kernel] *rsp=%016lx\n", *(uint64_t *)regs.return_rsp);
629 rkprintf("[Kernel] Insn: ");
630 for (i = 0; i < 16; i++)
631 rkprintf("%02x ", ip[i]);
632 rkprintf("\n");
636 else if (regs.irq_number == 0x80) /* Syscall? */
638 switch (regs.rax)
640 case SC_CAUSE:
641 core_Cause(SysBase);
642 break;
644 case SC_DISPATCH:
645 core_Dispatch(&regs);
646 break;
648 case SC_SWITCH:
649 core_Switch(&regs);
650 break;
652 case SC_SCHEDULE:
653 if (regs.ds != KERNEL_DS)
654 core_Schedule(&regs);
655 break;
659 if (KernelBase)
661 if (KernelBase->kb_Intr[regs.irq_number].lh_Type == KBL_APIC)
662 core_APIC_AckIntr(regs.irq_number);
664 if (KernelBase->kb_Intr[regs.irq_number].lh_Type == KBL_XTPIC)
665 core_XTPIC_AckIntr(regs.irq_number);
668 if (!IsListEmpty(&KernelBase->kb_Intr[regs.irq_number]))
670 struct IntrNode *in, *in2;
672 ForeachNodeSafe(&KernelBase->kb_Intr[regs.irq_number], in, in2)
674 if (in->in_Handler)
675 in->in_Handler(in->in_HandlerData, in->in_HandlerData2);
678 if (KernelBase->kb_Intr[regs.irq_number].lh_Type == KBL_XTPIC)
679 core_XTPIC_EnableIRQ(regs.irq_number);
683 while (die) asm volatile ("hlt");
686 asm(".text\n\t"
687 ".globl core_DefaultIRETQ\n\t"
688 ".type core_DefaultIRETQ,@function\n"
689 "core_DefaultIRETQ: iretq");