Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2)  * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * License.  See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * Copyright (C) 1994 - 1999, 2000, 01, 06 Ralf Baechle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * Copyright (C) 1995, 1996 Paul M. Antoine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * Copyright (C) 1998 Ulf Carlsson
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  * Copyright (C) 1999 Silicon Graphics, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  * Copyright (C) 2002, 2003, 2004, 2005, 2007  Maciej W. Rozycki
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  * Copyright (C) 2000, 2001, 2012 MIPS Technologies, Inc.  All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13)  * Copyright (C) 2014, Imagination Technologies Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/bug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/compiler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/context_tracking.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/cpu_pm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/kexec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/extable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/sched/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <linux/sched/debug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #include <linux/kallsyms.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #include <linux/memblock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #include <linux/kgdb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #include <linux/kdebug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #include <linux/kprobes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #include <linux/notifier.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #include <linux/kdb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #include <linux/perf_event.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #include <asm/addrspace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #include <asm/bootinfo.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #include <asm/branch.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #include <asm/break.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #include <asm/cop2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #include <asm/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #include <asm/cpu-type.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #include <asm/dsp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #include <asm/fpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #include <asm/fpu_emulator.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #include <asm/idle.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #include <asm/isa-rev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #include <asm/mips-cps.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #include <asm/mips-r2-to-r6-emul.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #include <asm/mipsregs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #include <asm/mipsmtregs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #include <asm/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #include <asm/msa.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #include <asm/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #include <asm/sections.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) #include <asm/siginfo.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) #include <asm/tlbdebug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) #include <asm/traps.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) #include <asm/watch.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #include <asm/mmu_context.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) #include <asm/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) #include <asm/stacktrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) #include <asm/tlbex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) #include <asm/uasm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) #include <asm/mach-loongson64/cpucfg-emul.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) extern void check_wait(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) extern asmlinkage void rollback_handle_int(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) extern asmlinkage void handle_int(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) extern asmlinkage void handle_adel(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) extern asmlinkage void handle_ades(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) extern asmlinkage void handle_ibe(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) extern asmlinkage void handle_dbe(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) extern asmlinkage void handle_sys(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) extern asmlinkage void handle_bp(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) extern asmlinkage void handle_ri(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) extern asmlinkage void handle_ri_rdhwr_tlbp(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) extern asmlinkage void handle_ri_rdhwr(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) extern asmlinkage void handle_cpu(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) extern asmlinkage void handle_ov(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) extern asmlinkage void handle_tr(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) extern asmlinkage void handle_msa_fpe(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) extern asmlinkage void handle_fpe(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) extern asmlinkage void handle_ftlb(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) extern asmlinkage void handle_gsexc(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) extern asmlinkage void handle_msa(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) extern asmlinkage void handle_mdmx(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) extern asmlinkage void handle_watch(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) extern asmlinkage void handle_mt(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) extern asmlinkage void handle_dsp(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) extern asmlinkage void handle_mcheck(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) extern asmlinkage void handle_reserved(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) extern void tlb_do_page_fault_0(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) void (*board_be_init)(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) void (*board_nmi_handler_setup)(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) void (*board_ejtag_handler_setup)(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) void (*board_bind_eic_interrupt)(int irq, int regset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) void (*board_ebase_setup)(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) void(*board_cache_error_setup)(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) static void show_raw_backtrace(unsigned long reg29, const char *loglvl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	unsigned long *sp = (unsigned long *)(reg29 & ~3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	unsigned long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	printk("%sCall Trace:", loglvl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) #ifdef CONFIG_KALLSYMS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	printk("%s\n", loglvl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	while (!kstack_end(sp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 		unsigned long __user *p =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 			(unsigned long __user *)(unsigned long)sp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 		if (__get_user(addr, p)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 			printk("%s (Bad stack address)", loglvl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 		if (__kernel_text_address(addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 			print_ip_sym(loglvl, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	printk("%s\n", loglvl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) #ifdef CONFIG_KALLSYMS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) int raw_show_trace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) static int __init set_raw_show_trace(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	raw_show_trace = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) __setup("raw_show_trace", set_raw_show_trace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) static void show_backtrace(struct task_struct *task, const struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 			   const char *loglvl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	unsigned long sp = regs->regs[29];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	unsigned long ra = regs->regs[31];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	unsigned long pc = regs->cp0_epc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	if (!task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 		task = current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	if (raw_show_trace || user_mode(regs) || !__kernel_text_address(pc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 		show_raw_backtrace(sp, loglvl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	printk("%sCall Trace:\n", loglvl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 		print_ip_sym(loglvl, pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 		pc = unwind_stack(task, &sp, pc, &ra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	} while (pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	pr_cont("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166)  * This routine abuses get_user()/put_user() to reference pointers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167)  * with at least a bit of error checking ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) static void show_stacktrace(struct task_struct *task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	const struct pt_regs *regs, const char *loglvl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	const int field = 2 * sizeof(unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	long stackdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	unsigned long __user *sp = (unsigned long __user *)regs->regs[29];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	printk("%sStack :", loglvl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	while ((unsigned long) sp & (PAGE_SIZE - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 		if (i && ((i % (64 / field)) == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 			pr_cont("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 			printk("%s       ", loglvl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 		if (i > 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 			pr_cont(" ...");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 		if (__get_user(stackdata, sp++)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 			pr_cont(" (Bad stack address)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 		pr_cont(" %0*lx", field, stackdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 		i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	pr_cont("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	show_backtrace(task, regs, loglvl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) void show_stack(struct task_struct *task, unsigned long *sp, const char *loglvl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	struct pt_regs regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	mm_segment_t old_fs = get_fs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	regs.cp0_status = KSU_KERNEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	if (sp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 		regs.regs[29] = (unsigned long)sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 		regs.regs[31] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 		regs.cp0_epc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 		if (task && task != current) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 			regs.regs[29] = task->thread.reg29;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 			regs.regs[31] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 			regs.cp0_epc = task->thread.reg31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 			prepare_frametrace(&regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	 * show_stack() deals exclusively with kernel mode, so be sure to access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	 * the stack in the kernel (not user) address space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	set_fs(KERNEL_DS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	show_stacktrace(task, &regs, loglvl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	set_fs(old_fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) static void show_code(unsigned int __user *pc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	long i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	unsigned short __user *pc16 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	printk("Code:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	if ((unsigned long)pc & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 		pc16 = (unsigned short __user *)((unsigned long)pc & ~1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	for(i = -3 ; i < 6 ; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 		unsigned int insn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 		if (pc16 ? __get_user(insn, pc16 + i) : __get_user(insn, pc + i)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 			pr_cont(" (Bad address in epc)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 		pr_cont("%c%0*x%c", (i?' ':'<'), pc16 ? 4 : 8, insn, (i?' ':'>'));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	pr_cont("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) static void __show_regs(const struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	const int field = 2 * sizeof(unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	unsigned int cause = regs->cp0_cause;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	unsigned int exccode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	show_regs_print_info(KERN_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	 * Saved main processor registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	for (i = 0; i < 32; ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 		if ((i % 4) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 			printk("$%2d   :", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 		if (i == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 			pr_cont(" %0*lx", field, 0UL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 		else if (i == 26 || i == 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 			pr_cont(" %*s", field, "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 			pr_cont(" %0*lx", field, regs->regs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 		i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 		if ((i % 4) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 			pr_cont("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) #ifdef CONFIG_CPU_HAS_SMARTMIPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	printk("Acx    : %0*lx\n", field, regs->acx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	if (MIPS_ISA_REV < 6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 		printk("Hi    : %0*lx\n", field, regs->hi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 		printk("Lo    : %0*lx\n", field, regs->lo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	 * Saved cp0 registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	printk("epc   : %0*lx %pS\n", field, regs->cp0_epc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	       (void *) regs->cp0_epc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	printk("ra    : %0*lx %pS\n", field, regs->regs[31],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	       (void *) regs->regs[31]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	printk("Status: %08x	", (uint32_t) regs->cp0_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	if (cpu_has_3kex) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 		if (regs->cp0_status & ST0_KUO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 			pr_cont("KUo ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 		if (regs->cp0_status & ST0_IEO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 			pr_cont("IEo ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 		if (regs->cp0_status & ST0_KUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 			pr_cont("KUp ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 		if (regs->cp0_status & ST0_IEP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 			pr_cont("IEp ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 		if (regs->cp0_status & ST0_KUC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 			pr_cont("KUc ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 		if (regs->cp0_status & ST0_IEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 			pr_cont("IEc ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	} else if (cpu_has_4kex) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 		if (regs->cp0_status & ST0_KX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 			pr_cont("KX ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 		if (regs->cp0_status & ST0_SX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 			pr_cont("SX ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 		if (regs->cp0_status & ST0_UX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 			pr_cont("UX ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 		switch (regs->cp0_status & ST0_KSU) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 		case KSU_USER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 			pr_cont("USER ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 		case KSU_SUPERVISOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 			pr_cont("SUPERVISOR ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 		case KSU_KERNEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 			pr_cont("KERNEL ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 			pr_cont("BAD_MODE ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 		if (regs->cp0_status & ST0_ERL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 			pr_cont("ERL ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 		if (regs->cp0_status & ST0_EXL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 			pr_cont("EXL ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 		if (regs->cp0_status & ST0_IE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 			pr_cont("IE ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	pr_cont("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	exccode = (cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	printk("Cause : %08x (ExcCode %02x)\n", cause, exccode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	if (1 <= exccode && exccode <= 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 		printk("BadVA : %0*lx\n", field, regs->cp0_badvaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	printk("PrId  : %08x (%s)\n", read_c0_prid(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	       cpu_name_string());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348)  * FIXME: really the generic show_regs should take a const pointer argument.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) void show_regs(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	__show_regs(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	dump_stack();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) void show_registers(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	const int field = 2 * sizeof(unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	mm_segment_t old_fs = get_fs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	__show_regs(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	print_modules();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	printk("Process %s (pid: %d, threadinfo=%p, task=%p, tls=%0*lx)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	       current->comm, current->pid, current_thread_info(), current,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	      field, current_thread_info()->tp_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	if (cpu_has_userlocal) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 		unsigned long tls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 		tls = read_c0_userlocal();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 		if (tls != current_thread_info()->tp_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 			printk("*HwTLS: %0*lx\n", field, tls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	if (!user_mode(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 		/* Necessary for getting the correct stack content */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 		set_fs(KERNEL_DS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	show_stacktrace(current, regs, KERN_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	show_code((unsigned int __user *) regs->cp0_epc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	printk("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	set_fs(old_fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) static DEFINE_RAW_SPINLOCK(die_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) void __noreturn die(const char *str, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	static int die_counter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	int sig = SIGSEGV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	oops_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	if (notify_die(DIE_OOPS, str, regs, 0, current->thread.trap_nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 		       SIGSEGV) == NOTIFY_STOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 		sig = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	console_verbose();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	raw_spin_lock_irq(&die_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	bust_spinlocks(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	printk("%s[#%d]:\n", str, ++die_counter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	show_registers(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	raw_spin_unlock_irq(&die_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	oops_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	if (in_interrupt())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 		panic("Fatal exception in interrupt");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	if (panic_on_oops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 		panic("Fatal exception");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	if (regs && kexec_should_crash(current))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 		crash_kexec(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	do_exit(sig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) extern struct exception_table_entry __start___dbe_table[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) extern struct exception_table_entry __stop___dbe_table[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) __asm__(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) "	.section	__dbe_table, \"a\"\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) "	.previous			\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) /* Given an address, look for it in the exception tables. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) static const struct exception_table_entry *search_dbe_tables(unsigned long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	const struct exception_table_entry *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	e = search_extable(__start___dbe_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 			   __stop___dbe_table - __start___dbe_table, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	if (!e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 		e = search_module_dbetables(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	return e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) asmlinkage void do_be(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	const int field = 2 * sizeof(unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	const struct exception_table_entry *fixup = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	int data = regs->cp0_cause & 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	int action = MIPS_BE_FATAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	enum ctx_state prev_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	prev_state = exception_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	/* XXX For now.	 Fixme, this searches the wrong table ...  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	if (data && !user_mode(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 		fixup = search_dbe_tables(exception_epc(regs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	if (fixup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 		action = MIPS_BE_FIXUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	if (board_be_handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 		action = board_be_handler(regs, fixup != NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 		mips_cm_error_report();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	switch (action) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	case MIPS_BE_DISCARD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	case MIPS_BE_FIXUP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 		if (fixup) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 			regs->cp0_epc = fixup->nextinsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	 * Assume it would be too dangerous to continue ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	printk(KERN_ALERT "%s bus error, epc == %0*lx, ra == %0*lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	       data ? "Data" : "Instruction",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	       field, regs->cp0_epc, field, regs->regs[31]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	if (notify_die(DIE_OOPS, "bus error", regs, 0, current->thread.trap_nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 		       SIGBUS) == NOTIFY_STOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	die_if_kernel("Oops", regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	force_sig(SIGBUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	exception_exit(prev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490)  * ll/sc, rdhwr, sync emulation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) #define OPCODE 0xfc000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) #define BASE   0x03e00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) #define RT     0x001f0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) #define OFFSET 0x0000ffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) #define LL     0xc0000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) #define SC     0xe0000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) #define SPEC0  0x00000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) #define SPEC3  0x7c000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) #define RD     0x0000f800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) #define FUNC   0x0000003f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) #define SYNC   0x0000000f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) #define RDHWR  0x0000003b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) /*  microMIPS definitions   */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) #define MM_POOL32A_FUNC 0xfc00ffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) #define MM_RDHWR        0x00006b3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) #define MM_RS           0x001f0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) #define MM_RT           0x03e00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513)  * The ll_bit is cleared by r*_switch.S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) unsigned int ll_bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) struct task_struct *ll_task;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) static inline int simulate_ll(struct pt_regs *regs, unsigned int opcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	unsigned long value, __user *vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	 * analyse the ll instruction that just caused a ri exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	 * and put the referenced address to addr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	/* sign extend offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	offset = opcode & OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	offset <<= 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	offset >>= 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	vaddr = (unsigned long __user *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 		((unsigned long)(regs->regs[(opcode & BASE) >> 21]) + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	if ((unsigned long)vaddr & 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 		return SIGBUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	if (get_user(value, vaddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 		return SIGSEGV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	preempt_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	if (ll_task == NULL || ll_task == current) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 		ll_bit = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 		ll_bit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	ll_task = current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	preempt_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	regs->regs[(opcode & RT) >> 16] = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) static inline int simulate_sc(struct pt_regs *regs, unsigned int opcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	unsigned long __user *vaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	unsigned long reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	long offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	 * analyse the sc instruction that just caused a ri exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	 * and put the referenced address to addr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	/* sign extend offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	offset = opcode & OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	offset <<= 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	offset >>= 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	vaddr = (unsigned long __user *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 		((unsigned long)(regs->regs[(opcode & BASE) >> 21]) + offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	reg = (opcode & RT) >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	if ((unsigned long)vaddr & 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 		return SIGBUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	preempt_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	if (ll_bit == 0 || ll_task != current) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 		regs->regs[reg] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 		preempt_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	preempt_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	if (put_user(regs->regs[reg], vaddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 		return SIGSEGV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	regs->regs[reg] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600)  * ll uses the opcode of lwc0 and sc uses the opcode of swc0.  That is both
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601)  * opcodes are supposed to result in coprocessor unusable exceptions if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602)  * executed on ll/sc-less processors.  That's the theory.  In practice a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603)  * few processors such as NEC's VR4100 throw reserved instruction exceptions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604)  * instead, so we're doing the emulation thing in both exception handlers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) static int simulate_llsc(struct pt_regs *regs, unsigned int opcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	if ((opcode & OPCODE) == LL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 		perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 				1, regs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 		return simulate_ll(regs, opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	if ((opcode & OPCODE) == SC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 		perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 				1, regs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 		return simulate_sc(regs, opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	return -1;			/* Must be something else ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623)  * Simulate trapping 'rdhwr' instructions to provide user accessible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624)  * registers not implemented in hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) static int simulate_rdhwr(struct pt_regs *regs, int rd, int rt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	struct thread_info *ti = task_thread_info(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 			1, regs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	switch (rd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	case MIPS_HWR_CPUNUM:		/* CPU number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 		regs->regs[rt] = smp_processor_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	case MIPS_HWR_SYNCISTEP:	/* SYNCI length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 		regs->regs[rt] = min(current_cpu_data.dcache.linesz,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 				     current_cpu_data.icache.linesz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	case MIPS_HWR_CC:		/* Read count register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 		regs->regs[rt] = read_c0_count();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	case MIPS_HWR_CCRES:		/* Count register resolution */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 		switch (current_cpu_type()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 		case CPU_20KC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 		case CPU_25KF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 			regs->regs[rt] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 			regs->regs[rt] = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	case MIPS_HWR_ULR:		/* Read UserLocal register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 		regs->regs[rt] = ti->tp_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) static int simulate_rdhwr_normal(struct pt_regs *regs, unsigned int opcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	if ((opcode & OPCODE) == SPEC3 && (opcode & FUNC) == RDHWR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 		int rd = (opcode & RD) >> 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 		int rt = (opcode & RT) >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 		simulate_rdhwr(regs, rd, rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	/* Not ours.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) static int simulate_rdhwr_mm(struct pt_regs *regs, unsigned int opcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	if ((opcode & MM_POOL32A_FUNC) == MM_RDHWR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 		int rd = (opcode & MM_RS) >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 		int rt = (opcode & MM_RT) >> 21;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 		simulate_rdhwr(regs, rd, rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	/* Not ours.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) static int simulate_sync(struct pt_regs *regs, unsigned int opcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	if ((opcode & OPCODE) == SPEC0 && (opcode & FUNC) == SYNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 		perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 				1, regs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	return -1;			/* Must be something else ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700)  * Loongson-3 CSR instructions emulation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) #ifdef CONFIG_CPU_LOONGSON3_CPUCFG_EMULATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) #define LWC2             0xc8000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) #define RS               BASE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) #define CSR_OPCODE2      0x00000118
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) #define CSR_OPCODE2_MASK 0x000007ff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) #define CSR_FUNC_MASK    RT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) #define CSR_FUNC_CPUCFG  0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) static int simulate_loongson3_cpucfg(struct pt_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 				     unsigned int opcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	int op = opcode & OPCODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	int op2 = opcode & CSR_OPCODE2_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 	int csr_func = (opcode & CSR_FUNC_MASK) >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	if (op == LWC2 && op2 == CSR_OPCODE2 && csr_func == CSR_FUNC_CPUCFG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 		int rd = (opcode & RD) >> 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 		int rs = (opcode & RS) >> 21;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 		__u64 sel = regs->regs[rs];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 		perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 		/* Do not emulate on unsupported core models. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		preempt_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 		if (!loongson3_cpucfg_emulation_enabled(&current_cpu_data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 			preempt_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 		regs->regs[rd] = loongson3_cpucfg_read_synthesized(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 			&current_cpu_data, sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 		preempt_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	/* Not ours.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) #endif /* CONFIG_CPU_LOONGSON3_CPUCFG_EMULATION */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) asmlinkage void do_ov(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	enum ctx_state prev_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	prev_state = exception_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	die_if_kernel("Integer overflow", regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	force_sig_fault(SIGFPE, FPE_INTOVF, (void __user *)regs->cp0_epc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	exception_exit(prev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) #ifdef CONFIG_MIPS_FP_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757)  * Send SIGFPE according to FCSR Cause bits, which must have already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758)  * been masked against Enable bits.  This is impotant as Inexact can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759)  * happen together with Overflow or Underflow, and `ptrace' can set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760)  * any bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 		     struct task_struct *tsk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	int si_code = FPE_FLTUNK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	if (fcr31 & FPU_CSR_INV_X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 		si_code = FPE_FLTINV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	else if (fcr31 & FPU_CSR_DIV_X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 		si_code = FPE_FLTDIV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	else if (fcr31 & FPU_CSR_OVF_X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 		si_code = FPE_FLTOVF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	else if (fcr31 & FPU_CSR_UDF_X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 		si_code = FPE_FLTUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	else if (fcr31 & FPU_CSR_INE_X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 		si_code = FPE_FLTRES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	force_sig_fault_to_task(SIGFPE, si_code, fault_addr, tsk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) int process_fpemu_return(int sig, void __user *fault_addr, unsigned long fcr31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	int si_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	struct vm_area_struct *vma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	switch (sig) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	case SIGFPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 		force_fcr31_sig(fcr31, fault_addr, current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	case SIGBUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 		force_sig_fault(SIGBUS, BUS_ADRERR, fault_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	case SIGSEGV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 		mmap_read_lock(current->mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 		vma = find_vma(current->mm, (unsigned long)fault_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 		if (vma && (vma->vm_start <= (unsigned long)fault_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 			si_code = SEGV_ACCERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 			si_code = SEGV_MAPERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 		mmap_read_unlock(current->mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 		force_sig_fault(SIGSEGV, si_code, fault_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 		force_sig(sig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) static int simulate_fp(struct pt_regs *regs, unsigned int opcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 		       unsigned long old_epc, unsigned long old_ra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	union mips_instruction inst = { .word = opcode };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	void __user *fault_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 	unsigned long fcr31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	int sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	/* If it's obviously not an FP instruction, skip it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	switch (inst.i_format.opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	case cop1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	case cop1x_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	case lwc1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	case ldc1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	case swc1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	case sdc1_op:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	 * do_ri skipped over the instruction via compute_return_epc, undo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 	 * that for the FPU emulator.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 	regs->cp0_epc = old_epc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	regs->regs[31] = old_ra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	/* Run the emulator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 				       &fault_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	 * We can't allow the emulated instruction to leave any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	 * enabled Cause bits set in $fcr31.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	fcr31 = mask_fcr31_x(current->thread.fpu.fcr31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	current->thread.fpu.fcr31 &= ~fcr31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	/* Restore the hardware register state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	own_fpu(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	/* Send a signal if required.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	process_fpemu_return(sig, fault_addr, fcr31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865)  * XXX Delayed fp exceptions when doing a lazy ctx switch XXX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	enum ctx_state prev_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	void __user *fault_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	int sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	prev_state = exception_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	if (notify_die(DIE_FP, "FP exception", regs, 0, current->thread.trap_nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 		       SIGFPE) == NOTIFY_STOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	/* Clear FCSR.Cause before enabling interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	write_32bit_cp1_register(CP1_STATUS, fcr31 & ~mask_fcr31_x(fcr31));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	local_irq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	die_if_kernel("FP exception in kernel code", regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	if (fcr31 & FPU_CSR_UNI_X) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		 * Unimplemented operation exception.  If we've got the full
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 		 * software emulator on-board, let's use it...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		 * Force FPU to dump state into task/thread context.  We're
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 		 * moving a lot of data here for what is probably a single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 		 * instruction, but the alternative is to pre-decode the FP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 		 * register operands before invoking the emulator, which seems
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 		 * a bit extreme for what should be an infrequent event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 		/* Run the emulator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 		sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 					       &fault_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 		 * We can't allow the emulated instruction to leave any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 		 * enabled Cause bits set in $fcr31.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 		fcr31 = mask_fcr31_x(current->thread.fpu.fcr31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 		current->thread.fpu.fcr31 &= ~fcr31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 		/* Restore the hardware register state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 		own_fpu(1);	/* Using the FPU again.	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 		sig = SIGFPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 		fault_addr = (void __user *) regs->cp0_epc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	/* Send a signal if required.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	process_fpemu_return(sig, fault_addr, fcr31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	exception_exit(prev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922)  * MIPS MT processors may have fewer FPU contexts than CPU threads. If we've
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923)  * emulated more than some threshold number of instructions, force migration to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924)  * a "CPU" that has FP support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) static void mt_ase_fp_affinity(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) #ifdef CONFIG_MIPS_MT_FPAFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	if (mt_fpemul_threshold > 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	     ((current->thread.emulated_fp++ > mt_fpemul_threshold))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 		 * If there's no FPU present, or if the application has already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 		 * restricted the allowed set to exclude any CPUs with FPUs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 		 * we'll skip the procedure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 		if (cpumask_intersects(&current->cpus_mask, &mt_fpu_cpumask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 			cpumask_t tmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 			current->thread.user_cpus_allowed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 				= current->cpus_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 			cpumask_and(&tmask, &current->cpus_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 				    &mt_fpu_cpumask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 			set_cpus_allowed_ptr(current, &tmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 			set_thread_flag(TIF_FPUBOUND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) #endif /* CONFIG_MIPS_MT_FPAFF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) #else /* !CONFIG_MIPS_FP_SUPPORT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) static int simulate_fp(struct pt_regs *regs, unsigned int opcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 		       unsigned long old_epc, unsigned long old_ra)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) #endif /* !CONFIG_MIPS_FP_SUPPORT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) void do_trap_or_bp(struct pt_regs *regs, unsigned int code, int si_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	const char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	char b[40];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	if (kgdb_ll_trap(DIE_TRAP, str, regs, code, current->thread.trap_nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 			 SIGTRAP) == NOTIFY_STOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) #endif /* CONFIG_KGDB_LOW_LEVEL_TRAP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 	if (notify_die(DIE_TRAP, str, regs, code, current->thread.trap_nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 		       SIGTRAP) == NOTIFY_STOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	 * A short test says that IRIX 5.3 sends SIGTRAP for all trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	 * insns, even for trap and break codes that indicate arithmetic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	 * failures.  Weird ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	 * But should we continue the brokenness???  --macro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	switch (code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	case BRK_OVERFLOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	case BRK_DIVZERO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 		scnprintf(b, sizeof(b), "%s instruction in kernel code", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 		die_if_kernel(b, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 		force_sig_fault(SIGFPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 				code == BRK_DIVZERO ? FPE_INTDIV : FPE_INTOVF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 				(void __user *) regs->cp0_epc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	case BRK_BUG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		die_if_kernel("Kernel bug detected", regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 		force_sig(SIGTRAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	case BRK_MEMU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 		 * This breakpoint code is used by the FPU emulator to retake
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 		 * control of the CPU after executing the instruction from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 		 * delay slot of an emulated branch.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 		 * Terminate if exception was recognized as a delay slot return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 		 * otherwise handle as normal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 		if (do_dsemulret(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 		die_if_kernel("Math emu break/trap", regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 		force_sig(SIGTRAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 		scnprintf(b, sizeof(b), "%s instruction in kernel code", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 		die_if_kernel(b, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 		if (si_code) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 			force_sig_fault(SIGTRAP, si_code, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 			force_sig(SIGTRAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) asmlinkage void do_bp(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	unsigned long epc = msk_isa16_mode(exception_epc(regs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	unsigned int opcode, bcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	enum ctx_state prev_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	mm_segment_t seg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	seg = get_fs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	if (!user_mode(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 		set_fs(KERNEL_DS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	prev_state = exception_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	if (get_isa16_mode(regs->cp0_epc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 		u16 instr[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 		if (__get_user(instr[0], (u16 __user *)epc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 			goto out_sigsegv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 		if (!cpu_has_mmips) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 			/* MIPS16e mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 			bcode = (instr[0] >> 5) & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 		} else if (mm_insn_16bit(instr[0])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 			/* 16-bit microMIPS BREAK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 			bcode = instr[0] & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 			/* 32-bit microMIPS BREAK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 			if (__get_user(instr[1], (u16 __user *)(epc + 2)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 				goto out_sigsegv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 			opcode = (instr[0] << 16) | instr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 			bcode = (opcode >> 6) & ((1 << 20) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 		if (__get_user(opcode, (unsigned int __user *)epc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 			goto out_sigsegv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 		bcode = (opcode >> 6) & ((1 << 20) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	 * There is the ancient bug in the MIPS assemblers that the break
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	 * code starts left to bit 16 instead to bit 6 in the opcode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	 * Gas is bug-compatible, but not always, grrr...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	 * We handle both cases with a simple heuristics.  --macro
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	if (bcode >= (1 << 10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 		bcode = ((bcode & ((1 << 10) - 1)) << 10) | (bcode >> 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	 * notify the kprobe handlers, if instruction is likely to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	 * pertain to them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	switch (bcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	case BRK_UPROBE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 		if (notify_die(DIE_UPROBE, "uprobe", regs, bcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 			       current->thread.trap_nr, SIGTRAP) == NOTIFY_STOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	case BRK_UPROBE_XOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 		if (notify_die(DIE_UPROBE_XOL, "uprobe_xol", regs, bcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 			       current->thread.trap_nr, SIGTRAP) == NOTIFY_STOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	case BRK_KPROBE_BP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		if (notify_die(DIE_BREAK, "debug", regs, bcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 			       current->thread.trap_nr, SIGTRAP) == NOTIFY_STOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	case BRK_KPROBE_SSTEPBP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 		if (notify_die(DIE_SSTEPBP, "single_step", regs, bcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 			       current->thread.trap_nr, SIGTRAP) == NOTIFY_STOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	do_trap_or_bp(regs, bcode, TRAP_BRKPT, "Break");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	set_fs(seg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	exception_exit(prev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) out_sigsegv:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	force_sig(SIGSEGV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) asmlinkage void do_tr(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	u32 opcode, tcode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	enum ctx_state prev_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	u16 instr[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	mm_segment_t seg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	unsigned long epc = msk_isa16_mode(exception_epc(regs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	seg = get_fs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 	if (!user_mode(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 		set_fs(KERNEL_DS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	prev_state = exception_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	if (get_isa16_mode(regs->cp0_epc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 		if (__get_user(instr[0], (u16 __user *)(epc + 0)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 		    __get_user(instr[1], (u16 __user *)(epc + 2)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 			goto out_sigsegv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 		opcode = (instr[0] << 16) | instr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 		/* Immediate versions don't provide a code.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 		if (!(opcode & OPCODE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 			tcode = (opcode >> 12) & ((1 << 4) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 		if (__get_user(opcode, (u32 __user *)epc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 			goto out_sigsegv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 		/* Immediate versions don't provide a code.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 		if (!(opcode & OPCODE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 			tcode = (opcode >> 6) & ((1 << 10) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 	do_trap_or_bp(regs, tcode, 0, "Trap");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 	set_fs(seg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	exception_exit(prev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) out_sigsegv:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	force_sig(SIGSEGV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) asmlinkage void do_ri(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	unsigned int __user *epc = (unsigned int __user *)exception_epc(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	unsigned long old_epc = regs->cp0_epc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	unsigned long old31 = regs->regs[31];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	enum ctx_state prev_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	unsigned int opcode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	int status = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	 * Avoid any kernel code. Just emulate the R2 instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	 * as quickly as possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	if (mipsr2_emulation && cpu_has_mips_r6 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	    likely(user_mode(regs)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 	    likely(get_user(opcode, epc) >= 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 		unsigned long fcr31 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 		status = mipsr2_decoder(regs, opcode, &fcr31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 		switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 		case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 		case SIGEMT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 		case SIGILL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 			goto no_r2_instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 			process_fpemu_return(status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 					     &current->thread.cp0_baduaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 					     fcr31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) no_r2_instr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 	prev_state = exception_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	if (notify_die(DIE_RI, "RI Fault", regs, 0, current->thread.trap_nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 		       SIGILL) == NOTIFY_STOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	die_if_kernel("Reserved instruction in kernel code", regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	if (unlikely(compute_return_epc(regs) < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	if (!get_isa16_mode(regs->cp0_epc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 		if (unlikely(get_user(opcode, epc) < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 			status = SIGSEGV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 		if (!cpu_has_llsc && status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 			status = simulate_llsc(regs, opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 		if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 			status = simulate_rdhwr_normal(regs, opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 		if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 			status = simulate_sync(regs, opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 		if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 			status = simulate_fp(regs, opcode, old_epc, old31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) #ifdef CONFIG_CPU_LOONGSON3_CPUCFG_EMULATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 		if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 			status = simulate_loongson3_cpucfg(regs, opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	} else if (cpu_has_mmips) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 		unsigned short mmop[2] = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 		if (unlikely(get_user(mmop[0], (u16 __user *)epc + 0) < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 			status = SIGSEGV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 		if (unlikely(get_user(mmop[1], (u16 __user *)epc + 1) < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 			status = SIGSEGV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 		opcode = mmop[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 		opcode = (opcode << 16) | mmop[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 		if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 			status = simulate_rdhwr_mm(regs, opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 		status = SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	if (unlikely(status > 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 		regs->cp0_epc = old_epc;		/* Undo skip-over.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 		regs->regs[31] = old31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 		force_sig(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	exception_exit(prev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)  * No lock; only written during early bootup by CPU 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) static RAW_NOTIFIER_HEAD(cu2_chain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) int __ref register_cu2_notifier(struct notifier_block *nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 	return raw_notifier_chain_register(&cu2_chain, nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) int cu2_notifier_call_chain(unsigned long val, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 	return raw_notifier_call_chain(&cu2_chain, val, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) static int default_cu2_call(struct notifier_block *nfb, unsigned long action,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 	void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	struct pt_regs *regs = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 	die_if_kernel("COP2: Unhandled kernel unaligned access or invalid "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 			      "instruction", regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	force_sig(SIGILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 	return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) #ifdef CONFIG_MIPS_FP_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) static int enable_restore_fp_context(int msa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 	int err, was_fpu_owner, prior_msa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 	bool first_fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	/* Initialize context if it hasn't been used already */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	first_fp = init_fp_ctx(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	if (first_fp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 		preempt_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 		err = own_fpu_inatomic(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 		if (msa && !err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 			enable_msa();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 			 * with MSA enabled, userspace can see MSACSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 			 * and MSA regs, but the values in them are from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 			 * other task before current task, restore them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 			 * from saved fp/msa context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 			write_msa_csr(current->thread.fpu.msacsr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 			 * own_fpu_inatomic(1) just restore low 64bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 			 * fix the high 64bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 			init_msa_upper();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 			set_thread_flag(TIF_USEDMSA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 			set_thread_flag(TIF_MSA_CTX_LIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 		preempt_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 	 * This task has formerly used the FP context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 	 * If this thread has no live MSA vector context then we can simply
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 	 * restore the scalar FP context. If it has live MSA vector context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 	 * (that is, it has or may have used MSA since last performing a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 	 * function call) then we'll need to restore the vector context. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 	 * applies even if we're currently only executing a scalar FP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	 * instruction. This is because if we were to later execute an MSA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	 * instruction then we'd either have to:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	 *  - Restore the vector context & clobber any registers modified by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 	 *    scalar FP instructions between now & then.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	 * or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	 *  - Not restore the vector context & lose the most significant bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 	 *    of all vector registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 	 * Neither of those options is acceptable. We cannot restore the least
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 	 * significant bits of the registers now & only restore the most
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 	 * significant bits later because the most significant bits of any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 	 * vector registers whose aliased FP register is modified now will have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 	 * been zeroed. We'd have no way to know that when restoring the vector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 	 * context & thus may load an outdated value for the most significant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 	 * bits of a vector register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 	if (!msa && !thread_msa_context_live())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 		return own_fpu(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	 * This task is using or has previously used MSA. Thus we require
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	 * that Status.FR == 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 	preempt_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 	was_fpu_owner = is_fpu_owner();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 	err = own_fpu_inatomic(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	enable_msa();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	write_msa_csr(current->thread.fpu.msacsr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	set_thread_flag(TIF_USEDMSA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	 * If this is the first time that the task is using MSA and it has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	 * previously used scalar FP in this time slice then we already nave
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	 * FP context which we shouldn't clobber. We do however need to clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	 * the upper 64b of each vector register so that this task has no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	 * opportunity to see data left behind by another.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 	prior_msa = test_and_set_thread_flag(TIF_MSA_CTX_LIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 	if (!prior_msa && was_fpu_owner) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 		init_msa_upper();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 	if (!prior_msa) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 		 * Restore the least significant 64b of each vector register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 		 * from the existing scalar FP context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 		_restore_fp(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 		 * The task has not formerly used MSA, so clear the upper 64b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 		 * of each vector register such that it cannot see data left
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 		 * behind by another task.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 		init_msa_upper();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 		/* We need to restore the vector context. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 		restore_msa(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 		/* Restore the scalar FP control & status register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 		if (!was_fpu_owner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 			write_32bit_cp1_register(CP1_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 						 current->thread.fpu.fcr31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 	preempt_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) #else /* !CONFIG_MIPS_FP_SUPPORT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) static int enable_restore_fp_context(int msa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 	return SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) #endif /* CONFIG_MIPS_FP_SUPPORT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) asmlinkage void do_cpu(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 	enum ctx_state prev_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 	unsigned int __user *epc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 	unsigned long old_epc, old31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 	unsigned int opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 	unsigned int cpid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 	int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 	prev_state = exception_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 	cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 	if (cpid != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 		die_if_kernel("do_cpu invoked from kernel context!", regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	switch (cpid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 		epc = (unsigned int __user *)exception_epc(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 		old_epc = regs->cp0_epc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 		old31 = regs->regs[31];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 		opcode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 		status = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 		if (unlikely(compute_return_epc(regs) < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 		if (!get_isa16_mode(regs->cp0_epc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 			if (unlikely(get_user(opcode, epc) < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 				status = SIGSEGV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 			if (!cpu_has_llsc && status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 				status = simulate_llsc(regs, opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 		if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 			status = SIGILL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 		if (unlikely(status > 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 			regs->cp0_epc = old_epc;	/* Undo skip-over.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 			regs->regs[31] = old31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 			force_sig(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) #ifdef CONFIG_MIPS_FP_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 	case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 		 * The COP3 opcode space and consequently the CP0.Status.CU3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 		 * bit and the CP0.Cause.CE=3 encoding have been removed as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 		 * of the MIPS III ISA.  From the MIPS IV and MIPS32r2 ISAs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 		 * up the space has been reused for COP1X instructions, that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 		 * are enabled by the CP0.Status.CU1 bit and consequently
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 		 * use the CP0.Cause.CE=1 encoding for Coprocessor Unusable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 		 * exceptions.  Some FPU-less processors that implement one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 		 * of these ISAs however use this code erroneously for COP1X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 		 * instructions.  Therefore we redirect this trap to the FP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 		 * emulator too.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 		if (raw_cpu_has_fpu || !cpu_has_mips_4_5_64_r2_r6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 			force_sig(SIGILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 	case 1: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 		void __user *fault_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 		unsigned long fcr31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 		int err, sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 		err = enable_restore_fp_context(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 		if (raw_cpu_has_fpu && !err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 		sig = fpu_emulator_cop1Handler(regs, &current->thread.fpu, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 					       &fault_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 		 * We can't allow the emulated instruction to leave
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 		 * any enabled Cause bits set in $fcr31.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 		fcr31 = mask_fcr31_x(current->thread.fpu.fcr31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 		current->thread.fpu.fcr31 &= ~fcr31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 		/* Send a signal if required.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 		if (!process_fpemu_return(sig, fault_addr, fcr31) && !err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 			mt_ase_fp_affinity();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) #else /* CONFIG_MIPS_FP_SUPPORT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 	case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 		force_sig(SIGILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) #endif /* CONFIG_MIPS_FP_SUPPORT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 	case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 		raw_notifier_call_chain(&cu2_chain, CU2_EXCEPTION, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 	exception_exit(prev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) asmlinkage void do_msa_fpe(struct pt_regs *regs, unsigned int msacsr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 	enum ctx_state prev_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 	prev_state = exception_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 	current->thread.trap_nr = (regs->cp0_cause >> 2) & 0x1f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 	if (notify_die(DIE_MSAFP, "MSA FP exception", regs, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 		       current->thread.trap_nr, SIGFPE) == NOTIFY_STOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 	/* Clear MSACSR.Cause before enabling interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 	write_msa_csr(msacsr & ~MSA_CSR_CAUSEF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 	local_irq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 	die_if_kernel("do_msa_fpe invoked from kernel context!", regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 	force_sig(SIGFPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 	exception_exit(prev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) asmlinkage void do_msa(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 	enum ctx_state prev_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 	prev_state = exception_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 	if (!cpu_has_msa || test_thread_flag(TIF_32BIT_FPREGS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 		force_sig(SIGILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	die_if_kernel("do_msa invoked from kernel context!", regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 	err = enable_restore_fp_context(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 		force_sig(SIGILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 	exception_exit(prev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) asmlinkage void do_mdmx(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 	enum ctx_state prev_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 	prev_state = exception_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	force_sig(SIGILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 	exception_exit(prev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)  * Called with interrupts disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) asmlinkage void do_watch(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 	enum ctx_state prev_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 	prev_state = exception_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 	 * Clear WP (bit 22) bit of cause register so we don't loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 	 * forever.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 	clear_c0_cause(CAUSEF_WP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 	 * If the current thread has the watch registers loaded, save
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 	 * their values and send SIGTRAP.  Otherwise another thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 	 * left the registers set, clear them and continue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	if (test_tsk_thread_flag(current, TIF_LOAD_WATCH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 		mips_read_watch_registers();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 		local_irq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 		force_sig_fault(SIGTRAP, TRAP_HWBKPT, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 		mips_clear_watch_registers();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 		local_irq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 	exception_exit(prev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) asmlinkage void do_mcheck(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 	int multi_match = regs->cp0_status & ST0_TS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 	enum ctx_state prev_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 	mm_segment_t old_fs = get_fs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 	prev_state = exception_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 	show_regs(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 	if (multi_match) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 		dump_tlb_regs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 		pr_info("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 		dump_tlb_all();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 	if (!user_mode(regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 		set_fs(KERNEL_DS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 	show_code((unsigned int __user *) regs->cp0_epc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 	set_fs(old_fs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 	 * Some chips may have other causes of machine check (e.g. SB1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 	 * graduation timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 	panic("Caught Machine Check exception - %scaused by multiple "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 	      "matching entries in the TLB.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 	      (multi_match) ? "" : "not ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) asmlinkage void do_mt(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 	int subcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 	subcode = (read_vpe_c0_vpecontrol() & VPECONTROL_EXCPT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 			>> VPECONTROL_EXCPT_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 	switch (subcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 		printk(KERN_DEBUG "Thread Underflow\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 		printk(KERN_DEBUG "Thread Overflow\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 	case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 		printk(KERN_DEBUG "Invalid YIELD Qualifier\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 	case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 		printk(KERN_DEBUG "Gating Storage Exception\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 	case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 		printk(KERN_DEBUG "YIELD Scheduler Exception\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 	case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 		printk(KERN_DEBUG "Gating Storage Scheduler Exception\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 		printk(KERN_DEBUG "*** UNKNOWN THREAD EXCEPTION %d ***\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 			subcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 	die_if_kernel("MIPS MT Thread exception in kernel", regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 	force_sig(SIGILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) asmlinkage void do_dsp(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 	if (cpu_has_dsp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 		panic("Unexpected DSP exception");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 	force_sig(SIGILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) asmlinkage void do_reserved(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 	 * Game over - no way to handle this if it ever occurs.	 Most probably
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 	 * caused by a new unknown cpu type or after another deadly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 	 * hard/software error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 	show_regs(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 	panic("Caught reserved exception %ld - should not happen.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 	      (regs->cp0_cause & 0x7f) >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) static int __initdata l1parity = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) static int __init nol1parity(char *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 	l1parity = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) __setup("nol1par", nol1parity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) static int __initdata l2parity = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) static int __init nol2parity(char *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 	l2parity = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) __setup("nol2par", nol2parity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693)  * Some MIPS CPUs can enable/disable for cache parity detection, but do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694)  * it different ways.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) static inline __init void parity_protection_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) #define ERRCTL_PE	0x80000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) #define ERRCTL_L2P	0x00800000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 	if (mips_cm_revision() >= CM_REV_CM3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 		ulong gcr_ectl, cp0_ectl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 		 * With CM3 systems we need to ensure that the L1 & L2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 		 * parity enables are set to the same value, since this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 		 * is presumed by the hardware engineers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 		 * If the user disabled either of L1 or L2 ECC checking,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 		 * disable both.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 		l1parity &= l2parity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 		l2parity &= l1parity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 		/* Probe L1 ECC support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 		cp0_ectl = read_c0_ecc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 		write_c0_ecc(cp0_ectl | ERRCTL_PE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 		back_to_back_c0_hazard();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 		cp0_ectl = read_c0_ecc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 		/* Probe L2 ECC support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 		gcr_ectl = read_gcr_err_control();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 		if (!(gcr_ectl & CM_GCR_ERR_CONTROL_L2_ECC_SUPPORT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 		    !(cp0_ectl & ERRCTL_PE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 			 * One of L1 or L2 ECC checking isn't supported,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 			 * so we cannot enable either.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 			l1parity = l2parity = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 		/* Configure L1 ECC checking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 		if (l1parity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 			cp0_ectl |= ERRCTL_PE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 			cp0_ectl &= ~ERRCTL_PE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 		write_c0_ecc(cp0_ectl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 		back_to_back_c0_hazard();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 		WARN_ON(!!(read_c0_ecc() & ERRCTL_PE) != l1parity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 		/* Configure L2 ECC checking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 		if (l2parity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 			gcr_ectl |= CM_GCR_ERR_CONTROL_L2_ECC_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 			gcr_ectl &= ~CM_GCR_ERR_CONTROL_L2_ECC_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 		write_gcr_err_control(gcr_ectl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 		gcr_ectl = read_gcr_err_control();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 		gcr_ectl &= CM_GCR_ERR_CONTROL_L2_ECC_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 		WARN_ON(!!gcr_ectl != l2parity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 		pr_info("Cache parity protection %sabled\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 			l1parity ? "en" : "dis");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 	switch (current_cpu_type()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 	case CPU_24K:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 	case CPU_34K:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 	case CPU_74K:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 	case CPU_1004K:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 	case CPU_1074K:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 	case CPU_INTERAPTIV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 	case CPU_PROAPTIV:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 	case CPU_P5600:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 	case CPU_QEMU_GENERIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 	case CPU_P6600:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 		{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 			unsigned long errctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 			unsigned int l1parity_present, l2parity_present;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 			errctl = read_c0_ecc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 			errctl &= ~(ERRCTL_PE|ERRCTL_L2P);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 			/* probe L1 parity support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) 			write_c0_ecc(errctl | ERRCTL_PE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 			back_to_back_c0_hazard();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 			l1parity_present = (read_c0_ecc() & ERRCTL_PE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 			/* probe L2 parity support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) 			write_c0_ecc(errctl|ERRCTL_L2P);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 			back_to_back_c0_hazard();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) 			l2parity_present = (read_c0_ecc() & ERRCTL_L2P);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 			if (l1parity_present && l2parity_present) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 				if (l1parity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 					errctl |= ERRCTL_PE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 				if (l1parity ^ l2parity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) 					errctl |= ERRCTL_L2P;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 			} else if (l1parity_present) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 				if (l1parity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 					errctl |= ERRCTL_PE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 			} else if (l2parity_present) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 				if (l2parity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) 					errctl |= ERRCTL_L2P;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 				/* No parity available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 			printk(KERN_INFO "Writing ErrCtl register=%08lx\n", errctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 			write_c0_ecc(errctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) 			back_to_back_c0_hazard();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 			errctl = read_c0_ecc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 			printk(KERN_INFO "Readback ErrCtl register=%08lx\n", errctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 			if (l1parity_present)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 				printk(KERN_INFO "Cache parity protection %sabled\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 				       (errctl & ERRCTL_PE) ? "en" : "dis");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 			if (l2parity_present) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 				if (l1parity_present && l1parity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 					errctl ^= ERRCTL_L2P;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 				printk(KERN_INFO "L2 cache parity protection %sabled\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 				       (errctl & ERRCTL_L2P) ? "en" : "dis");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 	case CPU_5KC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 	case CPU_5KE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 	case CPU_LOONGSON32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 		write_c0_ecc(0x80000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 		back_to_back_c0_hazard();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 		/* Set the PE bit (bit 31) in the c0_errctl register. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 		printk(KERN_INFO "Cache parity protection %sabled\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 		       (read_c0_ecc() & 0x80000000) ? "en" : "dis");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 	case CPU_20KC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 	case CPU_25KF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 		/* Clear the DE bit (bit 16) in the c0_status register. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 		printk(KERN_INFO "Enable cache parity protection for "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 		       "MIPS 20KC/25KF CPUs.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 		clear_c0_status(ST0_DE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) asmlinkage void cache_parity_error(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 	const int field = 2 * sizeof(unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 	unsigned int reg_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 	/* For the moment, report the problem and hang. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 	printk("Cache error exception:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 	printk("cp0_errorepc == %0*lx\n", field, read_c0_errorepc());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 	reg_val = read_c0_cacheerr();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 	printk("c0_cacheerr == %08x\n", reg_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 	printk("Decoded c0_cacheerr: %s cache fault in %s reference.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 	       reg_val & (1<<30) ? "secondary" : "primary",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 	       reg_val & (1<<31) ? "data" : "insn");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 	if ((cpu_has_mips_r2_r6) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 	    ((current_cpu_data.processor_id & 0xff0000) == PRID_COMP_MIPS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 		pr_err("Error bits: %s%s%s%s%s%s%s%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 			reg_val & (1<<29) ? "ED " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 			reg_val & (1<<28) ? "ET " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 			reg_val & (1<<27) ? "ES " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 			reg_val & (1<<26) ? "EE " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 			reg_val & (1<<25) ? "EB " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 			reg_val & (1<<24) ? "EI " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 			reg_val & (1<<23) ? "E1 " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 			reg_val & (1<<22) ? "E0 " : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 		pr_err("Error bits: %s%s%s%s%s%s%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 			reg_val & (1<<29) ? "ED " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 			reg_val & (1<<28) ? "ET " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 			reg_val & (1<<26) ? "EE " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 			reg_val & (1<<25) ? "EB " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 			reg_val & (1<<24) ? "EI " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 			reg_val & (1<<23) ? "E1 " : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 			reg_val & (1<<22) ? "E0 " : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 	printk("IDX: 0x%08x\n", reg_val & ((1<<22)-1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 	if (reg_val & (1<<22))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 		printk("DErrAddr0: 0x%0*lx\n", field, read_c0_derraddr0());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 	if (reg_val & (1<<23))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 		printk("DErrAddr1: 0x%0*lx\n", field, read_c0_derraddr1());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 	panic("Can't handle the cache error!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) asmlinkage void do_ftlb(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 	const int field = 2 * sizeof(unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 	unsigned int reg_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 	/* For the moment, report the problem and hang. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 	if ((cpu_has_mips_r2_r6) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 	    (((current_cpu_data.processor_id & 0xff0000) == PRID_COMP_MIPS) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 	    ((current_cpu_data.processor_id & 0xff0000) == PRID_COMP_LOONGSON))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 		pr_err("FTLB error exception, cp0_ecc=0x%08x:\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 		       read_c0_ecc());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 		pr_err("cp0_errorepc == %0*lx\n", field, read_c0_errorepc());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 		reg_val = read_c0_cacheerr();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 		pr_err("c0_cacheerr == %08x\n", reg_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 		if ((reg_val & 0xc0000000) == 0xc0000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 			pr_err("Decoded c0_cacheerr: FTLB parity error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 			pr_err("Decoded c0_cacheerr: %s cache fault in %s reference.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 			       reg_val & (1<<30) ? "secondary" : "primary",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 			       reg_val & (1<<31) ? "data" : "insn");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 		pr_err("FTLB error exception\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 	/* Just print the cacheerr bits for now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 	cache_parity_error();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) asmlinkage void do_gsexc(struct pt_regs *regs, u32 diag1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 	u32 exccode = (diag1 & LOONGSON_DIAG1_EXCCODE) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 			LOONGSON_DIAG1_EXCCODE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 	enum ctx_state prev_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 	prev_state = exception_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 	switch (exccode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 	case 0x08:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 		/* Undocumented exception, will trigger on certain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 		 * also-undocumented instructions accessible from userspace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 		 * Processor state is not otherwise corrupted, but currently
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 		 * we don't know how to proceed. Maybe there is some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 		 * undocumented control flag to enable the instructions?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 		force_sig(SIGILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 		/* None of the other exceptions, documented or not, have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 		 * further details given; none are encountered in the wild
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 		 * either. Panic in case some of them turn out to be fatal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 		show_regs(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 		panic("Unhandled Loongson exception - GSCause = %08x", diag1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 	exception_exit(prev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950)  * SDBBP EJTAG debug exception handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951)  * We skip the instruction and return to the next instruction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) void ejtag_exception_handler(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 	const int field = 2 * sizeof(unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 	unsigned long depc, old_epc, old_ra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 	unsigned int debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 	printk(KERN_DEBUG "SDBBP EJTAG debug exception - not handled yet, just ignored!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 	depc = read_c0_depc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 	debug = read_c0_debug();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 	printk(KERN_DEBUG "c0_depc = %0*lx, DEBUG = %08x\n", field, depc, debug);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 	if (debug & 0x80000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 		 * In branch delay slot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 		 * We cheat a little bit here and use EPC to calculate the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 		 * debug return address (DEPC). EPC is restored after the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 		 * calculation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 		old_epc = regs->cp0_epc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 		old_ra = regs->regs[31];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 		regs->cp0_epc = depc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 		compute_return_epc(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 		depc = regs->cp0_epc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 		regs->cp0_epc = old_epc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 		regs->regs[31] = old_ra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 		depc += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 	write_c0_depc(depc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 	printk(KERN_DEBUG "\n\n----- Enable EJTAG single stepping ----\n\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 	write_c0_debug(debug | 0x100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988)  * NMI exception handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989)  * No lock; only written during early bootup by CPU 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) static RAW_NOTIFIER_HEAD(nmi_chain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) int register_nmi_notifier(struct notifier_block *nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 	return raw_notifier_chain_register(&nmi_chain, nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) void __noreturn nmi_exception_handler(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 	char str[100];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 	nmi_enter();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 	raw_notifier_call_chain(&nmi_chain, 0, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 	bust_spinlocks(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 	snprintf(str, 100, "CPU%d NMI taken, CP0_EPC=%lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 		 smp_processor_id(), regs->cp0_epc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 	regs->cp0_epc = read_c0_errorepc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 	die(str, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 	nmi_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) #define VECTORSPACING 0x100	/* for EI/VI mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) unsigned long ebase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) EXPORT_SYMBOL_GPL(ebase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) unsigned long exception_handlers[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) unsigned long vi_handlers[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) void __init *set_except_vector(int n, void *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 	unsigned long handler = (unsigned long) addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 	unsigned long old_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) #ifdef CONFIG_CPU_MICROMIPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 	 * Only the TLB handlers are cache aligned with an even
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 	 * address. All other handlers are on an odd address and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 	 * require no modification. Otherwise, MIPS32 mode will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 	 * be entered when handling any TLB exceptions. That
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 	 * would be bad...since we must stay in microMIPS mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 	if (!(handler & 0x1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 		handler |= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 	old_handler = xchg(&exception_handlers[n], handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 	if (n == 0 && cpu_has_divec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) #ifdef CONFIG_CPU_MICROMIPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 		unsigned long jump_mask = ~((1 << 27) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 		unsigned long jump_mask = ~((1 << 28) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) 		u32 *buf = (u32 *)(ebase + 0x200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 		unsigned int k0 = 26;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 		if ((handler & jump_mask) == ((ebase + 0x200) & jump_mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 			uasm_i_j(&buf, handler & ~jump_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 			uasm_i_nop(&buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 			UASM_i_LA(&buf, k0, handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) 			uasm_i_jr(&buf, k0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 			uasm_i_nop(&buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) 		local_flush_icache_range(ebase + 0x200, (unsigned long)buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) 	return (void *)old_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) static void do_default_vi(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) 	show_regs(get_irq_regs());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) 	panic("Caught unexpected vectored interrupt.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 	unsigned long handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 	unsigned long old_handler = vi_handlers[n];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) 	int srssets = current_cpu_data.srsets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 	u16 *h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 	unsigned char *b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 	BUG_ON(!cpu_has_veic && !cpu_has_vint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 	if (addr == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 		handler = (unsigned long) do_default_vi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 		srs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 		handler = (unsigned long) addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 	vi_handlers[n] = handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 	b = (unsigned char *)(ebase + 0x200 + n*VECTORSPACING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 	if (srs >= srssets)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 		panic("Shadow register set %d not supported", srs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 	if (cpu_has_veic) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 		if (board_bind_eic_interrupt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 			board_bind_eic_interrupt(n, srs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 	} else if (cpu_has_vint) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 		/* SRSMap is only defined if shadow sets are implemented */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 		if (srssets > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 			change_c0_srsmap(0xf << n*4, srs << n*4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 	if (srs == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 		 * If no shadow set is selected then use the default handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 		 * that does normal register saving and standard interrupt exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 		extern char except_vec_vi, except_vec_vi_lui;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 		extern char except_vec_vi_ori, except_vec_vi_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 		extern char rollback_except_vec_vi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) 		char *vec_start = using_rollback_handler() ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 			&rollback_except_vec_vi : &except_vec_vi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) #if defined(CONFIG_CPU_MICROMIPS) || defined(CONFIG_CPU_BIG_ENDIAN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 		const int lui_offset = &except_vec_vi_lui - vec_start + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 		const int ori_offset = &except_vec_vi_ori - vec_start + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 		const int lui_offset = &except_vec_vi_lui - vec_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 		const int ori_offset = &except_vec_vi_ori - vec_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) 		const int handler_len = &except_vec_vi_end - vec_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 		if (handler_len > VECTORSPACING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) 			 * Sigh... panicing won't help as the console
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 			 * is probably not configured :(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 			panic("VECTORSPACING too small");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 		set_handler(((unsigned long)b - ebase), vec_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) #ifdef CONFIG_CPU_MICROMIPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 				(handler_len - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 				handler_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) 		h = (u16 *)(b + lui_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 		*h = (handler >> 16) & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) 		h = (u16 *)(b + ori_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) 		*h = (handler & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) 		local_flush_icache_range((unsigned long)b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 					 (unsigned long)(b+handler_len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 		 * In other cases jump directly to the interrupt handler. It
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 		 * is the handler's responsibility to save registers if required
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 		 * (eg hi/lo) and return from the exception using "eret".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 		u32 insn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) 		h = (u16 *)b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 		/* j handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) #ifdef CONFIG_CPU_MICROMIPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 		insn = 0xd4000000 | (((u32)handler & 0x07ffffff) >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 		insn = 0x08000000 | (((u32)handler & 0x0fffffff) >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) 		h[0] = (insn >> 16) & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 		h[1] = insn & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 		h[2] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 		h[3] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 		local_flush_icache_range((unsigned long)b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 					 (unsigned long)(b+8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 	return (void *)old_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) void *set_vi_handler(int n, vi_handler_t addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 	return set_vi_srs_handler(n, addr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) extern void tlb_init(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169)  * Timer interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) int cp0_compare_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) EXPORT_SYMBOL_GPL(cp0_compare_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) int cp0_compare_irq_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176)  * Performance counter IRQ or -1 if shared with timer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) int cp0_perfcount_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) EXPORT_SYMBOL_GPL(cp0_perfcount_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182)  * Fast debug channel IRQ or -1 if not present
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) int cp0_fdc_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) EXPORT_SYMBOL_GPL(cp0_fdc_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) static int noulri;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) static int __init ulri_disable(char *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) 	pr_info("Disabling ulri\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 	noulri = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) __setup("noulri", ulri_disable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) /* configure STATUS register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) static void configure_status(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 	 * Disable coprocessors and select 32-bit or 64-bit addressing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 	 * and the 16/32 or 32/32 FPR register model.  Reset the BEV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 	 * flag that some firmware may have left set and the TS bit (for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 	 * IP27).  Set XX for ISA IV code to work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 	unsigned int status_set = ST0_KERNEL_CUMASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) #ifdef CONFIG_64BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 	status_set |= ST0_FR|ST0_KX|ST0_SX|ST0_UX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 	if (current_cpu_data.isa_level & MIPS_CPU_ISA_IV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 		status_set |= ST0_XX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 	if (cpu_has_dsp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 		status_set |= ST0_MX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 	change_c0_status(ST0_CU|ST0_MX|ST0_RE|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 			 status_set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 	back_to_back_c0_hazard();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) unsigned int hwrena;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) EXPORT_SYMBOL_GPL(hwrena);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) /* configure HWRENA register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) static void configure_hwrena(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) 	hwrena = cpu_hwrena_impl_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) 	if (cpu_has_mips_r2_r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) 		hwrena |= MIPS_HWRENA_CPUNUM |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 			  MIPS_HWRENA_SYNCISTEP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 			  MIPS_HWRENA_CC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 			  MIPS_HWRENA_CCRES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 	if (!noulri && cpu_has_userlocal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 		hwrena |= MIPS_HWRENA_ULR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 	if (hwrena)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 		write_c0_hwrena(hwrena);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) static void configure_exception_vector(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) 	if (cpu_has_mips_r2_r6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) 		unsigned long sr = set_c0_status(ST0_BEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) 		/* If available, use WG to set top bits of EBASE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 		if (cpu_has_ebase_wg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) #ifdef CONFIG_64BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 			write_c0_ebase_64(ebase | MIPS_EBASE_WG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 			write_c0_ebase(ebase | MIPS_EBASE_WG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 		write_c0_ebase(ebase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 		write_c0_status(sr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 	if (cpu_has_veic || cpu_has_vint) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 		/* Setting vector spacing enables EI/VI mode  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 		change_c0_intctl(0x3e0, VECTORSPACING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 	if (cpu_has_divec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 		if (cpu_has_mipsmt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 			unsigned int vpflags = dvpe();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 			set_c0_cause(CAUSEF_IV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 			evpe(vpflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 			set_c0_cause(CAUSEF_IV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) void per_cpu_trap_init(bool is_boot_cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) 	unsigned int cpu = smp_processor_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 	configure_status();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 	configure_hwrena();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) 	configure_exception_vector();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 	 * Before R2 both interrupt numbers were fixed to 7, so on R2 only:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) 	 *  o read IntCtl.IPTI to determine the timer interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) 	 *  o read IntCtl.IPPCI to determine the performance counter interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 	 *  o read IntCtl.IPFDC to determine the fast debug channel interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 	if (cpu_has_mips_r2_r6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 		cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 		cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 		cp0_perfcount_irq = (read_c0_intctl() >> INTCTLB_IPPCI) & 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 		cp0_fdc_irq = (read_c0_intctl() >> INTCTLB_IPFDC) & 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 		if (!cp0_fdc_irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 			cp0_fdc_irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 		cp0_compare_irq = CP0_LEGACY_COMPARE_IRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 		cp0_compare_irq_shift = CP0_LEGACY_PERFCNT_IRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 		cp0_perfcount_irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 		cp0_fdc_irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 	if (cpu_has_mmid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 		cpu_data[cpu].asid_cache = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 	else if (!cpu_data[cpu].asid_cache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 		cpu_data[cpu].asid_cache = asid_first_version(cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 	mmgrab(&init_mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) 	current->active_mm = &init_mm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 	BUG_ON(current->mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 	enter_lazy_tlb(&init_mm, current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 	/* Boot CPU's cache setup in setup_arch(). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 	if (!is_boot_cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 		cpu_cache_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 	tlb_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 	TLBMISS_HANDLER_SETUP();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) /* Install CPU exception handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) void set_handler(unsigned long offset, void *addr, unsigned long size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) #ifdef CONFIG_CPU_MICROMIPS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 	memcpy((void *)(ebase + offset), ((unsigned char *)addr - 1), size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 	memcpy((void *)(ebase + offset), addr, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 	local_flush_icache_range(ebase + offset, ebase + offset + size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) static const char panic_null_cerr[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 	"Trying to set NULL cache error exception handler\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334)  * Install uncached CPU exception handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335)  * This is suitable only for the cache error exception which is the only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336)  * exception handler that is being run uncached.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) void set_uncached_handler(unsigned long offset, void *addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 	unsigned long size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 	unsigned long uncached_ebase = CKSEG1ADDR(ebase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 	if (!addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 		panic(panic_null_cerr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 	memcpy((void *)(uncached_ebase + offset), addr, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) static int __initdata rdhwr_noopt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) static int __init set_rdhwr_noopt(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 	rdhwr_noopt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) __setup("rdhwr_noopt", set_rdhwr_noopt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) void __init trap_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 	extern char except_vec3_generic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 	extern char except_vec4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 	extern char except_vec3_r4000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 	unsigned long i, vec_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 	phys_addr_t ebase_pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 	check_wait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 	if (!cpu_has_mips_r2_r6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 		ebase = CAC_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 		ebase_pa = virt_to_phys((void *)ebase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 		vec_size = 0x400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 		memblock_reserve(ebase_pa, vec_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 		if (cpu_has_veic || cpu_has_vint)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 			vec_size = 0x200 + VECTORSPACING*64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 			vec_size = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 		ebase_pa = memblock_phys_alloc(vec_size, 1 << fls(vec_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 		if (!ebase_pa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 			panic("%s: Failed to allocate %lu bytes align=0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 			      __func__, vec_size, 1 << fls(vec_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) 		 * Try to ensure ebase resides in KSeg0 if possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) 		 * It shouldn't generally be in XKPhys on MIPS64 to avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 		 * hitting a poorly defined exception base for Cache Errors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 		 * The allocation is likely to be in the low 512MB of physical,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 		 * in which case we should be able to convert to KSeg0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 		 * EVA is special though as it allows segments to be rearranged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 		 * and to become uncached during cache error handling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 		if (!IS_ENABLED(CONFIG_EVA) && !WARN_ON(ebase_pa >= 0x20000000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) 			ebase = CKSEG0ADDR(ebase_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 			ebase = (unsigned long)phys_to_virt(ebase_pa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 	if (cpu_has_mmips) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 		unsigned int config3 = read_c0_config3();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 		if (IS_ENABLED(CONFIG_CPU_MICROMIPS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) 			write_c0_config3(config3 | MIPS_CONF3_ISA_OE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 			write_c0_config3(config3 & ~MIPS_CONF3_ISA_OE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 	if (board_ebase_setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 		board_ebase_setup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 	per_cpu_trap_init(true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 	memblock_set_bottom_up(false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 	 * Copy the generic exception handlers to their final destination.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 	 * This will be overridden later as suitable for a particular
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 	 * configuration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 	set_handler(0x180, &except_vec3_generic, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 	 * Setup default vectors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 	for (i = 0; i <= 31; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 		set_except_vector(i, handle_reserved);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 	 * Copy the EJTAG debug exception vector handler code to it's final
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 	 * destination.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 	if (cpu_has_ejtag && board_ejtag_handler_setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) 		board_ejtag_handler_setup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 	 * Only some CPUs have the watch exceptions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 	if (cpu_has_watch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 		set_except_vector(EXCCODE_WATCH, handle_watch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 	 * Initialise interrupt handlers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) 	if (cpu_has_veic || cpu_has_vint) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) 		int nvec = cpu_has_veic ? 64 : 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) 		for (i = 0; i < nvec; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 			set_vi_handler(i, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 	else if (cpu_has_divec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) 		set_handler(0x200, &except_vec4, 0x8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 	 * Some CPUs can enable/disable for cache parity detection, but does
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 	 * it different ways.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 	parity_protection_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 	 * The Data Bus Errors / Instruction Bus Errors are signaled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) 	 * by external hardware.  Therefore these two exceptions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 	 * may have board specific handlers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 	if (board_be_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 		board_be_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 	set_except_vector(EXCCODE_INT, using_rollback_handler() ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 					rollback_handle_int : handle_int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 	set_except_vector(EXCCODE_MOD, handle_tlbm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 	set_except_vector(EXCCODE_TLBL, handle_tlbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 	set_except_vector(EXCCODE_TLBS, handle_tlbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) 	set_except_vector(EXCCODE_ADEL, handle_adel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 	set_except_vector(EXCCODE_ADES, handle_ades);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 	set_except_vector(EXCCODE_IBE, handle_ibe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) 	set_except_vector(EXCCODE_DBE, handle_dbe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 	set_except_vector(EXCCODE_SYS, handle_sys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 	set_except_vector(EXCCODE_BP, handle_bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 	if (rdhwr_noopt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 		set_except_vector(EXCCODE_RI, handle_ri);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) 		if (cpu_has_vtag_icache)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 			set_except_vector(EXCCODE_RI, handle_ri_rdhwr_tlbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) 		else if (current_cpu_type() == CPU_LOONGSON64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 			set_except_vector(EXCCODE_RI, handle_ri_rdhwr_tlbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) 			set_except_vector(EXCCODE_RI, handle_ri_rdhwr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) 	set_except_vector(EXCCODE_CPU, handle_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 	set_except_vector(EXCCODE_OV, handle_ov);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 	set_except_vector(EXCCODE_TR, handle_tr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 	set_except_vector(EXCCODE_MSAFPE, handle_msa_fpe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) 	if (board_nmi_handler_setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 		board_nmi_handler_setup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 	if (cpu_has_fpu && !cpu_has_nofpuex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) 		set_except_vector(EXCCODE_FPE, handle_fpe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 	if (cpu_has_ftlbparex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 		set_except_vector(MIPS_EXCCODE_TLBPAR, handle_ftlb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 	if (cpu_has_gsexcex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 		set_except_vector(LOONGSON_EXCCODE_GSEXC, handle_gsexc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 	if (cpu_has_rixiex) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 		set_except_vector(EXCCODE_TLBRI, tlb_do_page_fault_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 		set_except_vector(EXCCODE_TLBXI, tlb_do_page_fault_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 	set_except_vector(EXCCODE_MSADIS, handle_msa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 	set_except_vector(EXCCODE_MDMX, handle_mdmx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 	if (cpu_has_mcheck)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 		set_except_vector(EXCCODE_MCHECK, handle_mcheck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 	if (cpu_has_mipsmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) 		set_except_vector(EXCCODE_THREAD, handle_mt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 	set_except_vector(EXCCODE_DSPDIS, handle_dsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 	if (board_cache_error_setup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 		board_cache_error_setup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 	if (cpu_has_vce)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 		/* Special exception: R4[04]00 uses also the divec space. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 		set_handler(0x180, &except_vec3_r4000, 0x100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 	else if (cpu_has_4kex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 		set_handler(0x180, &except_vec3_generic, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 		set_handler(0x080, &except_vec3_generic, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 	local_flush_icache_range(ebase, ebase + vec_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 	sort_extable(__start___dbe_table, __stop___dbe_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 	cu2_notifier(default_cu2_call, 0x80000000);	/* Run last  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) static int trap_pm_notifier(struct notifier_block *self, unsigned long cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 			    void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 	case CPU_PM_ENTER_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 	case CPU_PM_EXIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 		configure_status();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 		configure_hwrena();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 		configure_exception_vector();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 		/* Restore register with CPU number for TLB handlers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 		TLBMISS_HANDLER_RESTORE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 	return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) static struct notifier_block trap_pm_notifier_block = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 	.notifier_call = trap_pm_notifier,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) static int __init trap_pm_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 	return cpu_pm_register_notifier(&trap_pm_notifier_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) arch_initcall(trap_pm_init);