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 <print.h>
00037 #include <debug.h>
00038 #include <panic.h>
00039 #include <arch/drivers/i8259.h>
00040 #include <func.h>
00041 #include <cpu.h>
00042 #include <arch/asm.h>
00043 #include <mm/tlb.h>
00044 #include <mm/as.h>
00045 #include <arch.h>
00046 #include <symtab.h>
00047 #include <arch/asm.h>
00048 #include <proc/scheduler.h>
00049 #include <proc/thread.h>
00050 #include <proc/task.h>
00051 #include <synch/spinlock.h>
00052 #include <arch/ddi/ddi.h>
00053 #include <interrupt.h>
00054 #include <ipc/irq.h>
00055 
00056 void print_info_errcode(int n, istate_t *istate)
00057 {
00058         char *symbol;
00059 /*      __u64 *x = &istate->stack[0]; */
00060 
00061         if (!(symbol=get_symtab_entry(istate->rip)))
00062                 symbol = "";
00063 
00064         printf("-----EXCEPTION(%d) OCCURED----- ( %s )\n",n, __FUNCTION__);
00065         printf("%%rip: %#llx (%s)\n",istate->rip, symbol);
00066         printf("ERROR_WORD=%#llx\n", istate->error_word);
00067         printf("%%rcs=%#llx, flags=%#llx, %%cr0=%#llx\n", istate->cs, istate->rflags, read_cr0());
00068         printf("%%rax=%#llx, %%rcx=%#llx, %%rdx=%#llx\n", istate->rax, istate->rcx, istate->rdx);
00069         printf("%%rsi=%#llx, %%rdi=%#llx, %%r8 =%#llx\n", istate->rsi, istate->rdi, istate->r8);
00070         printf("%%r9 =%#llx, %%r10 =%#llx, %%r11=%#llx\n", istate->r9, istate->r10, istate->r11);
00071 #ifdef CONFIG_DEBUG_ALLREGS     
00072         printf("%%r12=%#llx, %%r13=%#llx, %%r14=%#llx\n", istate->r12, istate->r13, istate->r14);
00073         printf("%%r15=%#llx, %%rbx=%#llx, %%rbp=%#llx\n", istate->r15, istate->rbx, &istate->rbp);
00074 #endif
00075         printf("%%rsp=%#llx\n", &istate->stack[0]);
00076 }
00077 
00078 /*
00079  * Interrupt and exception dispatching.
00080  */
00081 
00082 void (* disable_irqs_function)(__u16 irqmask) = NULL;
00083 void (* enable_irqs_function)(__u16 irqmask) = NULL;
00084 void (* eoi_function)(void) = NULL;
00085 
00086 void null_interrupt(int n, istate_t *istate)
00087 {
00088         fault_if_from_uspace(istate, "unserviced interrupt: %d", n);
00089         print_info_errcode(n, istate);
00090         panic("unserviced interrupt\n");
00091 }
00092 
00094 void gp_fault(int n, istate_t *istate)
00095 {
00096         if (TASK) {
00097                 count_t ver;
00098 
00099                 spinlock_lock(&TASK->lock);
00100                 ver = TASK->arch.iomapver;
00101                 spinlock_unlock(&TASK->lock);
00102 
00103                 if (CPU->arch.iomapver_copy != ver) {
00104                         /*
00105                          * This fault can be caused by an early access
00106                          * to I/O port because of an out-dated
00107                          * I/O Permission bitmap installed on CPU.
00108                          * Install the fresh copy and restart
00109                          * the instruction.
00110                          */
00111                         io_perm_bitmap_install();
00112                         return;
00113                 }
00114                 fault_if_from_uspace(istate, "general protection fault");
00115         }
00116 
00117         print_info_errcode(n, istate);
00118         panic("general protection fault\n");
00119 }
00120 
00121 void ss_fault(int n, istate_t *istate)
00122 {
00123         fault_if_from_uspace(istate, "stack fault");
00124         print_info_errcode(n, istate);
00125         panic("stack fault\n");
00126 }
00127 
00128 void nm_fault(int n, istate_t *istate)
00129 {
00130 #ifdef CONFIG_FPU_LAZY     
00131         scheduler_fpu_lazy_request();
00132 #else
00133         fault_if_from_uspace(istate, "fpu fault");
00134         panic("fpu fault");
00135 #endif
00136 }
00137 
00138 void tlb_shootdown_ipi(int n, istate_t *istate)
00139 {
00140         trap_virtual_eoi();
00141         tlb_shootdown_ipi_recv();
00142 }
00143 
00144 void trap_virtual_enable_irqs(__u16 irqmask)
00145 {
00146         if (enable_irqs_function)
00147                 enable_irqs_function(irqmask);
00148         else
00149                 panic("no enable_irqs_function\n");
00150 }
00151 
00152 void trap_virtual_disable_irqs(__u16 irqmask)
00153 {
00154         if (disable_irqs_function)
00155                 disable_irqs_function(irqmask);
00156         else
00157                 panic("no disable_irqs_function\n");
00158 }
00159 
00160 void trap_virtual_eoi(void)
00161 {
00162         if (eoi_function)
00163                 eoi_function();
00164         else
00165                 panic("no eoi_function\n");
00166 
00167 }
00168 
00169 static void ipc_int(int n, istate_t *istate)
00170 {
00171         ipc_irq_send_notif(n-IVT_IRQBASE);
00172         trap_virtual_eoi();
00173 }
00174 
00175 
00176 /* Reregister irq to be IPC-ready */
00177 void irq_ipc_bind_arch(__native irq)
00178 {
00179         if (irq == IRQ_CLK)
00180                 return;
00181         exc_register(IVT_IRQBASE+irq, "ipc_int", ipc_int);
00182         trap_virtual_enable_irqs(1 << irq);
00183 }
00184 

Generated on Sun Jun 18 16:26:58 2006 for HelenOS Kernel (amd64) by  doxygen 1.4.6