interrupt.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2005 Jakub Jermar
00003  * Copyright (C) 2005 Jakub Vana
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  *
00010  * - Redistributions of source code must retain the above copyright
00011  *   notice, this list of conditions and the following disclaimer.
00012  * - Redistributions in binary form must reproduce the above copyright
00013  *   notice, this list of conditions and the following disclaimer in the
00014  *   documentation and/or other materials provided with the distribution.
00015  * - The name of the author may not be used to endorse or promote products
00016  *   derived from this software without specific prior written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00019  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00020  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00021  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00023  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00024  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00025  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00026  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00027  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00036 #include <arch/interrupt.h>
00037 #include <panic.h>
00038 #include <print.h>
00039 #include <console/console.h>
00040 #include <arch/types.h>
00041 #include <arch/asm.h>
00042 #include <arch/barrier.h>
00043 #include <arch/register.h>
00044 #include <arch/drivers/it.h>
00045 #include <arch.h>
00046 #include <symtab.h>
00047 #include <debug.h>
00048 #include <syscall/syscall.h>
00049 #include <print.h>
00050 #include <proc/scheduler.h>
00051 #include <ipc/sysipc.h>
00052 #include <ipc/irq.h>
00053 #include <ipc/ipc.h>
00054 #include <interrupt.h>
00055 
00056 
00057 #define VECTORS_64_BUNDLE       20
00058 #define VECTORS_16_BUNDLE       48
00059 #define VECTORS_16_BUNDLE_START 0x5000
00060 #define VECTOR_MAX              0x7f00
00061 
00062 #define BUNDLE_SIZE             16
00063 
00064 
00065 char *vector_names_64_bundle[VECTORS_64_BUNDLE] = {
00066         "VHPT Translation vector",
00067         "Instruction TLB vector",
00068         "Data TLB vector",
00069         "Alternate Instruction TLB vector",
00070         "Alternate Data TLB vector",
00071         "Data Nested TLB vector",
00072         "Instruction Key Miss vector",
00073         "Data Key Miss vector",
00074         "Dirty-Bit vector",
00075         "Instruction Access-Bit vector",
00076         "Data Access-Bit vector"
00077         "Break Instruction vector",
00078         "External Interrupt vector"
00079         "Reserved",
00080         "Reserved",
00081         "Reserved",
00082         "Reserved",
00083         "Reserved",
00084         "Reserved",
00085         "Reserved"
00086 };
00087 
00088 char *vector_names_16_bundle[VECTORS_16_BUNDLE] = {
00089         "Page Not Present vector",
00090         "Key Permission vector",
00091         "Instruction Access rights vector",
00092         "Data Access Rights vector",
00093         "General Exception vector",
00094         "Disabled FP-Register vector",
00095         "NaT Consumption vector",
00096         "Speculation vector",
00097         "Reserved",
00098         "Debug vector",
00099         "Unaligned Reference vector",
00100         "Unsupported Data Reference vector",
00101         "Floating-point Fault vector",
00102         "Floating-point Trap vector",
00103         "Lower-Privilege Transfer Trap vector",
00104         "Taken Branch Trap vector",
00105         "Single STep Trap vector",
00106         "Reserved",
00107         "Reserved",
00108         "Reserved",
00109         "Reserved",
00110         "Reserved",
00111         "Reserved",
00112         "Reserved",
00113         "Reserved",
00114         "IA-32 Exception vector",
00115         "IA-32 Intercept vector",
00116         "IA-32 Interrupt vector",
00117         "Reserved",
00118         "Reserved",
00119         "Reserved"
00120 };
00121 
00122 static char *vector_to_string(__u16 vector);
00123 static void dump_interrupted_context(istate_t *istate);
00124 
00125 char *vector_to_string(__u16 vector)
00126 {
00127         ASSERT(vector <= VECTOR_MAX);
00128         
00129         if (vector >= VECTORS_16_BUNDLE_START)
00130                 return vector_names_16_bundle[(vector-VECTORS_16_BUNDLE_START)/(16*BUNDLE_SIZE)];
00131         else
00132                 return vector_names_64_bundle[vector/(64*BUNDLE_SIZE)];
00133 }
00134 
00135 void dump_interrupted_context(istate_t *istate)
00136 {
00137         char *ifa, *iipa, *iip;
00138 
00139         ifa = get_symtab_entry(istate->cr_ifa);
00140         iipa = get_symtab_entry(istate->cr_iipa);
00141         iip = get_symtab_entry(istate->cr_iip);
00142 
00143         putchar('\n');
00144         printf("Interrupted context dump:\n");
00145         printf("ar.bsp=%p\tar.bspstore=%p\n", istate->ar_bsp, istate->ar_bspstore);
00146         printf("ar.rnat=%#018llx\tar.rsc=%#018llx\n", istate->ar_rnat, istate->ar_rsc);
00147         printf("ar.ifs=%#018llx\tar.pfs=%#018llx\n", istate->ar_ifs, istate->ar_pfs);
00148         printf("cr.isr=%#018llx\tcr.ipsr=%#018llx\t\n", istate->cr_isr.value, istate->cr_ipsr);
00149         
00150         printf("cr.iip=%#018llx, #%d\t(%s)\n", istate->cr_iip, istate->cr_isr.ei, iip);
00151         printf("cr.iipa=%#018llx\t(%s)\n", istate->cr_iipa, iipa);
00152         printf("cr.ifa=%#018llx\t(%s)\n", istate->cr_ifa, ifa);
00153 }
00154 
00155 void general_exception(__u64 vector, istate_t *istate)
00156 {
00157         char *desc = "";
00158 
00159         switch (istate->cr_isr.ge_code) {
00160             case GE_ILLEGALOP:
00161                 desc = "Illegal Operation fault";
00162                 break;
00163             case GE_PRIVOP:
00164                 desc = "Privileged Operation fault";
00165                 break;
00166             case GE_PRIVREG:
00167                 desc = "Privileged Register fault";
00168                 break;
00169             case GE_RESREGFLD:
00170                 desc = "Reserved Register/Field fault";
00171                 break;
00172             case GE_DISBLDISTRAN:
00173                 desc = "Disabled Instruction Set Transition fault";
00174                 break;
00175             case GE_ILLEGALDEP:
00176                 desc = "Illegal Dependency fault";
00177                 break;
00178             default:
00179                 desc = "unknown";
00180                 break;
00181         }
00182 
00183         fault_if_from_uspace(istate, "General Exception (%s)", desc);
00184 
00185         dump_interrupted_context(istate);
00186         panic("General Exception (%s)\n", desc);
00187 }
00188 
00189 void fpu_enable(void);
00190 
00191 void disabled_fp_register(__u64 vector, istate_t *istate)
00192 {
00193 #ifdef CONFIG_FPU_LAZY 
00194         scheduler_fpu_lazy_request();   
00195 #else
00196         fault_if_from_uspace(istate, "Interruption: %#hx (%s)", (__u16) vector, vector_to_string(vector));
00197         dump_interrupted_context(istate);
00198         panic("Interruption: %#hx (%s)\n", (__u16) vector, vector_to_string(vector));
00199 #endif
00200 }
00201 
00202 
00203 void nop_handler(__u64 vector, istate_t *istate)
00204 {
00205 }
00206 
00207 
00208 
00210 int break_instruction(__u64 vector, istate_t *istate)
00211 {
00212         /*
00213          * Move to next instruction after BREAK.
00214          */
00215         if (istate->cr_ipsr.ri == 2) {
00216                 istate->cr_ipsr.ri = 0;
00217                 istate->cr_iip += 16;
00218         } else {
00219                 istate->cr_ipsr.ri++;
00220         }
00221 
00222         if (istate->in4 < SYSCALL_END)
00223                 return syscall_table[istate->in4](istate->in0, istate->in1, istate->in2, istate->in3);
00224         else
00225                 panic("Undefined syscall %d", istate->in4);
00226                 
00227         return -1;
00228 }
00229 
00230 void universal_handler(__u64 vector, istate_t *istate)
00231 {
00232         fault_if_from_uspace(istate,"Interruption: %#hx (%s)\n",(__u16) vector, vector_to_string(vector));
00233         dump_interrupted_context(istate);
00234         panic("Interruption: %#hx (%s)\n", (__u16) vector, vector_to_string(vector));
00235 }
00236 
00237 void external_interrupt(__u64 vector, istate_t *istate)
00238 {
00239         cr_ivr_t ivr;
00240         
00241         ivr.value = ivr_read();
00242         srlz_d();
00243 
00244         switch(ivr.vector) {
00245             case INTERRUPT_TIMER:
00246                 it_interrupt();
00247                 break;
00248             case INTERRUPT_SPURIOUS:
00249                 printf("cpu%d: spurious interrupt\n", CPU->id);
00250                 break;
00251             default:
00252                 panic("\nUnhandled External Interrupt Vector %d\n", ivr.vector);
00253                 break;
00254         }
00255 }
00256 
00257 void virtual_interrupt(__u64 irq,void *param)
00258 {
00259         switch(irq) {
00260                 case IRQ_KBD:
00261                         if(kbd_uspace) ipc_irq_send_notif(irq);
00262                         break;
00263                 default:
00264                         panic("\nUnhandled Virtual Interrupt request %d\n", irq);
00265                 break;
00266         }
00267 }
00268 
00269 /* Reregister irq to be IPC-ready */
00270 void irq_ipc_bind_arch(__native irq)
00271 {
00272         if(irq==IRQ_KBD) {
00273                 kbd_uspace=1;
00274                 return;
00275         }
00276         return;
00277         panic("not implemented\n");
00278         /* TODO */
00279 }
00280 

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