X-Git-Url: http://git.joshuawise.com/netwatch.git/blobdiff_plain/33e49b2e6d599bc56326841b5b373b9f76adc5f7..8e7d9af004f36ed0d2dc94d1e8254e2ff5a32503:/netwatch/traps.c diff --git a/netwatch/traps.c b/netwatch/traps.c index 1fc0977..25a404c 100644 --- a/netwatch/traps.c +++ b/netwatch/traps.c @@ -1,3 +1,13 @@ +/* traps.c + * Trap handling routines + * NetWatch system management mode administration console + * + * Copyright (c) 2008 Jacob Potter and Joshua Wise. All rights reserved. + * This program is free software; you can redistribute and/or modify it under + * the terms found in the file LICENSE in the root of this source tree. + * + */ + #include #include #include @@ -6,13 +16,29 @@ #define CS_SEGSEL 0x10 -#define FAULT_WRAPPER(func_name) asm ( \ +asm ( + "fault_wrapper_common:\n" + "push %eax\n" + "mov %cr2, %eax\n" + "push %eax\n" + "push %esp\n" + "call die\n" +); + +#define FAULT_WRAPPER(func_name, code) asm ( \ ".global " #func_name "_wrapper\n" \ #func_name "_wrapper:\n" \ - "mov %cr2, %eax\n" \ + "mov $" #code ", %eax\n" \ + "jmp fault_wrapper_common\n" \ +); void func_name##_wrapper(void); + +#define FAULT_WRAPPER1(func_name, code) asm ( \ + ".global " #func_name "_wrapper\n" \ + #func_name "_wrapper:\n" \ + "mov $0, %eax\n" \ "push %eax\n" \ - "push %esp\n" \ - "call " #func_name "\n" \ + "mov $" #code ", %eax\n" \ + "jmp fault_wrapper_common\n" \ ); void func_name##_wrapper(void); #define WRAPPER_INSTALL(idt, idt4_value, func_name, int_number) { \ @@ -26,58 +52,83 @@ /* The 16 bits at offset 4 from the start of an interrupt gate are a * bitfield, according to the Intel spec: * 15 P - Segment Present - set to 1 - * 14-13 DPL - Descriptor privilege level - set to 11 for trap/int, 00 for IPI + * 14-13 DPL - Descriptor privilege level - set to 00, since we're always in ring 0 * 12-8 01111 for 32-bit trap gates, 01110 for 32-bit interrupt gates * 7-0 Set to 0 - * Trap: binary 11101111 0000000, hex EF00. - * Interrupt: binary 11101110 0000000, hex EE00. */ -#define TRAP 0xEF00 -#define INTERRUPT 0xEE00 +#define TRAP 0x8F00 typedef struct trap_t { int cr2; + int fault_code; int error_code; int eip; int cs; int eflags; - int esp; - int ss; } trap_t; +static const char const * trapcodes[20] = { + "Divide by Zero", + "Debug Trap", + "NMI", + "Breakpoint Trap", + "Overflow Trap", + "Bound Range Fault", + "Invalid Opcode", + "Device Not Available", + "Double Fault", + "Coprocessor Overrun", + "Invalid TSS", + "Segmnet Not Present", + "Stack Fault", + "GPF", + "Page Fault", + "Reserved Trap", + "x87 FPE Pending", + "Alignment Check", + "Machine Check", + "SIMD FPE Fault" +}; + void die(struct trap_t * trap) { - outputf("Error %08x %%eip %08x", trap->error_code, trap->eip); - outputf("%%esp %08x %%eflags %08x", trap->esp, trap->eflags); - while(1) asm("hlt"); -} -void fault_gp(struct trap_t * trap) { - outputf("GENERAL PROTECTION FAULT"); - die(trap); -} + DBG(0x40 + trap->fault_code); -void fault_page(struct trap_t * trap) { - outputf("PAGE FAULT: %08x", trap->cr2); - die(trap); -} -void fault_divide(struct trap_t * trap) { - outputf("DIVISION FAULT"); - die(trap); -} -void double_fault(struct trap_t * trap) { - outputf("DOUBLE FAULT"); - die(trap); + if (trap->fault_code < 20) { + outputf("---\n%s", trapcodes[trap->fault_code]); + } else { + outputf("---\nUNKNOWN FAULT"); + } + + outputf("Error %08x %%eip %08x", trap->error_code, trap->eip); + outputf("%%cr2 %08x %%eflags %08x", trap->cr2, trap->eflags); + while(1) asm("hlt"); } -FAULT_WRAPPER(fault_gp); -FAULT_WRAPPER(fault_page); -FAULT_WRAPPER(fault_divide); -FAULT_WRAPPER(double_fault); +FAULT_WRAPPER1(fault_divide, 0); +FAULT_WRAPPER1(fault_db, 1); +FAULT_WRAPPER1(fault_nmi, 2); +FAULT_WRAPPER1(fault_3, 3); +FAULT_WRAPPER1(fault_overflow, 4); +FAULT_WRAPPER1(fault_oob, 5); +FAULT_WRAPPER1(fault_opcode, 6); +FAULT_WRAPPER1(fault_enofpu, 7); +FAULT_WRAPPER(double_fault, 8); +FAULT_WRAPPER1(fault_fpu, 9); +FAULT_WRAPPER(fault_invalid_tss, 10); +FAULT_WRAPPER(fault_noseg, 11); +FAULT_WRAPPER(fault_stack, 12); +FAULT_WRAPPER(fault_gp, 13); +FAULT_WRAPPER(fault_page, 14); +FAULT_WRAPPER1(fault_fpe, 16); +FAULT_WRAPPER(fault_ac, 17); +FAULT_WRAPPER1(fault_machine, 18); +FAULT_WRAPPER1(fault_other, 19); /* pseudo_descriptor and x86_gate structs from 15-410 basis code. */ struct x86_gate { -unsigned int filler[2]; //64 bits; or 8 bytes. + unsigned int filler[2]; //64 bits, or 8 bytes. }; static struct x86_gate idt[64]; @@ -89,17 +140,38 @@ struct pseudo_descriptor { } __attribute__((packed)); void traps_install(void) { + DBG(0xCA); + int i; struct pseudo_descriptor pdesc; pdesc.limit = sizeof(idt) - 1; - pdesc.linear_base = v2p(&idt); + pdesc.linear_base = (int)&idt; //v2p(&idt); + + DBG(0xCB); + + for (i = 0; i < 32; i++) + WRAPPER_INSTALL(idt, TRAP, fault_other, i); WRAPPER_INSTALL(idt, TRAP, fault_divide, T_DIVIDE_ERROR); + WRAPPER_INSTALL(idt, TRAP, fault_db, T_DEBUG); + WRAPPER_INSTALL(idt, TRAP, fault_nmi, T_NMI); + WRAPPER_INSTALL(idt, TRAP, fault_3, T_INT3); + WRAPPER_INSTALL(idt, TRAP, fault_overflow, T_OVERFLOW); + WRAPPER_INSTALL(idt, TRAP, fault_oob, T_OUT_OF_BOUNDS); + WRAPPER_INSTALL(idt, TRAP, fault_opcode, T_INVALID_OPCODE); + WRAPPER_INSTALL(idt, TRAP, fault_enofpu, T_NO_FPU); + WRAPPER_INSTALL(idt, TRAP, double_fault, T_DOUBLE_FAULT); + WRAPPER_INSTALL(idt, TRAP, fault_fpu, T_FPU_FAULT); + WRAPPER_INSTALL(idt, TRAP, fault_invalid_tss, T_INVALID_TSS); + WRAPPER_INSTALL(idt, TRAP, fault_noseg, T_SEGMENT_NOT_PRESENT); + WRAPPER_INSTALL(idt, TRAP, fault_stack, T_STACK_FAULT); WRAPPER_INSTALL(idt, TRAP, fault_gp, T_GENERAL_PROTECTION); WRAPPER_INSTALL(idt, TRAP, fault_page, T_PAGE_FAULT); - WRAPPER_INSTALL(idt, TRAP, double_fault, T_DOUBLE_FAULT); + WRAPPER_INSTALL(idt, TRAP, fault_fpe, T_FLOATING_POINT_ERROR); + WRAPPER_INSTALL(idt, TRAP, fault_ac, T_ALIGNMENT_CHECK); + WRAPPER_INSTALL(idt, TRAP, fault_machine, T_MACHINE_CHECK); - outb(0x80, 0xCC); + DBG(0xCC); asm volatile("lidt %0" : : "m" (pdesc.limit)); - outb(0x80, 0xCD); + DBG(0xCE); }