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 | |
parent | 10f650db1bcc193ea07d4f8c2f07315da38ea0c4 (diff) |
Support the MIPS32 / MIPS64 DSP ASE.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
34 files changed, 876 insertions, 139 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(); |
diff --git a/include/asm-mips/abi.h b/include/asm-mips/abi.h new file mode 100644 index 000000000000..2e7e651c3e3f --- /dev/null +++ b/include/asm-mips/abi.h | |||
@@ -0,0 +1,25 @@ | |||
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 */ | ||
diff --git a/include/asm-mips/cpu-features.h b/include/asm-mips/cpu-features.h index 012deda63e68..4930824a43aa 100644 --- a/include/asm-mips/cpu-features.h +++ b/include/asm-mips/cpu-features.h | |||
@@ -105,6 +105,10 @@ | |||
105 | #endif | 105 | #endif |
106 | #endif | 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 | * Certain CPUs may throw bizarre exceptions if not the whole cacheline | 113 | * Certain CPUs may throw bizarre exceptions if not the whole cacheline |
110 | * contains valid instructions. For these we ensure proper alignment of | 114 | * contains valid instructions. For these we ensure proper alignment of |
diff --git a/include/asm-mips/cpu.h b/include/asm-mips/cpu.h index a4f85a279c52..2a109a5e0932 100644 --- a/include/asm-mips/cpu.h +++ b/include/asm-mips/cpu.h | |||
@@ -77,6 +77,7 @@ | |||
77 | #define PRID_IMP_4KEMPR2 0x9100 | 77 | #define PRID_IMP_4KEMPR2 0x9100 |
78 | #define PRID_IMP_4KSD 0x9200 | 78 | #define PRID_IMP_4KSD 0x9200 |
79 | #define PRID_IMP_24K 0x9300 | 79 | #define PRID_IMP_24K 0x9300 |
80 | #define PRID_IMP_24KE 0x9600 | ||
80 | 81 | ||
81 | #define PRID_IMP_UNKNOWN 0xff00 | 82 | #define PRID_IMP_UNKNOWN 0xff00 |
82 | 83 | ||
@@ -232,5 +233,6 @@ | |||
232 | #define MIPS_ASE_MDMX 0x00000002 /* MIPS digital media extension */ | 233 | #define MIPS_ASE_MDMX 0x00000002 /* MIPS digital media extension */ |
233 | #define MIPS_ASE_MIPS3D 0x00000004 /* MIPS-3D */ | 234 | #define MIPS_ASE_MIPS3D 0x00000004 /* MIPS-3D */ |
234 | #define MIPS_ASE_SMARTMIPS 0x00000008 /* SmartMIPS */ | 235 | #define MIPS_ASE_SMARTMIPS 0x00000008 /* SmartMIPS */ |
236 | #define MIPS_ASE_DSP 0x00000010 /* Signal Processing ASE */ | ||
235 | 237 | ||
236 | #endif /* _ASM_CPU_H */ | 238 | #endif /* _ASM_CPU_H */ |
diff --git a/include/asm-mips/dsp.h b/include/asm-mips/dsp.h new file mode 100644 index 000000000000..50f556bb4978 --- /dev/null +++ b/include/asm-mips/dsp.h | |||
@@ -0,0 +1,83 @@ | |||
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 */ | ||
diff --git a/include/asm-mips/elf.h b/include/asm-mips/elf.h index bb031f3cd4db..a4db9ec95665 100644 --- a/include/asm-mips/elf.h +++ b/include/asm-mips/elf.h | |||
@@ -193,33 +193,76 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; | |||
193 | 193 | ||
194 | #ifdef __KERNEL__ | 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 | #ifdef CONFIG_32BIT | 202 | #ifdef CONFIG_32BIT |
197 | 203 | ||
198 | #define SET_PERSONALITY(ex, ibcs2) \ | 204 | #define SET_PERSONALITY(ex, ibcs2) \ |
199 | do { \ | 205 | do { \ |
200 | if (ibcs2) \ | 206 | if (ibcs2) \ |
201 | set_personality(PER_SVR4); \ | 207 | set_personality(PER_SVR4); \ |
202 | set_personality(PER_LINUX); \ | 208 | set_personality(PER_LINUX); \ |
209 | \ | ||
210 | current->thread.abi = &mips_abi; \ | ||
203 | } while (0) | 211 | } while (0) |
204 | 212 | ||
205 | #endif /* CONFIG_32BIT */ | 213 | #endif /* CONFIG_32BIT */ |
206 | 214 | ||
207 | #ifdef CONFIG_64BIT | 215 | #ifdef CONFIG_64BIT |
208 | 216 | ||
209 | #define SET_PERSONALITY(ex, ibcs2) \ | 217 | #ifdef CONFIG_MIPS32_N32 |
210 | do { current->thread.mflags &= ~MF_ABI_MASK; \ | 218 | #define __SET_PERSONALITY32_N32() \ |
211 | if ((ex).e_ident[EI_CLASS] == ELFCLASS32) { \ | 219 | do { \ |
212 | if ((((ex).e_flags & EF_MIPS_ABI2) != 0) && \ | 220 | current->thread.mflags |= MF_N32; \ |
213 | ((ex).e_flags & EF_MIPS_ABI) == 0) \ | 221 | current->thread.abi = &mips_abi_n32; \ |
214 | current->thread.mflags |= MF_N32; \ | 222 | } while (0) |
215 | else \ | 223 | #else |
216 | current->thread.mflags |= MF_O32; \ | 224 | #define __SET_PERSONALITY32_N32() \ |
217 | } else \ | 225 | do { } while (0) |
218 | current->thread.mflags |= MF_N64; \ | 226 | #endif |
219 | if (ibcs2) \ | 227 | |
220 | set_personality(PER_SVR4); \ | 228 | #ifdef CONFIG_MIPS32_O32 |
221 | else if (current->personality != PER_LINUX32) \ | 229 | #define __SET_PERSONALITY32_O32() \ |
222 | set_personality(PER_LINUX); \ | 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 | } while (0) | 266 | } while (0) |
224 | 267 | ||
225 | #endif /* CONFIG_64BIT */ | 268 | #endif /* CONFIG_64BIT */ |
diff --git a/include/asm-mips/inst.h b/include/asm-mips/inst.h index df912c2b381f..e0745f4ff624 100644 --- a/include/asm-mips/inst.h +++ b/include/asm-mips/inst.h | |||
@@ -62,10 +62,10 @@ enum rt_op { | |||
62 | spimi_op, unused_rt_op_0x05, unused_rt_op_0x06, unused_rt_op_0x07, | 62 | spimi_op, unused_rt_op_0x05, unused_rt_op_0x06, unused_rt_op_0x07, |
63 | tgei_op, tgeiu_op, tlti_op, tltiu_op, | 63 | tgei_op, tgeiu_op, tlti_op, tltiu_op, |
64 | teqi_op, unused_0x0d_rt_op, tnei_op, unused_0x0f_rt_op, | 64 | teqi_op, unused_0x0d_rt_op, tnei_op, unused_0x0f_rt_op, |
65 | bltzal_op, bgezal_op, bltzall_op, bgezall_op | 65 | bltzal_op, bgezal_op, bltzall_op, bgezall_op, |
66 | /* | 66 | rt_op_0x14, rt_op_0x15, rt_op_0x16, rt_op_0x17, |
67 | * The others (0x14 - 0x1f) are unused. | 67 | rt_op_0x18, rt_op_0x19, rt_op_0x1a, rt_op_0x1b, |
68 | */ | 68 | bposge32_op, rt_op_0x1d, rt_op_0x1e, rt_op_0x1f |
69 | }; | 69 | }; |
70 | 70 | ||
71 | /* | 71 | /* |
diff --git a/include/asm-mips/mach-ip22/cpu-feature-overrides.h b/include/asm-mips/mach-ip22/cpu-feature-overrides.h index 3c8896d9b133..a115940bd684 100644 --- a/include/asm-mips/mach-ip22/cpu-feature-overrides.h +++ b/include/asm-mips/mach-ip22/cpu-feature-overrides.h | |||
@@ -23,6 +23,8 @@ | |||
23 | #define cpu_has_dc_aliases (PAGE_SIZE < 0x4000) | 23 | #define cpu_has_dc_aliases (PAGE_SIZE < 0x4000) |
24 | #define cpu_has_ic_fills_f_dc 0 | 24 | #define cpu_has_ic_fills_f_dc 0 |
25 | 25 | ||
26 | #define cpu_has_dsp 0 | ||
27 | |||
26 | #define cpu_has_nofpuex 0 | 28 | #define cpu_has_nofpuex 0 |
27 | #define cpu_has_64bits 1 | 29 | #define cpu_has_64bits 1 |
28 | 30 | ||
diff --git a/include/asm-mips/mach-ip27/cpu-feature-overrides.h b/include/asm-mips/mach-ip27/cpu-feature-overrides.h index fe96d7358517..4c8a90051fd0 100644 --- a/include/asm-mips/mach-ip27/cpu-feature-overrides.h +++ b/include/asm-mips/mach-ip27/cpu-feature-overrides.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #define cpu_has_vtag_icache 0 | 25 | #define cpu_has_vtag_icache 0 |
26 | #define cpu_has_dc_aliases 0 | 26 | #define cpu_has_dc_aliases 0 |
27 | #define cpu_has_ic_fills_f_dc 0 | 27 | #define cpu_has_ic_fills_f_dc 0 |
28 | #define cpu_has_dsp 0 | ||
28 | #define cpu_icache_snoops_remote_store 1 | 29 | #define cpu_icache_snoops_remote_store 1 |
29 | 30 | ||
30 | #define cpu_has_nofpuex 0 | 31 | #define cpu_has_nofpuex 0 |
diff --git a/include/asm-mips/mach-ip32/cpu-feature-overrides.h b/include/asm-mips/mach-ip32/cpu-feature-overrides.h index 04713973c6c3..ab37fc1842ba 100644 --- a/include/asm-mips/mach-ip32/cpu-feature-overrides.h +++ b/include/asm-mips/mach-ip32/cpu-feature-overrides.h | |||
@@ -37,5 +37,6 @@ | |||
37 | #define cpu_has_ejtag 0 | 37 | #define cpu_has_ejtag 0 |
38 | #define cpu_has_vtag_icache 0 | 38 | #define cpu_has_vtag_icache 0 |
39 | #define cpu_has_ic_fills_f_dc 0 | 39 | #define cpu_has_ic_fills_f_dc 0 |
40 | #define cpu_has_dsp 0 | ||
40 | 41 | ||
41 | #endif /* __ASM_MACH_IP32_CPU_FEATURE_OVERRIDES_H */ | 42 | #endif /* __ASM_MACH_IP32_CPU_FEATURE_OVERRIDES_H */ |
diff --git a/include/asm-mips/mach-ja/cpu-feature-overrides.h b/include/asm-mips/mach-ja/cpu-feature-overrides.h index ca57e7db98bb..310609c0f4ad 100644 --- a/include/asm-mips/mach-ja/cpu-feature-overrides.h +++ b/include/asm-mips/mach-ja/cpu-feature-overrides.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #define cpu_has_vtag_icache 0 | 25 | #define cpu_has_vtag_icache 0 |
26 | #define cpu_has_dc_aliases 0 | 26 | #define cpu_has_dc_aliases 0 |
27 | #define cpu_has_ic_fills_f_dc 0 | 27 | #define cpu_has_ic_fills_f_dc 0 |
28 | #define cpu_has_dsp 0 | ||
28 | #define cpu_icache_snoops_remote_store 0 | 29 | #define cpu_icache_snoops_remote_store 0 |
29 | 30 | ||
30 | #define cpu_has_nofpuex 0 | 31 | #define cpu_has_nofpuex 0 |
diff --git a/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h b/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h index 7473512384bc..1812fc0408d3 100644 --- a/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h +++ b/include/asm-mips/mach-ocelot3/cpu-feature-overrides.h | |||
@@ -28,6 +28,7 @@ | |||
28 | #define cpu_has_vtag_icache 0 | 28 | #define cpu_has_vtag_icache 0 |
29 | #define cpu_has_dc_aliases 0 | 29 | #define cpu_has_dc_aliases 0 |
30 | #define cpu_has_ic_fills_f_dc 0 | 30 | #define cpu_has_ic_fills_f_dc 0 |
31 | #define cpu_has_dsp 0 | ||
31 | #define cpu_icache_snoops_remote_store 0 | 32 | #define cpu_icache_snoops_remote_store 0 |
32 | 33 | ||
33 | #define cpu_has_nofpuex 0 | 34 | #define cpu_has_nofpuex 0 |
diff --git a/include/asm-mips/mach-rm200/cpu-feature-overrides.h b/include/asm-mips/mach-rm200/cpu-feature-overrides.h index f48736032b2a..9b2a40524679 100644 --- a/include/asm-mips/mach-rm200/cpu-feature-overrides.h +++ b/include/asm-mips/mach-rm200/cpu-feature-overrides.h | |||
@@ -31,6 +31,7 @@ | |||
31 | #define cpu_has_vtag_icache 0 | 31 | #define cpu_has_vtag_icache 0 |
32 | #define cpu_has_dc_aliases (PAGE_SIZE < 0x4000) | 32 | #define cpu_has_dc_aliases (PAGE_SIZE < 0x4000) |
33 | #define cpu_has_ic_fills_f_dc 0 | 33 | #define cpu_has_ic_fills_f_dc 0 |
34 | #define cpu_has_dsp 0 | ||
34 | #define cpu_has_nofpuex 0 | 35 | #define cpu_has_nofpuex 0 |
35 | #define cpu_has_64bits 1 | 36 | #define cpu_has_64bits 1 |
36 | 37 | ||
diff --git a/include/asm-mips/mach-sibyte/cpu-feature-overrides.h b/include/asm-mips/mach-sibyte/cpu-feature-overrides.h index a3a2cc6014b2..193a666cd131 100644 --- a/include/asm-mips/mach-sibyte/cpu-feature-overrides.h +++ b/include/asm-mips/mach-sibyte/cpu-feature-overrides.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #define cpu_has_vtag_icache 1 | 25 | #define cpu_has_vtag_icache 1 |
26 | #define cpu_has_dc_aliases 0 | 26 | #define cpu_has_dc_aliases 0 |
27 | #define cpu_has_ic_fills_f_dc 0 | 27 | #define cpu_has_ic_fills_f_dc 0 |
28 | #define cpu_has_dsp 0 | ||
28 | #define cpu_icache_snoops_remote_store 0 | 29 | #define cpu_icache_snoops_remote_store 0 |
29 | 30 | ||
30 | #define cpu_has_nofpuex 0 | 31 | #define cpu_has_nofpuex 0 |
diff --git a/include/asm-mips/mach-yosemite/cpu-feature-overrides.h b/include/asm-mips/mach-yosemite/cpu-feature-overrides.h index 58603e3daca6..63e94342e087 100644 --- a/include/asm-mips/mach-yosemite/cpu-feature-overrides.h +++ b/include/asm-mips/mach-yosemite/cpu-feature-overrides.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #define cpu_has_vtag_icache 0 | 25 | #define cpu_has_vtag_icache 0 |
26 | #define cpu_has_dc_aliases 0 | 26 | #define cpu_has_dc_aliases 0 |
27 | #define cpu_has_ic_fills_f_dc 0 | 27 | #define cpu_has_ic_fills_f_dc 0 |
28 | #define cpu_has_dsp 0 | ||
28 | #define cpu_icache_snoops_remote_store 0 | 29 | #define cpu_icache_snoops_remote_store 0 |
29 | 30 | ||
30 | #define cpu_has_nofpuex 0 | 31 | #define cpu_has_nofpuex 0 |
diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h index 9b0ce451286e..1fad6ec1daa0 100644 --- a/include/asm-mips/mipsregs.h +++ b/include/asm-mips/mipsregs.h | |||
@@ -281,6 +281,11 @@ | |||
281 | #define ST0_DL (_ULCAST_(1) << 24) | 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 | * Bitfields in the TX39 family CP0 Configuration Register 3 | 289 | * Bitfields in the TX39 family CP0 Configuration Register 3 |
285 | */ | 290 | */ |
286 | #define TX39_CONF_ICS_SHIFT 19 | 291 | #define TX39_CONF_ICS_SHIFT 19 |
@@ -510,6 +515,7 @@ | |||
510 | #define MIPS_CONF3_VINT (_ULCAST_(1) << 5) | 515 | #define MIPS_CONF3_VINT (_ULCAST_(1) << 5) |
511 | #define MIPS_CONF3_VEIC (_ULCAST_(1) << 6) | 516 | #define MIPS_CONF3_VEIC (_ULCAST_(1) << 6) |
512 | #define MIPS_CONF3_LPA (_ULCAST_(1) << 7) | 517 | #define MIPS_CONF3_LPA (_ULCAST_(1) << 7) |
518 | #define MIPS_CONF3_DSP (_ULCAST_(1) << 10) | ||
513 | 519 | ||
514 | /* | 520 | /* |
515 | * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register. | 521 | * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register. |
@@ -986,6 +992,287 @@ do { \ | |||
986 | : "=r" (__res)); \ | 992 | : "=r" (__res)); \ |
987 | __res;}) | 993 | __res;}) |
988 | 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 | ||
1275 | |||
989 | /* | 1276 | /* |
990 | * TLB operations. | 1277 | * TLB operations. |
991 | * | 1278 | * |
diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h index d6466aa09fb7..f1980c6c3bcc 100644 --- a/include/asm-mips/processor.h +++ b/include/asm-mips/processor.h | |||
@@ -96,12 +96,26 @@ union mips_fpu_union { | |||
96 | {{0,},} \ | 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 | typedef struct { | 111 | typedef struct { |
100 | unsigned long seg; | 112 | unsigned long seg; |
101 | } mm_segment_t; | 113 | } mm_segment_t; |
102 | 114 | ||
103 | #define ARCH_MIN_TASKALIGN 8 | 115 | #define ARCH_MIN_TASKALIGN 8 |
104 | 116 | ||
117 | struct mips_abi; | ||
118 | |||
105 | /* | 119 | /* |
106 | * If you change thread_struct remember to change the #defines below too! | 120 | * If you change thread_struct remember to change the #defines below too! |
107 | */ | 121 | */ |
@@ -117,6 +131,9 @@ struct thread_struct { | |||
117 | /* Saved fpu/fpu emulator stuff. */ | 131 | /* Saved fpu/fpu emulator stuff. */ |
118 | union mips_fpu_union fpu; | 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 | /* Other stuff associated with the thread. */ | 137 | /* Other stuff associated with the thread. */ |
121 | unsigned long cp0_badvaddr; /* Last user fault */ | 138 | unsigned long cp0_badvaddr; /* Last user fault */ |
122 | unsigned long cp0_baduaddr; /* Last kernel fault accessing USEG */ | 139 | unsigned long cp0_baduaddr; /* Last kernel fault accessing USEG */ |
@@ -129,6 +146,7 @@ struct thread_struct { | |||
129 | unsigned long mflags; | 146 | unsigned long mflags; |
130 | unsigned long irix_trampoline; /* Wheee... */ | 147 | unsigned long irix_trampoline; /* Wheee... */ |
131 | unsigned long irix_oldctx; | 148 | unsigned long irix_oldctx; |
149 | struct mips_abi *abi; | ||
132 | }; | 150 | }; |
133 | 151 | ||
134 | #define MF_ABI_MASK (MF_32BIT_REGS | MF_32BIT_ADDR) | 152 | #define MF_ABI_MASK (MF_32BIT_REGS | MF_32BIT_ADDR) |
@@ -151,6 +169,10 @@ struct thread_struct { | |||
151 | */ \ | 169 | */ \ |
152 | INIT_FPU, \ | 170 | INIT_FPU, \ |
153 | /* \ | 171 | /* \ |
172 | * saved dsp/dsp emulator stuff \ | ||
173 | */ \ | ||
174 | INIT_DSP, \ | ||
175 | /* \ | ||
154 | * Other stuff associated with the process \ | 176 | * Other stuff associated with the process \ |
155 | */ \ | 177 | */ \ |
156 | 0, 0, 0, 0, \ | 178 | 0, 0, 0, 0, \ |
diff --git a/include/asm-mips/ptrace.h b/include/asm-mips/ptrace.h index 2b5c624c3d4f..8441a5ae96e3 100644 --- a/include/asm-mips/ptrace.h +++ b/include/asm-mips/ptrace.h | |||
@@ -22,6 +22,8 @@ | |||
22 | #define MMLO 68 | 22 | #define MMLO 68 |
23 | #define FPC_CSR 69 | 23 | #define FPC_CSR 69 |
24 | #define FPC_EIR 70 | 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 | * This struct defines the way the registers are stored on the stack during a | 29 | * This struct defines the way the registers are stored on the stack during a |
@@ -38,8 +40,8 @@ struct pt_regs { | |||
38 | 40 | ||
39 | /* Saved special registers. */ | 41 | /* Saved special registers. */ |
40 | unsigned long cp0_status; | 42 | unsigned long cp0_status; |
41 | unsigned long lo; | ||
42 | unsigned long hi; | 43 | unsigned long hi; |
44 | unsigned long lo; | ||
43 | unsigned long cp0_badvaddr; | 45 | unsigned long cp0_badvaddr; |
44 | unsigned long cp0_cause; | 46 | unsigned long cp0_cause; |
45 | unsigned long cp0_epc; | 47 | unsigned long cp0_epc; |
diff --git a/include/asm-mips/sigcontext.h b/include/asm-mips/sigcontext.h index f7fbebaa0744..8edabb0be23f 100644 --- a/include/asm-mips/sigcontext.h +++ b/include/asm-mips/sigcontext.h | |||
@@ -27,14 +27,15 @@ struct sigcontext { | |||
27 | unsigned int sc_fpc_csr; | 27 | unsigned int sc_fpc_csr; |
28 | unsigned int sc_fpc_eir; /* Unused */ | 28 | unsigned int sc_fpc_eir; /* Unused */ |
29 | unsigned int sc_used_math; | 29 | unsigned int sc_used_math; |
30 | unsigned int sc_ssflags; /* Unused */ | 30 | unsigned int sc_dsp; /* dsp status, was sc_ssflags */ |
31 | unsigned long long sc_mdhi; | 31 | unsigned long long sc_mdhi; |
32 | unsigned long long sc_mdlo; | 32 | unsigned long long sc_mdlo; |
33 | 33 | unsigned long sc_hi1; /* Was sc_cause */ | |
34 | unsigned int sc_cause; /* Unused */ | 34 | unsigned long sc_lo1; /* Was sc_badvaddr */ |
35 | unsigned int sc_badvaddr; /* Unused */ | 35 | unsigned long sc_hi2; /* Was sc_sigset[4] */ |
36 | 36 | unsigned long sc_lo2; | |
37 | unsigned long sc_sigset[4]; /* kernel's sigset_t */ | 37 | unsigned long sc_hi3; |
38 | unsigned long sc_lo3; | ||
38 | }; | 39 | }; |
39 | 40 | ||
40 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ | 41 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ |
@@ -48,19 +49,19 @@ struct sigcontext { | |||
48 | * Warning: this structure illdefined with sc_badvaddr being just an unsigned | 49 | * Warning: this structure illdefined with sc_badvaddr being just an unsigned |
49 | * int so it was changed to unsigned long in 2.6.0-test1. This may break | 50 | * int so it was changed to unsigned long in 2.6.0-test1. This may break |
50 | * binary compatibility - no prisoners. | 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 | struct sigcontext { | 55 | struct sigcontext { |
53 | unsigned long sc_regs[32]; | 56 | unsigned long sc_regs[32]; |
54 | unsigned long sc_fpregs[32]; | 57 | unsigned long sc_fpregs[32]; |
55 | unsigned long sc_mdhi; | 58 | unsigned long sc_hi[4]; |
56 | unsigned long sc_mdlo; | 59 | unsigned long sc_lo[4]; |
57 | unsigned long sc_pc; | 60 | unsigned long sc_pc; |
58 | unsigned long sc_badvaddr; | ||
59 | unsigned int sc_status; | ||
60 | unsigned int sc_fpc_csr; | 61 | unsigned int sc_fpc_csr; |
61 | unsigned int sc_fpc_eir; | ||
62 | unsigned int sc_used_math; | 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 | #ifdef __KERNEL__ | 67 | #ifdef __KERNEL__ |
@@ -68,23 +69,24 @@ struct sigcontext { | |||
68 | #include <linux/posix_types.h> | 69 | #include <linux/posix_types.h> |
69 | 70 | ||
70 | struct sigcontext32 { | 71 | struct sigcontext32 { |
71 | __u32 sc_regmask; /* Unused */ | 72 | __u32 sc_regmask; /* Unused */ |
72 | __u32 sc_status; | 73 | __u32 sc_status; |
73 | __u64 sc_pc; | 74 | __u64 sc_pc; |
74 | __u64 sc_regs[32]; | 75 | __u64 sc_regs[32]; |
75 | __u64 sc_fpregs[32]; | 76 | __u64 sc_fpregs[32]; |
76 | __u32 sc_ownedfp; /* Unused */ | 77 | __u32 sc_ownedfp; /* Unused */ |
77 | __u32 sc_fpc_csr; | 78 | __u32 sc_fpc_csr; |
78 | __u32 sc_fpc_eir; /* Unused */ | 79 | __u32 sc_fpc_eir; /* Unused */ |
79 | __u32 sc_used_math; | 80 | __u32 sc_used_math; |
80 | __u32 sc_ssflags; /* Unused */ | 81 | __u32 sc_dsp; /* dsp status, was sc_ssflags */ |
81 | __u64 sc_mdhi; | 82 | __u64 sc_mdhi; |
82 | __u64 sc_mdlo; | 83 | __u64 sc_mdlo; |
83 | 84 | __u32 sc_hi1; /* Was sc_cause */ | |
84 | __u32 sc_cause; /* Unused */ | 85 | __u32 sc_lo1; /* Was sc_badvaddr */ |
85 | __u32 sc_badvaddr; /* Unused */ | 86 | __u32 sc_hi2; /* Was sc_sigset[4] */ |
86 | 87 | __u32 sc_lo2; | |
87 | __u32 sc_sigset[4]; /* kernel's sigset_t */ | 88 | __u32 sc_hi3; |
89 | __u32 sc_lo3; | ||
88 | }; | 90 | }; |
89 | #endif /* __KERNEL__ */ | 91 | #endif /* __KERNEL__ */ |
90 | 92 | ||
diff --git a/include/asm-mips/signal.h b/include/asm-mips/signal.h index f2c470f1d369..8ca539e80d87 100644 --- a/include/asm-mips/signal.h +++ b/include/asm-mips/signal.h | |||
@@ -98,12 +98,39 @@ typedef unsigned long old_sigset_t; /* at least 32 bits */ | |||
98 | #define MINSIGSTKSZ 2048 | 98 | #define MINSIGSTKSZ 2048 |
99 | #define SIGSTKSZ 8192 | 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 | #define SIG_BLOCK 1 /* for blocking signals */ | 120 | #define SIG_BLOCK 1 /* for blocking signals */ |
102 | #define SIG_UNBLOCK 2 /* for unblocking signals */ | 121 | #define SIG_UNBLOCK 2 /* for unblocking signals */ |
103 | #define SIG_SETMASK 3 /* for setting the signal mask */ | 122 | #define SIG_SETMASK 3 /* for setting the signal mask */ |
104 | #define SIG_SETMASK32 256 /* Goodie from SGI for BSD compatibility: | 123 | #define SIG_SETMASK32 256 /* Goodie from SGI for BSD compatibility: |
105 | set only the low 32 bit of the sigset. */ | 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 | struct sigaction { | 135 | struct sigaction { |
109 | unsigned int sa_flags; | 136 | unsigned int sa_flags; |
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h index 6663efd49b27..cd3a6bca7abd 100644 --- a/include/asm-mips/system.h +++ b/include/asm-mips/system.h | |||
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | #include <asm/addrspace.h> | 18 | #include <asm/addrspace.h> |
19 | #include <asm/cpu-features.h> | 19 | #include <asm/cpu-features.h> |
20 | #include <asm/dsp.h> | ||
20 | #include <asm/ptrace.h> | 21 | #include <asm/ptrace.h> |
21 | #include <asm/war.h> | 22 | #include <asm/war.h> |
22 | #include <asm/interrupt.h> | 23 | #include <asm/interrupt.h> |
@@ -154,9 +155,13 @@ extern asmlinkage void *resume(void *last, void *next, void *next_ti); | |||
154 | 155 | ||
155 | struct task_struct; | 156 | struct task_struct; |
156 | 157 | ||
157 | #define switch_to(prev,next,last) \ | 158 | #define switch_to(prev,next,last) \ |
158 | do { \ | 159 | do { \ |
159 | (last) = resume(prev, next, next->thread_info); \ | 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 | } while(0) | 165 | } while(0) |
161 | 166 | ||
162 | #define ROT_IN_PIECES \ | 167 | #define ROT_IN_PIECES \ |