diff options
author | Paul Mundt <lethal@linux-sh.org> | 2008-09-21 06:04:55 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2008-09-21 06:04:55 -0400 |
commit | e7ab3cd251926d57ee11d7d320e8fb42c882ad22 (patch) | |
tree | 29dce1711413e010d30fb62c43cbe517a9de95bc /arch/sh/kernel/ptrace_32.c | |
parent | 4b4cf7595a8bce9b4dd64c241a8cb7336ecb9489 (diff) |
sh: Add FPU registers to regset interface.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/ptrace_32.c')
-rw-r--r-- | arch/sh/kernel/ptrace_32.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c index 0f44f2b51a60..29ca09d24ef8 100644 --- a/arch/sh/kernel/ptrace_32.c +++ b/arch/sh/kernel/ptrace_32.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <asm/processor.h> | 32 | #include <asm/processor.h> |
33 | #include <asm/mmu_context.h> | 33 | #include <asm/mmu_context.h> |
34 | #include <asm/syscalls.h> | 34 | #include <asm/syscalls.h> |
35 | #include <asm/fpu.h> | ||
35 | 36 | ||
36 | /* | 37 | /* |
37 | * This routine will get a word off of the process kernel stack. | 38 | * This routine will get a word off of the process kernel stack. |
@@ -145,6 +146,54 @@ static int genregs_set(struct task_struct *target, | |||
145 | return ret; | 146 | return ret; |
146 | } | 147 | } |
147 | 148 | ||
149 | #ifdef CONFIG_SH_FPU | ||
150 | int fpregs_get(struct task_struct *target, | ||
151 | const struct user_regset *regset, | ||
152 | unsigned int pos, unsigned int count, | ||
153 | void *kbuf, void __user *ubuf) | ||
154 | { | ||
155 | int ret; | ||
156 | |||
157 | ret = init_fpu(target); | ||
158 | if (ret) | ||
159 | return ret; | ||
160 | |||
161 | if ((boot_cpu_data.flags & CPU_HAS_FPU)) | ||
162 | return user_regset_copyout(&pos, &count, &kbuf, &ubuf, | ||
163 | &target->thread.fpu.hard, 0, -1); | ||
164 | |||
165 | return user_regset_copyout(&pos, &count, &kbuf, &ubuf, | ||
166 | &target->thread.fpu.soft, 0, -1); | ||
167 | } | ||
168 | |||
169 | static int fpregs_set(struct task_struct *target, | ||
170 | const struct user_regset *regset, | ||
171 | unsigned int pos, unsigned int count, | ||
172 | const void *kbuf, const void __user *ubuf) | ||
173 | { | ||
174 | int ret; | ||
175 | |||
176 | ret = init_fpu(target); | ||
177 | if (ret) | ||
178 | return ret; | ||
179 | |||
180 | set_stopped_child_used_math(target); | ||
181 | |||
182 | if ((boot_cpu_data.flags & CPU_HAS_FPU)) | ||
183 | return user_regset_copyin(&pos, &count, &kbuf, &ubuf, | ||
184 | &target->thread.fpu.hard, 0, -1); | ||
185 | |||
186 | return user_regset_copyin(&pos, &count, &kbuf, &ubuf, | ||
187 | &target->thread.fpu.soft, 0, -1); | ||
188 | } | ||
189 | |||
190 | static int fpregs_active(struct task_struct *target, | ||
191 | const struct user_regset *regset) | ||
192 | { | ||
193 | return tsk_used_math(target) ? regset->n : 0; | ||
194 | } | ||
195 | #endif | ||
196 | |||
148 | #ifdef CONFIG_SH_DSP | 197 | #ifdef CONFIG_SH_DSP |
149 | static int dspregs_get(struct task_struct *target, | 198 | static int dspregs_get(struct task_struct *target, |
150 | const struct user_regset *regset, | 199 | const struct user_regset *regset, |
@@ -194,6 +243,9 @@ static int dspregs_active(struct task_struct *target, | |||
194 | */ | 243 | */ |
195 | enum sh_regset { | 244 | enum sh_regset { |
196 | REGSET_GENERAL, | 245 | REGSET_GENERAL, |
246 | #ifdef CONFIG_SH_FPU | ||
247 | REGSET_FPU, | ||
248 | #endif | ||
197 | #ifdef CONFIG_SH_DSP | 249 | #ifdef CONFIG_SH_DSP |
198 | REGSET_DSP, | 250 | REGSET_DSP, |
199 | #endif | 251 | #endif |
@@ -214,6 +266,18 @@ static const struct user_regset sh_regsets[] = { | |||
214 | .set = genregs_set, | 266 | .set = genregs_set, |
215 | }, | 267 | }, |
216 | 268 | ||
269 | #ifdef CONFIG_SH_FPU | ||
270 | [REGSET_FPU] = { | ||
271 | .core_note_type = NT_PRFPREG, | ||
272 | .n = sizeof(struct user_fpu_struct) / sizeof(long), | ||
273 | .size = sizeof(long), | ||
274 | .align = sizeof(long), | ||
275 | .get = fpregs_get, | ||
276 | .set = fpregs_set, | ||
277 | .active = fpregs_active, | ||
278 | }, | ||
279 | #endif | ||
280 | |||
217 | #ifdef CONFIG_SH_DSP | 281 | #ifdef CONFIG_SH_DSP |
218 | [REGSET_DSP] = { | 282 | [REGSET_DSP] = { |
219 | .n = sizeof(struct pt_dspregs) / sizeof(long), | 283 | .n = sizeof(struct pt_dspregs) / sizeof(long), |
@@ -304,6 +368,18 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
304 | REGSET_GENERAL, | 368 | REGSET_GENERAL, |
305 | 0, sizeof(struct pt_regs), | 369 | 0, sizeof(struct pt_regs), |
306 | (const void __user *)data); | 370 | (const void __user *)data); |
371 | #ifdef CONFIG_SH_FPU | ||
372 | case PTRACE_GETFPREGS: | ||
373 | return copy_regset_to_user(child, &user_sh_native_view, | ||
374 | REGSET_FPU, | ||
375 | 0, sizeof(struct user_fpu_struct), | ||
376 | (void __user *)data); | ||
377 | case PTRACE_SETFPREGS: | ||
378 | return copy_regset_from_user(child, &user_sh_native_view, | ||
379 | REGSET_FPU, | ||
380 | 0, sizeof(struct user_fpu_struct), | ||
381 | (const void __user *)data); | ||
382 | #endif | ||
307 | #ifdef CONFIG_SH_DSP | 383 | #ifdef CONFIG_SH_DSP |
308 | case PTRACE_GETDSPREGS: | 384 | case PTRACE_GETDSPREGS: |
309 | return copy_regset_to_user(child, &user_sh_native_view, | 385 | return copy_regset_to_user(child, &user_sh_native_view, |