1/* 2 * linux/arch/h8300/platform/h8s/ptrace_h8s.c 3 * ptrace cpu depend helper functions 4 * 5 * Yoshinori Sato <ysato@users.sourceforge.jp> 6 * 7 * This file is subject to the terms and conditions of the GNU General 8 * Public License. See the file COPYING in the main directory of 9 * this archive for more details. 10 */ 11 12#include <linux/linkage.h> 13#include <linux/sched.h> 14#include <linux/errno.h> 15#include <asm/ptrace.h> 16 17#define CCR_MASK 0x6f 18#define EXR_TRACE 0x80 19 20/* Mapping from PT_xxx to the stack offset at which the register is 21 saved. Notice that usp has no stack-slot and needs to be treated 22 specially (see get_reg/put_reg below). */ 23static const int h8300_register_offset[] = { 24 PT_REG(er1), PT_REG(er2), PT_REG(er3), PT_REG(er4), 25 PT_REG(er5), PT_REG(er6), PT_REG(er0), PT_REG(orig_er0), 26 PT_REG(ccr), PT_REG(pc), 0, PT_REG(exr) 27}; 28 29/* read register */ 30long h8300_get_reg(struct task_struct *task, int regno) 31{ 32 switch (regno) { 33 case PT_USP: 34 return task->thread.usp + sizeof(long)*2 + 2; 35 case PT_CCR: 36 case PT_EXR: 37 return *(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]); 38 default: 39 return *(unsigned long *)(task->thread.esp0 + h8300_register_offset[regno]); 40 } 41} 42 43/* write register */ 44int h8300_put_reg(struct task_struct *task, int regno, unsigned long data) 45{ 46 unsigned short oldccr; 47 switch (regno) { 48 case PT_USP: 49 task->thread.usp = data - sizeof(long)*2 - 2; 50 case PT_CCR: 51 oldccr = *(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]); 52 oldccr &= ~CCR_MASK; 53 data &= CCR_MASK; 54 data |= oldccr; 55 *(unsigned short *)(task->thread.esp0 + h8300_register_offset[regno]) = data; 56 break; 57 case PT_EXR: 58 /* exr modify not support */ 59 return -EIO; 60 default: 61 *(unsigned long *)(task->thread.esp0 + h8300_register_offset[regno]) = data; 62 break; 63 } 64 return 0; 65} 66 67/* disable singlestep */ 68void user_disable_single_step(struct task_struct *child) 69{ 70 *(unsigned short *)(child->thread.esp0 + h8300_register_offset[PT_EXR]) &= ~EXR_TRACE; 71} 72 73/* enable singlestep */ 74void user_enable_single_step(struct task_struct *child) 75{ 76 *(unsigned short *)(child->thread.esp0 + h8300_register_offset[PT_EXR]) |= EXR_TRACE; 77} 78 79asmlinkage void trace_trap(unsigned long bp) 80{ 81 (void)bp; 82 force_sig(SIGTRAP,current); 83} 84