diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2005-05-31 07:49:19 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2005-10-29 14:31:17 -0400 |
commit | e50c0a8fa60da9ac0e0a70caa8a3a803815c1f2f (patch) | |
tree | 1928e8b0a4b7fb615e5a9f65dc934ba2e74cb9cd /arch/mips | |
parent | 10f650db1bcc193ea07d4f8c2f07315da38ea0c4 (diff) |
Support the MIPS32 / MIPS64 DSP ASE.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/kernel/asm-offsets.c | 26 | ||||
-rw-r--r-- | arch/mips/kernel/branch.c | 19 | ||||
-rw-r--r-- | arch/mips/kernel/cpu-probe.c | 3 | ||||
-rw-r--r-- | arch/mips/kernel/genex.S | 1 | ||||
-rw-r--r-- | arch/mips/kernel/process.c | 58 | ||||
-rw-r--r-- | arch/mips/kernel/ptrace.c | 38 | ||||
-rw-r--r-- | arch/mips/kernel/ptrace32.c | 38 | ||||
-rw-r--r-- | arch/mips/kernel/r4k_fpu.S | 5 | ||||
-rw-r--r-- | arch/mips/kernel/scall32-o32.S | 2 | ||||
-rw-r--r-- | arch/mips/kernel/setup.c | 9 | ||||
-rw-r--r-- | arch/mips/kernel/signal-common.h | 56 | ||||
-rw-r--r-- | arch/mips/kernel/signal.c | 52 | ||||
-rw-r--r-- | arch/mips/kernel/signal32.c | 34 | ||||
-rw-r--r-- | arch/mips/kernel/traps.c | 49 |
14 files changed, 308 insertions, 82 deletions
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index af69cdbdd50e..ca6b03c773be 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c | |||
@@ -95,7 +95,7 @@ void output_thread_info_defines(void) | |||
95 | offset("#define TI_PRE_COUNT ", struct thread_info, preempt_count); | 95 | offset("#define TI_PRE_COUNT ", struct thread_info, preempt_count); |
96 | offset("#define TI_ADDR_LIMIT ", struct thread_info, addr_limit); | 96 | offset("#define TI_ADDR_LIMIT ", struct thread_info, addr_limit); |
97 | offset("#define TI_RESTART_BLOCK ", struct thread_info, restart_block); | 97 | offset("#define TI_RESTART_BLOCK ", struct thread_info, restart_block); |
98 | offset("#define TI_TP_VALUE ", struct thread_info, tp_value); | 98 | offset("#define TI_TP_VALUE ", struct thread_info, tp_value); |
99 | constant("#define _THREAD_SIZE_ORDER ", THREAD_SIZE_ORDER); | 99 | constant("#define _THREAD_SIZE_ORDER ", THREAD_SIZE_ORDER); |
100 | constant("#define _THREAD_SIZE ", THREAD_SIZE); | 100 | constant("#define _THREAD_SIZE ", THREAD_SIZE); |
101 | constant("#define _THREAD_MASK ", THREAD_MASK); | 101 | constant("#define _THREAD_MASK ", THREAD_MASK); |
@@ -241,6 +241,7 @@ void output_mm_defines(void) | |||
241 | linefeed; | 241 | linefeed; |
242 | } | 242 | } |
243 | 243 | ||
244 | #ifdef CONFIG_32BIT | ||
244 | void output_sc_defines(void) | 245 | void output_sc_defines(void) |
245 | { | 246 | { |
246 | text("/* Linux sigcontext offsets. */"); | 247 | text("/* Linux sigcontext offsets. */"); |
@@ -252,10 +253,29 @@ void output_sc_defines(void) | |||
252 | offset("#define SC_STATUS ", struct sigcontext, sc_status); | 253 | offset("#define SC_STATUS ", struct sigcontext, sc_status); |
253 | offset("#define SC_FPC_CSR ", struct sigcontext, sc_fpc_csr); | 254 | offset("#define SC_FPC_CSR ", struct sigcontext, sc_fpc_csr); |
254 | offset("#define SC_FPC_EIR ", struct sigcontext, sc_fpc_eir); | 255 | offset("#define SC_FPC_EIR ", struct sigcontext, sc_fpc_eir); |
255 | offset("#define SC_CAUSE ", struct sigcontext, sc_cause); | 256 | offset("#define SC_HI1 ", struct sigcontext, sc_hi1); |
256 | offset("#define SC_BADVADDR ", struct sigcontext, sc_badvaddr); | 257 | offset("#define SC_LO1 ", struct sigcontext, sc_lo1); |
258 | offset("#define SC_HI2 ", struct sigcontext, sc_hi2); | ||
259 | offset("#define SC_LO2 ", struct sigcontext, sc_lo2); | ||
260 | offset("#define SC_HI3 ", struct sigcontext, sc_hi3); | ||
261 | offset("#define SC_LO3 ", struct sigcontext, sc_lo3); | ||
257 | linefeed; | 262 | linefeed; |
258 | } | 263 | } |
264 | #endif | ||
265 | |||
266 | #ifdef CONFIG_64BIT | ||
267 | void output_sc_defines(void) | ||
268 | { | ||
269 | text("/* Linux sigcontext offsets. */"); | ||
270 | offset("#define SC_REGS ", struct sigcontext, sc_regs); | ||
271 | offset("#define SC_FPREGS ", struct sigcontext, sc_fpregs); | ||
272 | offset("#define SC_MDHI ", struct sigcontext, sc_hi); | ||
273 | offset("#define SC_MDLO ", struct sigcontext, sc_lo); | ||
274 | offset("#define SC_PC ", struct sigcontext, sc_pc); | ||
275 | offset("#define SC_FPC_CSR ", struct sigcontext, sc_fpc_csr); | ||
276 | linefeed; | ||
277 | } | ||
278 | #endif | ||
259 | 279 | ||
260 | #ifdef CONFIG_MIPS32_COMPAT | 280 | #ifdef CONFIG_MIPS32_COMPAT |
261 | void output_sc32_defines(void) | 281 | void output_sc32_defines(void) |
diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c index 56aea5f526a7..374de839558d 100644 --- a/arch/mips/kernel/branch.c +++ b/arch/mips/kernel/branch.c | |||
@@ -22,7 +22,7 @@ | |||
22 | */ | 22 | */ |
23 | int __compute_return_epc(struct pt_regs *regs) | 23 | int __compute_return_epc(struct pt_regs *regs) |
24 | { | 24 | { |
25 | unsigned int *addr, bit, fcr31; | 25 | unsigned int *addr, bit, fcr31, dspcontrol; |
26 | long epc; | 26 | long epc; |
27 | union mips_instruction insn; | 27 | union mips_instruction insn; |
28 | 28 | ||
@@ -99,6 +99,18 @@ int __compute_return_epc(struct pt_regs *regs) | |||
99 | epc += 8; | 99 | epc += 8; |
100 | regs->cp0_epc = epc; | 100 | regs->cp0_epc = epc; |
101 | break; | 101 | break; |
102 | case bposge32_op: | ||
103 | if (!cpu_has_dsp) | ||
104 | goto sigill; | ||
105 | |||
106 | dspcontrol = rddsp(0x01); | ||
107 | |||
108 | if (dspcontrol >= 32) { | ||
109 | epc = epc + 4 + (insn.i_format.simmediate << 2); | ||
110 | } else | ||
111 | epc += 8; | ||
112 | regs->cp0_epc = epc; | ||
113 | break; | ||
102 | } | 114 | } |
103 | break; | 115 | break; |
104 | 116 | ||
@@ -200,4 +212,9 @@ unaligned: | |||
200 | printk("%s: unaligned epc - sending SIGBUS.\n", current->comm); | 212 | printk("%s: unaligned epc - sending SIGBUS.\n", current->comm); |
201 | force_sig(SIGBUS, current); | 213 | force_sig(SIGBUS, current); |
202 | return -EFAULT; | 214 | return -EFAULT; |
215 | |||
216 | sigill: | ||
217 | printk("%s: DSP branch but not DSP ASE - sending SIGBUS.\n", current->comm); | ||
218 | force_sig(SIGBUS, current); | ||
219 | return -EFAULT; | ||
203 | } | 220 | } |
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 552d2b6c191e..1ae7762fd084 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
@@ -482,6 +482,8 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c) | |||
482 | 482 | ||
483 | if (config3 & MIPS_CONF3_SM) | 483 | if (config3 & MIPS_CONF3_SM) |
484 | c->ases |= MIPS_ASE_SMARTMIPS; | 484 | c->ases |= MIPS_ASE_SMARTMIPS; |
485 | if (config3 & MIPS_CONF3_DSP) | ||
486 | c->ases |= MIPS_ASE_DSP; | ||
485 | 487 | ||
486 | return config3 & MIPS_CONF_M; | 488 | return config3 & MIPS_CONF_M; |
487 | } | 489 | } |
@@ -529,6 +531,7 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c) | |||
529 | c->cputype = CPU_20KC; | 531 | c->cputype = CPU_20KC; |
530 | break; | 532 | break; |
531 | case PRID_IMP_24K: | 533 | case PRID_IMP_24K: |
534 | case PRID_IMP_24KE: | ||
532 | c->cputype = CPU_24K; | 535 | c->cputype = CPU_24K; |
533 | break; | 536 | break; |
534 | case PRID_IMP_25KF: | 537 | case PRID_IMP_25KF: |
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index e5021c758ef0..349ec301168f 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S | |||
@@ -291,6 +291,7 @@ NESTED(nmi_handler, PT_SIZE, sp) | |||
291 | BUILD_HANDLER mdmx mdmx sti silent /* #22 */ | 291 | BUILD_HANDLER mdmx mdmx sti silent /* #22 */ |
292 | BUILD_HANDLER watch watch sti verbose /* #23 */ | 292 | BUILD_HANDLER watch watch sti verbose /* #23 */ |
293 | BUILD_HANDLER mcheck mcheck cli verbose /* #24 */ | 293 | BUILD_HANDLER mcheck mcheck cli verbose /* #24 */ |
294 | BUILD_HANDLER dsp dsp sti silent /* #26 */ | ||
294 | BUILD_HANDLER reserved reserved sti verbose /* others */ | 295 | BUILD_HANDLER reserved reserved sti verbose /* others */ |
295 | 296 | ||
296 | #ifdef CONFIG_64BIT | 297 | #ifdef CONFIG_64BIT |
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 368526af5f5e..98432097a86a 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
@@ -25,8 +25,10 @@ | |||
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/completion.h> | 26 | #include <linux/completion.h> |
27 | 27 | ||
28 | #include <asm/abi.h> | ||
28 | #include <asm/bootinfo.h> | 29 | #include <asm/bootinfo.h> |
29 | #include <asm/cpu.h> | 30 | #include <asm/cpu.h> |
31 | #include <asm/dsp.h> | ||
30 | #include <asm/fpu.h> | 32 | #include <asm/fpu.h> |
31 | #include <asm/pgtable.h> | 33 | #include <asm/pgtable.h> |
32 | #include <asm/system.h> | 34 | #include <asm/system.h> |
@@ -54,6 +56,54 @@ ATTRIB_NORET void cpu_idle(void) | |||
54 | } | 56 | } |
55 | } | 57 | } |
56 | 58 | ||
59 | extern int do_signal(sigset_t *oldset, struct pt_regs *regs); | ||
60 | extern int do_signal32(sigset_t *oldset, struct pt_regs *regs); | ||
61 | |||
62 | /* | ||
63 | * Native o32 and N64 ABI without DSP ASE | ||
64 | */ | ||
65 | extern void setup_frame(struct k_sigaction * ka, struct pt_regs *regs, | ||
66 | int signr, sigset_t *set); | ||
67 | extern void setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, | ||
68 | int signr, sigset_t *set, siginfo_t *info); | ||
69 | |||
70 | struct mips_abi mips_abi = { | ||
71 | .do_signal = do_signal, | ||
72 | #ifdef CONFIG_TRAD_SIGNALS | ||
73 | .setup_frame = setup_frame, | ||
74 | #endif | ||
75 | .setup_rt_frame = setup_rt_frame | ||
76 | }; | ||
77 | |||
78 | #ifdef CONFIG_MIPS32_O32 | ||
79 | /* | ||
80 | * o32 compatibility on 64-bit kernels, without DSP ASE | ||
81 | */ | ||
82 | extern void setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, | ||
83 | int signr, sigset_t *set); | ||
84 | extern void setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, | ||
85 | int signr, sigset_t *set, siginfo_t *info); | ||
86 | |||
87 | struct mips_abi mips_abi_32 = { | ||
88 | .do_signal = do_signal32, | ||
89 | .setup_frame = setup_frame_32, | ||
90 | .setup_rt_frame = setup_rt_frame_32 | ||
91 | }; | ||
92 | #endif /* CONFIG_MIPS32_O32 */ | ||
93 | |||
94 | #ifdef CONFIG_MIPS32_N32 | ||
95 | /* | ||
96 | * N32 on 64-bit kernels, without DSP ASE | ||
97 | */ | ||
98 | extern void setup_rt_frame_n32(struct k_sigaction * ka, struct pt_regs *regs, | ||
99 | int signr, sigset_t *set, siginfo_t *info); | ||
100 | |||
101 | struct mips_abi mips_abi_n32 = { | ||
102 | .do_signal = do_signal, | ||
103 | .setup_rt_frame = setup_rt_frame_n32 | ||
104 | }; | ||
105 | #endif /* CONFIG_MIPS32_N32 */ | ||
106 | |||
57 | asmlinkage void ret_from_fork(void); | 107 | asmlinkage void ret_from_fork(void); |
58 | 108 | ||
59 | void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) | 109 | void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) |
@@ -70,6 +120,8 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) | |||
70 | regs->cp0_status = status; | 120 | regs->cp0_status = status; |
71 | clear_used_math(); | 121 | clear_used_math(); |
72 | lose_fpu(); | 122 | lose_fpu(); |
123 | if (cpu_has_dsp) | ||
124 | __init_dsp(); | ||
73 | regs->cp0_epc = pc; | 125 | regs->cp0_epc = pc; |
74 | regs->regs[29] = sp; | 126 | regs->regs[29] = sp; |
75 | current_thread_info()->addr_limit = USER_DS; | 127 | current_thread_info()->addr_limit = USER_DS; |
@@ -95,9 +147,11 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, | |||
95 | 147 | ||
96 | preempt_disable(); | 148 | preempt_disable(); |
97 | 149 | ||
98 | if (is_fpu_owner()) { | 150 | if (is_fpu_owner()) |
99 | save_fp(p); | 151 | save_fp(p); |
100 | } | 152 | |
153 | if (cpu_has_dsp) | ||
154 | save_dsp(p); | ||
101 | 155 | ||
102 | preempt_enable(); | 156 | preempt_enable(); |
103 | 157 | ||
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index 49821ee18984..2441e32ce820 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | #include <asm/byteorder.h> | 31 | #include <asm/byteorder.h> |
32 | #include <asm/cpu.h> | 32 | #include <asm/cpu.h> |
33 | #include <asm/dsp.h> | ||
33 | #include <asm/fpu.h> | 34 | #include <asm/fpu.h> |
34 | #include <asm/mipsregs.h> | 35 | #include <asm/mipsregs.h> |
35 | #include <asm/pgtable.h> | 36 | #include <asm/pgtable.h> |
@@ -176,6 +177,27 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) | |||
176 | write_c0_status(flags); | 177 | write_c0_status(flags); |
177 | break; | 178 | break; |
178 | } | 179 | } |
180 | case DSP_BASE ... DSP_BASE + 5: | ||
181 | if (!cpu_has_dsp) { | ||
182 | tmp = 0; | ||
183 | ret = -EIO; | ||
184 | goto out_tsk; | ||
185 | } | ||
186 | if (child->thread.dsp.used_dsp) { | ||
187 | dspreg_t *dregs = __get_dsp_regs(child); | ||
188 | tmp = (unsigned long) (dregs[addr - DSP_BASE]); | ||
189 | } else { | ||
190 | tmp = -1; /* DSP registers yet used */ | ||
191 | } | ||
192 | break; | ||
193 | case DSP_CONTROL: | ||
194 | if (!cpu_has_dsp) { | ||
195 | tmp = 0; | ||
196 | ret = -EIO; | ||
197 | goto out_tsk; | ||
198 | } | ||
199 | tmp = child->thread.dsp.dspcontrol; | ||
200 | break; | ||
179 | default: | 201 | default: |
180 | tmp = 0; | 202 | tmp = 0; |
181 | ret = -EIO; | 203 | ret = -EIO; |
@@ -248,6 +270,22 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) | |||
248 | else | 270 | else |
249 | child->thread.fpu.soft.fcr31 = data; | 271 | child->thread.fpu.soft.fcr31 = data; |
250 | break; | 272 | break; |
273 | case DSP_BASE ... DSP_BASE + 5: | ||
274 | if (!cpu_has_dsp) { | ||
275 | ret = -EIO; | ||
276 | break; | ||
277 | } | ||
278 | |||
279 | dspreg_t *dregs = __get_dsp_regs(child); | ||
280 | dregs[addr - DSP_BASE] = data; | ||
281 | break; | ||
282 | case DSP_CONTROL: | ||
283 | if (!cpu_has_dsp) { | ||
284 | ret = -EIO; | ||
285 | break; | ||
286 | } | ||
287 | child->thread.dsp.dspcontrol = data; | ||
288 | break; | ||
251 | default: | 289 | default: |
252 | /* The rest are not allowed. */ | 290 | /* The rest are not allowed. */ |
253 | ret = -EIO; | 291 | ret = -EIO; |
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c index eb446e525908..5c45a5880226 100644 --- a/arch/mips/kernel/ptrace32.c +++ b/arch/mips/kernel/ptrace32.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/security.h> | 26 | #include <linux/security.h> |
27 | 27 | ||
28 | #include <asm/cpu.h> | 28 | #include <asm/cpu.h> |
29 | #include <asm/dsp.h> | ||
29 | #include <asm/fpu.h> | 30 | #include <asm/fpu.h> |
30 | #include <asm/mipsregs.h> | 31 | #include <asm/mipsregs.h> |
31 | #include <asm/pgtable.h> | 32 | #include <asm/pgtable.h> |
@@ -161,6 +162,27 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) | |||
161 | write_c0_status(flags); | 162 | write_c0_status(flags); |
162 | break; | 163 | break; |
163 | } | 164 | } |
165 | case DSP_BASE ... DSP_BASE + 5: | ||
166 | if (!cpu_has_dsp) { | ||
167 | tmp = 0; | ||
168 | ret = -EIO; | ||
169 | goto out_tsk; | ||
170 | } | ||
171 | if (child->thread.dsp.used_dsp) { | ||
172 | dspreg_t *dregs = __get_dsp_regs(child); | ||
173 | tmp = (unsigned long) (dregs[addr - DSP_BASE]); | ||
174 | } else { | ||
175 | tmp = -1; /* DSP registers yet used */ | ||
176 | } | ||
177 | break; | ||
178 | case DSP_CONTROL: | ||
179 | if (!cpu_has_dsp) { | ||
180 | tmp = 0; | ||
181 | ret = -EIO; | ||
182 | goto out_tsk; | ||
183 | } | ||
184 | tmp = child->thread.dsp.dspcontrol; | ||
185 | break; | ||
164 | default: | 186 | default: |
165 | tmp = 0; | 187 | tmp = 0; |
166 | ret = -EIO; | 188 | ret = -EIO; |
@@ -230,6 +252,22 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) | |||
230 | else | 252 | else |
231 | child->thread.fpu.soft.fcr31 = data; | 253 | child->thread.fpu.soft.fcr31 = data; |
232 | break; | 254 | break; |
255 | case DSP_BASE ... DSP_BASE + 5: | ||
256 | if (!cpu_has_dsp) { | ||
257 | ret = -EIO; | ||
258 | break; | ||
259 | } | ||
260 | |||
261 | dspreg_t *dregs = __get_dsp_regs(child); | ||
262 | dregs[addr - DSP_BASE] = data; | ||
263 | break; | ||
264 | case DSP_CONTROL: | ||
265 | if (!cpu_has_dsp) { | ||
266 | ret = -EIO; | ||
267 | break; | ||
268 | } | ||
269 | child->thread.dsp.dspcontrol = data; | ||
270 | break; | ||
233 | default: | 271 | default: |
234 | /* The rest are not allowed. */ | 272 | /* The rest are not allowed. */ |
235 | ret = -EIO; | 273 | ret = -EIO; |
diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S index 1a14c6b18829..283a98508fc8 100644 --- a/arch/mips/kernel/r4k_fpu.S +++ b/arch/mips/kernel/r4k_fpu.S | |||
@@ -32,7 +32,7 @@ | |||
32 | 32 | ||
33 | .set noreorder | 33 | .set noreorder |
34 | .set mips3 | 34 | .set mips3 |
35 | /* Save floating point context */ | 35 | |
36 | LEAF(_save_fp_context) | 36 | LEAF(_save_fp_context) |
37 | cfc1 t1, fcr31 | 37 | cfc1 t1, fcr31 |
38 | 38 | ||
@@ -74,9 +74,6 @@ LEAF(_save_fp_context) | |||
74 | EX sdc1 $f28, SC_FPREGS+224(a0) | 74 | EX sdc1 $f28, SC_FPREGS+224(a0) |
75 | EX sdc1 $f30, SC_FPREGS+240(a0) | 75 | EX sdc1 $f30, SC_FPREGS+240(a0) |
76 | EX sw t1, SC_FPC_CSR(a0) | 76 | EX sw t1, SC_FPC_CSR(a0) |
77 | cfc1 t0, $0 # implementation/version | ||
78 | EX sw t0, SC_FPC_EIR(a0) | ||
79 | |||
80 | jr ra | 77 | jr ra |
81 | li v0, 0 # success | 78 | li v0, 0 # success |
82 | END(_save_fp_context) | 79 | END(_save_fp_context) |
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 6fa1112512c8..c389dbaa279e 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S | |||
@@ -620,7 +620,7 @@ einval: li v0, -EINVAL | |||
620 | sys sys_ni_syscall 0 /* sys_vserver */ | 620 | sys sys_ni_syscall 0 /* sys_vserver */ |
621 | sys sys_waitid 5 | 621 | sys sys_waitid 5 |
622 | sys sys_ni_syscall 0 /* available, was setaltroot */ | 622 | sys sys_ni_syscall 0 /* available, was setaltroot */ |
623 | sys sys_add_key 5 | 623 | sys sys_add_key 5 /* 4280 */ |
624 | sys sys_request_key 4 | 624 | sys sys_request_key 4 |
625 | sys sys_keyctl 5 | 625 | sys sys_keyctl 5 |
626 | sys sys_set_thread_area 1 | 626 | sys sys_set_thread_area 1 |
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 6fc51b298304..9253dccefd07 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c | |||
@@ -549,3 +549,12 @@ int __init fpu_disable(char *s) | |||
549 | } | 549 | } |
550 | 550 | ||
551 | __setup("nofpu", fpu_disable); | 551 | __setup("nofpu", fpu_disable); |
552 | |||
553 | int __init dsp_disable(char *s) | ||
554 | { | ||
555 | cpu_data[0].ases &= ~MIPS_ASE_DSP; | ||
556 | |||
557 | return 1; | ||
558 | } | ||
559 | |||
560 | __setup("nodsp", dsp_disable); | ||
diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h index f9234df53253..3208ff528cd2 100644 --- a/arch/mips/kernel/signal-common.h +++ b/arch/mips/kernel/signal-common.h | |||
@@ -8,13 +8,14 @@ | |||
8 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. | 8 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/config.h> | ||
12 | |||
11 | static inline int | 13 | static inline int |
12 | setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc) | 14 | setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc) |
13 | { | 15 | { |
14 | int err = 0; | 16 | int err = 0; |
15 | 17 | ||
16 | err |= __put_user(regs->cp0_epc, &sc->sc_pc); | 18 | err |= __put_user(regs->cp0_epc, &sc->sc_pc); |
17 | err |= __put_user(regs->cp0_status, &sc->sc_status); | ||
18 | 19 | ||
19 | #define save_gp_reg(i) do { \ | 20 | #define save_gp_reg(i) do { \ |
20 | err |= __put_user(regs->regs[i], &sc->sc_regs[i]); \ | 21 | err |= __put_user(regs->regs[i], &sc->sc_regs[i]); \ |
@@ -30,10 +31,32 @@ setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc) | |||
30 | save_gp_reg(31); | 31 | save_gp_reg(31); |
31 | #undef save_gp_reg | 32 | #undef save_gp_reg |
32 | 33 | ||
34 | #ifdef CONFIG_32BIT | ||
33 | err |= __put_user(regs->hi, &sc->sc_mdhi); | 35 | err |= __put_user(regs->hi, &sc->sc_mdhi); |
34 | err |= __put_user(regs->lo, &sc->sc_mdlo); | 36 | err |= __put_user(regs->lo, &sc->sc_mdlo); |
35 | err |= __put_user(regs->cp0_cause, &sc->sc_cause); | 37 | if (cpu_has_dsp) { |
36 | err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr); | 38 | err |= __put_user(mfhi1(), &sc->sc_hi1); |
39 | err |= __put_user(mflo1(), &sc->sc_lo1); | ||
40 | err |= __put_user(mfhi2(), &sc->sc_hi2); | ||
41 | err |= __put_user(mflo2(), &sc->sc_lo2); | ||
42 | err |= __put_user(mfhi3(), &sc->sc_hi3); | ||
43 | err |= __put_user(mflo3(), &sc->sc_lo3); | ||
44 | err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp); | ||
45 | } | ||
46 | #endif | ||
47 | #ifdef CONFIG_64BIT | ||
48 | err |= __put_user(regs->hi, &sc->sc_hi[0]); | ||
49 | err |= __put_user(regs->lo, &sc->sc_lo[0]); | ||
50 | if (cpu_has_dsp) { | ||
51 | err |= __put_user(mfhi1(), &sc->sc_hi[1]); | ||
52 | err |= __put_user(mflo1(), &sc->sc_lo[1]); | ||
53 | err |= __put_user(mfhi2(), &sc->sc_hi[2]); | ||
54 | err |= __put_user(mflo2(), &sc->sc_lo[2]); | ||
55 | err |= __put_user(mfhi3(), &sc->sc_hi[3]); | ||
56 | err |= __put_user(mflo3(), &sc->sc_lo[3]); | ||
57 | err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp); | ||
58 | } | ||
59 | #endif | ||
37 | 60 | ||
38 | err |= __put_user(!!used_math(), &sc->sc_used_math); | 61 | err |= __put_user(!!used_math(), &sc->sc_used_math); |
39 | 62 | ||
@@ -61,15 +84,40 @@ out: | |||
61 | static inline int | 84 | static inline int |
62 | restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) | 85 | restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) |
63 | { | 86 | { |
64 | int err = 0; | ||
65 | unsigned int used_math; | 87 | unsigned int used_math; |
88 | unsigned long treg; | ||
89 | int err = 0; | ||
66 | 90 | ||
67 | /* Always make any pending restarted system calls return -EINTR */ | 91 | /* Always make any pending restarted system calls return -EINTR */ |
68 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | 92 | current_thread_info()->restart_block.fn = do_no_restart_syscall; |
69 | 93 | ||
70 | err |= __get_user(regs->cp0_epc, &sc->sc_pc); | 94 | err |= __get_user(regs->cp0_epc, &sc->sc_pc); |
95 | #ifdef CONFIG_32BIT | ||
71 | err |= __get_user(regs->hi, &sc->sc_mdhi); | 96 | err |= __get_user(regs->hi, &sc->sc_mdhi); |
72 | err |= __get_user(regs->lo, &sc->sc_mdlo); | 97 | err |= __get_user(regs->lo, &sc->sc_mdlo); |
98 | if (cpu_has_dsp) { | ||
99 | err |= __get_user(treg, &sc->sc_hi1); mthi1(treg); | ||
100 | err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg); | ||
101 | err |= __get_user(treg, &sc->sc_hi2); mthi2(treg); | ||
102 | err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg); | ||
103 | err |= __get_user(treg, &sc->sc_hi3); mthi3(treg); | ||
104 | err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg); | ||
105 | err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK); | ||
106 | } | ||
107 | #endif | ||
108 | #ifdef CONFIG_64BIT | ||
109 | err |= __get_user(regs->hi, &sc->sc_hi[0]); | ||
110 | err |= __get_user(regs->lo, &sc->sc_lo[0]); | ||
111 | if (cpu_has_dsp) { | ||
112 | err |= __get_user(treg, &sc->sc_hi[1]); mthi1(treg); | ||
113 | err |= __get_user(treg, &sc->sc_lo[1]); mthi1(treg); | ||
114 | err |= __get_user(treg, &sc->sc_hi[2]); mthi2(treg); | ||
115 | err |= __get_user(treg, &sc->sc_lo[2]); mthi2(treg); | ||
116 | err |= __get_user(treg, &sc->sc_hi[3]); mthi3(treg); | ||
117 | err |= __get_user(treg, &sc->sc_lo[3]); mthi3(treg); | ||
118 | err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK); | ||
119 | } | ||
120 | #endif | ||
73 | 121 | ||
74 | #define restore_gp_reg(i) do { \ | 122 | #define restore_gp_reg(i) do { \ |
75 | err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \ | 123 | err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \ |
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index eb127230cc9a..8504febf8b22 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/unistd.h> | 21 | #include <linux/unistd.h> |
22 | #include <linux/compiler.h> | 22 | #include <linux/compiler.h> |
23 | 23 | ||
24 | #include <asm/abi.h> | ||
24 | #include <asm/asm.h> | 25 | #include <asm/asm.h> |
25 | #include <linux/bitops.h> | 26 | #include <linux/bitops.h> |
26 | #include <asm/cacheflush.h> | 27 | #include <asm/cacheflush.h> |
@@ -36,7 +37,7 @@ | |||
36 | 37 | ||
37 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | 38 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) |
38 | 39 | ||
39 | static int do_signal(sigset_t *oldset, struct pt_regs *regs); | 40 | int do_signal(sigset_t *oldset, struct pt_regs *regs); |
40 | 41 | ||
41 | /* | 42 | /* |
42 | * Atomically swap in the new signal mask, and wait for a signal. | 43 | * Atomically swap in the new signal mask, and wait for a signal. |
@@ -216,7 +217,7 @@ _sys_sigreturn(nabi_no_regargs struct pt_regs regs) | |||
216 | badframe: | 217 | badframe: |
217 | force_sig(SIGSEGV, current); | 218 | force_sig(SIGSEGV, current); |
218 | } | 219 | } |
219 | #endif | 220 | #endif /* CONFIG_TRAD_SIGNALS */ |
220 | 221 | ||
221 | save_static_function(sys_rt_sigreturn); | 222 | save_static_function(sys_rt_sigreturn); |
222 | __attribute_used__ noinline static void | 223 | __attribute_used__ noinline static void |
@@ -262,7 +263,7 @@ badframe: | |||
262 | } | 263 | } |
263 | 264 | ||
264 | #ifdef CONFIG_TRAD_SIGNALS | 265 | #ifdef CONFIG_TRAD_SIGNALS |
265 | static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs, | 266 | void setup_frame(struct k_sigaction * ka, struct pt_regs *regs, |
266 | int signr, sigset_t *set) | 267 | int signr, sigset_t *set) |
267 | { | 268 | { |
268 | struct sigframe *frame; | 269 | struct sigframe *frame; |
@@ -318,7 +319,7 @@ give_sigsegv: | |||
318 | } | 319 | } |
319 | #endif | 320 | #endif |
320 | 321 | ||
321 | static void inline setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, | 322 | void setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, |
322 | int signr, sigset_t *set, siginfo_t *info) | 323 | int signr, sigset_t *set, siginfo_t *info) |
323 | { | 324 | { |
324 | struct rt_sigframe *frame; | 325 | struct rt_sigframe *frame; |
@@ -410,22 +411,10 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info, | |||
410 | 411 | ||
411 | regs->regs[0] = 0; /* Don't deal with this again. */ | 412 | regs->regs[0] = 0; /* Don't deal with this again. */ |
412 | 413 | ||
413 | #ifdef CONFIG_TRAD_SIGNALS | 414 | if (sig_uses_siginfo(ka)) |
414 | if (ka->sa.sa_flags & SA_SIGINFO) { | 415 | current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info); |
415 | #else | ||
416 | if (1) { | ||
417 | #endif | ||
418 | #ifdef CONFIG_MIPS32_N32 | ||
419 | if ((current->thread.mflags & MF_ABI_MASK) == MF_N32) | ||
420 | setup_rt_frame_n32 (ka, regs, sig, oldset, info); | ||
421 | else | ||
422 | #endif | ||
423 | setup_rt_frame(ka, regs, sig, oldset, info); | ||
424 | } | ||
425 | #ifdef CONFIG_TRAD_SIGNALS | ||
426 | else | 416 | else |
427 | setup_frame(ka, regs, sig, oldset); | 417 | current->thread.abi->setup_frame(ka, regs, sig, oldset); |
428 | #endif | ||
429 | 418 | ||
430 | spin_lock_irq(¤t->sighand->siglock); | 419 | spin_lock_irq(¤t->sighand->siglock); |
431 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 420 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
@@ -435,21 +424,12 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info, | |||
435 | spin_unlock_irq(¤t->sighand->siglock); | 424 | spin_unlock_irq(¤t->sighand->siglock); |
436 | } | 425 | } |
437 | 426 | ||
438 | extern int do_signal32(sigset_t *oldset, struct pt_regs *regs); | 427 | int do_signal(sigset_t *oldset, struct pt_regs *regs) |
439 | extern int do_irix_signal(sigset_t *oldset, struct pt_regs *regs); | ||
440 | |||
441 | static int do_signal(sigset_t *oldset, struct pt_regs *regs) | ||
442 | { | 428 | { |
443 | struct k_sigaction ka; | 429 | struct k_sigaction ka; |
444 | siginfo_t info; | 430 | siginfo_t info; |
445 | int signr; | 431 | int signr; |
446 | 432 | ||
447 | #ifdef CONFIG_BINFMT_ELF32 | ||
448 | if ((current->thread.mflags & MF_ABI_MASK) == MF_O32) { | ||
449 | return do_signal32(oldset, regs); | ||
450 | } | ||
451 | #endif | ||
452 | |||
453 | /* | 433 | /* |
454 | * We want the common case to go fast, which is why we may in certain | 434 | * We want the common case to go fast, which is why we may in certain |
455 | * cases get here from kernel mode. Just return without doing anything | 435 | * cases get here from kernel mode. Just return without doing anything |
@@ -501,18 +481,6 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, | |||
501 | { | 481 | { |
502 | /* deal with pending signal delivery */ | 482 | /* deal with pending signal delivery */ |
503 | if (thread_info_flags & _TIF_SIGPENDING) { | 483 | if (thread_info_flags & _TIF_SIGPENDING) { |
504 | #ifdef CONFIG_BINFMT_ELF32 | 484 | current->thread.abi->do_signal(oldset, regs); |
505 | if (likely((current->thread.mflags & MF_ABI_MASK) == MF_O32)) { | ||
506 | do_signal32(oldset, regs); | ||
507 | return; | ||
508 | } | ||
509 | #endif | ||
510 | #ifdef CONFIG_BINFMT_IRIX | ||
511 | if (unlikely(current->personality != PER_LINUX)) { | ||
512 | do_irix_signal(oldset, regs); | ||
513 | return; | ||
514 | } | ||
515 | #endif | ||
516 | do_signal(oldset, regs); | ||
517 | } | 485 | } |
518 | } | 486 | } |
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c index 5e7d0fa02672..8639e24732a5 100644 --- a/arch/mips/kernel/signal32.c +++ b/arch/mips/kernel/signal32.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/suspend.h> | 21 | #include <linux/suspend.h> |
22 | #include <linux/compiler.h> | 22 | #include <linux/compiler.h> |
23 | 23 | ||
24 | #include <asm/abi.h> | ||
24 | #include <asm/asm.h> | 25 | #include <asm/asm.h> |
25 | #include <linux/bitops.h> | 26 | #include <linux/bitops.h> |
26 | #include <asm/cacheflush.h> | 27 | #include <asm/cacheflush.h> |
@@ -334,8 +335,9 @@ asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs) | |||
334 | 335 | ||
335 | static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc) | 336 | static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc) |
336 | { | 337 | { |
338 | u32 used_math; | ||
337 | int err = 0; | 339 | int err = 0; |
338 | __u32 used_math; | 340 | s32 treg; |
339 | 341 | ||
340 | /* Always make any pending restarted system calls return -EINTR */ | 342 | /* Always make any pending restarted system calls return -EINTR */ |
341 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | 343 | current_thread_info()->restart_block.fn = do_no_restart_syscall; |
@@ -343,6 +345,15 @@ static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc) | |||
343 | err |= __get_user(regs->cp0_epc, &sc->sc_pc); | 345 | err |= __get_user(regs->cp0_epc, &sc->sc_pc); |
344 | err |= __get_user(regs->hi, &sc->sc_mdhi); | 346 | err |= __get_user(regs->hi, &sc->sc_mdhi); |
345 | err |= __get_user(regs->lo, &sc->sc_mdlo); | 347 | err |= __get_user(regs->lo, &sc->sc_mdlo); |
348 | if (cpu_has_dsp) { | ||
349 | err |= __get_user(treg, &sc->sc_hi1); mthi1(treg); | ||
350 | err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg); | ||
351 | err |= __get_user(treg, &sc->sc_hi2); mthi2(treg); | ||
352 | err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg); | ||
353 | err |= __get_user(treg, &sc->sc_hi3); mthi3(treg); | ||
354 | err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg); | ||
355 | err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK); | ||
356 | } | ||
346 | 357 | ||
347 | #define restore_gp_reg(i) do { \ | 358 | #define restore_gp_reg(i) do { \ |
348 | err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \ | 359 | err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \ |
@@ -562,8 +573,15 @@ static inline int setup_sigcontext32(struct pt_regs *regs, | |||
562 | 573 | ||
563 | err |= __put_user(regs->hi, &sc->sc_mdhi); | 574 | err |= __put_user(regs->hi, &sc->sc_mdhi); |
564 | err |= __put_user(regs->lo, &sc->sc_mdlo); | 575 | err |= __put_user(regs->lo, &sc->sc_mdlo); |
565 | err |= __put_user(regs->cp0_cause, &sc->sc_cause); | 576 | if (cpu_has_dsp) { |
566 | err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr); | 577 | err |= __put_user(rddsp(DSP_MASK), &sc->sc_hi1); |
578 | err |= __put_user(mfhi1(), &sc->sc_hi1); | ||
579 | err |= __put_user(mflo1(), &sc->sc_lo1); | ||
580 | err |= __put_user(mfhi2(), &sc->sc_hi2); | ||
581 | err |= __put_user(mflo2(), &sc->sc_lo2); | ||
582 | err |= __put_user(mfhi3(), &sc->sc_hi3); | ||
583 | err |= __put_user(mflo3(), &sc->sc_lo3); | ||
584 | } | ||
567 | 585 | ||
568 | err |= __put_user(!!used_math(), &sc->sc_used_math); | 586 | err |= __put_user(!!used_math(), &sc->sc_used_math); |
569 | 587 | ||
@@ -613,7 +631,7 @@ static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, | |||
613 | return (void *)((sp - frame_size) & ALMASK); | 631 | return (void *)((sp - frame_size) & ALMASK); |
614 | } | 632 | } |
615 | 633 | ||
616 | static inline void setup_frame(struct k_sigaction * ka, struct pt_regs *regs, | 634 | void setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, |
617 | int signr, sigset_t *set) | 635 | int signr, sigset_t *set) |
618 | { | 636 | { |
619 | struct sigframe *frame; | 637 | struct sigframe *frame; |
@@ -666,9 +684,7 @@ give_sigsegv: | |||
666 | force_sigsegv(signr, current); | 684 | force_sigsegv(signr, current); |
667 | } | 685 | } |
668 | 686 | ||
669 | static inline void setup_rt_frame(struct k_sigaction * ka, | 687 | void setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info) |
670 | struct pt_regs *regs, int signr, | ||
671 | sigset_t *set, siginfo_t *info) | ||
672 | { | 688 | { |
673 | struct rt_sigframe32 *frame; | 689 | struct rt_sigframe32 *frame; |
674 | int err = 0; | 690 | int err = 0; |
@@ -759,9 +775,9 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info, | |||
759 | regs->regs[0] = 0; /* Don't deal with this again. */ | 775 | regs->regs[0] = 0; /* Don't deal with this again. */ |
760 | 776 | ||
761 | if (ka->sa.sa_flags & SA_SIGINFO) | 777 | if (ka->sa.sa_flags & SA_SIGINFO) |
762 | setup_rt_frame(ka, regs, sig, oldset, info); | 778 | current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info); |
763 | else | 779 | else |
764 | setup_frame(ka, regs, sig, oldset); | 780 | current->thread.abi->setup_frame(ka, regs, sig, oldset); |
765 | 781 | ||
766 | spin_lock_irq(¤t->sighand->siglock); | 782 | spin_lock_irq(¤t->sighand->siglock); |
767 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 783 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
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(); |