aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/ptrace.c
diff options
context:
space:
mode:
authorMichael Neuling <mikey@neuling.org>2008-06-25 00:07:18 -0400
committerPaul Mackerras <paulus@samba.org>2008-06-30 21:28:46 -0400
commitc6e6771b87d4e339d27f1383c8a808ae9b4ee5b8 (patch)
tree1900b7350ec685c3a31f2233fd88a57e34725b5c /arch/powerpc/kernel/ptrace.c
parent6f3d8e6947ec98e358514fc0f7b2e37fe88a21bb (diff)
powerpc: Introduce VSX thread_struct and CONFIG_VSX
The layout of the new VSR registers and how they overlap on top of the legacy FPR and VR registers is: VSR doubleword 0 VSR doubleword 1 ---------------------------------------------------------------- VSR[0] | FPR[0] | | ---------------------------------------------------------------- VSR[1] | FPR[1] | | ---------------------------------------------------------------- | ... | | | ... | | ---------------------------------------------------------------- VSR[30] | FPR[30] | | ---------------------------------------------------------------- VSR[31] | FPR[31] | | ---------------------------------------------------------------- VSR[32] | VR[0] | ---------------------------------------------------------------- VSR[33] | VR[1] | ---------------------------------------------------------------- | ... | | ... | ---------------------------------------------------------------- VSR[62] | VR[30] | ---------------------------------------------------------------- VSR[63] | VR[31] | ---------------------------------------------------------------- VSX has 64 128bit registers. The first 32 regs overlap with the FP registers and hence extend them with and additional 64 bits. The second 32 regs overlap with the VMX registers. This commit introduces the thread_struct changes required to reflect this register layout. Ptrace and signals code is updated so that the floating point registers are correctly accessed from the thread_struct when CONFIG_VSX is enabled. Signed-off-by: Michael Neuling <mikey@neuling.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/ptrace.c')
-rw-r--r--arch/powerpc/kernel/ptrace.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 59ff08704e94..70fbde84b83f 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -215,29 +215,56 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset,
215 unsigned int pos, unsigned int count, 215 unsigned int pos, unsigned int count,
216 void *kbuf, void __user *ubuf) 216 void *kbuf, void __user *ubuf)
217{ 217{
218#ifdef CONFIG_VSX
219 double buf[33];
220 int i;
221#endif
218 flush_fp_to_thread(target); 222 flush_fp_to_thread(target);
219 223
224#ifdef CONFIG_VSX
225 /* copy to local buffer then write that out */
226 for (i = 0; i < 32 ; i++)
227 buf[i] = target->thread.TS_FPR(i);
228 memcpy(&buf[32], &target->thread.fpscr, sizeof(double));
229 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
230
231#else
220 BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) != 232 BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) !=
221 offsetof(struct thread_struct, TS_FPR(32))); 233 offsetof(struct thread_struct, TS_FPR(32)));
222 234
223 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, 235 return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
224 &target->thread.fpr, 0, -1); 236 &target->thread.fpr, 0, -1);
237#endif
225} 238}
226 239
227static int fpr_set(struct task_struct *target, const struct user_regset *regset, 240static int fpr_set(struct task_struct *target, const struct user_regset *regset,
228 unsigned int pos, unsigned int count, 241 unsigned int pos, unsigned int count,
229 const void *kbuf, const void __user *ubuf) 242 const void *kbuf, const void __user *ubuf)
230{ 243{
244#ifdef CONFIG_VSX
245 double buf[33];
246 int i;
247#endif
231 flush_fp_to_thread(target); 248 flush_fp_to_thread(target);
232 249
250#ifdef CONFIG_VSX
251 /* copy to local buffer then write that out */
252 i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
253 if (i)
254 return i;
255 for (i = 0; i < 32 ; i++)
256 target->thread.TS_FPR(i) = buf[i];
257 memcpy(&target->thread.fpscr, &buf[32], sizeof(double));
258 return 0;
259#else
233 BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) != 260 BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) !=
234 offsetof(struct thread_struct, TS_FPR(32))); 261 offsetof(struct thread_struct, TS_FPR(32)));
235 262
236 return user_regset_copyin(&pos, &count, &kbuf, &ubuf, 263 return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
237 &target->thread.fpr, 0, -1); 264 &target->thread.fpr, 0, -1);
265#endif
238} 266}
239 267
240
241#ifdef CONFIG_ALTIVEC 268#ifdef CONFIG_ALTIVEC
242/* 269/*
243 * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go. 270 * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.