aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/traps.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2015-02-19 10:00:34 -0500
committerRalf Baechle <ralf@linux-mips.org>2015-02-19 10:00:34 -0500
commit661af35e5fd878f915ed05dbbfe383f64133f98c (patch)
tree956b7efd662b682224e61060552fdcf4201101bf /arch/mips/kernel/traps.c
parentca5d25642e212f73492d332d95dc90ef46a0e8dc (diff)
parentf296e7c48d3155991b99f41372e1786c5be03457 (diff)
Merge branch 'mipsr6-for-3.20' of git://git.linux-mips.org/pub/scm/mchandras/linux into mips-for-linux-next
Diffstat (limited to 'arch/mips/kernel/traps.c')
-rw-r--r--arch/mips/kernel/traps.c41
1 files changed, 35 insertions, 6 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index d5fbfb51b9da..afa447e5e97f 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -46,6 +46,7 @@
46#include <asm/fpu.h> 46#include <asm/fpu.h>
47#include <asm/fpu_emulator.h> 47#include <asm/fpu_emulator.h>
48#include <asm/idle.h> 48#include <asm/idle.h>
49#include <asm/mips-r2-to-r6-emul.h>
49#include <asm/mipsregs.h> 50#include <asm/mipsregs.h>
50#include <asm/mipsmtregs.h> 51#include <asm/mipsmtregs.h>
51#include <asm/module.h> 52#include <asm/module.h>
@@ -837,7 +838,7 @@ out:
837 exception_exit(prev_state); 838 exception_exit(prev_state);
838} 839}
839 840
840static void do_trap_or_bp(struct pt_regs *regs, unsigned int code, 841void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
841 const char *str) 842 const char *str)
842{ 843{
843 siginfo_t info; 844 siginfo_t info;
@@ -1027,7 +1028,34 @@ asmlinkage void do_ri(struct pt_regs *regs)
1027 unsigned int opcode = 0; 1028 unsigned int opcode = 0;
1028 int status = -1; 1029 int status = -1;
1029 1030
1031 /*
1032 * Avoid any kernel code. Just emulate the R2 instruction
1033 * as quickly as possible.
1034 */
1035 if (mipsr2_emulation && cpu_has_mips_r6 &&
1036 likely(user_mode(regs))) {
1037 if (likely(get_user(opcode, epc) >= 0)) {
1038 status = mipsr2_decoder(regs, opcode);
1039 switch (status) {
1040 case 0:
1041 case SIGEMT:
1042 task_thread_info(current)->r2_emul_return = 1;
1043 return;
1044 case SIGILL:
1045 goto no_r2_instr;
1046 default:
1047 process_fpemu_return(status,
1048 &current->thread.cp0_baduaddr);
1049 task_thread_info(current)->r2_emul_return = 1;
1050 return;
1051 }
1052 }
1053 }
1054
1055no_r2_instr:
1056
1030 prev_state = exception_enter(); 1057 prev_state = exception_enter();
1058
1031 if (notify_die(DIE_RI, "RI Fault", regs, 0, regs_to_trapnr(regs), 1059 if (notify_die(DIE_RI, "RI Fault", regs, 0, regs_to_trapnr(regs),
1032 SIGILL) == NOTIFY_STOP) 1060 SIGILL) == NOTIFY_STOP)
1033 goto out; 1061 goto out;
@@ -1559,6 +1587,7 @@ static inline void parity_protection_init(void)
1559 case CPU_INTERAPTIV: 1587 case CPU_INTERAPTIV:
1560 case CPU_PROAPTIV: 1588 case CPU_PROAPTIV:
1561 case CPU_P5600: 1589 case CPU_P5600:
1590 case CPU_QEMU_GENERIC:
1562 { 1591 {
1563#define ERRCTL_PE 0x80000000 1592#define ERRCTL_PE 0x80000000
1564#define ERRCTL_L2P 0x00800000 1593#define ERRCTL_L2P 0x00800000
@@ -1648,7 +1677,7 @@ asmlinkage void cache_parity_error(void)
1648 printk("Decoded c0_cacheerr: %s cache fault in %s reference.\n", 1677 printk("Decoded c0_cacheerr: %s cache fault in %s reference.\n",
1649 reg_val & (1<<30) ? "secondary" : "primary", 1678 reg_val & (1<<30) ? "secondary" : "primary",
1650 reg_val & (1<<31) ? "data" : "insn"); 1679 reg_val & (1<<31) ? "data" : "insn");
1651 if (cpu_has_mips_r2 && 1680 if ((cpu_has_mips_r2_r6) &&
1652 ((current_cpu_data.processor_id & 0xff0000) == PRID_COMP_MIPS)) { 1681 ((current_cpu_data.processor_id & 0xff0000) == PRID_COMP_MIPS)) {
1653 pr_err("Error bits: %s%s%s%s%s%s%s%s\n", 1682 pr_err("Error bits: %s%s%s%s%s%s%s%s\n",
1654 reg_val & (1<<29) ? "ED " : "", 1683 reg_val & (1<<29) ? "ED " : "",
@@ -1688,7 +1717,7 @@ asmlinkage void do_ftlb(void)
1688 unsigned int reg_val; 1717 unsigned int reg_val;
1689 1718
1690 /* For the moment, report the problem and hang. */ 1719 /* For the moment, report the problem and hang. */
1691 if (cpu_has_mips_r2 && 1720 if ((cpu_has_mips_r2_r6) &&
1692 ((current_cpu_data.processor_id & 0xff0000) == PRID_COMP_MIPS)) { 1721 ((current_cpu_data.processor_id & 0xff0000) == PRID_COMP_MIPS)) {
1693 pr_err("FTLB error exception, cp0_ecc=0x%08x:\n", 1722 pr_err("FTLB error exception, cp0_ecc=0x%08x:\n",
1694 read_c0_ecc()); 1723 read_c0_ecc());
@@ -1977,7 +2006,7 @@ static void configure_hwrena(void)
1977{ 2006{
1978 unsigned int hwrena = cpu_hwrena_impl_bits; 2007 unsigned int hwrena = cpu_hwrena_impl_bits;
1979 2008
1980 if (cpu_has_mips_r2) 2009 if (cpu_has_mips_r2_r6)
1981 hwrena |= 0x0000000f; 2010 hwrena |= 0x0000000f;
1982 2011
1983 if (!noulri && cpu_has_userlocal) 2012 if (!noulri && cpu_has_userlocal)
@@ -2021,7 +2050,7 @@ void per_cpu_trap_init(bool is_boot_cpu)
2021 * o read IntCtl.IPTI to determine the timer interrupt 2050 * o read IntCtl.IPTI to determine the timer interrupt
2022 * o read IntCtl.IPPCI to determine the performance counter interrupt 2051 * o read IntCtl.IPPCI to determine the performance counter interrupt
2023 */ 2052 */
2024 if (cpu_has_mips_r2) { 2053 if (cpu_has_mips_r2_r6) {
2025 cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP; 2054 cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP;
2026 cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7; 2055 cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7;
2027 cp0_perfcount_irq = (read_c0_intctl() >> INTCTLB_IPPCI) & 7; 2056 cp0_perfcount_irq = (read_c0_intctl() >> INTCTLB_IPPCI) & 7;
@@ -2112,7 +2141,7 @@ void __init trap_init(void)
2112#else 2141#else
2113 ebase = CKSEG0; 2142 ebase = CKSEG0;
2114#endif 2143#endif
2115 if (cpu_has_mips_r2) 2144 if (cpu_has_mips_r2_r6)
2116 ebase += (read_c0_ebase() & 0x3ffff000); 2145 ebase += (read_c0_ebase() & 0x3ffff000);
2117 } 2146 }
2118 2147