diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/h8300/platform/h8s/ptrace_h8s.c |
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/h8300/platform/h8s/ptrace_h8s.c')
-rw-r--r-- | arch/h8300/platform/h8s/ptrace_h8s.c | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/arch/h8300/platform/h8s/ptrace_h8s.c b/arch/h8300/platform/h8s/ptrace_h8s.c new file mode 100644 index 00000000000..e8cd46f9255 --- /dev/null +++ b/arch/h8300/platform/h8s/ptrace_h8s.c @@ -0,0 +1,84 @@ +/* + * linux/arch/h8300/platform/h8s/ptrace_h8s.c + * ptrace cpu depend helper functions + * + * Yoshinori Sato <ysato@users.sourceforge.jp> + * + * This file is subject to the terms and conditions of the GNU General + * Public License. See the file COPYING in the main directory of + * this archive for more details. + */ + +#include <linux/linkage.h> +#include <linux/sched.h> +#include <linux/errno.h> +#include <asm/ptrace.h> + +#define CCR_MASK 0x6f +#define EXR_TRACE 0x80 + +/* Mapping from PT_xxx to the stack offset at which the register is + saved. Notice that usp has no stack-slot and needs to be treated + specially (see get_reg/put_reg below). */ +static const int h8300_register_offset[] = { + PT_REG(er1), PT_REG(er2), PT_REG(er3), PT_REG(er4), + PT_REG(er5), PT_REG(er6), PT_REG(er0), PT_REG(orig_er0), + PT_REG(ccr), PT_REG(pc), 0, PT_REG(exr) +}; + +/* read register */ +long h8300_get_reg(struct task_struct *task, int regno) +{ + switch (regno) { + case PT_USP: + return task->thread.usp + sizeof(long)*2 + 2; + case PT_CCR: + case PT_EXR: + return *(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]); + default: + return *(unsigned long *)(task->thread.esp0 + h8300_register_offset[regno]); + } +} + +/* write register */ +int h8300_put_reg(struct task_struct *task, int regno, unsigned long data) +{ + unsigned short oldccr; + switch (regno) { + case PT_USP: + task->thread.usp = data - sizeof(long)*2 - 2; + case PT_CCR: + oldccr = *(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]); + oldccr &= ~CCR_MASK; + data &= CCR_MASK; + data |= oldccr; + *(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]) = data; + break; + case PT_EXR: + /* exr modify not support */ + return -EIO; + default: + *(unsigned long *)(task->thread.esp0 + h8300_register_offset[regno]) = data; + break; + } + return 0; +} + +/* disable singlestep */ +void h8300_disable_trace(struct task_struct *child) +{ + *(unsigned short *)(child->thread.esp0 + h8300_register_offset[PT_EXR]) &= ~EXR_TRACE; +} + +/* enable singlestep */ +void h8300_enable_trace(struct task_struct *child) +{ + *(unsigned short *)(child->thread.esp0 + h8300_register_offset[PT_EXR]) |= EXR_TRACE; +} + +asmlinkage void trace_trap(unsigned long bp) +{ + (void)bp; + force_sig(SIGTRAP,current); +} + |