diff options
Diffstat (limited to 'arch/mips/kernel/traps.c')
-rw-r--r-- | arch/mips/kernel/traps.c | 49 |
1 files changed, 33 insertions, 16 deletions
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index b3ecd02757cb..9419a3542c24 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <asm/branch.h> | 25 | #include <asm/branch.h> |
26 | #include <asm/break.h> | 26 | #include <asm/break.h> |
27 | #include <asm/cpu.h> | 27 | #include <asm/cpu.h> |
28 | #include <asm/dsp.h> | ||
28 | #include <asm/fpu.h> | 29 | #include <asm/fpu.h> |
29 | #include <asm/module.h> | 30 | #include <asm/module.h> |
30 | #include <asm/pgtable.h> | 31 | #include <asm/pgtable.h> |
@@ -54,6 +55,7 @@ extern asmlinkage void handle_tr(void); | |||
54 | extern asmlinkage void handle_fpe(void); | 55 | extern asmlinkage void handle_fpe(void); |
55 | extern asmlinkage void handle_mdmx(void); | 56 | extern asmlinkage void handle_mdmx(void); |
56 | extern asmlinkage void handle_watch(void); | 57 | extern asmlinkage void handle_watch(void); |
58 | extern asmlinkage void handle_dsp(void); | ||
57 | extern asmlinkage void handle_mcheck(void); | 59 | extern asmlinkage void handle_mcheck(void); |
58 | extern asmlinkage void handle_reserved(void); | 60 | extern asmlinkage void handle_reserved(void); |
59 | 61 | ||
@@ -775,6 +777,14 @@ asmlinkage void do_mcheck(struct pt_regs *regs) | |||
775 | (regs->cp0_status & ST0_TS) ? "" : "not "); | 777 | (regs->cp0_status & ST0_TS) ? "" : "not "); |
776 | } | 778 | } |
777 | 779 | ||
780 | asmlinkage void do_dsp(struct pt_regs *regs) | ||
781 | { | ||
782 | if (cpu_has_dsp) | ||
783 | panic("Unexpected DSP exception\n"); | ||
784 | |||
785 | force_sig(SIGILL, current); | ||
786 | } | ||
787 | |||
778 | asmlinkage void do_reserved(struct pt_regs *regs) | 788 | asmlinkage void do_reserved(struct pt_regs *regs) |
779 | { | 789 | { |
780 | /* | 790 | /* |
@@ -984,9 +994,12 @@ void __init per_cpu_trap_init(void) | |||
984 | #endif | 994 | #endif |
985 | if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV) | 995 | if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV) |
986 | status_set |= ST0_XX; | 996 | status_set |= ST0_XX; |
987 | change_c0_status(ST0_CU|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX, | 997 | change_c0_status(ST0_CU|ST0_MX|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX, |
988 | status_set); | 998 | status_set); |
989 | 999 | ||
1000 | if (cpu_has_dsp) | ||
1001 | set_c0_status(ST0_MX); | ||
1002 | |||
990 | /* | 1003 | /* |
991 | * Some MIPS CPUs have a dedicated interrupt vector which reduces the | 1004 | * Some MIPS CPUs have a dedicated interrupt vector which reduces the |
992 | * interrupt processing overhead. Use it where available. | 1005 | * interrupt processing overhead. Use it where available. |
@@ -1078,21 +1091,6 @@ void __init trap_init(void) | |||
1078 | set_except_vector(11, handle_cpu); | 1091 | set_except_vector(11, handle_cpu); |
1079 | set_except_vector(12, handle_ov); | 1092 | set_except_vector(12, handle_ov); |
1080 | set_except_vector(13, handle_tr); | 1093 | set_except_vector(13, handle_tr); |
1081 | set_except_vector(22, handle_mdmx); | ||
1082 | |||
1083 | if (cpu_has_fpu && !cpu_has_nofpuex) | ||
1084 | set_except_vector(15, handle_fpe); | ||
1085 | |||
1086 | if (cpu_has_mcheck) | ||
1087 | set_except_vector(24, handle_mcheck); | ||
1088 | |||
1089 | if (cpu_has_vce) | ||
1090 | /* Special exception: R4[04]00 uses also the divec space. */ | ||
1091 | memcpy((void *)(CAC_BASE + 0x180), &except_vec3_r4000, 0x100); | ||
1092 | else if (cpu_has_4kex) | ||
1093 | memcpy((void *)(CAC_BASE + 0x180), &except_vec3_generic, 0x80); | ||
1094 | else | ||
1095 | memcpy((void *)(CAC_BASE + 0x080), &except_vec3_generic, 0x80); | ||
1096 | 1094 | ||
1097 | if (current_cpu_data.cputype == CPU_R6000 || | 1095 | if (current_cpu_data.cputype == CPU_R6000 || |
1098 | current_cpu_data.cputype == CPU_R6000A) { | 1096 | current_cpu_data.cputype == CPU_R6000A) { |
@@ -1108,6 +1106,25 @@ void __init trap_init(void) | |||
1108 | //set_except_vector(15, handle_ndc); | 1106 | //set_except_vector(15, handle_ndc); |
1109 | } | 1107 | } |
1110 | 1108 | ||
1109 | if (cpu_has_fpu && !cpu_has_nofpuex) | ||
1110 | set_except_vector(15, handle_fpe); | ||
1111 | |||
1112 | set_except_vector(22, handle_mdmx); | ||
1113 | |||
1114 | if (cpu_has_mcheck) | ||
1115 | set_except_vector(24, handle_mcheck); | ||
1116 | |||
1117 | if (cpu_has_dsp) | ||
1118 | set_except_vector(26, handle_dsp); | ||
1119 | |||
1120 | if (cpu_has_vce) | ||
1121 | /* Special exception: R4[04]00 uses also the divec space. */ | ||
1122 | memcpy((void *)(CAC_BASE + 0x180), &except_vec3_r4000, 0x100); | ||
1123 | else if (cpu_has_4kex) | ||
1124 | memcpy((void *)(CAC_BASE + 0x180), &except_vec3_generic, 0x80); | ||
1125 | else | ||
1126 | memcpy((void *)(CAC_BASE + 0x080), &except_vec3_generic, 0x80); | ||
1127 | |||
1111 | signal_init(); | 1128 | signal_init(); |
1112 | #ifdef CONFIG_MIPS32_COMPAT | 1129 | #ifdef CONFIG_MIPS32_COMPAT |
1113 | signal32_init(); | 1130 | signal32_init(); |