]> err.no Git - linux-2.6/blobdiff - arch/powerpc/kernel/ptrace.c
powerpc: Introduce VSX thread_struct and CONFIG_VSX
[linux-2.6] / arch / powerpc / kernel / ptrace.c
index 2a9fe97e452129c9cd843e8e404d327df8605f66..70fbde84b83f28fa9e6487421d2f5ffaa10ff117 100644 (file)
@@ -215,29 +215,56 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset,
                   unsigned int pos, unsigned int count,
                   void *kbuf, void __user *ubuf)
 {
+#ifdef CONFIG_VSX
+       double buf[33];
+       int i;
+#endif
        flush_fp_to_thread(target);
 
+#ifdef CONFIG_VSX
+       /* copy to local buffer then write that out */
+       for (i = 0; i < 32 ; i++)
+               buf[i] = target->thread.TS_FPR(i);
+       memcpy(&buf[32], &target->thread.fpscr, sizeof(double));
+       return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
+
+#else
        BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) !=
-                    offsetof(struct thread_struct, fpr[32]));
+                    offsetof(struct thread_struct, TS_FPR(32)));
 
        return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
                                   &target->thread.fpr, 0, -1);
+#endif
 }
 
 static int fpr_set(struct task_struct *target, const struct user_regset *regset,
                   unsigned int pos, unsigned int count,
                   const void *kbuf, const void __user *ubuf)
 {
+#ifdef CONFIG_VSX
+       double buf[33];
+       int i;
+#endif
        flush_fp_to_thread(target);
 
+#ifdef CONFIG_VSX
+       /* copy to local buffer then write that out */
+       i = user_regset_copyin(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
+       if (i)
+               return i;
+       for (i = 0; i < 32 ; i++)
+               target->thread.TS_FPR(i) = buf[i];
+       memcpy(&target->thread.fpscr, &buf[32], sizeof(double));
+       return 0;
+#else
        BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) !=
-                    offsetof(struct thread_struct, fpr[32]));
+                    offsetof(struct thread_struct, TS_FPR(32)));
 
        return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
                                  &target->thread.fpr, 0, -1);
+#endif
 }
 
-
 #ifdef CONFIG_ALTIVEC
 /*
  * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
@@ -728,7 +755,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                        tmp = ptrace_get_reg(child, (int) index);
                } else {
                        flush_fp_to_thread(child);
-                       tmp = ((unsigned long *)child->thread.fpr)[index - PT_FPR0];
+                       tmp = ((unsigned long *)child->thread.fpr)
+                               [TS_FPRWIDTH * (index - PT_FPR0)];
                }
                ret = put_user(tmp,(unsigned long __user *) data);
                break;
@@ -755,7 +783,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                        ret = ptrace_put_reg(child, index, data);
                } else {
                        flush_fp_to_thread(child);
-                       ((unsigned long *)child->thread.fpr)[index - PT_FPR0] = data;
+                       ((unsigned long *)child->thread.fpr)
+                               [TS_FPRWIDTH * (index - PT_FPR0)] = data;
                        ret = 0;
                }
                break;