OSDN Git Service

clean up 3rd round
[uclinux-h8/linux.git] / arch / h8300 / kernel / ptrace_s.c
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). */
23 static 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 */
30 long 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 +
38                                        h8300_register_offset[regno]);
39         default:
40             return *(unsigned long *)(task->thread.esp0 +
41                                       h8300_register_offset[regno]);
42         }
43 }
44
45 /* write register */
46 int h8300_put_reg(struct task_struct *task, int regno, unsigned long data)
47 {
48         unsigned short oldccr;
49         switch (regno) {
50         case PT_USP:
51                 task->thread.usp = data - sizeof(long)*2 - 2;
52         case PT_CCR:
53                 oldccr = *(unsigned short *)(task->thread.esp0 +
54                                              h8300_register_offset[regno]);
55                 oldccr &= ~CCR_MASK;
56                 data &= CCR_MASK;
57                 data |= oldccr;
58                 *(unsigned short *)(task->thread.esp0 +
59                                     h8300_register_offset[regno]) = data;
60                 break;
61         case PT_EXR:
62                 /* exr modify not support */
63                 return -EIO;
64         default:
65                 *(unsigned long *)(task->thread.esp0 +
66                                    h8300_register_offset[regno]) = data;
67                 break;
68         }
69         return 0;
70 }
71
72 /* disable singlestep */
73 void user_disable_single_step(struct task_struct *child)
74 {
75         *(unsigned short *)(child->thread.esp0 +
76                             h8300_register_offset[PT_EXR]) &= ~EXR_TRACE;
77 }
78
79 /* enable singlestep */
80 void user_enable_single_step(struct task_struct *child)
81 {
82         *(unsigned short *)(child->thread.esp0 +
83                             h8300_register_offset[PT_EXR]) |= EXR_TRACE;
84 }
85
86 asmlinkage void trace_trap(unsigned long bp)
87 {
88         (void)bp;
89         force_sig(SIGTRAP, current);
90 }