]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - include/asm-ppc64/ptrace-common.h
[PATCH] ppc64: Add PTRACE_{GET|SET}VRREGS
[linux-2.6-omap-h63xx.git] / include / asm-ppc64 / ptrace-common.h
1 /*
2  *  linux/arch/ppc64/kernel/ptrace-common.h
3  *
4  *    Copyright (c) 2002 Stephen Rothwell, IBM Coproration
5  *    Extracted from ptrace.c and ptrace32.c
6  *
7  * This file is subject to the terms and conditions of the GNU General
8  * Public License.  See the file README.legal in the main directory of
9  * this archive for more details.
10  */
11
12 #ifndef _PPC64_PTRACE_COMMON_H
13 #define _PPC64_PTRACE_COMMON_H
14
15 #include <linux/config.h>
16
17 /*
18  * Set of msr bits that gdb can change on behalf of a process.
19  */
20 #define MSR_DEBUGCHANGE (MSR_FE0 | MSR_SE | MSR_BE | MSR_FE1)
21
22 /*
23  * Get contents of register REGNO in task TASK.
24  */
25 static inline unsigned long get_reg(struct task_struct *task, int regno)
26 {
27         unsigned long tmp = 0;
28
29         /*
30          * Put the correct FP bits in, they might be wrong as a result
31          * of our lazy FP restore.
32          */
33         if (regno == PT_MSR) {
34                 tmp = ((unsigned long *)task->thread.regs)[PT_MSR];
35                 tmp |= task->thread.fpexc_mode;
36         } else if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long))) {
37                 tmp = ((unsigned long *)task->thread.regs)[regno];
38         }
39
40         return tmp;
41 }
42
43 /*
44  * Write contents of register REGNO in task TASK.
45  */
46 static inline int put_reg(struct task_struct *task, int regno,
47                           unsigned long data)
48 {
49         if (regno < PT_SOFTE) {
50                 if (regno == PT_MSR)
51                         data = (data & MSR_DEBUGCHANGE)
52                                 | (task->thread.regs->msr & ~MSR_DEBUGCHANGE);
53                 ((unsigned long *)task->thread.regs)[regno] = data;
54                 return 0;
55         }
56         return -EIO;
57 }
58
59 static inline void set_single_step(struct task_struct *task)
60 {
61         struct pt_regs *regs = task->thread.regs;
62         if (regs != NULL)
63                 regs->msr |= MSR_SE;
64         set_ti_thread_flag(task->thread_info, TIF_SINGLESTEP);
65 }
66
67 static inline void clear_single_step(struct task_struct *task)
68 {
69         struct pt_regs *regs = task->thread.regs;
70         if (regs != NULL)
71                 regs->msr &= ~MSR_SE;
72         clear_ti_thread_flag(task->thread_info, TIF_SINGLESTEP);
73 }
74
75 #ifdef CONFIG_ALTIVEC
76 /*
77  * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
78  * The transfer totals 34 quadword.  Quadwords 0-31 contain the
79  * corresponding vector registers.  Quadword 32 contains the vscr as the
80  * last word (offset 12) within that quadword.  Quadword 33 contains the
81  * vrsave as the first word (offset 0) within the quadword.
82  *
83  * This definition of the VMX state is compatible with the current PPC32
84  * ptrace interface.  This allows signal handling and ptrace to use the
85  * same structures.  This also simplifies the implementation of a bi-arch
86  * (combined (32- and 64-bit) gdb.
87  */
88
89 /*
90  * Get contents of AltiVec register state in task TASK
91  */
92 static inline int get_vrregs(unsigned long __user *data,
93                              struct task_struct *task)
94 {
95         unsigned long regsize;
96
97         /* copy AltiVec registers VR[0] .. VR[31] */
98         regsize = 32 * sizeof(vector128);
99         if (copy_to_user(data, task->thread.vr, regsize))
100                 return -EFAULT;
101         data += (regsize / sizeof(unsigned long));
102
103         /* copy VSCR */
104         regsize = 1 * sizeof(vector128);
105         if (copy_to_user(data, &task->thread.vscr, regsize))
106                 return -EFAULT;
107         data += (regsize / sizeof(unsigned long));
108
109         /* copy VRSAVE */
110         if (put_user(task->thread.vrsave, (u32 __user *)data))
111                 return -EFAULT;
112
113         return 0;
114 }
115
116 /*
117  * Write contents of AltiVec register state into task TASK.
118  */
119 static inline int set_vrregs(struct task_struct *task,
120                              unsigned long __user *data)
121 {
122         unsigned long regsize;
123
124         /* copy AltiVec registers VR[0] .. VR[31] */
125         regsize = 32 * sizeof(vector128);
126         if (copy_from_user(task->thread.vr, data, regsize))
127                 return -EFAULT;
128         data += (regsize / sizeof(unsigned long));
129
130         /* copy VSCR */
131         regsize = 1 * sizeof(vector128);
132         if (copy_from_user(&task->thread.vscr, data, regsize))
133                 return -EFAULT;
134         data += (regsize / sizeof(unsigned long));
135
136         /* copy VRSAVE */
137         if (get_user(task->thread.vrsave, (u32 __user *)data))
138                 return -EFAULT;
139
140         return 0;
141 }
142 #endif
143
144 #endif /* _PPC64_PTRACE_COMMON_H */