make the linux-ppc packags be in synch with other platforms
[tangerine.git] / arch / x86_64-pc / kernel / intr.c
blob8135e4939fffef5beef0e6f89fcae19e32ff157c
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()
216 int i;
217 uintptr_t off;
218 rkprintf("[Kernel] Setting all interrupt handlers to default value\n");
220 for (i=0; i < 256; i++)
222 if (interrupt[i])
223 off = (uintptr_t)interrupt[i];
224 else if (i == 0x80)
225 off = (uintptr_t)&IRQ0x80_intr;
226 else if (i == 0xfe)
227 off = (uintptr_t)&IRQ0xfe_intr;
228 else
229 off = (uintptr_t)&core_DefaultIRETQ;
231 IGATES[i].offset_low = off & 0xffff;
232 IGATES[i].offset_mid = (off >> 16) & 0xffff;
233 IGATES[i].offset_high = (off >> 32) & 0xffffffff;
234 IGATES[i].type = 0x0e;
235 IGATES[i].dpl = 3;
236 IGATES[i].p = 1;
237 IGATES[i].selector = KERNEL_CS;
238 IGATES[i].ist = 0;
241 asm volatile ("lidt %0"::"m"(IDT_sel));
245 void core_Cause(struct ExecBase *SysBase)
247 struct IntVector *iv = &SysBase->IntVects[INTB_SOFTINT];
249 /* If the SoftInt vector in SysBase is set, call it. It will do the rest for us */
250 if (iv->iv_Code)
252 AROS_UFC5(void, iv->iv_Code,
253 AROS_UFCA(ULONG, 0, D1),
254 AROS_UFCA(ULONG, 0, A0),
255 AROS_UFCA(APTR, 0, A1),
256 AROS_UFCA(APTR, iv->iv_Code, A5),
257 AROS_UFCA(struct ExecBase *, SysBase, A6)
262 static void core_APIC_AckIntr(uint8_t intnum)
264 struct KernelBase *KernelBase = TLS_GET(KernelBase);
265 asm volatile ("movl %0,(%1)"::"r"(0),"r"(KernelBase->kb_APICBase + 0xb0));
268 static void core_XTPIC_DisableIRQ(uint8_t irqnum)
270 struct KernelBase *KernelBase = TLS_GET(KernelBase);
271 irqnum &= 15;
272 KernelBase->kb_XTPIC_Mask |= 1 << irqnum;
274 if (irqnum >= 8)
276 outb((KernelBase->kb_XTPIC_Mask >> 8) & 0xff, 0xA1);
278 else
280 outb(KernelBase->kb_XTPIC_Mask & 0xff, 0x21);
284 static void core_XTPIC_EnableIRQ(uint8_t irqnum)
286 struct KernelBase *KernelBase = TLS_GET(KernelBase);
287 irqnum &= 15;
288 KernelBase->kb_XTPIC_Mask &= ~(1 << irqnum);
290 if (irqnum >= 8)
292 outb((KernelBase->kb_XTPIC_Mask >> 8) & 0xff, 0xA1);
294 else
296 outb(KernelBase->kb_XTPIC_Mask & 0xff, 0x21);
300 static void core_XTPIC_AckIntr(uint8_t intnum)
302 struct KernelBase *KernelBase = TLS_GET(KernelBase);
303 intnum &= 15;
304 KernelBase->kb_XTPIC_Mask |= 1 << intnum;
306 if (intnum >= 8)
308 outb((KernelBase->kb_XTPIC_Mask >> 8) & 0xff, 0xA1);
309 outb(0x62, 0x20);
310 outb(0x20, 0xa0);
312 else
314 outb(KernelBase->kb_XTPIC_Mask & 0xff, 0x21);
315 outb(0x20, 0x20);
319 void core_IRQHandle(regs_t regs)
321 struct ExecBase *SysBase = TLS_GET(SysBase); // *(struct ExecBase **)4;
322 struct KernelBase *KernelBase = TLS_GET(KernelBase);
323 struct Task *t = NULL;
324 int die = 0;
326 if (SysBase)
327 t = SysBase->ThisTask;
329 if ((regs.irq_number < 0x20) && regs.irq_number != 0x0e)
330 rkprintf("IRQ %02x:", regs.irq_number);
332 if (regs.irq_number == 0x03) /* Debug */
334 rkprintf("[Kernel] INT3 debug fault!\n");
336 rkprintf("[Kernel] stack=%04x:%012x rflags=%016x ip=%04x:%012x err=%08x\n",
337 regs.return_ss, regs.return_rsp, regs.return_rflags,
338 regs.return_cs, regs.return_rip, regs.error_code);
340 rkprintf("[Kernel] rax=%016lx rbx=%016lx rcx=%016lx rdx=%016lx\n", regs.rax, regs.rbx, regs.rcx, regs.rdx);
341 rkprintf("[Kernel] rsi=%016lx rdi=%016lx rbp=%016lx rsp=%016lx\n", regs.rsi, regs.rdi, regs.rbp, regs.return_rsp);
342 rkprintf("[Kernel] r08=%016lx r09=%016lx r10=%016lx r11=%016lx\n", regs.r8, regs.r9, regs.r10, regs.r11);
343 rkprintf("[Kernel] r12=%016lx r13=%016lx r14=%016lx r15=%016lx\n", regs.r12, regs.r13, regs.r14, regs.r15);
345 rkprintf("[Kenrel] Stack:\n");
346 int i;
347 uint64_t *ptr = (void*)regs.return_rsp;
348 for (i=0; i < 10; i++)
350 rkprintf("[Kernel] %02x: %016p\n", i*8, ptr[i]);
353 else if (regs.irq_number == 0x06) /* GPF */
355 rkprintf("[Kernel] UNDEFINED INSTRUCTION!\n");
357 if (t)
359 rkprintf("[Kernel] %s %p '%s'\n",
360 t->tc_Node.ln_Type == NT_TASK?"task":"process", t, t->tc_Node.ln_Name);
363 rkprintf("[Kernel] stack=%04x:%012x rflags=%016x ip=%04x:%012x err=%08x\n",
364 regs.return_ss, regs.return_rsp, regs.return_rflags,
365 regs.return_cs, regs.return_rip, regs.error_code);
367 rkprintf("[Kernel] rax=%016lx rbx=%016lx rcx=%016lx rdx=%016lx\n", regs.rax, regs.rbx, regs.rcx, regs.rdx);
368 rkprintf("[Kernel] rsi=%016lx rdi=%016lx rbp=%016lx rsp=%016lx\n", regs.rsi, regs.rdi, regs.rbp, regs.return_rsp);
369 rkprintf("[Kernel] r08=%016lx r09=%016lx r10=%016lx r11=%016lx\n", regs.r8, regs.r9, regs.r10, regs.r11);
370 rkprintf("[Kernel] r12=%016lx r13=%016lx r14=%016lx r15=%016lx\n", regs.r12, regs.r13, regs.r14, regs.r15);
371 die = 1;
373 int i;
374 uint8_t *ptr = (uint8_t *)regs.return_rip;
376 rkprintf("[Kernel] ");
378 for (i=0; i < 16; i++)
379 rkprintf("%02x ", ptr[i]);
381 rkprintf("\n");
383 else if (regs.irq_number == 0x07) /* GPF */
385 rkprintf("[Kernel] Device Not Available!\n");
387 if (t)
389 rkprintf("[Kernel] %s %p '%s'\n",
390 t->tc_Node.ln_Type == NT_TASK?"task":"process", t, t->tc_Node.ln_Name);
393 rkprintf("[Kernel] stack=%04x:%012x rflags=%016x ip=%04x:%012x err=%08x\n",
394 regs.return_ss, regs.return_rsp, regs.return_rflags,
395 regs.return_cs, regs.return_rip, regs.error_code);
397 rkprintf("[Kernel] rax=%016lx rbx=%016lx rcx=%016lx rdx=%016lx\n", regs.rax, regs.rbx, regs.rcx, regs.rdx);
398 rkprintf("[Kernel] rsi=%016lx rdi=%016lx rbp=%016lx rsp=%016lx\n", regs.rsi, regs.rdi, regs.rbp, regs.return_rsp);
399 rkprintf("[Kernel] r08=%016lx r09=%016lx r10=%016lx r11=%016lx\n", regs.r8, regs.r9, regs.r10, regs.r11);
400 rkprintf("[Kernel] r12=%016lx r13=%016lx r14=%016lx r15=%016lx\n", regs.r12, regs.r13, regs.r14, regs.r15);
401 die = 1;
403 else if (regs.irq_number == 0x0D) /* GPF */
405 rkprintf("[Kernel] GENERAL PROTECTION FAULT!\n");
407 if (t)
409 rkprintf("[Kernel] %s %p '%s'\n",
410 t->tc_Node.ln_Type == NT_TASK?"task":"process", t, t->tc_Node.ln_Name);
413 rkprintf("[Kernel] stack=%04x:%012x rflags=%016x ip=%04x:%012x err=%08x\n",
414 regs.return_ss, regs.return_rsp, regs.return_rflags,
415 regs.return_cs, regs.return_rip, regs.error_code);
417 rkprintf("[Kernel] rax=%016lx rbx=%016lx rcx=%016lx rdx=%016lx\n", regs.rax, regs.rbx, regs.rcx, regs.rdx);
418 rkprintf("[Kernel] rsi=%016lx rdi=%016lx rbp=%016lx rsp=%016lx\n", regs.rsi, regs.rdi, regs.rbp, regs.return_rsp);
419 rkprintf("[Kernel] r08=%016lx r09=%016lx r10=%016lx r11=%016lx\n", regs.r8, regs.r9, regs.r10, regs.r11);
420 rkprintf("[Kernel] r12=%016lx r13=%016lx r14=%016lx r15=%016lx\n", regs.r12, regs.r13, regs.r14, regs.r15);
421 rkprintf("[Kernel] *rsp=%016lx\n", *(uint64_t *)regs.return_rsp);
422 die = 1;
424 else if (regs.irq_number == 0x0e) /* Page fault */
426 void *ptr = rdcr(cr2);
427 unsigned char *ip = regs.return_rip;
428 int i;
430 die = 1;
432 if (ptr == (void*)4)
434 // rkprintf("[Kernel] ** Code at %012lx is trying to access the SysBase at 4UL.\n", regs.return_rip);
436 if ( (ip[0] & 0xfb) == 0x48 &&
437 ip[1] == 0x8b &&
438 (ip[2] & 0xc7) == 0x04 &&
439 ip[3] == 0x25
442 int reg = ((ip[2] >> 3) & 0x07) | ((ip[0] & 0x04) << 1);
444 switch(reg)
446 case 0:
447 regs.rax = SysBase;
448 break;
449 case 1:
450 regs.rcx = SysBase;
451 break;
452 case 2:
453 regs.rdx = SysBase;
454 break;
455 case 3:
456 regs.rbx = SysBase;
457 break;
458 // case 4: /* Cannot put SysBase into rSP register */
459 // regs.return_rsp = SysBase;
460 // break;
461 case 5:
462 regs.rbp = SysBase;
463 break;
464 case 6:
465 regs.rsi = SysBase;
466 break;
467 case 7:
468 regs.rdi = SysBase;
469 break;
470 case 8:
471 regs.r8 = SysBase;
472 break;
473 case 9:
474 regs.r9 = SysBase;
475 break;
476 case 10:
477 regs.r10 = SysBase;
478 break;
479 case 11:
480 regs.r11 = SysBase;
481 break;
482 case 12:
483 regs.r12 = SysBase;
484 break;
485 case 13:
486 regs.r13 = SysBase;
487 break;
488 case 14:
489 regs.r14 = SysBase;
490 break;
491 case 15:
492 regs.r15 = SysBase;
493 break;
496 regs.return_rip += 8;
498 die = 0;
500 else if ( (ip[0] & 0xfb) == 0x48 &&
501 ip[1] == 0x8b &&
502 (ip[2] & 0xc7) == 0x05
505 int reg = ((ip[2] >> 3) & 0x07) | ((ip[0] & 0x04) << 1);
507 switch(reg)
509 case 0:
510 regs.rax = SysBase;
511 break;
512 case 1:
513 regs.rcx = SysBase;
514 break;
515 case 2:
516 regs.rdx = SysBase;
517 break;
518 case 3:
519 regs.rbx = SysBase;
520 break;
521 // case 4: /* Cannot put SysBase into rSP register */
522 // regs.return_rsp = SysBase;
523 // break;
524 case 5:
525 regs.rbp = SysBase;
526 break;
527 case 6:
528 regs.rsi = SysBase;
529 break;
530 case 7:
531 regs.rdi = SysBase;
532 break;
533 case 8:
534 regs.r8 = SysBase;
535 break;
536 case 9:
537 regs.r9 = SysBase;
538 break;
539 case 10:
540 regs.r10 = SysBase;
541 break;
542 case 11:
543 regs.r11 = SysBase;
544 break;
545 case 12:
546 regs.r12 = SysBase;
547 break;
548 case 13:
549 regs.r13 = SysBase;
550 break;
551 case 14:
552 regs.r14 = SysBase;
553 break;
554 case 15:
555 regs.r15 = SysBase;
556 break;
559 regs.return_rip += 7;
561 die = 0;
565 if (die)
567 rkprintf("IRQ %02x:", regs.irq_number);
568 rkprintf("[Kernel] PAGE FAULT EXCEPTION! %016p\n",ptr);
570 if (t)
572 rkprintf("[Kernel] %s %p '%s'\n",
573 t->tc_Node.ln_Type == NT_TASK?"task":"process", t, t->tc_Node.ln_Name);
576 rkprintf("[Kernel] stack=%04x:%012x rflags=%016x ip=%04x:%012x err=%08x\n",
577 regs.return_ss, regs.return_rsp, regs.return_rflags,
578 regs.return_cs, regs.return_rip, regs.error_code);
580 rkprintf("[Kernel] rax=%016lx rbx=%016lx rcx=%016lx rdx=%016lx\n", regs.rax, regs.rbx, regs.rcx, regs.rdx);
581 rkprintf("[Kernel] rsi=%016lx rdi=%016lx rbp=%016lx rsp=%016lx\n", regs.rsi, regs.rdi, regs.rbp, regs.return_rsp);
582 rkprintf("[Kernel] r08=%016lx r09=%016lx r10=%016lx r11=%016lx\n", regs.r8, regs.r9, regs.r10, regs.r11);
583 rkprintf("[Kernel] r12=%016lx r13=%016lx r14=%016lx r15=%016lx\n", regs.r12, regs.r13, regs.r14, regs.r15);
584 rkprintf("[Kernel] *rsp=%016lx\n", *(uint64_t *)regs.return_rsp);
586 rkprintf("[Kernel] Insn: ");
587 for (i = 0; i < 16; i++)
588 rkprintf("%02x ", ip[i]);
589 rkprintf("\n");
593 else if (regs.irq_number == 0x80) /* Syscall? */
595 switch (regs.rax)
597 case SC_CAUSE:
598 core_Cause(SysBase);
599 break;
601 case SC_DISPATCH:
602 core_Dispatch(&regs);
603 break;
605 case SC_SWITCH:
606 core_Switch(&regs);
607 break;
609 case SC_SCHEDULE:
610 if (regs.ds != KERNEL_DS)
611 core_Schedule(&regs);
612 break;
616 if (KernelBase)
618 if (KernelBase->kb_Intr[regs.irq_number].lh_Type == KBL_APIC)
619 core_APIC_AckIntr(regs.irq_number);
621 if (KernelBase->kb_Intr[regs.irq_number].lh_Type == KBL_XTPIC)
622 core_XTPIC_AckIntr(regs.irq_number);
625 if (!IsListEmpty(&KernelBase->kb_Intr[regs.irq_number]))
627 struct IntrNode *in, *in2;
629 ForeachNodeSafe(&KernelBase->kb_Intr[regs.irq_number], in, in2)
631 if (in->in_Handler)
632 in->in_Handler(in->in_HandlerData, in->in_HandlerData2);
635 if (KernelBase->kb_Intr[regs.irq_number].lh_Type == KBL_XTPIC)
636 core_XTPIC_EnableIRQ(regs.irq_number);
640 while (die) asm volatile ("hlt");
643 asm(".text\n\t"
644 ".globl core_DefaultIRETQ\n\t"
645 ".type core_DefaultIRETQ,@function\n"
646 "core_DefaultIRETQ: iretq");