4 * Copyright (C) 2015 Yoshinori Sato <ysato@users.sourceforge.jp>
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
11 #include <linux/ptrace.h>
12 #include <linux/kgdb.h>
13 #include <linux/kdebug.h>
16 struct dbg_reg_def_t dbg_reg_def
[DBG_MAX_REG_NUM
] = {
17 { "er0", GDB_SIZEOF_REG
, offsetof(struct pt_regs
, er0
) },
18 { "er1", GDB_SIZEOF_REG
, offsetof(struct pt_regs
, er1
) },
19 { "er2", GDB_SIZEOF_REG
, offsetof(struct pt_regs
, er2
) },
20 { "er3", GDB_SIZEOF_REG
, offsetof(struct pt_regs
, er3
) },
21 { "er4", GDB_SIZEOF_REG
, offsetof(struct pt_regs
, er4
) },
22 { "er5", GDB_SIZEOF_REG
, offsetof(struct pt_regs
, er5
) },
23 { "er6", GDB_SIZEOF_REG
, offsetof(struct pt_regs
, er6
) },
24 { "sp", GDB_SIZEOF_REG
, offsetof(struct pt_regs
, sp
) },
25 { "ccr", GDB_SIZEOF_REG
, offsetof(struct pt_regs
, ccr
) },
26 { "pc", GDB_SIZEOF_REG
, offsetof(struct pt_regs
, pc
) },
27 { "cycles", GDB_SIZEOF_REG
, -1 },
28 #if defined(CONFIG_CPU_H8S)
29 { "exr", GDB_SIZEOF_REG
, offsetof(struct pt_regs
, exr
) },
31 { "tick", GDB_SIZEOF_REG
, -1 },
32 { "inst", GDB_SIZEOF_REG
, -1 },
35 char *dbg_get_reg(int regno
, void *mem
, struct pt_regs
*regs
)
37 if (regno
>= DBG_MAX_REG_NUM
|| regno
< 0)
42 #if defined(CONFIG_CPU_H8S)
45 *(u32
*)mem
= *(u16
*)((void *)regs
+
46 dbg_reg_def
[regno
].offset
);
49 if (dbg_reg_def
[regno
].offset
>= 0)
50 memcpy(mem
, (void *)regs
+ dbg_reg_def
[regno
].offset
,
51 dbg_reg_def
[regno
].size
);
53 memset(mem
, 0, dbg_reg_def
[regno
].size
);
56 return dbg_reg_def
[regno
].name
;
59 int dbg_set_reg(int regno
, void *mem
, struct pt_regs
*regs
)
61 if (regno
>= DBG_MAX_REG_NUM
|| regno
< 0)
66 #if defined(CONFIG_CPU_H8S)
69 *(u16
*)((void *)regs
+
70 dbg_reg_def
[regno
].offset
) = *(u32
*)mem
;
73 memcpy((void *)regs
+ dbg_reg_def
[regno
].offset
, mem
,
74 dbg_reg_def
[regno
].size
);
79 asmlinkage
void h8300_kgdb_trap(struct pt_regs
*regs
)
81 regs
->pc
&= 0x00ffffff;
82 if (kgdb_handle_exception(10, SIGTRAP
, 0, regs
))
84 if (*(u16
*)(regs
->pc
) == *(u16
*)&arch_kgdb_ops
.gdb_bpt_instr
)
85 regs
->pc
+= BREAK_INSTR_SIZE
;
86 regs
->pc
|= regs
->ccr
<< 24;
89 void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs
, struct task_struct
*p
)
91 memset((char *)gdb_regs
, 0, NUMREGBYTES
);
92 gdb_regs
[GDB_SP
] = p
->thread
.ksp
;
93 gdb_regs
[GDB_PC
] = KSTK_EIP(p
);
96 void kgdb_arch_set_pc(struct pt_regs
*regs
, unsigned long pc
)
101 int kgdb_arch_handle_exception(int vector
, int signo
, int err_code
,
102 char *remcom_in_buffer
, char *remcom_out_buffer
,
103 struct pt_regs
*regs
)
108 switch (remcom_in_buffer
[0]) {
111 /* handle the optional parameters */
112 ptr
= &remcom_in_buffer
[1];
113 if (kgdb_hex2long(&ptr
, &addr
))
119 return -1; /* this means that we do not want to exit from the handler */
122 int kgdb_arch_init(void)
127 void kgdb_arch_exit(void)
132 const struct kgdb_arch arch_kgdb_ops
= {
133 /* Breakpoint instruction: trapa #2 */
134 .gdb_bpt_instr
= { 0x57, 0x20 },