|
@@ -11,6 +11,9 @@
|
|
|
|
|
|
#ifndef _PPC64_PTRACE_COMMON_H
|
|
|
#define _PPC64_PTRACE_COMMON_H
|
|
|
+
|
|
|
+#include <linux/config.h>
|
|
|
+
|
|
|
/*
|
|
|
* Set of msr bits that gdb can change on behalf of a process.
|
|
|
*/
|
|
@@ -69,4 +72,73 @@ static inline void clear_single_step(struct task_struct *task)
|
|
|
clear_ti_thread_flag(task->thread_info, TIF_SINGLESTEP);
|
|
|
}
|
|
|
|
|
|
+#ifdef CONFIG_ALTIVEC
|
|
|
+/*
|
|
|
+ * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
|
|
|
+ * The transfer totals 34 quadword. Quadwords 0-31 contain the
|
|
|
+ * corresponding vector registers. Quadword 32 contains the vscr as the
|
|
|
+ * last word (offset 12) within that quadword. Quadword 33 contains the
|
|
|
+ * vrsave as the first word (offset 0) within the quadword.
|
|
|
+ *
|
|
|
+ * This definition of the VMX state is compatible with the current PPC32
|
|
|
+ * ptrace interface. This allows signal handling and ptrace to use the
|
|
|
+ * same structures. This also simplifies the implementation of a bi-arch
|
|
|
+ * (combined (32- and 64-bit) gdb.
|
|
|
+ */
|
|
|
+
|
|
|
+/*
|
|
|
+ * Get contents of AltiVec register state in task TASK
|
|
|
+ */
|
|
|
+static inline int get_vrregs(unsigned long __user *data,
|
|
|
+ struct task_struct *task)
|
|
|
+{
|
|
|
+ unsigned long regsize;
|
|
|
+
|
|
|
+ /* copy AltiVec registers VR[0] .. VR[31] */
|
|
|
+ regsize = 32 * sizeof(vector128);
|
|
|
+ if (copy_to_user(data, task->thread.vr, regsize))
|
|
|
+ return -EFAULT;
|
|
|
+ data += (regsize / sizeof(unsigned long));
|
|
|
+
|
|
|
+ /* copy VSCR */
|
|
|
+ regsize = 1 * sizeof(vector128);
|
|
|
+ if (copy_to_user(data, &task->thread.vscr, regsize))
|
|
|
+ return -EFAULT;
|
|
|
+ data += (regsize / sizeof(unsigned long));
|
|
|
+
|
|
|
+ /* copy VRSAVE */
|
|
|
+ if (put_user(task->thread.vrsave, (u32 __user *)data))
|
|
|
+ return -EFAULT;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Write contents of AltiVec register state into task TASK.
|
|
|
+ */
|
|
|
+static inline int set_vrregs(struct task_struct *task,
|
|
|
+ unsigned long __user *data)
|
|
|
+{
|
|
|
+ unsigned long regsize;
|
|
|
+
|
|
|
+ /* copy AltiVec registers VR[0] .. VR[31] */
|
|
|
+ regsize = 32 * sizeof(vector128);
|
|
|
+ if (copy_from_user(task->thread.vr, data, regsize))
|
|
|
+ return -EFAULT;
|
|
|
+ data += (regsize / sizeof(unsigned long));
|
|
|
+
|
|
|
+ /* copy VSCR */
|
|
|
+ regsize = 1 * sizeof(vector128);
|
|
|
+ if (copy_from_user(&task->thread.vscr, data, regsize))
|
|
|
+ return -EFAULT;
|
|
|
+ data += (regsize / sizeof(unsigned long));
|
|
|
+
|
|
|
+ /* copy VRSAVE */
|
|
|
+ if (get_user(task->thread.vrsave, (u32 __user *)data))
|
|
|
+ return -EFAULT;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
#endif /* _PPC64_PTRACE_COMMON_H */
|