]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/mips/kernel/traps.c
[MIPS] IP22: Complain if requesting the front panel irq failed.
[linux-2.6-omap-h63xx.git] / arch / mips / kernel / traps.c
index 37c562c4c8176f3dfe8dd88251ef1899b42b2ccf..632bce1bf420c51c2925fad5d44148b59145585e 100644 (file)
@@ -295,7 +295,8 @@ void show_regs(struct pt_regs *regs)
        if (1 <= cause && cause <= 5)
                printk("BadVA : %0*lx\n", field, regs->cp0_badvaddr);
 
-       printk("PrId  : %08x\n", read_c0_prid());
+       printk("PrId  : %08x (%s)\n", read_c0_prid(),
+              cpu_name_string());
 }
 
 void show_registers(struct pt_regs *regs)
@@ -326,6 +327,7 @@ void __noreturn die(const char * str, struct pt_regs * regs)
 #endif /* CONFIG_MIPS_MT_SMTC */
        printk("%s[#%d]:\n", str, ++die_counter);
        show_registers(regs);
+       add_taint(TAINT_DIE);
        spin_unlock_irq(&die_lock);
 
        if (in_interrupt())
@@ -605,6 +607,8 @@ asmlinkage void do_ov(struct pt_regs *regs)
  */
 asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
 {
+       siginfo_t info;
+
        die_if_kernel("FP exception in kernel code", regs);
 
        if (fcr31 & FPU_CSR_UNI_X) {
@@ -624,7 +628,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
                lose_fpu(1);
 
                /* Run the emulator */
-               sig = fpu_emulator_cop1Handler (regs, &current->thread.fpu, 1);
+               sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1);
 
                /*
                 * We can't allow the emulated instruction to leave any of
@@ -640,9 +644,22 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
                        force_sig(sig, current);
 
                return;
-       }
-
-       force_sig(SIGFPE, current);
+       } else if (fcr31 & FPU_CSR_INV_X)
+               info.si_code = FPE_FLTINV;
+       else if (fcr31 & FPU_CSR_DIV_X)
+               info.si_code = FPE_FLTDIV;
+       else if (fcr31 & FPU_CSR_OVF_X)
+               info.si_code = FPE_FLTOVF;
+       else if (fcr31 & FPU_CSR_UDF_X)
+               info.si_code = FPE_FLTUND;
+       else if (fcr31 & FPU_CSR_INE_X)
+               info.si_code = FPE_FLTRES;
+       else
+               info.si_code = __SI_FAULT;
+       info.si_signo = SIGFPE;
+       info.si_errno = 0;
+       info.si_addr = (void __user *) regs->cp0_epc;
+       force_sig_info(SIGFPE, &info, current);
 }
 
 asmlinkage void do_bp(struct pt_regs *regs)
@@ -774,7 +791,7 @@ static void mt_ase_fp_affinity(void)
                        cpus_and(tmask, current->thread.user_cpus_allowed,
                                 mt_fpu_cpumask);
                        set_cpus_allowed(current, tmask);
-                       current->thread.mflags |= MF_FPUBOUND;
+                       set_thread_flag(TIF_FPUBOUND);
                }
        }
 #endif /* CONFIG_MIPS_MT_FPAFF */
@@ -938,7 +955,7 @@ asmlinkage void do_reserved(struct pt_regs *regs)
  */
 static inline void parity_protection_init(void)
 {
-       switch (current_cpu_data.cputype) {
+       switch (current_cpu_type()) {
        case CPU_24K:
        case CPU_34K:
        case CPU_5KC:
@@ -1034,19 +1051,11 @@ void ejtag_exception_handler(struct pt_regs *regs)
 /*
  * NMI exception handler.
  */
-void nmi_exception_handler(struct pt_regs *regs)
+NORET_TYPE void ATTRIB_NORET nmi_exception_handler(struct pt_regs *regs)
 {
-#ifdef CONFIG_MIPS_MT_SMTC
-       unsigned long dvpret = dvpe();
        bust_spinlocks(1);
        printk("NMI taken!!!!\n");
-       mips_mt_regdump(dvpret);
-#else
-       bust_spinlocks(1);
-       printk("NMI taken!!!!\n");
-#endif /* CONFIG_MIPS_MT_SMTC */
        die("NMI", regs);
-       while(1) ;
 }
 
 #define VECTORSPACING 0x100    /* for EI/VI mode */
@@ -1067,8 +1076,8 @@ void *set_except_vector(int n, void *addr)
 
        exception_handlers[n] = handler;
        if (n == 0 && cpu_has_divec) {
-               *(volatile u32 *)(ebase + 0x200) = 0x08000000 |
-                                                (0x03ffffff & (handler >> 2));
+               *(u32 *)(ebase + 0x200) = 0x08000000 |
+                                         (0x03ffffff & (handler >> 2));
                flush_icache_range(ebase + 0x200, ebase + 0x204);
        }
        return (void *)old_handler;
@@ -1157,11 +1166,11 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
 
        if (cpu_has_veic) {
                if (board_bind_eic_interrupt)
-                       board_bind_eic_interrupt (n, srs);
+                       board_bind_eic_interrupt(n, srs);
        } else if (cpu_has_vint) {
                /* SRSMap is only defined if shadow sets are implemented */
                if (mips_srs_max() > 1)
-                       change_c0_srsmap (0xf << n*4, srs << n*4);
+                       change_c0_srsmap(0xf << n*4, srs << n*4);
        }
 
        if (srs == 0) {
@@ -1190,10 +1199,10 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
                         * Sigh... panicing won't help as the console
                         * is probably not configured :(
                         */
-                       panic ("VECTORSPACING too small");
+                       panic("VECTORSPACING too small");
                }
 
-               memcpy (b, &except_vec_vi, handler_len);
+               memcpy(b, &except_vec_vi, handler_len);
 #ifdef CONFIG_MIPS_MT_SMTC
                BUG_ON(n > 7);  /* Vector index %d exceeds SMTC maximum. */
 
@@ -1362,9 +1371,9 @@ void __init per_cpu_trap_init(void)
 #endif /* CONFIG_MIPS_MT_SMTC */
 
        if (cpu_has_veic || cpu_has_vint) {
-               write_c0_ebase (ebase);
+               write_c0_ebase(ebase);
                /* Setting vector spacing enables EI/VI mode  */
-               change_c0_intctl (0x3e0, VECTORSPACING);
+               change_c0_intctl(0x3e0, VECTORSPACING);
        }
        if (cpu_has_divec) {
                if (cpu_has_mipsmt) {
@@ -1382,8 +1391,8 @@ void __init per_cpu_trap_init(void)
         *  o read IntCtl.IPPCI to determine the performance counter interrupt
         */
        if (cpu_has_mips_r2) {
-               cp0_compare_irq = (read_c0_intctl () >> 29) & 7;
-               cp0_perfcount_irq = (read_c0_intctl () >> 26) & 7;
+               cp0_compare_irq = (read_c0_intctl() >> 29) & 7;
+               cp0_perfcount_irq = (read_c0_intctl() >> 26) & 7;
                if (cp0_perfcount_irq == cp0_compare_irq)
                        cp0_perfcount_irq = -1;
        } else {
@@ -1421,14 +1430,17 @@ void __init per_cpu_trap_init(void)
 }
 
 /* Install CPU exception handler */
-void __init set_handler (unsigned long offset, void *addr, unsigned long size)
+void __init set_handler(unsigned long offset, void *addr, unsigned long size)
 {
        memcpy((void *)(ebase + offset), addr, size);
        flush_icache_range(ebase + offset, ebase + offset + size);
 }
 
+static char panic_null_cerr[] __initdata =
+       "Trying to set NULL cache error exception handler";
+
 /* Install uncached CPU exception handler */
-void __init set_uncached_handler (unsigned long offset, void *addr, unsigned long size)
+void __init set_uncached_handler(unsigned long offset, void *addr, unsigned long size)
 {
 #ifdef CONFIG_32BIT
        unsigned long uncached_ebase = KSEG1ADDR(ebase);
@@ -1437,6 +1449,9 @@ void __init set_uncached_handler (unsigned long offset, void *addr, unsigned lon
        unsigned long uncached_ebase = TO_UNCAC(ebase);
 #endif
 
+       if (!addr)
+               panic(panic_null_cerr);
+
        memcpy((void *)(uncached_ebase + offset), addr, size);
 }
 
@@ -1456,7 +1471,7 @@ void __init trap_init(void)
        unsigned long i;
 
        if (cpu_has_veic || cpu_has_vint)
-               ebase = (unsigned long) alloc_bootmem_low_pages (0x200 + VECTORSPACING*64);
+               ebase = (unsigned long) alloc_bootmem_low_pages(0x200 + VECTORSPACING*64);
        else
                ebase = CAC_BASE;
 
@@ -1482,7 +1497,7 @@ void __init trap_init(void)
         * destination.
         */
        if (cpu_has_ejtag && board_ejtag_handler_setup)
-               board_ejtag_handler_setup ();
+               board_ejtag_handler_setup();
 
        /*
         * Only some CPUs have the watch exceptions.
@@ -1535,8 +1550,8 @@ void __init trap_init(void)
        set_except_vector(12, handle_ov);
        set_except_vector(13, handle_tr);
 
-       if (current_cpu_data.cputype == CPU_R6000 ||
-           current_cpu_data.cputype == CPU_R6000A) {
+       if (current_cpu_type() == CPU_R6000 ||
+           current_cpu_type() == CPU_R6000A) {
                /*
                 * The R6000 is the only R-series CPU that features a machine
                 * check exception (similar to the R4000 cache error) and