12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- /*
- * 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 user_disable_single_step(struct task_struct *child)
- {
- *(unsigned short *)(child->thread.esp0 + h8300_register_offset[PT_EXR]) &= ~EXR_TRACE;
- }
- /* enable singlestep */
- void user_enable_single_step(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);
- }
|