00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00035 #include <arch/interrupt.h>
00036 #include <syscall/syscall.h>
00037 #include <print.h>
00038 #include <debug.h>
00039 #include <panic.h>
00040 #include <arch/drivers/i8259.h>
00041 #include <func.h>
00042 #include <cpu.h>
00043 #include <arch/asm.h>
00044 #include <mm/tlb.h>
00045 #include <mm/as.h>
00046 #include <arch.h>
00047 #include <symtab.h>
00048 #include <proc/thread.h>
00049 #include <proc/task.h>
00050 #include <synch/spinlock.h>
00051 #include <arch/ddi/ddi.h>
00052 #include <ipc/sysipc.h>
00053 #include <interrupt.h>
00054
00055
00056
00057
00058
00059 void (* disable_irqs_function)(__u16 irqmask) = NULL;
00060 void (* enable_irqs_function)(__u16 irqmask) = NULL;
00061 void (* eoi_function)(void) = NULL;
00062
00063 void PRINT_INFO_ERRCODE(istate_t *istate)
00064 {
00065 char *symbol = get_symtab_entry(istate->eip);
00066
00067 if (!symbol)
00068 symbol = "";
00069
00070 if (CPU)
00071 printf("----------------EXCEPTION OCCURED (cpu%d)----------------\n", CPU->id);
00072 else
00073 printf("----------------EXCEPTION OCCURED----------------\n");
00074
00075 printf("%%eip: %#x (%s)\n",istate->eip,symbol);
00076 printf("ERROR_WORD=%#x\n", istate->error_word);
00077 printf("%%cs=%#x,flags=%#x\n", istate->cs, istate->eflags);
00078 printf("%%eax=%#x, %%ecx=%#x, %%edx=%#x, %%esp=%#x\n", istate->eax,istate->ecx,istate->edx,&istate->stack[0]);
00079 #ifdef CONFIG_DEBUG_ALLREGS
00080 printf("%%esi=%#x, %%edi=%#x, %%ebp=%#x, %%ebx=%#x\n", istate->esi,istate->edi,istate->ebp,istate->ebx);
00081 #endif
00082 printf("stack: %#x, %#x, %#x, %#x\n", istate->stack[0], istate->stack[1], istate->stack[2], istate->stack[3]);
00083 printf(" %#x, %#x, %#x, %#x\n", istate->stack[4], istate->stack[5], istate->stack[6], istate->stack[7]);
00084 }
00085
00086 void null_interrupt(int n, istate_t *istate)
00087 {
00088 fault_if_from_uspace(istate, "unserviced interrupt: %d", n);
00089
00090 PRINT_INFO_ERRCODE(istate);
00091 panic("unserviced interrupt: %d\n", n);
00092 }
00093
00095 void gp_fault(int n, istate_t *istate)
00096 {
00097 if (TASK) {
00098 count_t ver;
00099
00100 spinlock_lock(&TASK->lock);
00101 ver = TASK->arch.iomapver;
00102 spinlock_unlock(&TASK->lock);
00103
00104 if (CPU->arch.iomapver_copy != ver) {
00105
00106
00107
00108
00109
00110
00111
00112 io_perm_bitmap_install();
00113 return;
00114 }
00115 fault_if_from_uspace(istate, "general protection fault");
00116 }
00117
00118 PRINT_INFO_ERRCODE(istate);
00119 panic("general protection fault\n");
00120 }
00121
00122 void ss_fault(int n, istate_t *istate)
00123 {
00124 fault_if_from_uspace(istate, "stack fault");
00125
00126 PRINT_INFO_ERRCODE(istate);
00127 panic("stack fault\n");
00128 }
00129
00130 void simd_fp_exception(int n, istate_t *istate)
00131 {
00132 __u32 mxcsr;
00133 asm
00134 (
00135 "stmxcsr %0;\n"
00136 :"=m"(mxcsr)
00137 );
00138 fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR: %#zx",
00139 (__native)mxcsr);
00140
00141 PRINT_INFO_ERRCODE(istate);
00142 printf("MXCSR: %#zx\n",(__native)(mxcsr));
00143 panic("SIMD FP exception(19)\n");
00144 }
00145
00146 void nm_fault(int n, istate_t *istate)
00147 {
00148 #ifdef CONFIG_FPU_LAZY
00149 scheduler_fpu_lazy_request();
00150 #else
00151 fault_if_from_uspace(istate, "fpu fault");
00152 panic("fpu fault");
00153 #endif
00154 }
00155
00156 void syscall(int n, istate_t *istate)
00157 {
00158 panic("Obsolete syscall handler.");
00159 }
00160
00161 void tlb_shootdown_ipi(int n, istate_t *istate)
00162 {
00163 trap_virtual_eoi();
00164 tlb_shootdown_ipi_recv();
00165 }
00166
00167 void trap_virtual_enable_irqs(__u16 irqmask)
00168 {
00169 if (enable_irqs_function)
00170 enable_irqs_function(irqmask);
00171 else
00172 panic("no enable_irqs_function\n");
00173 }
00174
00175 void trap_virtual_disable_irqs(__u16 irqmask)
00176 {
00177 if (disable_irqs_function)
00178 disable_irqs_function(irqmask);
00179 else
00180 panic("no disable_irqs_function\n");
00181 }
00182
00183 void trap_virtual_eoi(void)
00184 {
00185 if (eoi_function)
00186 eoi_function();
00187 else
00188 panic("no eoi_function\n");
00189
00190 }
00191
00192 static void ipc_int(int n, istate_t *istate)
00193 {
00194 ipc_irq_send_notif(n-IVT_IRQBASE);
00195 trap_virtual_eoi();
00196 }
00197
00198
00199
00200 void irq_ipc_bind_arch(__native irq)
00201 {
00202 if (irq == IRQ_CLK)
00203 return;
00204 exc_register(IVT_IRQBASE+irq, "ipc_int", ipc_int);
00205 trap_virtual_enable_irqs(1 << irq);
00206 }
00207