Logo Search packages:      
Sourcecode: linux version File versions

ptrace_h8s.c

/*
 *  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);
}


Generated by  Doxygen 1.6.0   Back to index