Commit | Line | Data |
---|---|---|
1da177e4 LT |
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 + h8300_register_offset[regno]); | |
38 | default: | |
39 | return *(unsigned long *)(task->thread.esp0 + h8300_register_offset[regno]); | |
40 | } | |
41 | } | |
42 | ||
43 | /* write register */ | |
44 | int 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 */ | |
857fb252 | 68 | void user_disable_single_step(struct task_struct *child) |
1da177e4 LT |
69 | { |
70 | *(unsigned short *)(child->thread.esp0 + h8300_register_offset[PT_EXR]) &= ~EXR_TRACE; | |
71 | } | |
72 | ||
73 | /* enable singlestep */ | |
857fb252 | 74 | void user_enable_single_step(struct task_struct *child) |
1da177e4 LT |
75 | { |
76 | *(unsigned short *)(child->thread.esp0 + h8300_register_offset[PT_EXR]) |= EXR_TRACE; | |
77 | } | |
78 | ||
79 | asmlinkage void trace_trap(unsigned long bp) | |
80 | { | |
81 | (void)bp; | |
82 | force_sig(SIGTRAP,current); | |
83 | } | |
84 |