--- zzzz-none-000/linux-3.10.107/arch/mips/kernel/traps.c 2017-06-27 09:49:32.000000000 +0000 +++ vr9-7490-729/linux-3.10.107/arch/mips/kernel/traps.c 2021-11-10 11:53:54.000000000 +0000 @@ -55,7 +55,21 @@ #include #include #include +#if defined(CONFIG_MACH_ATHEROS) +#include +#endif/*--- #if defined(CONFIG_MACH_ATHEROS) ---*/ +#if defined(CONFIG_AVM_ENHANCED) +#include +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ +#if defined(CONFIG_AVM_SIMPLE_PROFILING) +#include +#endif /*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ #include +#include + +#if defined(CONFIG_VR9) || defined(CONFIG_AR10) +#include +#endif/*--- #if defined(CONFIG_VR9) || defined(CONFIG_AR10) ---*/ extern void check_wait(void); extern asmlinkage void rollback_handle_int(void); @@ -76,6 +90,7 @@ extern asmlinkage void handle_ov(void); extern asmlinkage void handle_tr(void); extern asmlinkage void handle_fpe(void); +extern asmlinkage void handle_ftlb(void); extern asmlinkage void handle_mdmx(void); extern asmlinkage void handle_watch(void); extern asmlinkage void handle_mt(void); @@ -83,6 +98,10 @@ extern asmlinkage void handle_mcheck(void); extern asmlinkage void handle_reserved(void); +#if defined(CONFIG_AVM_ENHANCED) +unsigned int avm_nmi_taken; +extern unsigned long kernelsp[NR_CPUS]; +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ void (*board_be_init)(void); int (*board_be_handler)(struct pt_regs *regs, int is_fixup); void (*board_nmi_handler_setup)(void); @@ -104,13 +123,18 @@ unsigned long __user *p = (unsigned long __user *)(unsigned long)sp++; if (__get_user(addr, p)) { - printk(" (Bad stack address)"); + printk(KERN_EMERG" (Bad stack address)"); break; } - if (__kernel_text_address(addr)) + if (__kernel_text_address(addr)) { +#if defined(CONFIG_AVM_ENHANCED) + printk(KERN_EMERG"%04lx: [<%p>] %pS\n", (unsigned long)sp & THREAD_MASK,(void *) addr, (void *) addr); +#else/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ print_ip_sym(addr); +#endif/*--- #else ---*//*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ } - printk("\n"); + } + printk(KERN_EMERG"\n"); } #ifdef CONFIG_KALLSYMS @@ -122,12 +146,18 @@ } __setup("raw_show_trace", set_raw_show_trace); #endif - -static void show_backtrace(struct task_struct *task, const struct pt_regs *regs) +#if !defined(CONFIG_AVM_ENHANCED) +static +#endif/*--- #if !defined(CONFIG_AVM_ENHANCED) ---*/ +void show_backtrace(struct task_struct *task, const struct pt_regs *regs) { unsigned long sp = regs->regs[29]; unsigned long ra = regs->regs[31]; unsigned long pc = regs->cp0_epc; +#if defined(CONFIG_AVM_ENHANCED) + unsigned long first_ra = ra; + unsigned long first_sp = sp; +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ if (!task) task = current; @@ -136,12 +166,33 @@ show_raw_backtrace(sp); return; } - printk("Call Trace:\n"); + printk(KERN_ERR"Call Trace:\n"); do { +#if defined(CONFIG_AVM_ENHANCED) + printk(KERN_ERR"%04lx: [<%p>] %pS\n", sp & THREAD_MASK,(void *) pc, (void *) pc); +#else/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ print_ip_sym(pc); +#endif/*--- #else ---*//*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ pc = unwind_stack(task, &sp, pc, &ra); +#if defined(CONFIG_AVM_ENHANCED) + if(first_ra) { + if(pc == 0) { + /**--------------------------------------------------------------------------------**\ + * es gibt Funktionen (z.B. _raw_spin_lock_bh), wo direkt in eine andere Funktion + * per bxx symbol+offset(!=0) (z.b. _raw_read_unlock_bh+0xa4) gesprungen wird. In diesem Fall + * funktioniert die Ermittlung von ra ueber den Stack nicht, da der Stackoffset der + * angeprungenen Funktion mit Offset 0 ermittelt wird - passiert dies beim ersten Aufruf + * wo ja ra noch korrekt im Register koennen wir hier das ra direkt verwenden + * (siehe JZ-30655) + \**--------------------------------------------------------------------------------**/ + pc = first_ra; + sp = first_sp; + } + first_ra = 0; /*--- nur initial das Register ra verwenden ---*/ + } +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ } while (pc); - printk("\n"); + printk(KERN_EMERG"\n"); } /* @@ -175,6 +226,9 @@ i++; } printk("\n"); +#if defined(CONFIG_AVM_ENHANCED) + show_stacktrace_memoryclassifier(regs); +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ show_backtrace(task, regs); } @@ -207,24 +261,41 @@ long i; unsigned short __user *pc16 = NULL; - printk("\nCode:"); + printk(KERN_EMERG"\nCode:"); if ((unsigned long)pc & 1) pc16 = (unsigned short __user *)((unsigned long)pc & ~1); for(i = -3 ; i < 6 ; i++) { unsigned int insn; if (pc16 ? __get_user(insn, pc16 + i) : __get_user(insn, pc + i)) { - printk(" (Bad address in epc)\n"); + printk(KERN_EMERG" (Bad address in epc)\n"); break; } printk("%c%0*x%c", (i?' ':'<'), pc16 ? 4 : 8, insn, (i?' ':'>')); } } +#if defined(CONFIG_AVM_ENHANCED) +char *get_kernel_or_user_symbol(char *txt, unsigned int maxttxlen, const struct pt_regs *regs, unsigned long addr){ + unsigned long gp; + txt[0] = 0; + if(!user_mode(regs)) { + snprintf(txt, maxttxlen, "%pS", (void *)addr); + return txt; + } + /*--- wir sind im USER-Mode: Spezialbehandlung fuer gp-Ermittlung (da virtuelle Adressen) ---*/ + gp = kernelsp[smp_processor_id()] & ~THREAD_MASK; /*--- kseg0-gp ermitteln ---*/ + return get_user_symbol(txt, maxttxlen, gp, addr); +} +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ static void __show_regs(const struct pt_regs *regs) { +#if defined(CONFIG_AVM_ENHANCED) + char txt[KSYM_NAME_LEN]; +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ const int field = 2 * sizeof(unsigned long); unsigned int cause = regs->cp0_cause; + unsigned int exccode; int i; show_regs_print_info(KERN_DEFAULT); @@ -248,11 +319,18 @@ } #ifdef CONFIG_CPU_HAS_SMARTMIPS - printk("Acx : %0*lx\n", field, regs->acx); + printk(KERN_ERR"Acx : %0*lx\n", field, regs->acx); #endif - printk("Hi : %0*lx\n", field, regs->hi); - printk("Lo : %0*lx\n", field, regs->lo); + printk(KERN_ERR"Hi : %0*lx\n", field, regs->hi); + printk(KERN_ERR"Lo : %0*lx\n", field, regs->lo); +#ifdef CONFIG_CPU_HAS_DSP_ASE + printk(KERN_ERR"ac1Hi: %0*lx ac1Lo: %0*lx\n", field, regs->ac1hi, field, regs->ac1lo); + printk(KERN_ERR"ac2Hi: %0*lx ac2Lo: %0*lx\n", field, regs->ac2hi, field, regs->ac2lo); + printk(KERN_ERR"ac3Hi: %0*lx ac3Lo: %0*lx\n", field, regs->ac3hi, field, regs->ac3lo); + printk(KERN_ERR"dspcontrol: %0*lx\n", field, regs->dspctrl); +#endif /* CONFIG_CPU_HAS_DSP_ASE */ +#if !defined(CONFIG_AVM_ENHANCED) /* * Saved cp0 registers */ @@ -261,8 +339,9 @@ printk(" %s\n", print_tainted()); printk("ra : %0*lx %pS\n", field, regs->regs[31], (void *) regs->regs[31]); +#endif/*--- #if !defined(CONFIG_AVM_ENHANCED) ---*/ - printk("Status: %08x ", (uint32_t) regs->cp0_status); + printk(KERN_ERR"Status: %08x ", (uint32_t) regs->cp0_status); if (current_cpu_data.isa_level == MIPS_CPU_ISA_I) { if (regs->cp0_status & ST0_KUO) @@ -307,14 +386,44 @@ } printk("\n"); + exccode = (cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE; +#if defined(CONFIG_AVM_ENHANCED) + printk(KERN_ERR"Cause : %08x exc_code:%d %s\n", cause, exccode, + exccode == 1 ? "Mod" : + exccode == 2 ? "TLBL" : + exccode == 3 ? "TLBS" : + exccode == 4 ? "AdEL" : + exccode == 5 ? "AdES" : + exccode == 6 ? "IBE" : + exccode == 7 ? "DBE" : + exccode == 25 ? "Thread" : + exccode == 23 ? "WATCH" : + exccode == 31 ? "CacheErr" : "" + ); +#else /*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ printk("Cause : %08x\n", cause); - +#endif/*--- #else ---*//*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ cause = (cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE; - if (1 <= cause && cause <= 5) - printk("BadVA : %0*lx\n", field, regs->cp0_badvaddr); - - printk("PrId : %08x (%s)\n", read_c0_prid(), - cpu_name_string()); + if (1 <= cause && cause <= 5) { +#if defined(CONFIG_AVM_ENHANCED) + txt[0] = 0; + /*--- tricky: slab-poisoning killed highest bit --*/ + if((regs->cp0_badvaddr & 0x80000000) == 0x0) { + lookup_symbol_name(regs->cp0_badvaddr | 0x80000000, txt); + } + printk(KERN_ERR"BadVA : %0*lx %s%s\n", field, regs->cp0_badvaddr, txt[0] ? "? maybe " : "", txt); +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ + } +#if defined(CONFIG_AVM_ENHANCED) +/*--- printk(KERN_ERR"errepc: %08lx %pS\n", read_c0_errorepc(), (void *)read_c0_errorepc()); ---*/ + printk(KERN_ERR"epc : %0*lx %s\n", field, regs->cp0_epc, get_kernel_or_user_symbol(txt, sizeof(txt), regs, regs->cp0_epc)); + printk(KERN_ERR"ra : %0*lx %s\n", field, regs->regs[31], get_kernel_or_user_symbol(txt, sizeof(txt), regs, regs->regs[31])); + printk(KERN_ERR" %s\n", print_tainted()); +#endif/*--- #else ---*//*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ + printk(KERN_ERR"PrId : %08x (%s)\n", read_c0_prid(), cpu_name_string()); +#if defined(CONFIG_AVM_ENHANCED) + show_register_memoryclassifier(regs); +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ } /* @@ -325,9 +434,10 @@ __show_regs((struct pt_regs *)regs); } -void show_registers(struct pt_regs *regs) +void show_registers(const struct pt_regs *regs) { const int field = 2 * sizeof(unsigned long); + mm_segment_t old_fs = get_fs(); __show_regs(regs); print_modules(); @@ -342,9 +452,12 @@ printk("*HwTLS: %0*lx\n", field, tls); } + if (!user_mode(regs)) + set_fs(KERNEL_DS); show_stacktrace(current, regs); show_code((unsigned int __user *) regs->cp0_epc); printk("\n"); + set_fs(old_fs); } static int regs_to_trapnr(struct pt_regs *regs) @@ -354,13 +467,13 @@ static DEFINE_RAW_SPINLOCK(die_lock); +/*--------------------------------------------------------------------------------*\ + * mbahr: eigentliche Behandlung im notifier (inklusive panic() - avm_enh/avm_reboot_status.c) ! +\*--------------------------------------------------------------------------------*/ void __noreturn die(const char *str, struct pt_regs *regs) { static int die_counter; int sig = SIGSEGV; -#ifdef CONFIG_MIPS_MT_SMTC - unsigned long dvpret; -#endif /* CONFIG_MIPS_MT_SMTC */ oops_enter(); @@ -369,14 +482,7 @@ console_verbose(); raw_spin_lock_irq(&die_lock); -#ifdef CONFIG_MIPS_MT_SMTC - dvpret = dvpe(); -#endif /* CONFIG_MIPS_MT_SMTC */ bust_spinlocks(1); -#ifdef CONFIG_MIPS_MT_SMTC - mips_mt_regdump(dvpret); -#endif /* CONFIG_MIPS_MT_SMTC */ - printk("%s[#%d]:\n", str, ++die_counter); show_registers(regs); add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); @@ -388,8 +494,6 @@ panic("Fatal exception in interrupt"); if (panic_on_oops) { - printk(KERN_EMERG "Fatal exception: panic in 5 seconds"); - ssleep(5); panic("Fatal exception"); } @@ -424,6 +528,10 @@ int data = regs->cp0_cause & 4; int action = MIPS_BE_FATAL; +#if defined(CONFIG_AVM_SIMPLE_PROFILING) + avm_simple_profiling_log(avm_profile_data_type_exception_begin, regs->cp0_epc, + (regs->cp0_cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE); +#endif /*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ /* XXX For now. Fixme, this searches the wrong table ... */ if (data && !user_mode(regs)) fixup = search_dbe_tables(exception_epc(regs)); @@ -434,6 +542,10 @@ if (board_be_handler) action = board_be_handler(regs, fixup != NULL); +#if defined(CONFIG_AVM_SIMPLE_PROFILING) + avm_simple_profiling_log(avm_profile_data_type_exception_end, regs->cp0_epc, + (regs->cp0_cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE); +#endif /*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ switch (action) { case MIPS_BE_DISCARD: return; @@ -457,6 +569,9 @@ == NOTIFY_STOP) return; +#if defined(CONFIG_AVM_ENHANCED) + avm_nmi_taken = ~0xdeadbabe; +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ die_if_kernel("Oops", regs); force_sig(SIGBUS, current); } @@ -675,6 +790,9 @@ { siginfo_t info; +#if defined(CONFIG_AVM_ENHANCED) + show_code_position_by_epc("kernel integer overflow", regs); +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ die_if_kernel("Integer overflow", regs); info.si_code = FPE_INTOVF; @@ -715,6 +833,9 @@ { siginfo_t info = {0}; +#if defined(CONFIG_AVM_ENHANCED) + show_code_position_by_epc("kernel-floatingpoint-exception", regs); +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), SIGFPE) == NOTIFY_STOP) return; @@ -807,6 +928,9 @@ force_sig_info(SIGFPE, &info, current); break; case BRK_BUG: +#if defined(CONFIG_AVM_ENHANCED) + show_bug_by_bugtable(regs); +#endif /*--- #ifdef CONFIG_BUG_EXTRA_INFO ---*/ die_if_kernel("Kernel bug detected", regs); force_sig(SIGTRAP, current); break; @@ -837,7 +961,16 @@ unsigned int opcode, bcode; unsigned long epc; u16 instr[2]; +#ifdef CONFIG_EVA + mm_segment_t seg; + seg = get_fs(); + if (!user_mode(regs)) + set_fs(KERNEL_DS); +#endif +#if defined(CONFIG_AVM_ENHANCED) + show_code_position_by_epc("kernel-breakpoint", regs); +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ if (get_isa16_mode(regs->cp0_epc)) { /* Calculate EPC. */ epc = exception_epc(regs); @@ -852,6 +985,9 @@ goto out_sigsegv; bcode = (instr[0] >> 6) & 0x3f; do_trap_or_bp(regs, bcode, "Break"); +#ifdef CONFIG_EVA + set_fs(seg); +#endif return; } } else { @@ -875,23 +1011,35 @@ */ switch (bcode) { case BRK_KPROBE_BP: - if (notify_die(DIE_BREAK, "debug", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP) + if (notify_die(DIE_BREAK, "debug", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP) { +#ifdef CONFIG_EVA + set_fs(seg); +#endif return; - else + } else break; case BRK_KPROBE_SSTEPBP: - if (notify_die(DIE_SSTEPBP, "single_step", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP) + if (notify_die(DIE_SSTEPBP, "single_step", regs, bcode, regs_to_trapnr(regs), SIGTRAP) == NOTIFY_STOP) { +#ifdef CONFIG_EVA + set_fs(seg); +#endif return; - else + } else break; default: break; } do_trap_or_bp(regs, bcode, "Break"); +#ifdef CONFIG_EVA + set_fs(seg); +#endif return; out_sigsegv: +#ifdef CONFIG_EVA + set_fs(seg); +#endif force_sig(SIGSEGV, current); } @@ -901,6 +1049,17 @@ u16 instr[2]; unsigned long epc = msk_isa16_mode(exception_epc(regs)); +#if defined(CONFIG_AVM_ENHANCED) + show_code_position_by_epc("kernel-trap", regs); +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ +#ifdef CONFIG_EVA + mm_segment_t seg; + + seg = get_fs(); + if (!user_mode(regs)) + set_fs(KERNEL_DS); +#endif + if (get_isa16_mode(regs->cp0_epc)) { if (__get_user(instr[0], (u16 __user *)(epc + 0)) || __get_user(instr[1], (u16 __user *)(epc + 2))) @@ -1114,20 +1273,28 @@ /* Fall through. */ case 1: - if (used_math()) /* Using the FPU again. */ - own_fpu(1); - else { /* First time FPU user. */ - init_fpu(); + status = 0; + if (used_math()) /* Using the FPU again. */ + status = own_fpu(1); + else { /* First time FPU user. */ + status = init_fpu(); +#ifndef CONFIG_MIPS_INCOMPATIBLE_FPU_EMULATION + if (status) { + force_sig(SIGFPE, current); + return; + } +#endif + set_used_math(); } - if (!raw_cpu_has_fpu) { + if ((!raw_cpu_has_fpu) || status) { int sig; void __user *fault_addr = NULL; sig = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 0, &fault_addr); - if (!process_fpemu_return(sig, fault_addr)) + if ((!process_fpemu_return(sig, fault_addr)) && !status) mt_ase_fp_affinity(); } @@ -1152,7 +1319,20 @@ asmlinkage void do_watch(struct pt_regs *regs) { u32 cause; - +#if defined(CONFIG_AVM_SIMPLE_PROFILING) + avm_simple_profiling_log(avm_profile_data_type_exception_begin, regs->cp0_epc, + (regs->cp0_cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE); +#endif /*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ + +#if defined(CONFIG_AVM_WP) + if (avm_wp_dispatcher(regs)) { +#if defined(CONFIG_AVM_SIMPLE_PROFILING) + avm_simple_profiling_log(avm_profile_data_type_exception_end, regs->cp0_epc, + (regs->cp0_cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE); +#endif /*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ + return; + } +#endif /* * Clear WP (bit 22) bit of cause register so we don't loop * forever. @@ -1174,6 +1354,10 @@ mips_clear_watch_registers(); local_irq_enable(); } +#if defined(CONFIG_AVM_SIMPLE_PROFILING) + avm_simple_profiling_log(avm_profile_data_type_exception_end, regs->cp0_epc, + (regs->cp0_cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE); +#endif /*--- #if defined(CONFIG_AVM_SIMPLE_PROFILING) ---*/ } asmlinkage void do_mcheck(struct pt_regs *regs) @@ -1243,7 +1427,7 @@ asmlinkage void do_dsp(struct pt_regs *regs) { if (cpu_has_dsp) - panic("Unexpected DSP exception"); + panic("Unexpected DSP exception\n"); force_sig(SIGILL, current); } @@ -1286,6 +1470,10 @@ case CPU_34K: case CPU_74K: case CPU_1004K: + case CPU_1074K: + case CPU_PROAPTIV: + case CPU_P5600: + case CPU_INTERAPTIV: { #define ERRCTL_PE 0x80000000 #define ERRCTL_L2P 0x00800000 @@ -1367,22 +1555,26 @@ unsigned int reg_val; /* For the moment, report the problem and hang. */ - printk("Cache error exception:\n"); + printk("Cache error exception, cp0_ecc=0x%08x:\n",read_c0_ecc()); printk("cp0_errorepc == %0*lx\n", field, read_c0_errorepc()); reg_val = read_c0_cacheerr(); printk("c0_cacheerr == %08x\n", reg_val); - printk("Decoded c0_cacheerr: %s cache fault in %s reference.\n", - reg_val & (1<<30) ? "secondary" : "primary", - reg_val & (1<<31) ? "data" : "insn"); - printk("Error bits: %s%s%s%s%s%s%s\n", + if ((reg_val & 0xc0000000) == 0xc0000000) + printk("Decoded c0_cacheerr: FTLB parity error\n"); + else + printk("Decoded c0_cacheerr: %s cache fault in %s reference.\n", + reg_val & (1<<30) ? "secondary" : "primary", + reg_val & (1<<31) ? "data" : "insn"); + printk("Error bits: %s%s%s%s%s%s%s%s\n", reg_val & (1<<29) ? "ED " : "", reg_val & (1<<28) ? "ET " : "", + reg_val & (1<<27) ? "ES " : "", reg_val & (1<<26) ? "EE " : "", reg_val & (1<<25) ? "EB " : "", - reg_val & (1<<24) ? "EI " : "", - reg_val & (1<<23) ? "E1 " : "", - reg_val & (1<<22) ? "E0 " : ""); + reg_val & (1<<24) ? "EI/EF " : "", + reg_val & (1<<23) ? "E1/SP " : "", + reg_val & (1<<22) ? "E0/EW " : ""); printk("IDX: 0x%08x\n", reg_val & ((1<<22)-1)); #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) @@ -1396,6 +1588,45 @@ panic("Can't handle the cache error!"); } +asmlinkage void do_ftlb(void) +{ + const int field = 2 * sizeof(unsigned long); + unsigned int reg_val; + + /* For the moment, report the problem and hang. */ + printk("FTLB error exception, cp0_ecc=0x%08x:\n",read_c0_ecc()); + printk("cp0_errorepc == %0*lx\n", field, read_c0_errorepc()); + reg_val = read_c0_cacheerr(); + printk("c0_cacheerr == %08x\n", reg_val); + + if ((reg_val & 0xc0000000) == 0xc0000000) + printk("Decoded c0_cacheerr: FTLB parity error\n"); + else + printk("Decoded c0_cacheerr: %s cache fault in %s reference.\n", + reg_val & (1<<30) ? "secondary" : "primary", + reg_val & (1<<31) ? "data" : "insn"); + printk("Error bits: %s%s%s%s%s%s%s%s\n", + reg_val & (1<<29) ? "ED " : "", + reg_val & (1<<28) ? "ET " : "", + reg_val & (1<<27) ? "ES " : "", + reg_val & (1<<26) ? "EE " : "", + reg_val & (1<<25) ? "EB " : "", + reg_val & (1<<24) ? "EI/EF " : "", + reg_val & (1<<23) ? "E1/SP " : "", + reg_val & (1<<22) ? "E0/EW " : ""); + printk("IDX: 0x%08x\n", reg_val & ((1<<22)-1)); + +#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) + if (reg_val & (1<<22)) + printk("DErrAddr0: 0x%0*lx\n", field, read_c0_derraddr0()); + + if (reg_val & (1<<23)) + printk("DErrAddr1: 0x%0*lx\n", field, read_c0_derraddr1()); +#endif + + panic("Can't handle the FTLB parity error!"); +} + /* * SDBBP EJTAG debug exception handler. * We skip the instruction and return to the next instruction. @@ -1445,12 +1676,19 @@ return raw_notifier_chain_register(&nmi_chain, nb); } -void __noreturn nmi_exception_handler(struct pt_regs *regs) -{ - raw_notifier_call_chain(&nmi_chain, 0, regs); - bust_spinlocks(1); - printk("NMI taken!!!!\n"); - die("NMI", regs); + +/*--------------------------------------------------------------------------------*\ + * mbahr: eigentliche Behandlung im notifier (inklusive die() - avm_new/ifxmips_wdt.c bzw. avm_new/ath_wdt.c) ! +\*--------------------------------------------------------------------------------*/ +void __noreturn nmi_exception_handler(struct pt_regs *regs) { +#if defined(CONFIG_AVM_ENHANCED) + avm_tick_jiffies_update(); /*--- auch im NMI-Fall jiffies korrigieren ---*/ +#endif/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ + raw_notifier_call_chain(&nmi_chain, 0, regs); + bust_spinlocks(1); + console_verbose(); + printk("NMI taken!!!!\n"); + die("NMI", regs); } #define VECTORSPACING 0x100 /* for EI/VI mode */ @@ -1513,7 +1751,6 @@ unsigned char *b; BUG_ON(!cpu_has_veic && !cpu_has_vint); - BUG_ON((n < 0) && (n > 9)); if (addr == NULL) { handler = (unsigned long) do_default_vi; @@ -1687,7 +1924,7 @@ if (cpu_has_dsp) status_set |= ST0_MX; - change_c0_status(ST0_CU|ST0_MX|ST0_RE|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX, + change_c0_status(ST0_CU|ST0_MX|ST0_RE|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX, status_set); if (cpu_has_mips_r2) @@ -1705,6 +1942,10 @@ if (cpu_has_veic || cpu_has_vint) { unsigned long sr = set_c0_status(ST0_BEV); +#ifdef CONFIG_EVA + write_c0_ebase(ebase|MIPS_EBASE_WG); + back_to_back_c0_hazard(); +#endif write_c0_ebase(ebase); write_c0_status(sr); /* Setting vector spacing enables EI/VI mode */ @@ -1770,7 +2011,7 @@ } /* Install CPU exception handler */ -void __cpuinit set_handler(unsigned long offset, void *addr, unsigned long size) +void set_handler(unsigned long offset, void *addr, unsigned long size) { #ifdef CONFIG_CPU_MICROMIPS memcpy((void *)(ebase + offset), ((unsigned char *)addr - 1), size); @@ -1822,6 +2063,22 @@ return; /* Already done */ #endif +#if 0 + if (cpu_has_veic ) printk(KERN_ERR"[%s] cpu_has_veic \n", __FUNCTION__); + if (cpu_has_vint) printk(KERN_ERR"[%s] cpu_has_vint\n", __FUNCTION__); + if (cpu_has_ejtag ) printk(KERN_ERR"[%s] cpu_has_ejtag \n", __FUNCTION__); + if (cpu_has_watch) printk(KERN_ERR"[%s] cpu_has_watch\n", __FUNCTION__); + if (cpu_has_divec) printk(KERN_ERR"[%s] cpu_has_divec\n", __FUNCTION__); + if (cpu_has_vtag_icache ) printk(KERN_ERR"[%s] cpu_has_vtag_icache \n", __FUNCTION__); + if (cpu_has_fpu ) printk(KERN_ERR"[%s] cpu_has_fpu \n", __FUNCTION__); + if (cpu_has_nofpuex) printk(KERN_ERR"[%s] cpu_has_nofpuex\n", __FUNCTION__); + if (cpu_has_mcheck) printk(KERN_ERR"[%s] cpu_has_mcheck\n", __FUNCTION__); + if (cpu_has_mipsmt) printk(KERN_ERR"[%s] cpu_has_mipsmt\n", __FUNCTION__); + if (cpu_has_vce) printk(KERN_ERR"[%s] cpu_has_vce\n", __FUNCTION__); + if (cpu_has_4kex) printk(KERN_ERR"[%s] cpu_has_4kex\n", __FUNCTION__); + if (cpu_has_dsp) printk(KERN_ERR"[%s] cpu_has_dsp\n", __FUNCTION__); +#endif + if (cpu_has_veic || cpu_has_vint) { unsigned long size = 0x200 + VECTORSPACING*64; ebase = (unsigned long) @@ -1837,6 +2094,15 @@ ebase += (read_c0_ebase() & 0x3ffff000); } + if (cpu_has_mmips) { + unsigned int config3 = read_c0_config3(); + + if (IS_ENABLED(CONFIG_CPU_MICROMIPS)) + write_c0_config3(config3 | MIPS_CONF3_ISA_OE); + else + write_c0_config3(config3 & ~MIPS_CONF3_ISA_OE); + } + if (board_ebase_setup) board_ebase_setup(); per_cpu_trap_init(true); @@ -1934,6 +2200,7 @@ if (cpu_has_fpu && !cpu_has_nofpuex) set_except_vector(15, handle_fpe); + set_except_vector(16, handle_ftlb); set_except_vector(22, handle_mdmx); if (cpu_has_mcheck)