4 * Copyright (C) 2012 Synopsys, Inc. (www.synopsys.com)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
11 #include <linux/kgdb.h>
12 #include <linux/sched.h>
13 #include <asm/disasm.h>
14 #include <asm/cacheflush.h>
16 static void to_gdb_regs(unsigned long *gdb_regs
, struct pt_regs
*kernel_regs
,
17 struct callee_regs
*cregs
)
21 for (regno
= 0; regno
<= 26; regno
++)
22 gdb_regs
[_R0
+ regno
] = get_reg(regno
, kernel_regs
, cregs
);
24 for (regno
= 27; regno
< GDB_MAX_REGS
; regno
++)
27 gdb_regs
[_FP
] = kernel_regs
->fp
;
28 gdb_regs
[__SP
] = kernel_regs
->sp
;
29 gdb_regs
[_BLINK
] = kernel_regs
->blink
;
30 gdb_regs
[_RET
] = kernel_regs
->ret
;
31 gdb_regs
[_STATUS32
] = kernel_regs
->status32
;
32 gdb_regs
[_LP_COUNT
] = kernel_regs
->lp_count
;
33 gdb_regs
[_LP_END
] = kernel_regs
->lp_end
;
34 gdb_regs
[_LP_START
] = kernel_regs
->lp_start
;
35 gdb_regs
[_BTA
] = kernel_regs
->bta
;
36 gdb_regs
[_STOP_PC
] = kernel_regs
->ret
;
39 static void from_gdb_regs(unsigned long *gdb_regs
, struct pt_regs
*kernel_regs
,
40 struct callee_regs
*cregs
)
44 for (regno
= 0; regno
<= 26; regno
++)
45 set_reg(regno
, gdb_regs
[regno
+ _R0
], kernel_regs
, cregs
);
47 kernel_regs
->fp
= gdb_regs
[_FP
];
48 kernel_regs
->sp
= gdb_regs
[__SP
];
49 kernel_regs
->blink
= gdb_regs
[_BLINK
];
50 kernel_regs
->ret
= gdb_regs
[_RET
];
51 kernel_regs
->status32
= gdb_regs
[_STATUS32
];
52 kernel_regs
->lp_count
= gdb_regs
[_LP_COUNT
];
53 kernel_regs
->lp_end
= gdb_regs
[_LP_END
];
54 kernel_regs
->lp_start
= gdb_regs
[_LP_START
];
55 kernel_regs
->bta
= gdb_regs
[_BTA
];
59 void pt_regs_to_gdb_regs(unsigned long *gdb_regs
, struct pt_regs
*kernel_regs
)
61 to_gdb_regs(gdb_regs
, kernel_regs
, (struct callee_regs
*)
62 current
->thread
.callee_reg
);
65 void gdb_regs_to_pt_regs(unsigned long *gdb_regs
, struct pt_regs
*kernel_regs
)
67 from_gdb_regs(gdb_regs
, kernel_regs
, (struct callee_regs
*)
68 current
->thread
.callee_reg
);
71 void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs
,
72 struct task_struct
*task
)
75 to_gdb_regs(gdb_regs
, task_pt_regs(task
),
76 (struct callee_regs
*) task
->thread
.callee_reg
);
79 struct single_step_data_t
{
81 unsigned long address
[2];
86 static void undo_single_step(struct pt_regs
*regs
)
88 if (single_step_data
.armed
) {
91 for (i
= 0; i
< (single_step_data
.is_branch
? 2 : 1); i
++) {
92 memcpy((void *) single_step_data
.address
[i
],
93 &single_step_data
.opcode
[i
],
96 flush_icache_range(single_step_data
.address
[i
],
97 single_step_data
.address
[i
] +
100 single_step_data
.armed
= 0;
104 static void place_trap(unsigned long address
, void *save
)
106 memcpy(save
, (void *) address
, BREAK_INSTR_SIZE
);
107 memcpy((void *) address
, &arch_kgdb_ops
.gdb_bpt_instr
,
109 flush_icache_range(address
, address
+ BREAK_INSTR_SIZE
);
112 static void do_single_step(struct pt_regs
*regs
)
114 single_step_data
.is_branch
= disasm_next_pc((unsigned long)
115 regs
->ret
, regs
, (struct callee_regs
*)
116 current
->thread
.callee_reg
,
117 &single_step_data
.address
[0],
118 &single_step_data
.address
[1]);
120 place_trap(single_step_data
.address
[0], &single_step_data
.opcode
[0]);
122 if (single_step_data
.is_branch
) {
123 place_trap(single_step_data
.address
[1],
124 &single_step_data
.opcode
[1]);
127 single_step_data
.armed
++;
130 int kgdb_arch_handle_exception(int e_vector
, int signo
, int err_code
,
131 char *remcomInBuffer
, char *remcomOutBuffer
,
132 struct pt_regs
*regs
)
137 undo_single_step(regs
);
139 switch (remcomInBuffer
[0]) {
142 ptr
= &remcomInBuffer
[1];
143 if (kgdb_hex2long(&ptr
, &addr
))
148 atomic_set(&kgdb_cpu_doing_single_step
, -1);
150 if (remcomInBuffer
[0] == 's') {
151 do_single_step(regs
);
152 atomic_set(&kgdb_cpu_doing_single_step
,
161 unsigned long kgdb_arch_pc(int exception
, struct pt_regs
*regs
)
163 return instruction_pointer(regs
);
166 int kgdb_arch_init(void)
168 single_step_data
.armed
= 0;
172 void kgdb_trap(struct pt_regs
*regs
)
174 /* trap_s 3 is used for breakpoints that overwrite existing
175 * instructions, while trap_s 4 is used for compiled breakpoints.
177 * with trap_s 3 breakpoints the original instruction needs to be
178 * restored and continuation needs to start at the location of the
181 * with trap_s 4 (compiled) breakpoints, continuation needs to
182 * start after the breakpoint.
184 if (regs
->ecr_param
== 3)
185 instruction_pointer(regs
) -= BREAK_INSTR_SIZE
;
187 kgdb_handle_exception(1, SIGTRAP
, 0, regs
);
190 void kgdb_arch_exit(void)
194 void kgdb_arch_set_pc(struct pt_regs
*regs
, unsigned long ip
)
196 instruction_pointer(regs
) = ip
;
199 static void kgdb_call_nmi_hook(void *ignored
)
201 kgdb_nmicallback(raw_smp_processor_id(), NULL
);
204 void kgdb_roundup_cpus(unsigned long flags
)
207 smp_call_function(kgdb_call_nmi_hook
, NULL
, 0);
211 struct kgdb_arch arch_kgdb_ops
= {
212 /* breakpoint instruction: TRAP_S 0x3 */
213 #ifdef CONFIG_CPU_BIG_ENDIAN
214 .gdb_bpt_instr
= {0x78, 0x7e},
216 .gdb_bpt_instr
= {0x7e, 0x78},