Raw IP and ICMP fixes
[reactos.git] / reactos / ntoskrnl / ke / i386 / exp.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /*
20 * PROJECT: ReactOS kernel
21 * FILE: ntoskrnl/ke/i386/exp.c
22 * PURPOSE: Handling exceptions
23 * PROGRAMMER: David Welch (welch@cwcom.net)
24 * REVISION HISTORY:
25 * ??/??/??: Created
26 */
27
28 /* INCLUDES *****************************************************************/
29
30 #include <ddk/ntddk.h>
31 #include <internal/config.h>
32 #include <internal/ntoskrnl.h>
33 #include <internal/ke.h>
34 #include <internal/i386/segment.h>
35 #include <internal/i386/mm.h>
36 #include <internal/module.h>
37 #include <internal/mm.h>
38 #include <internal/ps.h>
39 #include <internal/trap.h>
40 #include <ntdll/ldr.h>
41
42 #define NDEBUG
43 #include <internal/debug.h>
44
45 /* GLOBALS *****************************************************************/
46
47 #define _STR(x) #x
48 #define STR(x) _STR(x)
49
50 extern void interrupt_handler2e(void);
51 extern void interrupt_handler2d(void);
52
53 extern VOID KiTrap0(VOID);
54 extern VOID KiTrap1(VOID);
55 extern VOID KiTrap2(VOID);
56 extern VOID KiTrap3(VOID);
57 extern VOID KiTrap4(VOID);
58 extern VOID KiTrap5(VOID);
59 extern VOID KiTrap6(VOID);
60 extern VOID KiTrap7(VOID);
61 extern VOID KiTrap8(VOID);
62 extern VOID KiTrap9(VOID);
63 extern VOID KiTrap10(VOID);
64 extern VOID KiTrap11(VOID);
65 extern VOID KiTrap12(VOID);
66 extern VOID KiTrap13(VOID);
67 extern VOID KiTrap14(VOID);
68 extern VOID KiTrap15(VOID);
69 extern VOID KiTrap16(VOID);
70 extern VOID KiTrapUnknown(VOID);
71
72 extern ULONG init_stack;
73 extern ULONG init_stack_top;
74
75 static char *ExceptionTypeStrings[] =
76 {
77 "Divide Error",
78 "Debug Trap",
79 "NMI",
80 "Breakpoint",
81 "Overflow",
82 "BOUND range exceeded",
83 "Invalid Opcode",
84 "No Math Coprocessor",
85 "Double Fault",
86 "Unknown(9)",
87 "Invalid TSS",
88 "Segment Not Present",
89 "Stack Segment Fault",
90 "General Protection",
91 "Page Fault",
92 "Math Fault",
93 "Alignment Check",
94 "Machine Check"
95 };
96
97 /* FUNCTIONS ****************************************************************/
98
99 extern unsigned int _text_start__, _text_end__;
100
101 STATIC BOOLEAN
102 print_kernel_address(PVOID address)
103 {
104 #ifdef KDBG
105 ULONG Offset;
106 PSYMBOL Symbol, NextSymbol;
107 BOOLEAN Printed = FALSE;
108 ULONG NextAddress;
109 #endif /* KDBG */
110 PLIST_ENTRY current_entry;
111 MODULE_TEXT_SECTION* current;
112 extern LIST_ENTRY ModuleTextListHead;
113
114 current_entry = ModuleTextListHead.Flink;
115
116 while (current_entry != &ModuleTextListHead &&
117 current_entry != NULL)
118 {
119 current =
120 CONTAINING_RECORD(current_entry, MODULE_TEXT_SECTION, ListEntry);
121
122 if (address >= (PVOID)current->Base &&
123 address < (PVOID)(current->Base + current->Length))
124 {
125
126 #ifdef KDBG
127
128 Offset = (ULONG)((ULONG)address - current->Base);
129 Symbol = current->Symbols.Symbols;
130 while (Symbol != NULL)
131 {
132 NextSymbol = Symbol->Next;
133 if (NextSymbol != NULL)
134 NextAddress = NextSymbol->RelativeAddress;
135 else
136 NextAddress = current->Length;
137
138 if ((Offset >= Symbol->RelativeAddress) &&
139 (Offset < NextAddress))
140 {
141 DbgPrint("<%ws: %x (%wZ)>", current->Name, Offset, &Symbol->Name);
142 Printed = TRUE;
143 break;
144 }
145 Symbol = NextSymbol;
146 }
147 if (!Printed)
148 DbgPrint("<%ws: %x>", current->Name, Offset);
149
150 #else /* KDBG */
151
152 DbgPrint("<%ws: %x>", current->Name,
153 address - current->Base);
154
155 #endif /* KDBG */
156
157 return(TRUE);
158 }
159
160 current_entry = current_entry->Flink;
161 }
162 return(FALSE);
163 }
164
165 STATIC BOOLEAN
166 print_user_address(PVOID address)
167 {
168 #ifdef KDBG
169 ULONG Offset;
170 PSYMBOL Symbol, NextSymbol;
171 BOOLEAN Printed = FALSE;
172 ULONG NextAddress;
173 #endif /* KDBG */
174 PLIST_ENTRY current_entry;
175 PLDR_MODULE current;
176 PEPROCESS CurrentProcess;
177 PPEB Peb = NULL;
178
179 CurrentProcess = PsGetCurrentProcess();
180 if (NULL != CurrentProcess)
181 {
182 Peb = CurrentProcess->Peb;
183 }
184
185 if (NULL == Peb)
186 {
187 DbgPrint("<%x>", address);
188 return(TRUE);
189 }
190
191 current_entry = Peb->Ldr->InLoadOrderModuleList.Flink;
192
193 while (current_entry != &Peb->Ldr->InLoadOrderModuleList &&
194 current_entry != NULL)
195 {
196 current =
197 CONTAINING_RECORD(current_entry, LDR_MODULE, InLoadOrderModuleList);
198
199 if (address >= (PVOID)current->BaseAddress &&
200 address < (PVOID)(current->BaseAddress + current->SizeOfImage))
201 {
202 #ifdef KDBG
203
204 Offset = (ULONG)(address - current->BaseAddress);
205 Symbol = current->Symbols.Symbols;
206 while (Symbol != NULL)
207 {
208 NextSymbol = Symbol->Next;
209 if (NextSymbol != NULL)
210 NextAddress = NextSymbol->RelativeAddress;
211 else
212 NextAddress = current->SizeOfImage;
213
214 if ((Offset >= Symbol->RelativeAddress) &&
215 (Offset < NextAddress))
216 {
217 DbgPrint("<%wZ: %x (%wZ)>",
218 &current->BaseDllName, Offset, &Symbol->Name);
219 Printed = TRUE;
220 break;
221 }
222 Symbol = NextSymbol;
223 }
224 if (!Printed)
225 DbgPrint("<%wZ: %x>", &current->BaseDllName, Offset);
226
227 #else /* KDBG */
228
229 DbgPrint("<%wZ: %x>", &current->BaseDllName,
230 address - current->BaseAddress);
231
232 #endif /* KDBG */
233
234 return(TRUE);
235 }
236
237 current_entry = current_entry->Flink;
238 }
239 return(FALSE);
240 }
241
242 STATIC BOOLEAN
243 print_address(PVOID address)
244 {
245 /* FIXME: There is a variable with this value somewhere...use it */
246 if ((ULONG)address >= 0xc0000000)
247 {
248 return print_kernel_address(address);
249 }
250 else
251 {
252 return print_user_address(address);
253 }
254 }
255
256 #if 0
257 ULONG
258 KiUserTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2)
259 {
260 EXCEPTION_RECORD Er;
261
262 if (ExceptionNr == 0)
263 {
264 Er.ExceptionCode = STATUS_INTEGER_DIVIDE_BY_ZERO;
265 }
266 else if (ExceptionNr == 1)
267 {
268 Er.ExceptionCode = STATUS_SINGLE_STEP;
269 }
270 else if (ExceptionNr == 3)
271 {
272 Er.ExceptionCode = STATUS_BREAKPOINT;
273 }
274 else if (ExceptionNr == 4)
275 {
276 Er.ExceptionCode = STATUS_INTEGER_OVERFLOW;
277 }
278 else if (ExceptionNr == 5)
279 {
280 Er.ExceptionCode = STATUS_ARRAY_BOUNDS_EXCEEDED;
281 }
282 else if (ExceptionNr == 6)
283 {
284 Er.ExceptionCode = STATUS_ILLEGAL_INSTRUCTION;
285 }
286 else
287 {
288 Er.ExceptionCode = STATUS_ACCESS_VIOLATION;
289 }
290 Er.ExceptionFlags = 0;
291 Er.ExceptionRecord = NULL;
292 Er.ExceptionAddress = (PVOID)Tf->Eip;
293 if (ExceptionNr == 14)
294 {
295 Er.NumberParameters = 2;
296 Er.ExceptionInformation[0] = Tf->ErrorCode & 0x1;
297 Er.ExceptionInformation[1] = (ULONG)Cr2;
298 }
299 else
300 {
301 Er.NumberParameters = 0;
302 }
303
304
305 KiDispatchException(&Er, 0, Tf, UserMode, TRUE);
306 return(0);
307 }
308 #endif
309
310 ULONG
311 KiUserTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2)
312 {
313 PULONG Frame;
314 ULONG cr3;
315 ULONG i;
316
317 /*
318 * Get the PDBR
319 */
320 __asm__("movl %%cr3,%0\n\t" : "=d" (cr3));
321
322 /*
323 * Print out the CPU registers
324 */
325 if (ExceptionNr < 19)
326 {
327 DbgPrint("%s Exception: %d(%x)\n", ExceptionTypeStrings[ExceptionNr],
328 ExceptionNr, Tf->ErrorCode&0xffff);
329 }
330 else
331 {
332 DbgPrint("Exception: %d(%x)\n", ExceptionNr, Tf->ErrorCode&0xffff);
333 }
334 DbgPrint("CS:EIP %x:%x ", Tf->Cs&0xffff, Tf->Eip);
335 print_address((PVOID)Tf->Eip);
336 DbgPrint("\n");
337 __asm__("movl %%cr3,%0\n\t" : "=d" (cr3));
338 DbgPrint("CR2 %x CR3 %x ", Cr2, cr3);
339 DbgPrint("Process: %x ",PsGetCurrentProcess());
340 if (PsGetCurrentProcess() != NULL)
341 {
342 DbgPrint("Pid: %x <", PsGetCurrentProcess()->UniqueProcessId);
343 DbgPrint("%.8s> ", PsGetCurrentProcess()->ImageFileName);
344 }
345 if (PsGetCurrentThread() != NULL)
346 {
347 DbgPrint("Thrd: %x Tid: %x",
348 PsGetCurrentThread(),
349 PsGetCurrentThread()->Cid.UniqueThread);
350 }
351 DbgPrint("\n");
352 DbgPrint("DS %x ES %x FS %x GS %x\n", Tf->Ds&0xffff, Tf->Es&0xffff,
353 Tf->Fs&0xffff, Tf->Gs&0xfff);
354 DbgPrint("EAX: %.8x EBX: %.8x ECX: %.8x\n", Tf->Eax, Tf->Ebx, Tf->Ecx);
355 DbgPrint("EDX: %.8x EBP: %.8x ESI: %.8x\n", Tf->Edx, Tf->Ebp, Tf->Esi);
356 DbgPrint("EDI: %.8x EFLAGS: %.8x ", Tf->Edi, Tf->Eflags);
357 DbgPrint("SS:ESP %x:%x\n", Tf->Ss, Tf->Esp);
358
359 #if 0
360 stack=(PULONG)(Tf->Esp);
361
362 DbgPrint("Stack:\n");
363 for (i=0; i<64; i++)
364 {
365 if (MmIsPagePresent(NULL,&stack[i]))
366 {
367 DbgPrint("%.8x ",stack[i]);
368 if (((i+1)%8) == 0)
369 {
370 DbgPrint("\n");
371 }
372 }
373 }
374 #endif
375
376 #if 0
377 if (MmIsPagePresent(NULL, (PVOID)Tf->Eip))
378 {
379 unsigned char instrs[512];
380
381 memcpy(instrs, (PVOID)Tf->Eip, 512);
382
383 DbgPrint("Instrs: ");
384
385 for (i=0; i<10; i++)
386 {
387 DbgPrint("%x ", instrs[i]);
388 }
389 }
390 #endif
391
392 /*
393 * Dump the stack frames
394 */
395 DbgPrint("Frames: ");
396 i = 1;
397 Frame = (PULONG)Tf->Ebp;
398 while (Frame != NULL)
399 {
400 print_address((PVOID)Frame[1]);
401 Frame = (PULONG)Frame[0];
402 i++;
403 }
404
405 /*
406 * Kill the faulting task
407 */
408 __asm__("sti\n\t");
409 ZwTerminateProcess(NtCurrentProcess(),
410 STATUS_NONCONTINUABLE_EXCEPTION);
411
412 /*
413 * If terminating the process fails then bugcheck
414 */
415 KeBugCheck(0);
416 return(0);
417 }
418
419 ULONG
420 KiDoubleFaultHandler(VOID)
421 {
422 unsigned int cr2;
423 unsigned int i;
424 PULONG stack;
425 ULONG StackLimit;
426 ULONG Esp0;
427 ULONG ExceptionNr = 8;
428 KTSS* OldTss;
429
430 /* Use the address of the trap frame as approximation to the ring0 esp */
431 OldTss = KeGetCurrentKPCR()->TSS;
432 Esp0 = OldTss->Esp0;
433
434 /* Get CR2 */
435 __asm__("movl %%cr2,%0\n\t" : "=d" (cr2));
436
437 /*
438 * Check for stack underflow
439 */
440 if (PsGetCurrentThread() != NULL &&
441 Esp0 < (ULONG)PsGetCurrentThread()->Tcb.StackLimit)
442 {
443 DbgPrint("Stack underflow (tf->esp %x Limit %x)\n",
444 Esp0, (ULONG)PsGetCurrentThread()->Tcb.StackLimit);
445 ExceptionNr = 12;
446 }
447
448 /*
449 * Print out the CPU registers
450 */
451 if (ExceptionNr < 19)
452 {
453 DbgPrint("%s Exception: %d(%x)\n", ExceptionTypeStrings[ExceptionNr],
454 ExceptionNr, 0);
455 }
456 else
457 {
458 DbgPrint("Exception: %d(%x)\n", ExceptionNr, 0);
459 }
460 DbgPrint("CS:EIP %x:%x ", OldTss->Cs, OldTss->Eip);
461 print_address((PVOID)OldTss->Eip);
462 DbgPrint("\n");
463 DbgPrint("cr2 %x cr3 %x ", cr2, OldTss->Cr3);
464 DbgPrint("Proc: %x ",PsGetCurrentProcess());
465 if (PsGetCurrentProcess() != NULL)
466 {
467 DbgPrint("Pid: %x <", PsGetCurrentProcess()->UniqueProcessId);
468 DbgPrint("%.8s> ", PsGetCurrentProcess()->ImageFileName);
469 }
470 if (PsGetCurrentThread() != NULL)
471 {
472 DbgPrint("Thrd: %x Tid: %x",
473 PsGetCurrentThread(),
474 PsGetCurrentThread()->Cid.UniqueThread);
475 }
476 DbgPrint("\n");
477 DbgPrint("DS %x ES %x FS %x GS %x\n", OldTss->Ds, OldTss->Es,
478 OldTss->Fs, OldTss->Gs);
479 DbgPrint("EAX: %.8x EBX: %.8x ECX: %.8x\n", OldTss->Eax, OldTss->Ebx,
480 OldTss->Ecx);
481 DbgPrint("EDX: %.8x EBP: %.8x ESI: %.8x\n", OldTss->Edx, OldTss->Ebp,
482 OldTss->Esi);
483 DbgPrint("EDI: %.8x EFLAGS: %.8x ", OldTss->Edi, OldTss->Eflags);
484 if (OldTss->Cs == KERNEL_CS)
485 {
486 DbgPrint("kESP %.8x ", Esp0);
487 if (PsGetCurrentThread() != NULL)
488 {
489 DbgPrint("kernel stack base %x\n",
490 PsGetCurrentThread()->Tcb.StackLimit);
491
492 }
493 }
494 else
495 {
496 DbgPrint("User ESP %.8x\n", OldTss->Esp);
497 }
498 if ((OldTss->Cs & 0xffff) == KERNEL_CS)
499 {
500 DbgPrint("ESP %x\n", Esp0);
501 stack = (PULONG) (Esp0 + 24);
502 stack = (PULONG)(((ULONG)stack) & (~0x3));
503 if (PsGetCurrentThread() != NULL)
504 {
505 StackLimit = (ULONG)PsGetCurrentThread()->Tcb.StackBase;
506 }
507 else
508 {
509 StackLimit = (ULONG)&init_stack_top;
510 }
511
512 DbgPrint("stack<%p>: ", stack);
513
514 for (i = 0; i < 18 && (((ULONG)&stack[i+5]) < StackLimit); i = i + 6)
515 {
516 DbgPrint("%.8x %.8x %.8x %.8x\n",
517 stack[i], stack[i+1],
518 stack[i+2], stack[i+3],
519 stack[i+4], stack[i+5]);
520 }
521 DbgPrint("Frames:\n");
522 for (i = 0; i < 32 && (((ULONG)&stack[i]) < StackLimit); i++)
523 {
524 if (stack[i] > ((unsigned int) &_text_start__) &&
525 !(stack[i] >= ((ULONG)&init_stack) &&
526 stack[i] <= ((ULONG)&init_stack_top)))
527 {
528 print_address((PVOID)stack[i]);
529 DbgPrint(" ");
530 }
531 }
532 }
533
534 DbgPrint("\n");
535 for(;;);
536 }
537
538 ULONG
539 KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
540 /*
541 * FUNCTION: Called by the lowlevel execption handlers to print an amusing
542 * message and halt the computer
543 * ARGUMENTS:
544 * Complete CPU context
545 */
546 {
547 unsigned int cr2, cr3;
548 unsigned int i;
549 // unsigned int j, sym;
550 NTSTATUS Status;
551 ULONG Esp0;
552 ULONG StackLimit;
553 PULONG Frame;
554
555 /* Use the address of the trap frame as approximation to the ring0 esp */
556 Esp0 = (ULONG)&Tf->Eip;
557
558 /* Get CR2 */
559 __asm__("movl %%cr2,%0\n\t" : "=d" (cr2));
560
561 /*
562 * If this was a V86 mode exception then handle it specially
563 */
564 if (Tf->Eflags & (1 << 17))
565 {
566 return(KeV86Exception(ExceptionNr, Tf, cr2));
567 }
568
569 /*
570 * Check for stack underflow, this may be obsolete
571 */
572 if (PsGetCurrentThread() != NULL &&
573 Esp0 < (ULONG)PsGetCurrentThread()->Tcb.StackLimit)
574 {
575 DbgPrint("Stack underflow (tf->esp %x Limit %x)\n",
576 Esp0, (ULONG)PsGetCurrentThread()->Tcb.StackLimit);
577 ExceptionNr = 12;
578 }
579
580 /*
581 * Maybe handle the page fault and return
582 */
583 if (ExceptionNr == 14)
584 {
585 __asm__("sti\n\t");
586 Status = MmPageFault(Tf->Cs&0xffff,
587 &Tf->Eip,
588 &Tf->Eax,
589 cr2,
590 Tf->ErrorCode);
591 if (NT_SUCCESS(Status))
592 {
593 return(0);
594 }
595 }
596
597 /*
598 * Handle user exceptions differently
599 */
600 if ((Tf->Cs & 0xFFFF) == USER_CS)
601 {
602 return(KiUserTrapHandler(Tf, ExceptionNr, (PVOID)cr2));
603 }
604
605 /*
606 * Print out the CPU registers
607 */
608 if (ExceptionNr < 19)
609 {
610 DbgPrint("%s Exception: %d(%x)\n", ExceptionTypeStrings[ExceptionNr],
611 ExceptionNr, Tf->ErrorCode&0xffff);
612 }
613 else
614 {
615 DbgPrint("Exception: %d(%x)\n", ExceptionNr, Tf->ErrorCode&0xffff);
616 }
617 DbgPrint("Processor: %d CS:EIP %x:%x ", KeGetCurrentProcessorNumber(),
618 Tf->Cs&0xffff, Tf->Eip);
619 print_address((PVOID)Tf->Eip);
620 DbgPrint("\n");
621 __asm__("movl %%cr3,%0\n\t" : "=d" (cr3));
622 DbgPrint("cr2 %x cr3 %x ", cr2, cr3);
623 DbgPrint("Proc: %x ",PsGetCurrentProcess());
624 if (PsGetCurrentProcess() != NULL)
625 {
626 DbgPrint("Pid: %x <", PsGetCurrentProcess()->UniqueProcessId);
627 DbgPrint("%.8s> ", PsGetCurrentProcess()->ImageFileName);
628 }
629 if (PsGetCurrentThread() != NULL)
630 {
631 DbgPrint("Thrd: %x Tid: %x",
632 PsGetCurrentThread(),
633 PsGetCurrentThread()->Cid.UniqueThread);
634 }
635 DbgPrint("\n");
636 DbgPrint("DS %x ES %x FS %x GS %x\n", Tf->Ds&0xffff, Tf->Es&0xffff,
637 Tf->Fs&0xffff, Tf->Gs&0xfff);
638 DbgPrint("EAX: %.8x EBX: %.8x ECX: %.8x\n", Tf->Eax, Tf->Ebx, Tf->Ecx);
639 DbgPrint("EDX: %.8x EBP: %.8x ESI: %.8x\n", Tf->Edx, Tf->Ebp, Tf->Esi);
640 DbgPrint("EDI: %.8x EFLAGS: %.8x ", Tf->Edi, Tf->Eflags);
641 if ((Tf->Cs&0xffff) == KERNEL_CS)
642 {
643 DbgPrint("kESP %.8x ", Esp0);
644 if (PsGetCurrentThread() != NULL)
645 {
646 DbgPrint("kernel stack base %x\n",
647 PsGetCurrentThread()->Tcb.StackLimit);
648
649 }
650 }
651
652 DbgPrint("ESP %x\n", Esp0);
653
654 if (PsGetCurrentThread() != NULL)
655 {
656 StackLimit = (ULONG)PsGetCurrentThread()->Tcb.StackBase;
657 }
658 else
659 {
660 StackLimit = (ULONG)&init_stack_top;
661 }
662
663 /*
664 * Dump the stack frames
665 */
666 DbgPrint("Frames: ");
667 i = 1;
668 Frame = (PULONG)Tf->Ebp;
669 while (Frame != NULL)
670 {
671 print_address((PVOID)Frame[1]);
672 Frame = (PULONG)Frame[0];
673 i++;
674 }
675 if ((i % 8) != 0)
676 {
677 DbgPrint("\n");
678 }
679
680 for(;;);
681 }
682
683 VOID
684 KeDumpStackFrames(PULONG Frame)
685 {
686 ULONG i;
687
688 DbgPrint("Frames: ");
689 i = 1;
690 while (Frame != NULL)
691 {
692 print_address((PVOID)Frame[1]);
693 Frame = (PULONG)Frame[0];
694 i++;
695 }
696 if ((i % 8) != 0)
697 {
698 DbgPrint("\n");
699 }
700 }
701
702 static void set_system_call_gate(unsigned int sel, unsigned int func)
703 {
704 DPRINT("sel %x %d\n",sel,sel);
705 KiIdt[sel].a = (((int)func)&0xffff) +
706 (KERNEL_CS << 16);
707 KiIdt[sel].b = 0xef00 + (((int)func)&0xffff0000);
708 DPRINT("idt[sel].b %x\n",KiIdt[sel].b);
709 }
710
711 static void set_interrupt_gate(unsigned int sel, unsigned int func)
712 {
713 DPRINT("set_interrupt_gate(sel %d, func %x)\n",sel,func);
714 KiIdt[sel].a = (((int)func)&0xffff) +
715 (KERNEL_CS << 16);
716 KiIdt[sel].b = 0x8f00 + (((int)func)&0xffff0000);
717 }
718
719 static void
720 set_task_gate(unsigned int sel, unsigned task_sel)
721 {
722 KiIdt[sel].a = task_sel << 16;
723 KiIdt[sel].b = 0x8500;
724 }
725
726 VOID
727 KeInitExceptions(VOID)
728 /*
729 * FUNCTION: Initalize CPU exception handling
730 */
731 {
732 int i;
733
734 DPRINT("KeInitExceptions()\n");
735
736 /*
737 * Set up the other gates
738 */
739 set_interrupt_gate(0, (ULONG)KiTrap0);
740 set_interrupt_gate(1, (ULONG)KiTrap1);
741 set_interrupt_gate(2, (ULONG)KiTrap2);
742 set_interrupt_gate(3, (ULONG)KiTrap3);
743 set_interrupt_gate(4, (ULONG)KiTrap4);
744 set_interrupt_gate(5, (ULONG)KiTrap5);
745 set_interrupt_gate(6, (ULONG)KiTrap6);
746 set_interrupt_gate(7, (ULONG)KiTrap7);
747 set_task_gate(8, TRAP_TSS_SELECTOR);
748 set_interrupt_gate(9, (ULONG)KiTrap9);
749 set_interrupt_gate(10, (ULONG)KiTrap10);
750 set_interrupt_gate(11, (ULONG)KiTrap11);
751 set_interrupt_gate(12, (ULONG)KiTrap12);
752 set_interrupt_gate(13, (ULONG)KiTrap13);
753 set_interrupt_gate(14, (ULONG)KiTrap14);
754 set_interrupt_gate(15, (ULONG)KiTrap15);
755 set_interrupt_gate(16, (ULONG)KiTrap16);
756
757 for (i=17;i<256;i++)
758 {
759 set_interrupt_gate(i,(int)KiTrapUnknown);
760 }
761
762 set_system_call_gate(0x2d,(int)interrupt_handler2d);
763 set_system_call_gate(0x2e,(int)interrupt_handler2e);
764 }