Don't map NOLOAD sections
[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/ntoskrnl.h>
32 #include <internal/ke.h>
33 #include <internal/i386/segment.h>
34 #include <internal/i386/mm.h>
35 #include <internal/module.h>
36 #include <internal/mm.h>
37 #include <internal/ps.h>
38 #include <internal/trap.h>
39
40 #define NDEBUG
41 #include <internal/debug.h>
42
43 /* GLOBALS *****************************************************************/
44
45 #define _STR(x) #x
46 #define STR(x) _STR(x)
47
48 extern void interrupt_handler2e(void);
49 extern void interrupt_handler2d(void);
50
51 extern VOID KiTrap0(VOID);
52 extern VOID KiTrap1(VOID);
53 extern VOID KiTrap2(VOID);
54 extern VOID KiTrap3(VOID);
55 extern VOID KiTrap4(VOID);
56 extern VOID KiTrap5(VOID);
57 extern VOID KiTrap6(VOID);
58 extern VOID KiTrap7(VOID);
59 extern VOID KiTrap8(VOID);
60 extern VOID KiTrap9(VOID);
61 extern VOID KiTrap10(VOID);
62 extern VOID KiTrap11(VOID);
63 extern VOID KiTrap12(VOID);
64 extern VOID KiTrap13(VOID);
65 extern VOID KiTrap14(VOID);
66 extern VOID KiTrap15(VOID);
67 extern VOID KiTrap16(VOID);
68 extern VOID KiTrapUnknown(VOID);
69
70 extern ULONG init_stack;
71 extern ULONG init_stack_top;
72
73 static char KiNullLdt[8] = {0,};
74
75 /* FUNCTIONS ****************************************************************/
76
77 extern unsigned int _text_start__, _text_end__;
78
79 STATIC BOOLEAN
80 print_address(PVOID address)
81 {
82 PLIST_ENTRY current_entry;
83 MODULE_TEXT_SECTION* current;
84 extern LIST_ENTRY ModuleTextListHead;
85
86 current_entry = ModuleTextListHead.Flink;
87
88 while (current_entry != &ModuleTextListHead &&
89 current_entry != NULL)
90 {
91 current =
92 CONTAINING_RECORD(current_entry, MODULE_TEXT_SECTION, ListEntry);
93
94 if (address >= (PVOID)current->Base &&
95 address < (PVOID)(current->Base + current->Length))
96 {
97 DbgPrint("<%ws: %x>", current->Name,
98 address - current->Base);
99 return(TRUE);
100 }
101
102 current_entry = current_entry->Flink;
103 }
104 #if 0
105 DbgPrint("<%x>", address);
106 #endif
107 return(FALSE);
108 }
109
110 ULONG
111 KiUserTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2)
112 {
113 EXCEPTION_RECORD Er;
114
115 if (ExceptionNr == 0)
116 {
117 Er.ExceptionCode = STATUS_INTEGER_DIVIDE_BY_ZERO;
118 }
119 else if (ExceptionNr == 1)
120 {
121 Er.ExceptionCode = STATUS_SINGLE_STEP;
122 }
123 else if (ExceptionNr == 3)
124 {
125 Er.ExceptionCode = STATUS_BREAKPOINT;
126 }
127 else if (ExceptionNr == 4)
128 {
129 Er.ExceptionCode = STATUS_INTEGER_OVERFLOW;
130 }
131 else if (ExceptionNr == 5)
132 {
133 Er.ExceptionCode = STATUS_ARRAY_BOUNDS_EXCEEDED;
134 }
135 else if (ExceptionNr == 6)
136 {
137 Er.ExceptionCode = STATUS_ILLEGAL_INSTRUCTION;
138 }
139 else
140 {
141 Er.ExceptionCode = STATUS_ACCESS_VIOLATION;
142 }
143 Er.ExceptionFlags = 0;
144 Er.ExceptionRecord = NULL;
145 Er.ExceptionAddress = (PVOID)Tf->Eip;
146 if (ExceptionNr == 14)
147 {
148 Er.NumberParameters = 2;
149 Er.ExceptionInformation[0] = Tf->ErrorCode & 0x1;
150 Er.ExceptionInformation[1] = (ULONG)Cr2;
151 }
152 else
153 {
154 Er.NumberParameters = 0;
155 }
156
157
158 KiDispatchException(&Er, 0, Tf, UserMode, TRUE);
159 return(0);
160 }
161
162 ULONG
163 KiDoubleFaultHandler(VOID)
164 {
165 unsigned int cr2;
166 unsigned int i;
167 PULONG stack;
168 ULONG StackLimit;
169 ULONG Esp0;
170 ULONG ExceptionNr = 8;
171 extern KTSS KiTss;
172 static char *TypeStrings[] =
173 {
174 "Divide Error",
175 "Debug Trap",
176 "NMI",
177 "Breakpoint",
178 "Overflow",
179 "BOUND range exceeded",
180 "Invalid Opcode",
181 "No Math Coprocessor",
182 "Double Fault",
183 "Unknown(9)",
184 "Invalid TSS",
185 "Segment Not Present",
186 "Stack Segment Fault",
187 "General Protection",
188 "Page Fault",
189 "Math Fault",
190 "Alignment Check",
191 "Machine Check"
192 };
193
194 /* Use the address of the trap frame as approximation to the ring0 esp */
195 Esp0 = KiTss.Esp0;
196
197 /* Get CR2 */
198 __asm__("movl %%cr2,%0\n\t" : "=d" (cr2));
199
200 /*
201 * Check for stack underflow
202 */
203 if (PsGetCurrentThread() != NULL &&
204 Esp0 < (ULONG)PsGetCurrentThread()->Tcb.StackLimit)
205 {
206 DbgPrint("Stack underflow (tf->esp %x Limit %x)\n",
207 Esp0, (ULONG)PsGetCurrentThread()->Tcb.StackLimit);
208 ExceptionNr = 12;
209 }
210
211 /*
212 * Print out the CPU registers
213 */
214 if (ExceptionNr < 19)
215 {
216 DbgPrint("%s Exception: %d(%x)\n",TypeStrings[ExceptionNr],
217 ExceptionNr, 0);
218 }
219 else
220 {
221 DbgPrint("Exception: %d(%x)\n", ExceptionNr, 0);
222 }
223 DbgPrint("CS:EIP %x:%x ", KiTss.Cs, KiTss.Eip);
224 print_address((PVOID)KiTss.Eip);
225 DbgPrint("\n");
226 DbgPrint("cr2 %x cr3 %x ", cr2, KiTss.Cr3);
227 DbgPrint("Proc: %x ",PsGetCurrentProcess());
228 if (PsGetCurrentProcess() != NULL)
229 {
230 DbgPrint("Pid: %x <", PsGetCurrentProcess()->UniqueProcessId);
231 DbgPrint("%.8s> ", PsGetCurrentProcess()->ImageFileName);
232 }
233 if (PsGetCurrentThread() != NULL)
234 {
235 DbgPrint("Thrd: %x Tid: %x",
236 PsGetCurrentThread(),
237 PsGetCurrentThread()->Cid.UniqueThread);
238 }
239 DbgPrint("\n");
240 DbgPrint("DS %x ES %x FS %x GS %x\n", KiTss.Ds, KiTss.Es,
241 KiTss.Fs, KiTss.Gs);
242 DbgPrint("EAX: %.8x EBX: %.8x ECX: %.8x\n", KiTss.Eax, KiTss.Ebx,
243 KiTss.Ecx);
244 DbgPrint("EDX: %.8x EBP: %.8x ESI: %.8x\n", KiTss.Edx, KiTss.Ebp,
245 KiTss.Esi);
246 DbgPrint("EDI: %.8x EFLAGS: %.8x ", KiTss.Edi, KiTss.Eflags);
247 if (KiTss.Cs == KERNEL_CS)
248 {
249 DbgPrint("kESP %.8x ", Esp0);
250 if (PsGetCurrentThread() != NULL)
251 {
252 DbgPrint("kernel stack base %x\n",
253 PsGetCurrentThread()->Tcb.StackLimit);
254
255 }
256 }
257 else
258 {
259 DbgPrint("User ESP %.8x\n", KiTss.Esp);
260 }
261 if ((KiTss.Cs & 0xffff) == KERNEL_CS)
262 {
263 DbgPrint("ESP %x\n", Esp0);
264 stack = (PULONG) (Esp0 + 24);
265 stack = (PULONG)(((ULONG)stack) & (~0x3));
266 if (PsGetCurrentThread() != NULL)
267 {
268 StackLimit = (ULONG)PsGetCurrentThread()->Tcb.StackBase;
269 }
270 else
271 {
272 StackLimit = (ULONG)&init_stack_top;
273 }
274
275 DbgPrint("stack<%p>: ", stack);
276
277 for (i = 0; i < 18 && (((ULONG)&stack[i+5]) < StackLimit); i = i + 6)
278 {
279 DbgPrint("%.8x %.8x %.8x %.8x\n",
280 stack[i], stack[i+1],
281 stack[i+2], stack[i+3],
282 stack[i+4], stack[i+5]);
283 }
284 DbgPrint("Frames:\n");
285 for (i = 0; i < 32 && (((ULONG)&stack[i]) < StackLimit); i++)
286 {
287 if (stack[i] > ((unsigned int) &_text_start__) &&
288 !(stack[i] >= ((ULONG)&init_stack) &&
289 stack[i] <= ((ULONG)&init_stack_top)))
290 {
291 print_address((PVOID)stack[i]);
292 DbgPrint(" ");
293 }
294 }
295 }
296
297 DbgPrint("\n");
298 for(;;);
299 }
300
301 ULONG
302 KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
303 /*
304 * FUNCTION: Called by the lowlevel execption handlers to print an amusing
305 * message and halt the computer
306 * ARGUMENTS:
307 * Complete CPU context
308 */
309 {
310 unsigned int cr2, cr3;
311 unsigned int i;
312 // unsigned int j, sym;
313 PULONG stack;
314 NTSTATUS Status;
315 ULONG Esp0;
316 ULONG StackLimit;
317 static char *TypeStrings[] =
318 {
319 "Divide Error",
320 "Debug Trap",
321 "NMI",
322 "Breakpoint",
323 "Overflow",
324 "BOUND range exceeded",
325 "Invalid Opcode",
326 "No Math Coprocessor",
327 "Double Fault",
328 "Unknown(9)",
329 "Invalid TSS",
330 "Segment Not Present",
331 "Stack Segment Fault",
332 "General Protection",
333 "Page Fault",
334 "Math Fault",
335 "Alignment Check",
336 "Machine Check"
337 };
338
339 /* Use the address of the trap frame as approximation to the ring0 esp */
340 Esp0 = (ULONG)&Tf->Eip;
341
342 /* Get CR2 */
343 __asm__("movl %%cr2,%0\n\t" : "=d" (cr2));
344
345 /*
346 * If this was a V86 mode exception then handle it specially
347 */
348 if (Tf->Eflags & (1 << 17))
349 {
350 return(KeV86Exception(ExceptionNr, Tf, cr2));
351 }
352
353 /*
354 * Check for stack underflow
355 */
356 if (PsGetCurrentThread() != NULL &&
357 Esp0 < (ULONG)PsGetCurrentThread()->Tcb.StackLimit)
358 {
359 DbgPrint("Stack underflow (tf->esp %x Limit %x)\n",
360 Esp0, (ULONG)PsGetCurrentThread()->Tcb.StackLimit);
361 ExceptionNr = 12;
362 }
363
364 if (ExceptionNr == 14)
365 {
366 __asm__("sti\n\t");
367 Status = MmPageFault(Tf->Cs&0xffff,
368 &Tf->Eip,
369 &Tf->Eax,
370 cr2,
371 Tf->ErrorCode);
372 if (NT_SUCCESS(Status))
373 {
374 return(0);
375 }
376 }
377
378 #if 0
379 if ((Tf->Cs & 0xFFFF) == USER_CS)
380 {
381 return(KiUserTrapHandler(Tf, ExceptionNr, (PVOID)cr2));
382 }
383 #endif
384
385 /*
386 * Print out the CPU registers
387 */
388 if (ExceptionNr < 19)
389 {
390 DbgPrint("%s Exception: %d(%x)\n",TypeStrings[ExceptionNr],
391 ExceptionNr, Tf->ErrorCode&0xffff);
392 }
393 else
394 {
395 DbgPrint("Exception: %d(%x)\n", ExceptionNr, Tf->ErrorCode&0xffff);
396 }
397 DbgPrint("CS:EIP %x:%x ", Tf->Cs&0xffff, Tf->Eip);
398 print_address((PVOID)Tf->Eip);
399 DbgPrint("\n");
400 __asm__("movl %%cr3,%0\n\t" : "=d" (cr3));
401 DbgPrint("cr2 %x cr3 %x ", cr2, cr3);
402 DbgPrint("Proc: %x ",PsGetCurrentProcess());
403 if (PsGetCurrentProcess() != NULL)
404 {
405 DbgPrint("Pid: %x <", PsGetCurrentProcess()->UniqueProcessId);
406 DbgPrint("%.8s> ", PsGetCurrentProcess()->ImageFileName);
407 }
408 if (PsGetCurrentThread() != NULL)
409 {
410 DbgPrint("Thrd: %x Tid: %x",
411 PsGetCurrentThread(),
412 PsGetCurrentThread()->Cid.UniqueThread);
413 }
414 DbgPrint("\n");
415 DbgPrint("DS %x ES %x FS %x GS %x\n", Tf->Ds&0xffff, Tf->Es&0xffff,
416 Tf->Fs&0xffff, Tf->Gs&0xfff);
417 DbgPrint("EAX: %.8x EBX: %.8x ECX: %.8x\n", Tf->Eax, Tf->Ebx, Tf->Ecx);
418 DbgPrint("EDX: %.8x EBP: %.8x ESI: %.8x\n", Tf->Edx, Tf->Ebp, Tf->Esi);
419 DbgPrint("EDI: %.8x EFLAGS: %.8x ", Tf->Edi, Tf->Eflags);
420 if ((Tf->Cs&0xffff) == KERNEL_CS)
421 {
422 DbgPrint("kESP %.8x ", Esp0);
423 if (PsGetCurrentThread() != NULL)
424 {
425 DbgPrint("kernel stack base %x\n",
426 PsGetCurrentThread()->Tcb.StackLimit);
427
428 }
429 }
430 else
431 {
432 DbgPrint("User ESP %.8x\n", Tf->Esp);
433 }
434 if ((Tf->Cs & 0xffff) == KERNEL_CS)
435 {
436 DbgPrint("ESP %x\n", Esp0);
437 stack = (PULONG) (Esp0 + 24);
438 stack = (PULONG)(((ULONG)stack) & (~0x3));
439
440 DbgPrint("stack<%p>: ", stack);
441
442 if (PsGetCurrentThread() != NULL)
443 {
444 StackLimit = (ULONG)PsGetCurrentThread()->Tcb.StackBase;
445 }
446 else
447 {
448 StackLimit = (ULONG)&init_stack_top;
449 }
450
451 for (i = 0; i < 18; i = i + 6)
452 {
453 DbgPrint("%.8x %.8x %.8x %.8x\n",
454 stack[i], stack[i+1],
455 stack[i+2], stack[i+3],
456 stack[i+4], stack[i+5]);
457 }
458 DbgPrint("Frames:\n");
459 for (i = 0; i < 32 && ((ULONG)&stack[i] < StackLimit); i++)
460 {
461 if (stack[i] > ((unsigned int) &_text_start__) &&
462 !(stack[i] >= ((ULONG)&init_stack) &&
463 stack[i] <= ((ULONG)&init_stack_top)))
464 {
465 // DbgPrint(" %.8x", stack[i]);
466 print_address((PVOID)stack[i]);
467 DbgPrint(" ");
468 }
469 }
470 }
471 else
472 {
473 #if 1
474 DbgPrint("SS:ESP %x:%x\n", Tf->Ss, Tf->Esp);
475 stack=(PULONG)(Tf->Esp);
476
477 DbgPrint("Stack:\n");
478 for (i=0; i<64; i++)
479 {
480 if (MmIsPagePresent(NULL,&stack[i]))
481 {
482 DbgPrint("%.8x ",stack[i]);
483 if (((i+1)%8) == 0)
484 {
485 DbgPrint("\n");
486 }
487 }
488 }
489
490 if (MmIsPagePresent(NULL, (PVOID)Tf->Eip))
491 {
492 unsigned char instrs[512];
493
494 memcpy(instrs, (PVOID)Tf->Eip, 512);
495
496 DbgPrint("Instrs: ");
497
498 for (i=0; i<10; i++)
499 {
500 DbgPrint("%x ", instrs[i]);
501 }
502 }
503 #endif
504 }
505
506 DbgPrint("\n");
507 if ((Tf->Cs&0xffff) == USER_CS &&
508 Tf->Eip < KERNEL_BASE)
509 {
510 DbgPrint("Killing current task\n");
511 KeLowerIrql(PASSIVE_LEVEL);
512 if ((Tf->Cs&0xffff) == USER_CS)
513 {
514 ZwTerminateProcess(NtCurrentProcess(),
515 STATUS_NONCONTINUABLE_EXCEPTION);
516 }
517 }
518 for(;;);
519 }
520
521 VOID
522 KeDumpStackFrames(PVOID _Stack, ULONG NrFrames)
523 {
524 PULONG Stack = (PULONG)_Stack;
525 ULONG i;
526 ULONG StackLimit;
527
528 Stack = (PVOID)(((ULONG)Stack) & (~0x3));
529 DbgPrint("Stack: %x\n", Stack);
530 if (PsGetCurrentThread() != NULL)
531 {
532 DbgPrint("kernel stack base %x\n",
533 PsGetCurrentThread()->Tcb.StackLimit);
534 }
535
536 if (PsGetCurrentThread() != NULL)
537 {
538 StackLimit = (ULONG)PsGetCurrentThread()->Tcb.StackBase;
539 }
540 else
541 {
542 StackLimit = (ULONG)&init_stack_top;
543 }
544
545 DbgPrint("Frames:\n");
546 for (i=0; i<NrFrames && ((ULONG)&Stack[i] < StackLimit); i++)
547 {
548 if (Stack[i] > KERNEL_BASE)
549 {
550 print_address((PVOID)Stack[i]);
551 DbgPrint(" ");
552 }
553 if (Stack[i] == 0xceafbeef)
554 {
555 DbgPrint("IRQ ");
556 }
557 }
558 DbgPrint("\n");
559 }
560
561 static void set_system_call_gate(unsigned int sel, unsigned int func)
562 {
563 DPRINT("sel %x %d\n",sel,sel);
564 KiIdt[sel].a = (((int)func)&0xffff) +
565 (KERNEL_CS << 16);
566 KiIdt[sel].b = 0xef00 + (((int)func)&0xffff0000);
567 DPRINT("idt[sel].b %x\n",KiIdt[sel].b);
568 }
569
570 static void set_interrupt_gate(unsigned int sel, unsigned int func)
571 {
572 DPRINT("set_interrupt_gate(sel %d, func %x)\n",sel,func);
573 KiIdt[sel].a = (((int)func)&0xffff) +
574 (KERNEL_CS << 16);
575 KiIdt[sel].b = 0x8f00 + (((int)func)&0xffff0000);
576 }
577
578 static void
579 set_task_gate(unsigned int sel, unsigned task_sel)
580 {
581 KiIdt[sel].a = task_sel << 16;
582 KiIdt[sel].b = 0x8500;
583 }
584
585 void KeInitExceptions(void)
586 /*
587 * FUNCTION: Initalize CPU exception handling
588 */
589 {
590 int i;
591 ULONG base, length;
592 extern USHORT KiGdt[];
593 extern unsigned int trap_stack_top;
594 extern KTSS KiTss;
595 extern KTSS KiTrapTss;
596 ULONG cr3;
597
598 DPRINT("KeInitExceptions()\n",0);
599
600 __asm__("movl %%cr3,%0\n\t" : "=d" (cr3));
601
602 /*
603 * Set up an a descriptor for the LDT
604 */
605 memset(KiNullLdt, 0, sizeof(KiNullLdt));
606 base = (unsigned int)&KiNullLdt;
607 length = sizeof(KiNullLdt) - 1;
608
609 KiGdt[(LDT_SELECTOR / 2) + 0] = (length & 0xFFFF);
610 KiGdt[(LDT_SELECTOR / 2) + 1] = (base & 0xFFFF);
611 KiGdt[(LDT_SELECTOR / 2) + 2] = ((base & 0xFF0000) >> 16) | 0x8200;
612 KiGdt[(LDT_SELECTOR / 2) + 3] = ((length & 0xF0000) >> 16) |
613 ((base & 0xFF000000) >> 16);
614
615 /*
616 * Set up a descriptor for the TSS
617 */
618 memset(&KiTss, 0, sizeof(KiTss));
619 base = (unsigned int)&KiTss;
620 length = sizeof(KiTss) - 1;
621
622 KiGdt[(TSS_SELECTOR / 2) + 0] = (length & 0xFFFF);
623 KiGdt[(TSS_SELECTOR / 2) + 1] = (base & 0xFFFF);
624 KiGdt[(TSS_SELECTOR / 2) + 2] = ((base & 0xFF0000) >> 16) | 0x8900;
625 KiGdt[(TSS_SELECTOR / 2) + 3] = ((length & 0xF0000) >> 16) |
626 ((base & 0xFF000000) >> 16);
627
628 /*
629 * Initialize the TSS
630 */
631 KiTss.Esp0 = (ULONG)&init_stack_top;
632 KiTss.Ss0 = KERNEL_DS;
633 // KiTss.IoMapBase = FIELD_OFFSET(KTSS, IoBitmap);
634 KiTss.IoMapBase = 0xFFFF; /* No i/o bitmap */
635 KiTss.IoBitmap[0] = 0xFF;
636 KiTss.Ldt = LDT_SELECTOR;
637
638 /*
639 * Load the task register
640 */
641 __asm__("ltr %%ax"
642 : /* no output */
643 : "a" (TSS_SELECTOR));
644
645 /*
646 * Set up the TSS for handling double faults
647 */
648 memset(&KiTrapTss, 0, sizeof(KiTrapTss));
649 base = (unsigned int)&KiTrapTss;
650 length = sizeof(KiTrapTss) - 1;
651
652 KiGdt[(TRAP_TSS_SELECTOR / 2) + 0] = (length & 0xFFFF);
653 KiGdt[(TRAP_TSS_SELECTOR / 2) + 1] = (base & 0xFFFF);
654 KiGdt[(TRAP_TSS_SELECTOR / 2) + 2] = ((base & 0xFF0000) >> 16) | 0x8900;
655 KiGdt[(TRAP_TSS_SELECTOR / 2) + 3] = ((length & 0xF0000) >> 16) |
656 ((base & 0xFF000000) >> 16);
657
658 KiTrapTss.Eflags = 0;
659 KiTrapTss.Esp0 = (ULONG)&trap_stack_top;
660 KiTrapTss.Ss0 = KERNEL_DS;
661 KiTrapTss.Esp = (ULONG)&trap_stack_top;
662 KiTrapTss.Cs = KERNEL_CS;
663 KiTrapTss.Eip = (ULONG)KiTrap8;
664 KiTrapTss.Ss = KERNEL_DS;
665 KiTrapTss.Ds = KERNEL_DS;
666 KiTrapTss.Es = KERNEL_DS;
667 KiTrapTss.Fs = PCR_SELECTOR;
668 KiTrapTss.IoMapBase = 0xFFFF; /* No i/o bitmap */
669 KiTrapTss.IoBitmap[0] = 0xFF;
670 KiTrapTss.Ldt = LDT_SELECTOR;
671 KiTrapTss.Cr3 = cr3;
672
673 /*
674 * Set up the other gates
675 */
676 set_interrupt_gate(0, (ULONG)KiTrap0);
677 set_interrupt_gate(1, (ULONG)KiTrap1);
678 set_interrupt_gate(2, (ULONG)KiTrap2);
679 set_interrupt_gate(3, (ULONG)KiTrap3);
680 set_interrupt_gate(4, (ULONG)KiTrap4);
681 set_interrupt_gate(5, (ULONG)KiTrap5);
682 set_interrupt_gate(6, (ULONG)KiTrap6);
683 set_interrupt_gate(7, (ULONG)KiTrap7);
684 set_task_gate(8, TRAP_TSS_SELECTOR);
685 set_interrupt_gate(9, (ULONG)KiTrap9);
686 set_interrupt_gate(10, (ULONG)KiTrap10);
687 set_interrupt_gate(11, (ULONG)KiTrap11);
688 set_interrupt_gate(12, (ULONG)KiTrap12);
689 set_interrupt_gate(13, (ULONG)KiTrap13);
690 set_interrupt_gate(14, (ULONG)KiTrap14);
691 set_interrupt_gate(15, (ULONG)KiTrap15);
692 set_interrupt_gate(16, (ULONG)KiTrap16);
693
694 for (i=17;i<256;i++)
695 {
696 set_interrupt_gate(i,(int)KiTrapUnknown);
697 }
698
699 set_system_call_gate(0x2d,(int)interrupt_handler2d);
700 set_system_call_gate(0x2e,(int)interrupt_handler2e);
701 }