Commit e50c0a8fa60da9ac0e0a70caa8a3a803815c1f2f
1 parent
10f650db1b
Exists in
master
and in
7 other branches
Support the MIPS32 / MIPS64 DSP ASE.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Showing 34 changed files with 876 additions and 139 deletions Side-by-side Diff
- arch/mips/kernel/asm-offsets.c
- arch/mips/kernel/branch.c
- arch/mips/kernel/cpu-probe.c
- arch/mips/kernel/genex.S
- arch/mips/kernel/process.c
- arch/mips/kernel/ptrace.c
- arch/mips/kernel/ptrace32.c
- arch/mips/kernel/r4k_fpu.S
- arch/mips/kernel/scall32-o32.S
- arch/mips/kernel/setup.c
- arch/mips/kernel/signal-common.h
- arch/mips/kernel/signal.c
- arch/mips/kernel/signal32.c
- arch/mips/kernel/traps.c
- include/asm-mips/abi.h
- include/asm-mips/cpu-features.h
- include/asm-mips/cpu.h
- include/asm-mips/dsp.h
- include/asm-mips/elf.h
- include/asm-mips/inst.h
- include/asm-mips/mach-ip22/cpu-feature-overrides.h
- include/asm-mips/mach-ip27/cpu-feature-overrides.h
- include/asm-mips/mach-ip32/cpu-feature-overrides.h
- include/asm-mips/mach-ja/cpu-feature-overrides.h
- include/asm-mips/mach-ocelot3/cpu-feature-overrides.h
- include/asm-mips/mach-rm200/cpu-feature-overrides.h
- include/asm-mips/mach-sibyte/cpu-feature-overrides.h
- include/asm-mips/mach-yosemite/cpu-feature-overrides.h
- include/asm-mips/mipsregs.h
- include/asm-mips/processor.h
- include/asm-mips/ptrace.h
- include/asm-mips/sigcontext.h
- include/asm-mips/signal.h
- include/asm-mips/system.h
arch/mips/kernel/asm-offsets.c
... | ... | @@ -95,7 +95,7 @@ |
95 | 95 | offset("#define TI_PRE_COUNT ", struct thread_info, preempt_count); |
96 | 96 | offset("#define TI_ADDR_LIMIT ", struct thread_info, addr_limit); |
97 | 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 | 99 | constant("#define _THREAD_SIZE_ORDER ", THREAD_SIZE_ORDER); |
100 | 100 | constant("#define _THREAD_SIZE ", THREAD_SIZE); |
101 | 101 | constant("#define _THREAD_MASK ", THREAD_MASK); |
... | ... | @@ -241,6 +241,7 @@ |
241 | 241 | linefeed; |
242 | 242 | } |
243 | 243 | |
244 | +#ifdef CONFIG_32BIT | |
244 | 245 | void output_sc_defines(void) |
245 | 246 | { |
246 | 247 | text("/* Linux sigcontext offsets. */"); |
247 | 248 | |
... | ... | @@ -252,10 +253,29 @@ |
252 | 253 | offset("#define SC_STATUS ", struct sigcontext, sc_status); |
253 | 254 | offset("#define SC_FPC_CSR ", struct sigcontext, sc_fpc_csr); |
254 | 255 | offset("#define SC_FPC_EIR ", struct sigcontext, sc_fpc_eir); |
255 | - offset("#define SC_CAUSE ", struct sigcontext, sc_cause); | |
256 | - offset("#define SC_BADVADDR ", struct sigcontext, sc_badvaddr); | |
256 | + offset("#define SC_HI1 ", struct sigcontext, sc_hi1); | |
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 | 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 | 280 | #ifdef CONFIG_MIPS32_COMPAT |
261 | 281 | void output_sc32_defines(void) |
arch/mips/kernel/branch.c
... | ... | @@ -22,7 +22,7 @@ |
22 | 22 | */ |
23 | 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 | 26 | long epc; |
27 | 27 | union mips_instruction insn; |
28 | 28 | |
... | ... | @@ -99,6 +99,18 @@ |
99 | 99 | epc += 8; |
100 | 100 | regs->cp0_epc = epc; |
101 | 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 | 115 | break; |
104 | 116 | |
... | ... | @@ -198,6 +210,11 @@ |
198 | 210 | |
199 | 211 | unaligned: |
200 | 212 | printk("%s: unaligned epc - sending SIGBUS.\n", current->comm); |
213 | + force_sig(SIGBUS, current); | |
214 | + return -EFAULT; | |
215 | + | |
216 | +sigill: | |
217 | + printk("%s: DSP branch but not DSP ASE - sending SIGBUS.\n", current->comm); | |
201 | 218 | force_sig(SIGBUS, current); |
202 | 219 | return -EFAULT; |
203 | 220 | } |
arch/mips/kernel/cpu-probe.c
... | ... | @@ -482,6 +482,8 @@ |
482 | 482 | |
483 | 483 | if (config3 & MIPS_CONF3_SM) |
484 | 484 | c->ases |= MIPS_ASE_SMARTMIPS; |
485 | + if (config3 & MIPS_CONF3_DSP) | |
486 | + c->ases |= MIPS_ASE_DSP; | |
485 | 487 | |
486 | 488 | return config3 & MIPS_CONF_M; |
487 | 489 | } |
... | ... | @@ -529,6 +531,7 @@ |
529 | 531 | c->cputype = CPU_20KC; |
530 | 532 | break; |
531 | 533 | case PRID_IMP_24K: |
534 | + case PRID_IMP_24KE: | |
532 | 535 | c->cputype = CPU_24K; |
533 | 536 | break; |
534 | 537 | case PRID_IMP_25KF: |
arch/mips/kernel/genex.S
... | ... | @@ -291,6 +291,7 @@ |
291 | 291 | BUILD_HANDLER mdmx mdmx sti silent /* #22 */ |
292 | 292 | BUILD_HANDLER watch watch sti verbose /* #23 */ |
293 | 293 | BUILD_HANDLER mcheck mcheck cli verbose /* #24 */ |
294 | + BUILD_HANDLER dsp dsp sti silent /* #26 */ | |
294 | 295 | BUILD_HANDLER reserved reserved sti verbose /* others */ |
295 | 296 | |
296 | 297 | #ifdef CONFIG_64BIT |
arch/mips/kernel/process.c
... | ... | @@ -25,8 +25,10 @@ |
25 | 25 | #include <linux/init.h> |
26 | 26 | #include <linux/completion.h> |
27 | 27 | |
28 | +#include <asm/abi.h> | |
28 | 29 | #include <asm/bootinfo.h> |
29 | 30 | #include <asm/cpu.h> |
31 | +#include <asm/dsp.h> | |
30 | 32 | #include <asm/fpu.h> |
31 | 33 | #include <asm/pgtable.h> |
32 | 34 | #include <asm/system.h> |
... | ... | @@ -54,6 +56,54 @@ |
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 | 107 | asmlinkage void ret_from_fork(void); |
58 | 108 | |
59 | 109 | void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) |
... | ... | @@ -70,6 +120,8 @@ |
70 | 120 | regs->cp0_status = status; |
71 | 121 | clear_used_math(); |
72 | 122 | lose_fpu(); |
123 | + if (cpu_has_dsp) | |
124 | + __init_dsp(); | |
73 | 125 | regs->cp0_epc = pc; |
74 | 126 | regs->regs[29] = sp; |
75 | 127 | current_thread_info()->addr_limit = USER_DS; |
76 | 128 | |
... | ... | @@ -95,9 +147,11 @@ |
95 | 147 | |
96 | 148 | preempt_disable(); |
97 | 149 | |
98 | - if (is_fpu_owner()) { | |
150 | + if (is_fpu_owner()) | |
99 | 151 | save_fp(p); |
100 | - } | |
152 | + | |
153 | + if (cpu_has_dsp) | |
154 | + save_dsp(p); | |
101 | 155 | |
102 | 156 | preempt_enable(); |
103 | 157 |
arch/mips/kernel/ptrace.c
... | ... | @@ -30,6 +30,7 @@ |
30 | 30 | |
31 | 31 | #include <asm/byteorder.h> |
32 | 32 | #include <asm/cpu.h> |
33 | +#include <asm/dsp.h> | |
33 | 34 | #include <asm/fpu.h> |
34 | 35 | #include <asm/mipsregs.h> |
35 | 36 | #include <asm/pgtable.h> |
... | ... | @@ -176,6 +177,27 @@ |
176 | 177 | write_c0_status(flags); |
177 | 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 | 201 | default: |
180 | 202 | tmp = 0; |
181 | 203 | ret = -EIO; |
... | ... | @@ -247,6 +269,22 @@ |
247 | 269 | child->thread.fpu.hard.fcr31 = data; |
248 | 270 | else |
249 | 271 | child->thread.fpu.soft.fcr31 = data; |
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; | |
250 | 288 | break; |
251 | 289 | default: |
252 | 290 | /* The rest are not allowed. */ |
arch/mips/kernel/ptrace32.c
... | ... | @@ -26,6 +26,7 @@ |
26 | 26 | #include <linux/security.h> |
27 | 27 | |
28 | 28 | #include <asm/cpu.h> |
29 | +#include <asm/dsp.h> | |
29 | 30 | #include <asm/fpu.h> |
30 | 31 | #include <asm/mipsregs.h> |
31 | 32 | #include <asm/pgtable.h> |
... | ... | @@ -161,6 +162,27 @@ |
161 | 162 | write_c0_status(flags); |
162 | 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 | 186 | default: |
165 | 187 | tmp = 0; |
166 | 188 | ret = -EIO; |
... | ... | @@ -229,6 +251,22 @@ |
229 | 251 | child->thread.fpu.hard.fcr31 = data; |
230 | 252 | else |
231 | 253 | child->thread.fpu.soft.fcr31 = data; |
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; | |
232 | 270 | break; |
233 | 271 | default: |
234 | 272 | /* The rest are not allowed. */ |
arch/mips/kernel/r4k_fpu.S
... | ... | @@ -32,7 +32,7 @@ |
32 | 32 | |
33 | 33 | .set noreorder |
34 | 34 | .set mips3 |
35 | - /* Save floating point context */ | |
35 | + | |
36 | 36 | LEAF(_save_fp_context) |
37 | 37 | cfc1 t1, fcr31 |
38 | 38 | |
... | ... | @@ -74,9 +74,6 @@ |
74 | 74 | EX sdc1 $f28, SC_FPREGS+224(a0) |
75 | 75 | EX sdc1 $f30, SC_FPREGS+240(a0) |
76 | 76 | EX sw t1, SC_FPC_CSR(a0) |
77 | - cfc1 t0, $0 # implementation/version | |
78 | - EX sw t0, SC_FPC_EIR(a0) | |
79 | - | |
80 | 77 | jr ra |
81 | 78 | li v0, 0 # success |
82 | 79 | END(_save_fp_context) |
arch/mips/kernel/scall32-o32.S
... | ... | @@ -620,7 +620,7 @@ |
620 | 620 | sys sys_ni_syscall 0 /* sys_vserver */ |
621 | 621 | sys sys_waitid 5 |
622 | 622 | sys sys_ni_syscall 0 /* available, was setaltroot */ |
623 | - sys sys_add_key 5 | |
623 | + sys sys_add_key 5 /* 4280 */ | |
624 | 624 | sys sys_request_key 4 |
625 | 625 | sys sys_keyctl 5 |
626 | 626 | sys sys_set_thread_area 1 |
arch/mips/kernel/setup.c
arch/mips/kernel/signal-common.h
... | ... | @@ -8,13 +8,14 @@ |
8 | 8 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. |
9 | 9 | */ |
10 | 10 | |
11 | +#include <linux/config.h> | |
12 | + | |
11 | 13 | static inline int |
12 | 14 | setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc) |
13 | 15 | { |
14 | 16 | int err = 0; |
15 | 17 | |
16 | 18 | err |= __put_user(regs->cp0_epc, &sc->sc_pc); |
17 | - err |= __put_user(regs->cp0_status, &sc->sc_status); | |
18 | 19 | |
19 | 20 | #define save_gp_reg(i) do { \ |
20 | 21 | err |= __put_user(regs->regs[i], &sc->sc_regs[i]); \ |
21 | 22 | |
... | ... | @@ -30,10 +31,32 @@ |
30 | 31 | save_gp_reg(31); |
31 | 32 | #undef save_gp_reg |
32 | 33 | |
34 | +#ifdef CONFIG_32BIT | |
33 | 35 | err |= __put_user(regs->hi, &sc->sc_mdhi); |
34 | 36 | err |= __put_user(regs->lo, &sc->sc_mdlo); |
35 | - err |= __put_user(regs->cp0_cause, &sc->sc_cause); | |
36 | - err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr); | |
37 | + if (cpu_has_dsp) { | |
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 | 61 | err |= __put_user(!!used_math(), &sc->sc_used_math); |
39 | 62 | |
40 | 63 | |
41 | 64 | |
42 | 65 | |
... | ... | @@ -61,15 +84,40 @@ |
61 | 84 | static inline int |
62 | 85 | restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) |
63 | 86 | { |
64 | - int err = 0; | |
65 | 87 | unsigned int used_math; |
88 | + unsigned long treg; | |
89 | + int err = 0; | |
66 | 90 | |
67 | 91 | /* Always make any pending restarted system calls return -EINTR */ |
68 | 92 | current_thread_info()->restart_block.fn = do_no_restart_syscall; |
69 | 93 | |
70 | 94 | err |= __get_user(regs->cp0_epc, &sc->sc_pc); |
95 | +#ifdef CONFIG_32BIT | |
71 | 96 | err |= __get_user(regs->hi, &sc->sc_mdhi); |
72 | 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 | 122 | #define restore_gp_reg(i) do { \ |
75 | 123 | err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \ |
arch/mips/kernel/signal.c
... | ... | @@ -21,6 +21,7 @@ |
21 | 21 | #include <linux/unistd.h> |
22 | 22 | #include <linux/compiler.h> |
23 | 23 | |
24 | +#include <asm/abi.h> | |
24 | 25 | #include <asm/asm.h> |
25 | 26 | #include <linux/bitops.h> |
26 | 27 | #include <asm/cacheflush.h> |
... | ... | @@ -36,7 +37,7 @@ |
36 | 37 | |
37 | 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 | 43 | * Atomically swap in the new signal mask, and wait for a signal. |
... | ... | @@ -216,7 +217,7 @@ |
216 | 217 | badframe: |
217 | 218 | force_sig(SIGSEGV, current); |
218 | 219 | } |
219 | -#endif | |
220 | +#endif /* CONFIG_TRAD_SIGNALS */ | |
220 | 221 | |
221 | 222 | save_static_function(sys_rt_sigreturn); |
222 | 223 | __attribute_used__ noinline static void |
... | ... | @@ -262,7 +263,7 @@ |
262 | 263 | } |
263 | 264 | |
264 | 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 | 267 | int signr, sigset_t *set) |
267 | 268 | { |
268 | 269 | struct sigframe *frame; |
... | ... | @@ -318,7 +319,7 @@ |
318 | 319 | } |
319 | 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 | 323 | int signr, sigset_t *set, siginfo_t *info) |
323 | 324 | { |
324 | 325 | struct rt_sigframe *frame; |
325 | 326 | |
... | ... | @@ -410,22 +411,10 @@ |
410 | 411 | |
411 | 412 | regs->regs[0] = 0; /* Don't deal with this again. */ |
412 | 413 | |
413 | -#ifdef CONFIG_TRAD_SIGNALS | |
414 | - if (ka->sa.sa_flags & SA_SIGINFO) { | |
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 | |
414 | + if (sig_uses_siginfo(ka)) | |
415 | + current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info); | |
426 | 416 | else |
427 | - setup_frame(ka, regs, sig, oldset); | |
428 | -#endif | |
417 | + current->thread.abi->setup_frame(ka, regs, sig, oldset); | |
429 | 418 | |
430 | 419 | spin_lock_irq(¤t->sighand->siglock); |
431 | 420 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
432 | 421 | |
... | ... | @@ -435,21 +424,12 @@ |
435 | 424 | spin_unlock_irq(¤t->sighand->siglock); |
436 | 425 | } |
437 | 426 | |
438 | -extern int do_signal32(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) | |
427 | +int do_signal(sigset_t *oldset, struct pt_regs *regs) | |
442 | 428 | { |
443 | 429 | struct k_sigaction ka; |
444 | 430 | siginfo_t info; |
445 | 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 | 434 | * We want the common case to go fast, which is why we may in certain |
455 | 435 | * cases get here from kernel mode. Just return without doing anything |
... | ... | @@ -501,19 +481,7 @@ |
501 | 481 | { |
502 | 482 | /* deal with pending signal delivery */ |
503 | 483 | if (thread_info_flags & _TIF_SIGPENDING) { |
504 | -#ifdef CONFIG_BINFMT_ELF32 | |
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); | |
484 | + current->thread.abi->do_signal(oldset, regs); | |
517 | 485 | } |
518 | 486 | } |
arch/mips/kernel/signal32.c
... | ... | @@ -21,6 +21,7 @@ |
21 | 21 | #include <linux/suspend.h> |
22 | 22 | #include <linux/compiler.h> |
23 | 23 | |
24 | +#include <asm/abi.h> | |
24 | 25 | #include <asm/asm.h> |
25 | 26 | #include <linux/bitops.h> |
26 | 27 | #include <asm/cacheflush.h> |
27 | 28 | |
... | ... | @@ -334,8 +335,9 @@ |
334 | 335 | |
335 | 336 | static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc) |
336 | 337 | { |
338 | + u32 used_math; | |
337 | 339 | int err = 0; |
338 | - __u32 used_math; | |
340 | + s32 treg; | |
339 | 341 | |
340 | 342 | /* Always make any pending restarted system calls return -EINTR */ |
341 | 343 | current_thread_info()->restart_block.fn = do_no_restart_syscall; |
... | ... | @@ -343,6 +345,15 @@ |
343 | 345 | err |= __get_user(regs->cp0_epc, &sc->sc_pc); |
344 | 346 | err |= __get_user(regs->hi, &sc->sc_mdhi); |
345 | 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 | 358 | #define restore_gp_reg(i) do { \ |
348 | 359 | err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \ |
... | ... | @@ -562,8 +573,15 @@ |
562 | 573 | |
563 | 574 | err |= __put_user(regs->hi, &sc->sc_mdhi); |
564 | 575 | err |= __put_user(regs->lo, &sc->sc_mdlo); |
565 | - err |= __put_user(regs->cp0_cause, &sc->sc_cause); | |
566 | - err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr); | |
576 | + if (cpu_has_dsp) { | |
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 | 586 | err |= __put_user(!!used_math(), &sc->sc_used_math); |
569 | 587 | |
... | ... | @@ -613,7 +631,7 @@ |
613 | 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 | 635 | int signr, sigset_t *set) |
618 | 636 | { |
619 | 637 | struct sigframe *frame; |
... | ... | @@ -666,9 +684,7 @@ |
666 | 684 | force_sigsegv(signr, current); |
667 | 685 | } |
668 | 686 | |
669 | -static inline void setup_rt_frame(struct k_sigaction * ka, | |
670 | - struct pt_regs *regs, int signr, | |
671 | - sigset_t *set, siginfo_t *info) | |
687 | +void setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info) | |
672 | 688 | { |
673 | 689 | struct rt_sigframe32 *frame; |
674 | 690 | int err = 0; |
675 | 691 | |
... | ... | @@ -759,9 +775,9 @@ |
759 | 775 | regs->regs[0] = 0; /* Don't deal with this again. */ |
760 | 776 | |
761 | 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 | 779 | else |
764 | - setup_frame(ka, regs, sig, oldset); | |
780 | + current->thread.abi->setup_frame(ka, regs, sig, oldset); | |
765 | 781 | |
766 | 782 | spin_lock_irq(¤t->sighand->siglock); |
767 | 783 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
arch/mips/kernel/traps.c
... | ... | @@ -25,6 +25,7 @@ |
25 | 25 | #include <asm/branch.h> |
26 | 26 | #include <asm/break.h> |
27 | 27 | #include <asm/cpu.h> |
28 | +#include <asm/dsp.h> | |
28 | 29 | #include <asm/fpu.h> |
29 | 30 | #include <asm/module.h> |
30 | 31 | #include <asm/pgtable.h> |
... | ... | @@ -54,6 +55,7 @@ |
54 | 55 | extern asmlinkage void handle_fpe(void); |
55 | 56 | extern asmlinkage void handle_mdmx(void); |
56 | 57 | extern asmlinkage void handle_watch(void); |
58 | +extern asmlinkage void handle_dsp(void); | |
57 | 59 | extern asmlinkage void handle_mcheck(void); |
58 | 60 | extern asmlinkage void handle_reserved(void); |
59 | 61 | |
... | ... | @@ -775,6 +777,14 @@ |
775 | 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 | 788 | asmlinkage void do_reserved(struct pt_regs *regs) |
779 | 789 | { |
780 | 790 | /* |
781 | 791 | |
... | ... | @@ -984,9 +994,12 @@ |
984 | 994 | #endif |
985 | 995 | if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV) |
986 | 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 | 998 | status_set); |
989 | 999 | |
1000 | + if (cpu_has_dsp) | |
1001 | + set_c0_status(ST0_MX); | |
1002 | + | |
990 | 1003 | /* |
991 | 1004 | * Some MIPS CPUs have a dedicated interrupt vector which reduces the |
992 | 1005 | * interrupt processing overhead. Use it where available. |
993 | 1006 | |
... | ... | @@ -1078,22 +1091,7 @@ |
1078 | 1091 | set_except_vector(11, handle_cpu); |
1079 | 1092 | set_except_vector(12, handle_ov); |
1080 | 1093 | set_except_vector(13, handle_tr); |
1081 | - set_except_vector(22, handle_mdmx); | |
1082 | 1094 | |
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 | - | |
1097 | 1095 | if (current_cpu_data.cputype == CPU_R6000 || |
1098 | 1096 | current_cpu_data.cputype == CPU_R6000A) { |
1099 | 1097 | /* |
... | ... | @@ -1107,6 +1105,25 @@ |
1107 | 1105 | //set_except_vector(14, handle_mc); |
1108 | 1106 | //set_except_vector(15, handle_ndc); |
1109 | 1107 | } |
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); | |
1110 | 1127 | |
1111 | 1128 | signal_init(); |
1112 | 1129 | #ifdef CONFIG_MIPS32_COMPAT |
include/asm-mips/abi.h
1 | +/* | |
2 | + * This file is subject to the terms and conditions of the GNU General Public | |
3 | + * License. See the file "COPYING" in the main directory of this archive | |
4 | + * for more details. | |
5 | + * | |
6 | + * Copyright (C) 2005 by Ralf Baechle | |
7 | + * Copyright (C) 2005 MIPS Technologies, Inc. | |
8 | + */ | |
9 | +#ifndef _ASM_ABI_H | |
10 | +#define _ASM_ABI_H | |
11 | + | |
12 | +#include <asm/signal.h> | |
13 | +#include <asm/siginfo.h> | |
14 | + | |
15 | +struct mips_abi { | |
16 | + int (* const do_signal)(sigset_t *oldset, struct pt_regs *regs); | |
17 | + int (* const setup_frame)(struct k_sigaction * ka, | |
18 | + struct pt_regs *regs, int signr, | |
19 | + sigset_t *set); | |
20 | + int (* const setup_rt_frame)(struct k_sigaction * ka, | |
21 | + struct pt_regs *regs, int signr, | |
22 | + sigset_t *set, siginfo_t *info); | |
23 | +}; | |
24 | + | |
25 | +#endif /* _ASM_ABI_H */ |
include/asm-mips/cpu-features.h
... | ... | @@ -105,6 +105,10 @@ |
105 | 105 | #endif |
106 | 106 | #endif |
107 | 107 | |
108 | +#ifndef cpu_has_dsp | |
109 | +#define cpu_has_dsp (cpu_data[0].ases & MIPS_ASE_DSP) | |
110 | +#endif | |
111 | + | |
108 | 112 | /* |
109 | 113 | * Certain CPUs may throw bizarre exceptions if not the whole cacheline |
110 | 114 | * contains valid instructions. For these we ensure proper alignment of |
include/asm-mips/cpu.h
... | ... | @@ -77,6 +77,7 @@ |
77 | 77 | #define PRID_IMP_4KEMPR2 0x9100 |
78 | 78 | #define PRID_IMP_4KSD 0x9200 |
79 | 79 | #define PRID_IMP_24K 0x9300 |
80 | +#define PRID_IMP_24KE 0x9600 | |
80 | 81 | |
81 | 82 | #define PRID_IMP_UNKNOWN 0xff00 |
82 | 83 | |
... | ... | @@ -232,6 +233,7 @@ |
232 | 233 | #define MIPS_ASE_MDMX 0x00000002 /* MIPS digital media extension */ |
233 | 234 | #define MIPS_ASE_MIPS3D 0x00000004 /* MIPS-3D */ |
234 | 235 | #define MIPS_ASE_SMARTMIPS 0x00000008 /* SmartMIPS */ |
236 | +#define MIPS_ASE_DSP 0x00000010 /* Signal Processing ASE */ | |
235 | 237 | |
236 | 238 | #endif /* _ASM_CPU_H */ |
include/asm-mips/dsp.h
1 | +/* | |
2 | + * Copyright (C) 2005 Mips Technologies | |
3 | + * Author: Chris Dearman, chris@mips.com derived from fpu.h | |
4 | + * | |
5 | + * This program is free software; you can redistribute it and/or modify it | |
6 | + * under the terms of the GNU General Public License as published by the | |
7 | + * Free Software Foundation; either version 2 of the License, or (at your | |
8 | + * option) any later version. | |
9 | + */ | |
10 | +#ifndef _ASM_DSP_H | |
11 | +#define _ASM_DSP_H | |
12 | + | |
13 | +#include <asm/cpu.h> | |
14 | +#include <asm/cpu-features.h> | |
15 | +#include <asm/hazards.h> | |
16 | +#include <asm/mipsregs.h> | |
17 | + | |
18 | +#define DSP_DEFAULT 0x00000000 | |
19 | +#define DSP_MASK 0x1f | |
20 | + | |
21 | +#define __enable_dsp_hazard() \ | |
22 | +do { \ | |
23 | + asm("_ehb"); \ | |
24 | +} while (0) | |
25 | + | |
26 | +static inline void __init_dsp(void) | |
27 | +{ | |
28 | + mthi1(0); | |
29 | + mtlo1(0); | |
30 | + mthi2(0); | |
31 | + mtlo2(0); | |
32 | + mthi3(0); | |
33 | + mtlo3(0); | |
34 | + wrdsp(DSP_DEFAULT, DSP_MASK); | |
35 | +} | |
36 | + | |
37 | +static inline void init_dsp(void) | |
38 | +{ | |
39 | + if (cpu_has_dsp) | |
40 | + __init_dsp(); | |
41 | +} | |
42 | + | |
43 | +#define __save_dsp(tsk) \ | |
44 | +do { \ | |
45 | + tsk->thread.dsp.dspr[0] = mfhi1(); \ | |
46 | + tsk->thread.dsp.dspr[1] = mflo1(); \ | |
47 | + tsk->thread.dsp.dspr[2] = mfhi2(); \ | |
48 | + tsk->thread.dsp.dspr[3] = mflo2(); \ | |
49 | + tsk->thread.dsp.dspr[4] = mfhi3(); \ | |
50 | + tsk->thread.dsp.dspr[5] = mflo3(); \ | |
51 | +} while (0) | |
52 | + | |
53 | +#define save_dsp(tsk) \ | |
54 | +do { \ | |
55 | + if (cpu_has_dsp) \ | |
56 | + __save_dsp(tsk); \ | |
57 | +} while (0) | |
58 | + | |
59 | +#define __restore_dsp(tsk) \ | |
60 | +do { \ | |
61 | + mthi1(tsk->thread.dsp.dspr[0]); \ | |
62 | + mtlo1(tsk->thread.dsp.dspr[1]); \ | |
63 | + mthi2(tsk->thread.dsp.dspr[2]); \ | |
64 | + mtlo2(tsk->thread.dsp.dspr[3]); \ | |
65 | + mthi3(tsk->thread.dsp.dspr[4]); \ | |
66 | + mtlo3(tsk->thread.dsp.dspr[5]); \ | |
67 | +} while (0) | |
68 | + | |
69 | +#define restore_dsp(tsk) \ | |
70 | +do { \ | |
71 | + if (cpu_has_dsp) \ | |
72 | + __restore_dsp(tsk); \ | |
73 | +} while (0) | |
74 | + | |
75 | +#define __get_dsp_regs(tsk) \ | |
76 | +({ \ | |
77 | + if (tsk == current) \ | |
78 | + __save_dsp(current); \ | |
79 | + \ | |
80 | + tsk->thread.dsp.dspr; \ | |
81 | +}) | |
82 | + | |
83 | +#endif /* _ASM_DSP_H */ |
include/asm-mips/elf.h
... | ... | @@ -193,33 +193,76 @@ |
193 | 193 | |
194 | 194 | #ifdef __KERNEL__ |
195 | 195 | |
196 | +struct mips_abi; | |
197 | + | |
198 | +extern struct mips_abi mips_abi; | |
199 | +extern struct mips_abi mips_abi_32; | |
200 | +extern struct mips_abi mips_abi_n32; | |
201 | + | |
196 | 202 | #ifdef CONFIG_32BIT |
197 | 203 | |
198 | -#define SET_PERSONALITY(ex, ibcs2) \ | |
199 | -do { \ | |
200 | - if (ibcs2) \ | |
201 | - set_personality(PER_SVR4); \ | |
202 | - set_personality(PER_LINUX); \ | |
204 | +#define SET_PERSONALITY(ex, ibcs2) \ | |
205 | +do { \ | |
206 | + if (ibcs2) \ | |
207 | + set_personality(PER_SVR4); \ | |
208 | + set_personality(PER_LINUX); \ | |
209 | + \ | |
210 | + current->thread.abi = &mips_abi; \ | |
203 | 211 | } while (0) |
204 | 212 | |
205 | 213 | #endif /* CONFIG_32BIT */ |
206 | 214 | |
207 | 215 | #ifdef CONFIG_64BIT |
208 | 216 | |
209 | -#define SET_PERSONALITY(ex, ibcs2) \ | |
210 | -do { current->thread.mflags &= ~MF_ABI_MASK; \ | |
211 | - if ((ex).e_ident[EI_CLASS] == ELFCLASS32) { \ | |
212 | - if ((((ex).e_flags & EF_MIPS_ABI2) != 0) && \ | |
213 | - ((ex).e_flags & EF_MIPS_ABI) == 0) \ | |
214 | - current->thread.mflags |= MF_N32; \ | |
215 | - else \ | |
216 | - current->thread.mflags |= MF_O32; \ | |
217 | - } else \ | |
218 | - current->thread.mflags |= MF_N64; \ | |
219 | - if (ibcs2) \ | |
220 | - set_personality(PER_SVR4); \ | |
221 | - else if (current->personality != PER_LINUX32) \ | |
222 | - set_personality(PER_LINUX); \ | |
217 | +#ifdef CONFIG_MIPS32_N32 | |
218 | +#define __SET_PERSONALITY32_N32() \ | |
219 | + do { \ | |
220 | + current->thread.mflags |= MF_N32; \ | |
221 | + current->thread.abi = &mips_abi_n32; \ | |
222 | + } while (0) | |
223 | +#else | |
224 | +#define __SET_PERSONALITY32_N32() \ | |
225 | + do { } while (0) | |
226 | +#endif | |
227 | + | |
228 | +#ifdef CONFIG_MIPS32_O32 | |
229 | +#define __SET_PERSONALITY32_O32() \ | |
230 | + do { \ | |
231 | + current->thread.mflags |= MF_O32; \ | |
232 | + current->thread.abi = &mips_abi_32; \ | |
233 | + } while (0) | |
234 | +#else | |
235 | +#define __SET_PERSONALITY32_O32() \ | |
236 | + do { } while (0) | |
237 | +#endif | |
238 | + | |
239 | +#ifdef CONFIG_MIPS32_COMPAT | |
240 | +#define __SET_PERSONALITY32(ex) \ | |
241 | +do { \ | |
242 | + if ((((ex).e_flags & EF_MIPS_ABI2) != 0) && \ | |
243 | + ((ex).e_flags & EF_MIPS_ABI) == 0) \ | |
244 | + __SET_PERSONALITY32_N32(); \ | |
245 | + else \ | |
246 | + __SET_PERSONALITY32_O32(); \ | |
247 | +} while (0) | |
248 | +#else | |
249 | +#define __SET_PERSONALITY32(ex) do { } while (0) | |
250 | +#endif | |
251 | + | |
252 | +#define SET_PERSONALITY(ex, ibcs2) \ | |
253 | +do { \ | |
254 | + current->thread.mflags &= ~MF_ABI_MASK; \ | |
255 | + if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ | |
256 | + __SET_PERSONALITY32(ex); \ | |
257 | + else { \ | |
258 | + current->thread.mflags |= MF_N64; \ | |
259 | + current->thread.abi = &mips_abi; \ | |
260 | + } \ | |
261 | + \ | |
262 | + if (ibcs2) \ | |
263 | + set_personality(PER_SVR4); \ | |
264 | + else if (current->personality != PER_LINUX32) \ | |
265 | + set_personality(PER_LINUX); \ | |
223 | 266 | } while (0) |
224 | 267 | |
225 | 268 | #endif /* CONFIG_64BIT */ |
include/asm-mips/inst.h
... | ... | @@ -62,10 +62,10 @@ |
62 | 62 | spimi_op, unused_rt_op_0x05, unused_rt_op_0x06, unused_rt_op_0x07, |
63 | 63 | tgei_op, tgeiu_op, tlti_op, tltiu_op, |
64 | 64 | teqi_op, unused_0x0d_rt_op, tnei_op, unused_0x0f_rt_op, |
65 | - bltzal_op, bgezal_op, bltzall_op, bgezall_op | |
66 | - /* | |
67 | - * The others (0x14 - 0x1f) are unused. | |
68 | - */ | |
65 | + bltzal_op, bgezal_op, bltzall_op, bgezall_op, | |
66 | + rt_op_0x14, rt_op_0x15, rt_op_0x16, rt_op_0x17, | |
67 | + rt_op_0x18, rt_op_0x19, rt_op_0x1a, rt_op_0x1b, | |
68 | + bposge32_op, rt_op_0x1d, rt_op_0x1e, rt_op_0x1f | |
69 | 69 | }; |
70 | 70 | |
71 | 71 | /* |
include/asm-mips/mach-ip22/cpu-feature-overrides.h
include/asm-mips/mach-ip27/cpu-feature-overrides.h
include/asm-mips/mach-ip32/cpu-feature-overrides.h
include/asm-mips/mach-ja/cpu-feature-overrides.h
include/asm-mips/mach-ocelot3/cpu-feature-overrides.h
include/asm-mips/mach-rm200/cpu-feature-overrides.h
include/asm-mips/mach-sibyte/cpu-feature-overrides.h
include/asm-mips/mach-yosemite/cpu-feature-overrides.h
include/asm-mips/mipsregs.h
... | ... | @@ -281,6 +281,11 @@ |
281 | 281 | #define ST0_DL (_ULCAST_(1) << 24) |
282 | 282 | |
283 | 283 | /* |
284 | + * Enable the MIPS DSP ASE | |
285 | + */ | |
286 | +#define ST0_MX 0x01000000 | |
287 | + | |
288 | +/* | |
284 | 289 | * Bitfields in the TX39 family CP0 Configuration Register 3 |
285 | 290 | */ |
286 | 291 | #define TX39_CONF_ICS_SHIFT 19 |
... | ... | @@ -510,6 +515,7 @@ |
510 | 515 | #define MIPS_CONF3_VINT (_ULCAST_(1) << 5) |
511 | 516 | #define MIPS_CONF3_VEIC (_ULCAST_(1) << 6) |
512 | 517 | #define MIPS_CONF3_LPA (_ULCAST_(1) << 7) |
518 | +#define MIPS_CONF3_DSP (_ULCAST_(1) << 10) | |
513 | 519 | |
514 | 520 | /* |
515 | 521 | * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register. |
... | ... | @@ -985,6 +991,287 @@ |
985 | 991 | ".set\tpop" \ |
986 | 992 | : "=r" (__res)); \ |
987 | 993 | __res;}) |
994 | + | |
995 | +#define rddsp(mask) \ | |
996 | +({ \ | |
997 | + unsigned int __res; \ | |
998 | + \ | |
999 | + __asm__ __volatile__( \ | |
1000 | + " .set push \n" \ | |
1001 | + " .set noat \n" \ | |
1002 | + " # rddsp $1, %x1 \n" \ | |
1003 | + " .word 0x7c000cb8 | (%x1 << 16) \n" \ | |
1004 | + " move %0, $1 \n" \ | |
1005 | + " .set pop \n" \ | |
1006 | + : "=r" (__res) \ | |
1007 | + : "i" (mask)); \ | |
1008 | + __res; \ | |
1009 | +}) | |
1010 | + | |
1011 | +#define wrdsp(val, mask) \ | |
1012 | +do { \ | |
1013 | + unsigned int __res; \ | |
1014 | + \ | |
1015 | + __asm__ __volatile__( \ | |
1016 | + " .set push \n" \ | |
1017 | + " .set noat \n" \ | |
1018 | + " move $1, %0 \n" \ | |
1019 | + " # wrdsp $1, %x1 \n" \ | |
1020 | + " .word 0x7c2004f8 | (%x1 << 15) \n" \ | |
1021 | + " .set pop \n" \ | |
1022 | + : \ | |
1023 | + : "r" (val), "i" (mask)); \ | |
1024 | + __res; \ | |
1025 | +} while (0) | |
1026 | + | |
1027 | +#if 0 /* Need DSP ASE capable assembler ... */ | |
1028 | +#define mflo0() ({ long mflo0; __asm__("mflo %0, $ac0" : "=r" (mflo0)); mflo0;}) | |
1029 | +#define mflo1() ({ long mflo1; __asm__("mflo %0, $ac1" : "=r" (mflo1)); mflo1;}) | |
1030 | +#define mflo2() ({ long mflo2; __asm__("mflo %0, $ac2" : "=r" (mflo2)); mflo2;}) | |
1031 | +#define mflo3() ({ long mflo3; __asm__("mflo %0, $ac3" : "=r" (mflo3)); mflo3;}) | |
1032 | + | |
1033 | +#define mfhi0() ({ long mfhi0; __asm__("mfhi %0, $ac0" : "=r" (mfhi0)); mfhi0;}) | |
1034 | +#define mfhi1() ({ long mfhi1; __asm__("mfhi %0, $ac1" : "=r" (mfhi1)); mfhi1;}) | |
1035 | +#define mfhi2() ({ long mfhi2; __asm__("mfhi %0, $ac2" : "=r" (mfhi2)); mfhi2;}) | |
1036 | +#define mfhi3() ({ long mfhi3; __asm__("mfhi %0, $ac3" : "=r" (mfhi3)); mfhi3;}) | |
1037 | + | |
1038 | +#define mtlo0(x) __asm__("mtlo %0, $ac0" ::"r" (x)) | |
1039 | +#define mtlo1(x) __asm__("mtlo %0, $ac1" ::"r" (x)) | |
1040 | +#define mtlo2(x) __asm__("mtlo %0, $ac2" ::"r" (x)) | |
1041 | +#define mtlo3(x) __asm__("mtlo %0, $ac3" ::"r" (x)) | |
1042 | + | |
1043 | +#define mthi0(x) __asm__("mthi %0, $ac0" ::"r" (x)) | |
1044 | +#define mthi1(x) __asm__("mthi %0, $ac1" ::"r" (x)) | |
1045 | +#define mthi2(x) __asm__("mthi %0, $ac2" ::"r" (x)) | |
1046 | +#define mthi3(x) __asm__("mthi %0, $ac3" ::"r" (x)) | |
1047 | + | |
1048 | +#else | |
1049 | + | |
1050 | +#define mfhi0() \ | |
1051 | +({ \ | |
1052 | + unsigned long __treg; \ | |
1053 | + \ | |
1054 | + __asm__ __volatile__( \ | |
1055 | + " .set push \n" \ | |
1056 | + " .set noat \n" \ | |
1057 | + " # mfhi %0, $ac0 \n" \ | |
1058 | + " .word 0x00000810 \n" \ | |
1059 | + " move %0, $1 \n" \ | |
1060 | + " .set pop \n" \ | |
1061 | + : "=r" (__treg)); \ | |
1062 | + __treg; \ | |
1063 | +}) | |
1064 | + | |
1065 | +#define mfhi1() \ | |
1066 | +({ \ | |
1067 | + unsigned long __treg; \ | |
1068 | + \ | |
1069 | + __asm__ __volatile__( \ | |
1070 | + " .set push \n" \ | |
1071 | + " .set noat \n" \ | |
1072 | + " # mfhi %0, $ac1 \n" \ | |
1073 | + " .word 0x00200810 \n" \ | |
1074 | + " move %0, $1 \n" \ | |
1075 | + " .set pop \n" \ | |
1076 | + : "=r" (__treg)); \ | |
1077 | + __treg; \ | |
1078 | +}) | |
1079 | + | |
1080 | +#define mfhi2() \ | |
1081 | +({ \ | |
1082 | + unsigned long __treg; \ | |
1083 | + \ | |
1084 | + __asm__ __volatile__( \ | |
1085 | + " .set push \n" \ | |
1086 | + " .set noat \n" \ | |
1087 | + " # mfhi %0, $ac2 \n" \ | |
1088 | + " .word 0x00400810 \n" \ | |
1089 | + " move %0, $1 \n" \ | |
1090 | + " .set pop \n" \ | |
1091 | + : "=r" (__treg)); \ | |
1092 | + __treg; \ | |
1093 | +}) | |
1094 | + | |
1095 | +#define mfhi3() \ | |
1096 | +({ \ | |
1097 | + unsigned long __treg; \ | |
1098 | + \ | |
1099 | + __asm__ __volatile__( \ | |
1100 | + " .set push \n" \ | |
1101 | + " .set noat \n" \ | |
1102 | + " # mfhi %0, $ac3 \n" \ | |
1103 | + " .word 0x00600810 \n" \ | |
1104 | + " move %0, $1 \n" \ | |
1105 | + " .set pop \n" \ | |
1106 | + : "=r" (__treg)); \ | |
1107 | + __treg; \ | |
1108 | +}) | |
1109 | + | |
1110 | +#define mflo0() \ | |
1111 | +({ \ | |
1112 | + unsigned long __treg; \ | |
1113 | + \ | |
1114 | + __asm__ __volatile__( \ | |
1115 | + " .set push \n" \ | |
1116 | + " .set noat \n" \ | |
1117 | + " # mflo %0, $ac0 \n" \ | |
1118 | + " .word 0x00000812 \n" \ | |
1119 | + " move %0, $1 \n" \ | |
1120 | + " .set pop \n" \ | |
1121 | + : "=r" (__treg)); \ | |
1122 | + __treg; \ | |
1123 | +}) | |
1124 | + | |
1125 | +#define mflo1() \ | |
1126 | +({ \ | |
1127 | + unsigned long __treg; \ | |
1128 | + \ | |
1129 | + __asm__ __volatile__( \ | |
1130 | + " .set push \n" \ | |
1131 | + " .set noat \n" \ | |
1132 | + " # mflo %0, $ac1 \n" \ | |
1133 | + " .word 0x00200812 \n" \ | |
1134 | + " move %0, $1 \n" \ | |
1135 | + " .set pop \n" \ | |
1136 | + : "=r" (__treg)); \ | |
1137 | + __treg; \ | |
1138 | +}) | |
1139 | + | |
1140 | +#define mflo2() \ | |
1141 | +({ \ | |
1142 | + unsigned long __treg; \ | |
1143 | + \ | |
1144 | + __asm__ __volatile__( \ | |
1145 | + " .set push \n" \ | |
1146 | + " .set noat \n" \ | |
1147 | + " # mflo %0, $ac2 \n" \ | |
1148 | + " .word 0x00400812 \n" \ | |
1149 | + " move %0, $1 \n" \ | |
1150 | + " .set pop \n" \ | |
1151 | + : "=r" (__treg)); \ | |
1152 | + __treg; \ | |
1153 | +}) | |
1154 | + | |
1155 | +#define mflo3() \ | |
1156 | +({ \ | |
1157 | + unsigned long __treg; \ | |
1158 | + \ | |
1159 | + __asm__ __volatile__( \ | |
1160 | + " .set push \n" \ | |
1161 | + " .set noat \n" \ | |
1162 | + " # mflo %0, $ac3 \n" \ | |
1163 | + " .word 0x00600812 \n" \ | |
1164 | + " move %0, $1 \n" \ | |
1165 | + " .set pop \n" \ | |
1166 | + : "=r" (__treg)); \ | |
1167 | + __treg; \ | |
1168 | +}) | |
1169 | + | |
1170 | +#define mthi0(x) \ | |
1171 | +do { \ | |
1172 | + __asm__ __volatile__( \ | |
1173 | + " .set push \n" \ | |
1174 | + " .set noat \n" \ | |
1175 | + " move $1, %0 \n" \ | |
1176 | + " # mthi $1, $ac0 \n" \ | |
1177 | + " .word 0x00200011 \n" \ | |
1178 | + " .set pop \n" \ | |
1179 | + : \ | |
1180 | + : "r" (x)); \ | |
1181 | +} while (0) | |
1182 | + | |
1183 | +#define mthi1(x) \ | |
1184 | +do { \ | |
1185 | + __asm__ __volatile__( \ | |
1186 | + " .set push \n" \ | |
1187 | + " .set noat \n" \ | |
1188 | + " move $1, %0 \n" \ | |
1189 | + " # mthi $1, $ac1 \n" \ | |
1190 | + " .word 0x00200811 \n" \ | |
1191 | + " .set pop \n" \ | |
1192 | + : \ | |
1193 | + : "r" (x)); \ | |
1194 | +} while (0) | |
1195 | + | |
1196 | +#define mthi2(x) \ | |
1197 | +do { \ | |
1198 | + __asm__ __volatile__( \ | |
1199 | + " .set push \n" \ | |
1200 | + " .set noat \n" \ | |
1201 | + " move $1, %0 \n" \ | |
1202 | + " # mthi $1, $ac2 \n" \ | |
1203 | + " .word 0x00201011 \n" \ | |
1204 | + " .set pop \n" \ | |
1205 | + : \ | |
1206 | + : "r" (x)); \ | |
1207 | +} while (0) | |
1208 | + | |
1209 | +#define mthi3(x) \ | |
1210 | +do { \ | |
1211 | + __asm__ __volatile__( \ | |
1212 | + " .set push \n" \ | |
1213 | + " .set noat \n" \ | |
1214 | + " move $1, %0 \n" \ | |
1215 | + " # mthi $1, $ac3 \n" \ | |
1216 | + " .word 0x00201811 \n" \ | |
1217 | + " .set pop \n" \ | |
1218 | + : \ | |
1219 | + : "r" (x)); \ | |
1220 | +} while (0) | |
1221 | + | |
1222 | +#define mtlo0(x) \ | |
1223 | +do { \ | |
1224 | + __asm__ __volatile__( \ | |
1225 | + " .set push \n" \ | |
1226 | + " .set noat \n" \ | |
1227 | + " move $1, %0 \n" \ | |
1228 | + " # mtlo $1, $ac0 \n" \ | |
1229 | + " .word 0x00200013 \n" \ | |
1230 | + " .set pop \n" \ | |
1231 | + : \ | |
1232 | + : "r" (x)); \ | |
1233 | +} while (0) | |
1234 | + | |
1235 | +#define mtlo1(x) \ | |
1236 | +do { \ | |
1237 | + __asm__ __volatile__( \ | |
1238 | + " .set push \n" \ | |
1239 | + " .set noat \n" \ | |
1240 | + " move $1, %0 \n" \ | |
1241 | + " # mtlo $1, $ac1 \n" \ | |
1242 | + " .word 0x00200813 \n" \ | |
1243 | + " .set pop \n" \ | |
1244 | + : \ | |
1245 | + : "r" (x)); \ | |
1246 | +} while (0) | |
1247 | + | |
1248 | +#define mtlo2(x) \ | |
1249 | +do { \ | |
1250 | + __asm__ __volatile__( \ | |
1251 | + " .set push \n" \ | |
1252 | + " .set noat \n" \ | |
1253 | + " move $1, %0 \n" \ | |
1254 | + " # mtlo $1, $ac2 \n" \ | |
1255 | + " .word 0x00201013 \n" \ | |
1256 | + " .set pop \n" \ | |
1257 | + : \ | |
1258 | + : "r" (x)); \ | |
1259 | +} while (0) | |
1260 | + | |
1261 | +#define mtlo3(x) \ | |
1262 | +do { \ | |
1263 | + __asm__ __volatile__( \ | |
1264 | + " .set push \n" \ | |
1265 | + " .set noat \n" \ | |
1266 | + " move $1, %0 \n" \ | |
1267 | + " # mtlo $1, $ac3 \n" \ | |
1268 | + " .word 0x00201813 \n" \ | |
1269 | + " .set pop \n" \ | |
1270 | + : \ | |
1271 | + : "r" (x)); \ | |
1272 | +} while (0) | |
1273 | + | |
1274 | +#endif | |
988 | 1275 | |
989 | 1276 | /* |
990 | 1277 | * TLB operations. |
include/asm-mips/processor.h
... | ... | @@ -96,12 +96,26 @@ |
96 | 96 | {{0,},} \ |
97 | 97 | } |
98 | 98 | |
99 | +#define NUM_DSP_REGS 6 | |
100 | + | |
101 | +typedef __u32 dspreg_t; | |
102 | + | |
103 | +struct mips_dsp_state { | |
104 | + dspreg_t dspr[NUM_DSP_REGS]; | |
105 | + unsigned int dspcontrol; | |
106 | + unsigned short used_dsp; | |
107 | +}; | |
108 | + | |
109 | +#define INIT_DSP {{0,},} | |
110 | + | |
99 | 111 | typedef struct { |
100 | 112 | unsigned long seg; |
101 | 113 | } mm_segment_t; |
102 | 114 | |
103 | 115 | #define ARCH_MIN_TASKALIGN 8 |
104 | 116 | |
117 | +struct mips_abi; | |
118 | + | |
105 | 119 | /* |
106 | 120 | * If you change thread_struct remember to change the #defines below too! |
107 | 121 | */ |
... | ... | @@ -117,6 +131,9 @@ |
117 | 131 | /* Saved fpu/fpu emulator stuff. */ |
118 | 132 | union mips_fpu_union fpu; |
119 | 133 | |
134 | + /* Saved state of the DSP ASE, if available. */ | |
135 | + struct mips_dsp_state dsp; | |
136 | + | |
120 | 137 | /* Other stuff associated with the thread. */ |
121 | 138 | unsigned long cp0_badvaddr; /* Last user fault */ |
122 | 139 | unsigned long cp0_baduaddr; /* Last kernel fault accessing USEG */ |
... | ... | @@ -129,6 +146,7 @@ |
129 | 146 | unsigned long mflags; |
130 | 147 | unsigned long irix_trampoline; /* Wheee... */ |
131 | 148 | unsigned long irix_oldctx; |
149 | + struct mips_abi *abi; | |
132 | 150 | }; |
133 | 151 | |
134 | 152 | #define MF_ABI_MASK (MF_32BIT_REGS | MF_32BIT_ADDR) |
... | ... | @@ -150,6 +168,10 @@ |
150 | 168 | * saved fpu/fpu emulator stuff \ |
151 | 169 | */ \ |
152 | 170 | INIT_FPU, \ |
171 | + /* \ | |
172 | + * saved dsp/dsp emulator stuff \ | |
173 | + */ \ | |
174 | + INIT_DSP, \ | |
153 | 175 | /* \ |
154 | 176 | * Other stuff associated with the process \ |
155 | 177 | */ \ |
include/asm-mips/ptrace.h
... | ... | @@ -22,6 +22,8 @@ |
22 | 22 | #define MMLO 68 |
23 | 23 | #define FPC_CSR 69 |
24 | 24 | #define FPC_EIR 70 |
25 | +#define DSP_BASE 71 /* 3 more hi / lo register pairs */ | |
26 | +#define DSP_CONTROL 77 | |
25 | 27 | |
26 | 28 | /* |
27 | 29 | * This struct defines the way the registers are stored on the stack during a |
28 | 30 | |
... | ... | @@ -38,8 +40,8 @@ |
38 | 40 | |
39 | 41 | /* Saved special registers. */ |
40 | 42 | unsigned long cp0_status; |
41 | - unsigned long lo; | |
42 | 43 | unsigned long hi; |
44 | + unsigned long lo; | |
43 | 45 | unsigned long cp0_badvaddr; |
44 | 46 | unsigned long cp0_cause; |
45 | 47 | unsigned long cp0_epc; |
include/asm-mips/sigcontext.h
... | ... | @@ -27,14 +27,15 @@ |
27 | 27 | unsigned int sc_fpc_csr; |
28 | 28 | unsigned int sc_fpc_eir; /* Unused */ |
29 | 29 | unsigned int sc_used_math; |
30 | - unsigned int sc_ssflags; /* Unused */ | |
30 | + unsigned int sc_dsp; /* dsp status, was sc_ssflags */ | |
31 | 31 | unsigned long long sc_mdhi; |
32 | 32 | unsigned long long sc_mdlo; |
33 | - | |
34 | - unsigned int sc_cause; /* Unused */ | |
35 | - unsigned int sc_badvaddr; /* Unused */ | |
36 | - | |
37 | - unsigned long sc_sigset[4]; /* kernel's sigset_t */ | |
33 | + unsigned long sc_hi1; /* Was sc_cause */ | |
34 | + unsigned long sc_lo1; /* Was sc_badvaddr */ | |
35 | + unsigned long sc_hi2; /* Was sc_sigset[4] */ | |
36 | + unsigned long sc_lo2; | |
37 | + unsigned long sc_hi3; | |
38 | + unsigned long sc_lo3; | |
38 | 39 | }; |
39 | 40 | |
40 | 41 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ |
41 | 42 | |
42 | 43 | |
43 | 44 | |
44 | 45 | |
... | ... | @@ -48,19 +49,19 @@ |
48 | 49 | * Warning: this structure illdefined with sc_badvaddr being just an unsigned |
49 | 50 | * int so it was changed to unsigned long in 2.6.0-test1. This may break |
50 | 51 | * binary compatibility - no prisoners. |
52 | + * DSP ASE in 2.6.12-rc4. Turn sc_mdhi and sc_mdlo into an array of four | |
53 | + * entries, add sc_dsp and sc_reserved for padding. No prisoners. | |
51 | 54 | */ |
52 | 55 | struct sigcontext { |
53 | 56 | unsigned long sc_regs[32]; |
54 | 57 | unsigned long sc_fpregs[32]; |
55 | - unsigned long sc_mdhi; | |
56 | - unsigned long sc_mdlo; | |
58 | + unsigned long sc_hi[4]; | |
59 | + unsigned long sc_lo[4]; | |
57 | 60 | unsigned long sc_pc; |
58 | - unsigned long sc_badvaddr; | |
59 | - unsigned int sc_status; | |
60 | 61 | unsigned int sc_fpc_csr; |
61 | - unsigned int sc_fpc_eir; | |
62 | 62 | unsigned int sc_used_math; |
63 | - unsigned int sc_cause; | |
63 | + unsigned int sc_dsp; | |
64 | + unsigned int sc_reserved; | |
64 | 65 | }; |
65 | 66 | |
66 | 67 | #ifdef __KERNEL__ |
... | ... | @@ -68,23 +69,24 @@ |
68 | 69 | #include <linux/posix_types.h> |
69 | 70 | |
70 | 71 | struct sigcontext32 { |
71 | - __u32 sc_regmask; /* Unused */ | |
72 | - __u32 sc_status; | |
73 | - __u64 sc_pc; | |
74 | - __u64 sc_regs[32]; | |
75 | - __u64 sc_fpregs[32]; | |
76 | - __u32 sc_ownedfp; /* Unused */ | |
77 | - __u32 sc_fpc_csr; | |
78 | - __u32 sc_fpc_eir; /* Unused */ | |
79 | - __u32 sc_used_math; | |
80 | - __u32 sc_ssflags; /* Unused */ | |
81 | - __u64 sc_mdhi; | |
82 | - __u64 sc_mdlo; | |
83 | - | |
84 | - __u32 sc_cause; /* Unused */ | |
85 | - __u32 sc_badvaddr; /* Unused */ | |
86 | - | |
87 | - __u32 sc_sigset[4]; /* kernel's sigset_t */ | |
72 | + __u32 sc_regmask; /* Unused */ | |
73 | + __u32 sc_status; | |
74 | + __u64 sc_pc; | |
75 | + __u64 sc_regs[32]; | |
76 | + __u64 sc_fpregs[32]; | |
77 | + __u32 sc_ownedfp; /* Unused */ | |
78 | + __u32 sc_fpc_csr; | |
79 | + __u32 sc_fpc_eir; /* Unused */ | |
80 | + __u32 sc_used_math; | |
81 | + __u32 sc_dsp; /* dsp status, was sc_ssflags */ | |
82 | + __u64 sc_mdhi; | |
83 | + __u64 sc_mdlo; | |
84 | + __u32 sc_hi1; /* Was sc_cause */ | |
85 | + __u32 sc_lo1; /* Was sc_badvaddr */ | |
86 | + __u32 sc_hi2; /* Was sc_sigset[4] */ | |
87 | + __u32 sc_lo2; | |
88 | + __u32 sc_hi3; | |
89 | + __u32 sc_lo3; | |
88 | 90 | }; |
89 | 91 | #endif /* __KERNEL__ */ |
90 | 92 |
include/asm-mips/signal.h
... | ... | @@ -98,12 +98,39 @@ |
98 | 98 | #define MINSIGSTKSZ 2048 |
99 | 99 | #define SIGSTKSZ 8192 |
100 | 100 | |
101 | +#ifdef __KERNEL__ | |
102 | + | |
103 | +/* | |
104 | + * These values of sa_flags are used only by the kernel as part of the | |
105 | + * irq handling routines. | |
106 | + * | |
107 | + * SA_INTERRUPT is also used by the irq handling routines. | |
108 | + * SA_SHIRQ flag is for shared interrupt support on PCI and EISA. | |
109 | + */ | |
110 | +#define SA_SAMPLE_RANDOM SA_RESTART | |
111 | + | |
112 | +#ifdef CONFIG_TRAD_SIGNALS | |
113 | +#define sig_uses_siginfo(ka) ((ka)->sa.sa_flags & SA_SIGINFO) | |
114 | +#else | |
115 | +#define sig_uses_siginfo(ka) (1) | |
116 | +#endif | |
117 | + | |
118 | +#endif /* __KERNEL__ */ | |
119 | + | |
101 | 120 | #define SIG_BLOCK 1 /* for blocking signals */ |
102 | 121 | #define SIG_UNBLOCK 2 /* for unblocking signals */ |
103 | 122 | #define SIG_SETMASK 3 /* for setting the signal mask */ |
104 | 123 | #define SIG_SETMASK32 256 /* Goodie from SGI for BSD compatibility: |
105 | 124 | set only the low 32 bit of the sigset. */ |
106 | -#include <asm-generic/signal.h> | |
125 | + | |
126 | +/* Type of a signal handler. */ | |
127 | +typedef void __signalfn_t(int); | |
128 | +typedef __signalfn_t __user *__sighandler_t; | |
129 | + | |
130 | +/* Fake signal functions */ | |
131 | +#define SIG_DFL ((__sighandler_t)0) /* default signal handling */ | |
132 | +#define SIG_IGN ((__sighandler_t)1) /* ignore signal */ | |
133 | +#define SIG_ERR ((__sighandler_t)-1) /* error return from signal */ | |
107 | 134 | |
108 | 135 | struct sigaction { |
109 | 136 | unsigned int sa_flags; |
include/asm-mips/system.h
... | ... | @@ -17,6 +17,7 @@ |
17 | 17 | |
18 | 18 | #include <asm/addrspace.h> |
19 | 19 | #include <asm/cpu-features.h> |
20 | +#include <asm/dsp.h> | |
20 | 21 | #include <asm/ptrace.h> |
21 | 22 | #include <asm/war.h> |
22 | 23 | #include <asm/interrupt.h> |
... | ... | @@ -154,9 +155,13 @@ |
154 | 155 | |
155 | 156 | struct task_struct; |
156 | 157 | |
157 | -#define switch_to(prev,next,last) \ | |
158 | -do { \ | |
159 | - (last) = resume(prev, next, next->thread_info); \ | |
158 | +#define switch_to(prev,next,last) \ | |
159 | +do { \ | |
160 | + if (cpu_has_dsp) \ | |
161 | + __save_dsp(prev); \ | |
162 | + (last) = resume(prev, next, next->thread_info); \ | |
163 | + if (cpu_has_dsp) \ | |
164 | + __restore_dsp(current); \ | |
160 | 165 | } while(0) |
161 | 166 | |
162 | 167 | #define ROT_IN_PIECES \ |