diff options
author | Paul Mundt <lethal@linux-sh.org> | 2008-09-12 09:42:10 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2008-09-12 09:42:10 -0400 |
commit | 5dadb34394d59313e2e763ae8e2fc911e9fc557c (patch) | |
tree | 843585369634453507a9d226d6b1299eb33d14b0 | |
parent | 6bff1592d85c9fa1f1d9d4de1cd0e104279544a6 (diff) |
sh: Add DSP registers to regset interface.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r-- | arch/sh/Kconfig | 2 | ||||
-rw-r--r-- | arch/sh/include/asm/elf.h | 5 | ||||
-rw-r--r-- | arch/sh/include/asm/ptrace.h | 3 | ||||
-rw-r--r-- | arch/sh/kernel/ptrace_32.c | 86 |
4 files changed, 65 insertions, 31 deletions
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index f995d134ab3a..acaba1bdd8a6 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
@@ -23,7 +23,7 @@ config SUPERH32 | |||
23 | def_bool !SUPERH64 | 23 | def_bool !SUPERH64 |
24 | select HAVE_KPROBES | 24 | select HAVE_KPROBES |
25 | select HAVE_KRETPROBES | 25 | select HAVE_KRETPROBES |
26 | select HAVE_ARCH_TRACEHOOK if (!SH_FPU && !SH_DSP) | 26 | select HAVE_ARCH_TRACEHOOK if !SH_FPU |
27 | 27 | ||
28 | config SUPERH64 | 28 | config SUPERH64 |
29 | def_bool y if CPU_SH5 | 29 | def_bool y if CPU_SH5 |
diff --git a/arch/sh/include/asm/elf.h b/arch/sh/include/asm/elf.h index 455d9e1e1438..7c2363f8250e 100644 --- a/arch/sh/include/asm/elf.h +++ b/arch/sh/include/asm/elf.h | |||
@@ -108,11 +108,10 @@ typedef struct user_fpu_struct elf_fpregset_t; | |||
108 | #define elf_check_fdpic(x) ((x)->e_flags & EF_SH_FDPIC) | 108 | #define elf_check_fdpic(x) ((x)->e_flags & EF_SH_FDPIC) |
109 | #define elf_check_const_displacement(x) ((x)->e_flags & EF_SH_PIC) | 109 | #define elf_check_const_displacement(x) ((x)->e_flags & EF_SH_PIC) |
110 | 110 | ||
111 | #if defined(CONFIG_SUPERH32) && \ | 111 | #if defined(CONFIG_SUPERH32) && !defined(CONFIG_SH_FPU) |
112 | (!defined(CONFIG_SH_FPU) && !defined(CONFIG_SH_DSP)) | ||
113 | /* | 112 | /* |
114 | * Enable dump using regset for general purpose registers, use this as | 113 | * Enable dump using regset for general purpose registers, use this as |
115 | * the default once the FPU and DSP registers are moved over also. | 114 | * the default once the FPU registers are moved over also. |
116 | */ | 115 | */ |
117 | #define CORE_DUMP_USE_REGSET | 116 | #define CORE_DUMP_USE_REGSET |
118 | #endif | 117 | #endif |
diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h index bf73646e2d2b..3ad18e91bca6 100644 --- a/arch/sh/include/asm/ptrace.h +++ b/arch/sh/include/asm/ptrace.h | |||
@@ -123,6 +123,9 @@ extern void user_disable_single_step(struct task_struct *); | |||
123 | #define task_pt_regs(task) \ | 123 | #define task_pt_regs(task) \ |
124 | ((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE \ | 124 | ((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE \ |
125 | - sizeof(struct pt_dspregs) - sizeof(unsigned long)) - 1) | 125 | - sizeof(struct pt_dspregs) - sizeof(unsigned long)) - 1) |
126 | #define task_pt_dspregs(task) \ | ||
127 | ((struct pt_dspregs *) (task_stack_page(task) + THREAD_SIZE \ | ||
128 | - sizeof(unsigned long)) - 1) | ||
126 | #else | 129 | #else |
127 | #define task_pt_regs(task) \ | 130 | #define task_pt_regs(task) \ |
128 | ((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE \ | 131 | ((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE \ |
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c index 5e3ba10255cd..20b103f6c33b 100644 --- a/arch/sh/kernel/ptrace_32.c +++ b/arch/sh/kernel/ptrace_32.c | |||
@@ -145,11 +145,50 @@ static int genregs_set(struct task_struct *target, | |||
145 | return ret; | 145 | return ret; |
146 | } | 146 | } |
147 | 147 | ||
148 | #ifdef CONFIG_SH_DSP | ||
149 | static int dspregs_get(struct task_struct *target, | ||
150 | const struct user_regset *regset, | ||
151 | unsigned int pos, unsigned int count, | ||
152 | void *kbuf, void __user *ubuf) | ||
153 | { | ||
154 | const struct pt_dspregs *regs = task_pt_dspregs(target); | ||
155 | int ret; | ||
156 | |||
157 | ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, regs, | ||
158 | 0, sizeof(struct pt_dspregs)); | ||
159 | if (!ret) | ||
160 | ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, | ||
161 | sizeof(struct pt_dspregs), -1); | ||
162 | |||
163 | return ret; | ||
164 | } | ||
165 | |||
166 | static int dspregs_set(struct task_struct *target, | ||
167 | const struct user_regset *regset, | ||
168 | unsigned int pos, unsigned int count, | ||
169 | const void *kbuf, const void __user *ubuf) | ||
170 | { | ||
171 | struct pt_dspregs *regs = task_pt_dspregs(target); | ||
172 | int ret; | ||
173 | |||
174 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, regs, | ||
175 | 0, sizeof(struct pt_dspregs)); | ||
176 | if (!ret) | ||
177 | ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, | ||
178 | sizeof(struct pt_dspregs), -1); | ||
179 | |||
180 | return ret; | ||
181 | } | ||
182 | #endif | ||
183 | |||
148 | /* | 184 | /* |
149 | * These are our native regset flavours. | 185 | * These are our native regset flavours. |
150 | */ | 186 | */ |
151 | enum sh_regset { | 187 | enum sh_regset { |
152 | REGSET_GENERAL, | 188 | REGSET_GENERAL, |
189 | #ifdef CONFIG_SH_DSP | ||
190 | REGSET_DSP, | ||
191 | #endif | ||
153 | }; | 192 | }; |
154 | 193 | ||
155 | static const struct user_regset sh_regsets[] = { | 194 | static const struct user_regset sh_regsets[] = { |
@@ -166,6 +205,16 @@ static const struct user_regset sh_regsets[] = { | |||
166 | .get = genregs_get, | 205 | .get = genregs_get, |
167 | .set = genregs_set, | 206 | .set = genregs_set, |
168 | }, | 207 | }, |
208 | |||
209 | #ifdef CONFIG_SH_DSP | ||
210 | [REGSET_DSP] = { | ||
211 | .n = sizeof(struct pt_dspregs) / sizeof(long), | ||
212 | .size = sizeof(long), | ||
213 | .align = sizeof(long), | ||
214 | .get = dspregs_get, | ||
215 | .set = dspregs_set, | ||
216 | }, | ||
217 | #endif | ||
169 | }; | 218 | }; |
170 | 219 | ||
171 | static const struct user_regset_view user_sh_native_view = { | 220 | static const struct user_regset_view user_sh_native_view = { |
@@ -242,33 +291,16 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
242 | 0, sizeof(struct pt_regs), | 291 | 0, sizeof(struct pt_regs), |
243 | (const void __user *)data); | 292 | (const void __user *)data); |
244 | #ifdef CONFIG_SH_DSP | 293 | #ifdef CONFIG_SH_DSP |
245 | case PTRACE_GETDSPREGS: { | 294 | case PTRACE_GETDSPREGS: |
246 | unsigned long dp; | 295 | return copy_regset_to_user(child, &user_sh_native_view, |
247 | 296 | REGSET_DSP, | |
248 | ret = -EIO; | 297 | 0, sizeof(struct pt_dspregs), |
249 | dp = ((unsigned long) child) + THREAD_SIZE - | 298 | (void __user *)data); |
250 | sizeof(struct pt_dspregs); | 299 | case PTRACE_SETDSPREGS: |
251 | if (*((int *) (dp - 4)) == SR_FD) { | 300 | return copy_regset_from_user(child, &user_sh_native_view, |
252 | copy_to_user((void *)addr, (void *) dp, | 301 | REGSET_DSP, |
253 | sizeof(struct pt_dspregs)); | 302 | 0, sizeof(struct pt_dspregs), |
254 | ret = 0; | 303 | (const void __user *)data); |
255 | } | ||
256 | break; | ||
257 | } | ||
258 | |||
259 | case PTRACE_SETDSPREGS: { | ||
260 | unsigned long dp; | ||
261 | |||
262 | ret = -EIO; | ||
263 | dp = ((unsigned long) child) + THREAD_SIZE - | ||
264 | sizeof(struct pt_dspregs); | ||
265 | if (*((int *) (dp - 4)) == SR_FD) { | ||
266 | copy_from_user((void *) dp, (void *)addr, | ||
267 | sizeof(struct pt_dspregs)); | ||
268 | ret = 0; | ||
269 | } | ||
270 | break; | ||
271 | } | ||
272 | #endif | 304 | #endif |
273 | #ifdef CONFIG_BINFMT_ELF_FDPIC | 305 | #ifdef CONFIG_BINFMT_ELF_FDPIC |
274 | case PTRACE_GETFDPIC: { | 306 | case PTRACE_GETFDPIC: { |