aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/signal-common.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/signal-common.h')
-rw-r--r--arch/mips/kernel/signal-common.h90
1 files changed, 80 insertions, 10 deletions
diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h
index f9234df53253..0f66ae5838b9 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
11static inline int 13static inline int
12setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc) 14setup_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:
61static inline int 84static inline int
62restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) 85restore_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]); \
@@ -112,7 +160,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
112static inline void * 160static inline void *
113get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) 161get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
114{ 162{
115 unsigned long sp, almask; 163 unsigned long sp;
116 164
117 /* Default to using normal stack */ 165 /* Default to using normal stack */
118 sp = regs->regs[29]; 166 sp = regs->regs[29];
@@ -128,10 +176,32 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
128 if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0)) 176 if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
129 sp = current->sas_ss_sp + current->sas_ss_size; 177 sp = current->sas_ss_sp + current->sas_ss_size;
130 178
131 if (PLAT_TRAMPOLINE_STUFF_LINE) 179 return (void *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? 32 : ALMASK));
132 almask = ~(PLAT_TRAMPOLINE_STUFF_LINE - 1); 180}
133 else 181
134 almask = ALMASK; 182static inline int install_sigtramp(unsigned int __user *tramp,
183 unsigned int syscall)
184{
185 int err;
186
187 /*
188 * Set up the return code ...
189 *
190 * li v0, __NR__foo_sigreturn
191 * syscall
192 */
193
194 err = __put_user(0x24020000 + syscall, tramp + 0);
195 err |= __put_user(0x0000000c , tramp + 1);
196 if (ICACHE_REFILLS_WORKAROUND_WAR) {
197 err |= __put_user(0, tramp + 2);
198 err |= __put_user(0, tramp + 3);
199 err |= __put_user(0, tramp + 4);
200 err |= __put_user(0, tramp + 5);
201 err |= __put_user(0, tramp + 6);
202 err |= __put_user(0, tramp + 7);
203 }
204 flush_cache_sigtramp((unsigned long) tramp);
135 205
136 return (void *)((sp - frame_size) & almask); 206 return err;
137} 207}