diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2015-02-19 10:00:34 -0500 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2015-02-19 10:00:34 -0500 |
commit | 661af35e5fd878f915ed05dbbfe383f64133f98c (patch) | |
tree | 956b7efd662b682224e61060552fdcf4201101bf /arch/mips/kernel/traps.c | |
parent | ca5d25642e212f73492d332d95dc90ef46a0e8dc (diff) | |
parent | f296e7c48d3155991b99f41372e1786c5be03457 (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.c | 41 |
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 | ||
840 | static void do_trap_or_bp(struct pt_regs *regs, unsigned int code, | 841 | void 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 | ¤t->thread.cp0_baduaddr); | ||
1049 | task_thread_info(current)->r2_emul_return = 1; | ||
1050 | return; | ||
1051 | } | ||
1052 | } | ||
1053 | } | ||
1054 | |||
1055 | no_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 | ||