interrupt.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2001-2004 Jakub Jermar
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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  * Interrupt and exception dispatching.
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                          * This fault can be caused by an early access
00107                          * to I/O port because of an out-dated
00108                          * I/O Permission bitmap installed on CPU.
00109                          * Install the fresh copy and restart
00110                          * the instruction.
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 /* Reregister irq to be IPC-ready */
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 

Generated on Sun Jun 18 16:38:51 2006 for HelenOS Kernel (ia32) by  doxygen 1.4.6