00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <agnix/agnix.h>
00015 #include <agnix/init.h>
00016 #include <agnix/adi/adi.h>
00017 #include <agnix/linkage.h>
00018 #include <agnix/console.h>
00019 #include <agnix/irq.h>
00020 #include <agnix/faults.h>
00021 #include <asm/regs.h>
00022 #include <asm/segment.h>
00023
00024 #define TRAP_BUILD(nr, routine) \
00025 asmlinkage void TRAP_##nr(void);\
00026 __asm__ ( \
00027 "\n.align 16,0x90\n" \
00028 "TRAP_"#nr":\n\t" \
00029 "pushl $0\n\t" \
00030 REG_SAVE \
00031 "call "#routine"\n\t" \
00032 REG_RESTORE \
00033 "addl $4, %esp\n\t" \
00034 "iret\n\t" \
00035 );
00036
00037 #define TRAP_BUILD_ERROR(nr, routine) \
00038 asmlinkage void TRAP_##nr(void);\
00039 __asm__ ( \
00040 "\n.align 16,0x90\n" \
00041 "TRAP_"#nr":\n\t" \
00042 REG_SAVE \
00043 "call "#routine"\n\t" \
00044 REG_RESTORE \
00045 "addl $4, %esp\n\t" \
00046 "iret\n\t" \
00047 );
00048
00049 #define TRAP_BUILD_NAME(name, text) \
00050 asmlinkage void TRAP_##name(u32 error) \
00051 { \
00052 printk(#text); \
00053 for(;;); \
00054 }
00055
00056 int was_pgfault = 0;
00057
00058 asmlinkage void TRAP_dev_not_avail(u32 error)
00059 {
00060
00061 __asm__ __volatile__ ("clts");
00062 }
00063
00064 asmlinkage void TRAP_general_protection(u32 error)
00065 {
00066 printk("general protection %x\n", error);
00067 for(;;);
00068 }
00069
00070 asmlinkage void TRAP_page_fault(u32 error)
00071 {
00072 u32 cr2;
00073
00074 __asm__ __volatile__ ("movl %%cr2, %%eax"
00075 :"=a"(cr2)
00076 :);
00077
00078 if (!was_pgfault) {
00079 printk("page fault %08x %x\n", cr2, error & 0x03);
00080 for(;;);
00081 printk("cr2 == %x\n", cr2);
00082 was_pgfault = 1;
00083 }
00084
00085 }
00086
00087 TRAP_BUILD_NAME(divide_fault, "divide fault");
00088 TRAP_BUILD_NAME(debug, "debug");
00089 TRAP_BUILD_NAME(nmi, "nmi");
00090 TRAP_BUILD_NAME(int_3, "int 3");
00091 TRAP_BUILD_NAME(overflow, "overflow");
00092 TRAP_BUILD_NAME(bounds, "bounds");
00093 TRAP_BUILD_NAME(invalid_op, "invalid op");
00094 TRAP_BUILD_NAME(double_fault, "double fault");
00095 TRAP_BUILD_NAME(coprocessor_seg_overrun, "coprocessor segment overrun");
00096 TRAP_BUILD_NAME(invalid_TSS, "invalid TSS");
00097 TRAP_BUILD_NAME(seg_not_present, "segment not present");
00098 TRAP_BUILD_NAME(stack_seg, "stack segment");
00099 TRAP_BUILD_NAME(coprocessor_error, "coprocessor error");
00100 TRAP_BUILD_NAME(align_check, "alignment check");
00101 TRAP_BUILD_NAME(reserved, "reserved");
00102
00103 TRAP_BUILD(00, TRAP_divide_fault);
00104 TRAP_BUILD(01, TRAP_debug);
00105 TRAP_BUILD_ERROR(02, TRAP_nmi);
00106 TRAP_BUILD(03, TRAP_int_3);
00107 TRAP_BUILD(04, TRAP_overflow);
00108 TRAP_BUILD(05, TRAP_bounds);
00109 TRAP_BUILD(06, TRAP_invalid_op);
00110 TRAP_BUILD(07, TRAP_dev_not_avail);
00111 TRAP_BUILD_ERROR(08, TRAP_double_fault);
00112 TRAP_BUILD(09, TRAP_coprocessor_seg_overrun);
00113 TRAP_BUILD_ERROR(10, TRAP_invalid_TSS);
00114 TRAP_BUILD_ERROR(11, TRAP_seg_not_present);
00115 TRAP_BUILD_ERROR(12, TRAP_stack_seg);
00116 TRAP_BUILD_ERROR(13, TRAP_general_protection);
00117 TRAP_BUILD_ERROR(14, TRAP_page_fault);
00118 TRAP_BUILD(15, TRAP_reserved);
00119 TRAP_BUILD(16, TRAP_coprocessor_error);
00120 TRAP_BUILD_ERROR(17, TRAP_align_check);
00121
00122 int faults_init(void)
00123 {
00124 u32 flags;
00125 save_flags(flags); __cli();
00126
00127 set_trap_gate(0, __KERNEL_CS, TRAP_00, 0);
00128 set_trap_gate(1, __KERNEL_CS, TRAP_01, 0);
00129 set_interrupt_gate(2, __KERNEL_CS, TRAP_02, 0);
00130 set_interrupt_gate(3, __KERNEL_CS, TRAP_03, 0);
00131 set_interrupt_gate(4, __KERNEL_CS, TRAP_04, 0);
00132 set_interrupt_gate(5, __KERNEL_CS, TRAP_05, 0);
00133 set_trap_gate(6, __KERNEL_CS, TRAP_06, 0);
00134 set_trap_gate(7, __KERNEL_CS, TRAP_07, 0);
00135 set_trap_gate(8, __KERNEL_CS, TRAP_08, 0);
00136 set_trap_gate(9, __KERNEL_CS, TRAP_09, 0);
00137 set_trap_gate(10, __KERNEL_CS, TRAP_10, 0);
00138 set_trap_gate(11, __KERNEL_CS, TRAP_11, 0);
00139 set_trap_gate(12, __KERNEL_CS, TRAP_12, 0);
00140 set_trap_gate(13, __KERNEL_CS, TRAP_13, 0);
00141 set_interrupt_gate(14, __KERNEL_CS, TRAP_14, 0);
00142 set_trap_gate(15, __KERNEL_CS, TRAP_15, 0);
00143 set_trap_gate(16, __KERNEL_CS, TRAP_16, 0);
00144 set_trap_gate(17, __KERNEL_CS, TRAP_17, 0);
00145
00146 restore_flags(flags);
00147
00148 return 0;
00149 }