aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/traps.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/traps.c')
-rw-r--r--arch/mips/kernel/traps.c71
1 files changed, 58 insertions, 13 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index f9c8746be8d6..e0b499694d18 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -78,6 +78,7 @@ extern asmlinkage void handle_cpu(void);
78extern asmlinkage void handle_ov(void); 78extern asmlinkage void handle_ov(void);
79extern asmlinkage void handle_tr(void); 79extern asmlinkage void handle_tr(void);
80extern asmlinkage void handle_fpe(void); 80extern asmlinkage void handle_fpe(void);
81extern asmlinkage void handle_ftlb(void);
81extern asmlinkage void handle_mdmx(void); 82extern asmlinkage void handle_mdmx(void);
82extern asmlinkage void handle_watch(void); 83extern asmlinkage void handle_watch(void);
83extern asmlinkage void handle_mt(void); 84extern asmlinkage void handle_mt(void);
@@ -1080,7 +1081,7 @@ asmlinkage void do_cpu(struct pt_regs *regs)
1080 unsigned long old_epc, old31; 1081 unsigned long old_epc, old31;
1081 unsigned int opcode; 1082 unsigned int opcode;
1082 unsigned int cpid; 1083 unsigned int cpid;
1083 int status; 1084 int status, err;
1084 unsigned long __maybe_unused flags; 1085 unsigned long __maybe_unused flags;
1085 1086
1086 prev_state = exception_enter(); 1087 prev_state = exception_enter();
@@ -1153,19 +1154,19 @@ asmlinkage void do_cpu(struct pt_regs *regs)
1153 1154
1154 case 1: 1155 case 1:
1155 if (used_math()) /* Using the FPU again. */ 1156 if (used_math()) /* Using the FPU again. */
1156 own_fpu(1); 1157 err = own_fpu(1);
1157 else { /* First time FPU user. */ 1158 else { /* First time FPU user. */
1158 init_fpu(); 1159 err = init_fpu();
1159 set_used_math(); 1160 set_used_math();
1160 } 1161 }
1161 1162
1162 if (!raw_cpu_has_fpu) { 1163 if (!raw_cpu_has_fpu || err) {
1163 int sig; 1164 int sig;
1164 void __user *fault_addr = NULL; 1165 void __user *fault_addr = NULL;
1165 sig = fpu_emulator_cop1Handler(regs, 1166 sig = fpu_emulator_cop1Handler(regs,
1166 &current->thread.fpu, 1167 &current->thread.fpu,
1167 0, &fault_addr); 1168 0, &fault_addr);
1168 if (!process_fpemu_return(sig, fault_addr)) 1169 if (!process_fpemu_return(sig, fault_addr) && !err)
1169 mt_ase_fp_affinity(); 1170 mt_ase_fp_affinity();
1170 } 1171 }
1171 1172
@@ -1336,6 +1337,8 @@ static inline void parity_protection_init(void)
1336 case CPU_34K: 1337 case CPU_34K:
1337 case CPU_74K: 1338 case CPU_74K:
1338 case CPU_1004K: 1339 case CPU_1004K:
1340 case CPU_INTERAPTIV:
1341 case CPU_PROAPTIV:
1339 { 1342 {
1340#define ERRCTL_PE 0x80000000 1343#define ERRCTL_PE 0x80000000
1341#define ERRCTL_L2P 0x00800000 1344#define ERRCTL_L2P 0x00800000
@@ -1425,14 +1428,27 @@ asmlinkage void cache_parity_error(void)
1425 printk("Decoded c0_cacheerr: %s cache fault in %s reference.\n", 1428 printk("Decoded c0_cacheerr: %s cache fault in %s reference.\n",
1426 reg_val & (1<<30) ? "secondary" : "primary", 1429 reg_val & (1<<30) ? "secondary" : "primary",
1427 reg_val & (1<<31) ? "data" : "insn"); 1430 reg_val & (1<<31) ? "data" : "insn");
1428 printk("Error bits: %s%s%s%s%s%s%s\n", 1431 if (cpu_has_mips_r2 &&
1429 reg_val & (1<<29) ? "ED " : "", 1432 ((current_cpu_data.processor_id && 0xff0000) == PRID_COMP_MIPS)) {
1430 reg_val & (1<<28) ? "ET " : "", 1433 pr_err("Error bits: %s%s%s%s%s%s%s%s\n",
1431 reg_val & (1<<26) ? "EE " : "", 1434 reg_val & (1<<29) ? "ED " : "",
1432 reg_val & (1<<25) ? "EB " : "", 1435 reg_val & (1<<28) ? "ET " : "",
1433 reg_val & (1<<24) ? "EI " : "", 1436 reg_val & (1<<27) ? "ES " : "",
1434 reg_val & (1<<23) ? "E1 " : "", 1437 reg_val & (1<<26) ? "EE " : "",
1435 reg_val & (1<<22) ? "E0 " : ""); 1438 reg_val & (1<<25) ? "EB " : "",
1439 reg_val & (1<<24) ? "EI " : "",
1440 reg_val & (1<<23) ? "E1 " : "",
1441 reg_val & (1<<22) ? "E0 " : "");
1442 } else {
1443 pr_err("Error bits: %s%s%s%s%s%s%s\n",
1444 reg_val & (1<<29) ? "ED " : "",
1445 reg_val & (1<<28) ? "ET " : "",
1446 reg_val & (1<<26) ? "EE " : "",
1447 reg_val & (1<<25) ? "EB " : "",
1448 reg_val & (1<<24) ? "EI " : "",
1449 reg_val & (1<<23) ? "E1 " : "",
1450 reg_val & (1<<22) ? "E0 " : "");
1451 }
1436 printk("IDX: 0x%08x\n", reg_val & ((1<<22)-1)); 1452 printk("IDX: 0x%08x\n", reg_val & ((1<<22)-1));
1437 1453
1438#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) 1454#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
@@ -1446,6 +1462,34 @@ asmlinkage void cache_parity_error(void)
1446 panic("Can't handle the cache error!"); 1462 panic("Can't handle the cache error!");
1447} 1463}
1448 1464
1465asmlinkage void do_ftlb(void)
1466{
1467 const int field = 2 * sizeof(unsigned long);
1468 unsigned int reg_val;
1469
1470 /* For the moment, report the problem and hang. */
1471 if (cpu_has_mips_r2 &&
1472 ((current_cpu_data.processor_id && 0xff0000) == PRID_COMP_MIPS)) {
1473 pr_err("FTLB error exception, cp0_ecc=0x%08x:\n",
1474 read_c0_ecc());
1475 pr_err("cp0_errorepc == %0*lx\n", field, read_c0_errorepc());
1476 reg_val = read_c0_cacheerr();
1477 pr_err("c0_cacheerr == %08x\n", reg_val);
1478
1479 if ((reg_val & 0xc0000000) == 0xc0000000) {
1480 pr_err("Decoded c0_cacheerr: FTLB parity error\n");
1481 } else {
1482 pr_err("Decoded c0_cacheerr: %s cache fault in %s reference.\n",
1483 reg_val & (1<<30) ? "secondary" : "primary",
1484 reg_val & (1<<31) ? "data" : "insn");
1485 }
1486 } else {
1487 pr_err("FTLB error exception\n");
1488 }
1489 /* Just print the cacheerr bits for now */
1490 cache_parity_error();
1491}
1492
1449/* 1493/*
1450 * SDBBP EJTAG debug exception handler. 1494 * SDBBP EJTAG debug exception handler.
1451 * We skip the instruction and return to the next instruction. 1495 * We skip the instruction and return to the next instruction.
@@ -1995,6 +2039,7 @@ void __init trap_init(void)
1995 if (cpu_has_fpu && !cpu_has_nofpuex) 2039 if (cpu_has_fpu && !cpu_has_nofpuex)
1996 set_except_vector(15, handle_fpe); 2040 set_except_vector(15, handle_fpe);
1997 2041
2042 set_except_vector(16, handle_ftlb);
1998 set_except_vector(22, handle_mdmx); 2043 set_except_vector(22, handle_mdmx);
1999 2044
2000 if (cpu_has_mcheck) 2045 if (cpu_has_mcheck)