aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/mn10300/include/asm/thread_info.h4
-rw-r--r--arch/mn10300/kernel/kgdb.c322
-rw-r--r--arch/mn10300/kernel/switch_to.S111
3 files changed, 425 insertions, 12 deletions
diff --git a/arch/mn10300/include/asm/thread_info.h b/arch/mn10300/include/asm/thread_info.h
index aa07a4a5d794..c139fa17e2e4 100644
--- a/arch/mn10300/include/asm/thread_info.h
+++ b/arch/mn10300/include/asm/thread_info.h
@@ -129,7 +129,11 @@ static inline unsigned long current_stack_pointer(void)
129#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL) 129#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL)
130#endif 130#endif
131 131
132#ifndef CONFIG_KGDB
132#define free_thread_info(ti) kfree((ti)) 133#define free_thread_info(ti) kfree((ti))
134#else
135extern void free_thread_info(struct thread_info *);
136#endif
133#define get_thread_info(ti) get_task_struct((ti)->task) 137#define get_thread_info(ti) get_task_struct((ti)->task)
134#define put_thread_info(ti) put_task_struct((ti)->task) 138#define put_thread_info(ti) put_task_struct((ti)->task)
135 139
diff --git a/arch/mn10300/kernel/kgdb.c b/arch/mn10300/kernel/kgdb.c
index 7d575f553099..f6c981db2a36 100644
--- a/arch/mn10300/kernel/kgdb.c
+++ b/arch/mn10300/kernel/kgdb.c
@@ -9,6 +9,7 @@
9 * 2 of the Licence, or (at your option) any later version. 9 * 2 of the Licence, or (at your option) any later version.
10 */ 10 */
11 11
12#include <linux/slab.h>
12#include <linux/ptrace.h> 13#include <linux/ptrace.h>
13#include <linux/kgdb.h> 14#include <linux/kgdb.h>
14#include <linux/uaccess.h> 15#include <linux/uaccess.h>
@@ -19,6 +20,13 @@
19#include "internal.h" 20#include "internal.h"
20 21
21/* 22/*
23 * Software single-stepping breakpoint save (used by __switch_to())
24 */
25static struct thread_info *kgdb_sstep_thread;
26u8 *kgdb_sstep_bp_addr[2];
27u8 kgdb_sstep_bp[2];
28
29/*
22 * Copy kernel exception frame registers to the GDB register file 30 * Copy kernel exception frame registers to the GDB register file
23 */ 31 */
24void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs) 32void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
@@ -118,8 +126,293 @@ struct kgdb_arch arch_kgdb_ops = {
118 .flags = KGDB_HW_BREAKPOINT, 126 .flags = KGDB_HW_BREAKPOINT,
119}; 127};
120 128
129static const unsigned char mn10300_kgdb_insn_sizes[256] =
130{
131 /* 1 2 3 4 5 6 7 8 9 a b c d e f */
132 1, 3, 3, 3, 1, 3, 3, 3, 1, 3, 3, 3, 1, 3, 3, 3, /* 0 */
133 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 1 */
134 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, /* 2 */
135 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, /* 3 */
136 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, /* 4 */
137 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, /* 5 */
138 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6 */
139 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 7 */
140 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* 8 */
141 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* 9 */
142 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* a */
143 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* b */
144 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 2, /* c */
145 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d */
146 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* e */
147 0, 2, 2, 2, 2, 2, 2, 4, 0, 3, 0, 4, 0, 6, 7, 1 /* f */
148};
149
121/* 150/*
122 * Handle unknown packets and [Ccs] packets 151 * Attempt to emulate single stepping by means of breakpoint instructions.
152 * Although there is a single-step trace flag in EPSW, its use is not
153 * sufficiently documented and is only intended for use with the JTAG debugger.
154 */
155static int kgdb_arch_do_singlestep(struct pt_regs *regs)
156{
157 unsigned long arg;
158 unsigned size;
159 u8 *pc = (u8 *)regs->pc, *sp = (u8 *)(regs + 1), cur;
160 u8 *x = NULL, *y = NULL;
161 int ret;
162
163 ret = probe_kernel_read(&cur, pc, 1);
164 if (ret < 0)
165 return ret;
166
167 size = mn10300_kgdb_insn_sizes[cur];
168 if (size > 0) {
169 x = pc + size;
170 goto set_x;
171 }
172
173 switch (cur) {
174 /* Bxx (d8,PC) */
175 case 0xc0 ... 0xca:
176 ret = probe_kernel_read(&arg, pc + 1, 1);
177 if (ret < 0)
178 return ret;
179 x = pc + 2;
180 if (arg >= 0 && arg <= 2)
181 goto set_x;
182 y = pc + (s8)arg;
183 goto set_x_and_y;
184
185 /* LXX (d8,PC) */
186 case 0xd0 ... 0xda:
187 x = pc + 1;
188 if (regs->pc == regs->lar)
189 goto set_x;
190 y = (u8 *)regs->lar;
191 goto set_x_and_y;
192
193 /* SETLB - loads the next four bytes into the LIR register
194 * (which mustn't include a breakpoint instruction) */
195 case 0xdb:
196 x = pc + 5;
197 goto set_x;
198
199 /* JMP (d16,PC) or CALL (d16,PC) */
200 case 0xcc:
201 case 0xcd:
202 ret = probe_kernel_read(&arg, pc + 1, 2);
203 if (ret < 0)
204 return ret;
205 x = pc + (s16)arg;
206 goto set_x;
207
208 /* JMP (d32,PC) or CALL (d32,PC) */
209 case 0xdc:
210 case 0xdd:
211 ret = probe_kernel_read(&arg, pc + 1, 4);
212 if (ret < 0)
213 return ret;
214 x = pc + (s32)arg;
215 goto set_x;
216
217 /* RETF */
218 case 0xde:
219 x = (u8 *)regs->mdr;
220 goto set_x;
221
222 /* RET */
223 case 0xdf:
224 ret = probe_kernel_read(&arg, pc + 2, 1);
225 if (ret < 0)
226 return ret;
227 ret = probe_kernel_read(&x, sp + (s8)arg, 4);
228 if (ret < 0)
229 return ret;
230 goto set_x;
231
232 case 0xf0:
233 ret = probe_kernel_read(&cur, pc + 1, 1);
234 if (ret < 0)
235 return ret;
236
237 if (cur >= 0xf0 && cur <= 0xf7) {
238 /* JMP (An) / CALLS (An) */
239 switch (cur & 3) {
240 case 0: x = (u8 *)regs->a0; break;
241 case 1: x = (u8 *)regs->a1; break;
242 case 2: x = (u8 *)regs->a2; break;
243 case 3: x = (u8 *)regs->a3; break;
244 }
245 goto set_x;
246 } else if (cur == 0xfc) {
247 /* RETS */
248 ret = probe_kernel_read(&x, sp, 4);
249 if (ret < 0)
250 return ret;
251 goto set_x;
252 } else if (cur == 0xfd) {
253 /* RTI */
254 ret = probe_kernel_read(&x, sp + 4, 4);
255 if (ret < 0)
256 return ret;
257 goto set_x;
258 } else {
259 x = pc + 2;
260 goto set_x;
261 }
262 break;
263
264 /* potential 3-byte conditional branches */
265 case 0xf8:
266 ret = probe_kernel_read(&cur, pc + 1, 1);
267 if (ret < 0)
268 return ret;
269 x = pc + 3;
270
271 if (cur >= 0xe8 && cur <= 0xeb) {
272 ret = probe_kernel_read(&arg, pc + 2, 1);
273 if (ret < 0)
274 return ret;
275 if (arg >= 0 && arg <= 3)
276 goto set_x;
277 y = pc + (s8)arg;
278 goto set_x_and_y;
279 }
280 goto set_x;
281
282 case 0xfa:
283 ret = probe_kernel_read(&cur, pc + 1, 1);
284 if (ret < 0)
285 return ret;
286
287 if (cur == 0xff) {
288 /* CALLS (d16,PC) */
289 ret = probe_kernel_read(&arg, pc + 2, 2);
290 if (ret < 0)
291 return ret;
292 x = pc + (s16)arg;
293 goto set_x;
294 }
295
296 x = pc + 4;
297 goto set_x;
298
299 case 0xfc:
300 ret = probe_kernel_read(&cur, pc + 1, 1);
301 if (ret < 0)
302 return ret;
303
304 if (cur == 0xff) {
305 /* CALLS (d32,PC) */
306 ret = probe_kernel_read(&arg, pc + 2, 4);
307 if (ret < 0)
308 return ret;
309 x = pc + (s32)arg;
310 goto set_x;
311 }
312
313 x = pc + 6;
314 goto set_x;
315 }
316
317 return 0;
318
319set_x:
320 kgdb_sstep_bp_addr[0] = x;
321 kgdb_sstep_bp_addr[1] = NULL;
322 ret = probe_kernel_read(&kgdb_sstep_bp[0], x, 1);
323 if (ret < 0)
324 return ret;
325 ret = probe_kernel_write(x, &arch_kgdb_ops.gdb_bpt_instr, 1);
326 if (ret < 0)
327 return ret;
328 kgdb_sstep_thread = current_thread_info();
329 debugger_local_cache_flushinv_one(x);
330 return ret;
331
332set_x_and_y:
333 kgdb_sstep_bp_addr[0] = x;
334 kgdb_sstep_bp_addr[1] = y;
335 ret = probe_kernel_read(&kgdb_sstep_bp[0], x, 1);
336 if (ret < 0)
337 return ret;
338 ret = probe_kernel_read(&kgdb_sstep_bp[1], y, 1);
339 if (ret < 0)
340 return ret;
341 ret = probe_kernel_write(x, &arch_kgdb_ops.gdb_bpt_instr, 1);
342 if (ret < 0)
343 return ret;
344 ret = probe_kernel_write(y, &arch_kgdb_ops.gdb_bpt_instr, 1);
345 if (ret < 0) {
346 probe_kernel_write(kgdb_sstep_bp_addr[0],
347 &kgdb_sstep_bp[0], 1);
348 } else {
349 kgdb_sstep_thread = current_thread_info();
350 }
351 debugger_local_cache_flushinv_one(x);
352 debugger_local_cache_flushinv_one(y);
353 return ret;
354}
355
356/*
357 * Remove emplaced single-step breakpoints, returning true if we hit one of
358 * them.
359 */
360static bool kgdb_arch_undo_singlestep(struct pt_regs *regs)
361{
362 bool hit = false;
363 u8 *x = kgdb_sstep_bp_addr[0], *y = kgdb_sstep_bp_addr[1];
364 u8 opcode;
365
366 if (kgdb_sstep_thread == current_thread_info()) {
367 if (x) {
368 if (x == (u8 *)regs->pc)
369 hit = true;
370 if (probe_kernel_read(&opcode, x,
371 1) < 0 ||
372 opcode != 0xff)
373 BUG();
374 probe_kernel_write(x, &kgdb_sstep_bp[0], 1);
375 debugger_local_cache_flushinv_one(x);
376 }
377 if (y) {
378 if (y == (u8 *)regs->pc)
379 hit = true;
380 if (probe_kernel_read(&opcode, y,
381 1) < 0 ||
382 opcode != 0xff)
383 BUG();
384 probe_kernel_write(y, &kgdb_sstep_bp[1], 1);
385 debugger_local_cache_flushinv_one(y);
386 }
387 }
388
389 kgdb_sstep_bp_addr[0] = NULL;
390 kgdb_sstep_bp_addr[1] = NULL;
391 kgdb_sstep_thread = NULL;
392 return hit;
393}
394
395/*
396 * Catch a single-step-pending thread being deleted and make sure the global
397 * single-step state is cleared. At this point the breakpoints should have
398 * been removed by __switch_to().
399 */
400void free_thread_info(struct thread_info *ti)
401{
402 if (kgdb_sstep_thread == ti) {
403 kgdb_sstep_thread = NULL;
404
405 /* However, we may now be running in degraded mode, with most
406 * of the CPUs disabled until such a time as KGDB is reentered,
407 * so force immediate reentry */
408 kgdb_breakpoint();
409 }
410 kfree(ti);
411}
412
413/*
414 * Handle unknown packets and [CcsDk] packets
415 * - at this point breakpoints have been installed
123 */ 416 */
124int kgdb_arch_handle_exception(int vector, int signo, int err_code, 417int kgdb_arch_handle_exception(int vector, int signo, int err_code,
125 char *remcom_in_buffer, char *remcom_out_buffer, 418 char *remcom_in_buffer, char *remcom_out_buffer,
@@ -130,21 +423,22 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code,
130 423
131 switch (remcom_in_buffer[0]) { 424 switch (remcom_in_buffer[0]) {
132 case 'c': 425 case 'c':
133 if (kgdb_contthread && kgdb_contthread != current) { 426 case 's':
134 strcpy(remcom_out_buffer, "E00");
135 break;
136 }
137
138 kgdb_contthread = NULL;
139
140 /* try to read optional parameter, pc unchanged if no parm */ 427 /* try to read optional parameter, pc unchanged if no parm */
141 ptr = &remcom_in_buffer[1]; 428 ptr = &remcom_in_buffer[1];
142 if (kgdb_hex2long(&ptr, &addr)) 429 if (kgdb_hex2long(&ptr, &addr))
143 regs->pc = addr; 430 regs->pc = addr;
144 return 0; 431 case 'D':
432 case 'k':
433 atomic_set(&kgdb_cpu_doing_single_step, -1);
145 434
146 case 's': 435 if (remcom_in_buffer[0] == 's') {
147 break; /* we don't do hardware single stepping */ 436 kgdb_arch_do_singlestep(regs);
437 kgdb_single_step = 1;
438 atomic_set(&kgdb_cpu_doing_single_step,
439 raw_smp_processor_id());
440 }
441 return 0;
148 } 442 }
149 return -1; /* this means that we do not want to exit from the handler */ 443 return -1; /* this means that we do not want to exit from the handler */
150} 444}
@@ -158,6 +452,12 @@ int debugger_intercept(enum exception_code excep, int signo, int si_code,
158{ 452{
159 int ret; 453 int ret;
160 454
455 if (kgdb_arch_undo_singlestep(regs)) {
456 excep = EXCEP_TRAP;
457 signo = SIGTRAP;
458 si_code = TRAP_TRACE;
459 }
460
161 ret = kgdb_handle_exception(excep, signo, si_code, regs); 461 ret = kgdb_handle_exception(excep, signo, si_code, regs);
162 462
163 debugger_local_cache_flushinv(); 463 debugger_local_cache_flushinv();
diff --git a/arch/mn10300/kernel/switch_to.S b/arch/mn10300/kernel/switch_to.S
index 9074d0fb8788..de3e74fc9ea0 100644
--- a/arch/mn10300/kernel/switch_to.S
+++ b/arch/mn10300/kernel/switch_to.S
@@ -39,11 +39,17 @@ ENTRY(__switch_to)
39 39
40 # save prev context 40 # save prev context
41 mov __switch_back,d0 41 mov __switch_back,d0
42 mov d0,(THREAD_PC,a0)
43 mov sp,a2 42 mov sp,a2
44 mov a2,(THREAD_SP,a0) 43 mov a2,(THREAD_SP,a0)
45 mov a3,(THREAD_A3,a0) 44 mov a3,(THREAD_A3,a0)
46 45
46#ifdef CONFIG_KGDB
47 btst 0xff,(kgdb_single_step)
48 bne __switch_to__lift_sstep_bp
49__switch_to__continue:
50#endif
51 mov d0,(THREAD_PC,a0)
52
47 mov (THREAD_A3,a1),a3 53 mov (THREAD_A3,a1),a3
48 mov (THREAD_SP,a1),a2 54 mov (THREAD_SP,a1),a2
49 55
@@ -68,3 +74,106 @@ ENTRY(__switch_to)
68__switch_back: 74__switch_back:
69 and ~EPSW_NMID,epsw 75 and ~EPSW_NMID,epsw
70 ret [d2,d3,a2,a3,exreg1],32 76 ret [d2,d3,a2,a3,exreg1],32
77
78#ifdef CONFIG_KGDB
79###############################################################################
80#
81# Lift the single-step breakpoints when the task being traced is switched out
82# A0 = prev
83# A1 = next
84#
85###############################################################################
86__switch_to__lift_sstep_bp:
87 add -12,sp
88 mov a0,e4
89 mov a1,e5
90
91 # Clear the single-step flag to prevent us coming this way until we get
92 # switched back in
93 bclr 0xff,(kgdb_single_step)
94
95 # Remove first breakpoint
96 mov (kgdb_sstep_bp_addr),a2
97 cmp 0,a2
98 beq 1f
99 movbu (kgdb_sstep_bp),d0
100 movbu d0,(a2)
101#if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
102 mov a2,d0
103 mov a2,d1
104 add 1,d1
105 calls flush_icache_range
106#endif
1071:
108
109 # Remove second breakpoint
110 mov (kgdb_sstep_bp_addr+4),a2
111 cmp 0,a2
112 beq 2f
113 movbu (kgdb_sstep_bp+1),d0
114 movbu d0,(a2)
115#if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
116 mov a2,d0
117 mov a2,d1
118 add 1,d1
119 calls flush_icache_range
120#endif
1212:
122
123 # Change the resumption address and return
124 mov __switch_back__reinstall_sstep_bp,d0
125 mov e4,a0
126 mov e5,a1
127 add 12,sp
128 bra __switch_to__continue
129
130###############################################################################
131#
132# Reinstall the single-step breakpoints when the task being traced is switched
133# back in (A1 points to the new thread_struct).
134#
135###############################################################################
136__switch_back__reinstall_sstep_bp:
137 add -12,sp
138 mov a0,e4 # save the return value
139 mov 0xff,d3
140
141 # Reinstall first breakpoint
142 mov (kgdb_sstep_bp_addr),a2
143 cmp 0,a2
144 beq 1f
145 movbu (a2),d0
146 movbu d0,(kgdb_sstep_bp)
147 movbu d3,(a2)
148#if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
149 mov a2,d0
150 mov a2,d1
151 add 1,d1
152 calls flush_icache_range
153#endif
1541:
155
156 # Reinstall second breakpoint
157 mov (kgdb_sstep_bp_addr+4),a2
158 cmp 0,a2
159 beq 2f
160 movbu (a2),d0
161 movbu d0,(kgdb_sstep_bp+1)
162 movbu d3,(a2)
163#if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
164 mov a2,d0
165 mov a2,d1
166 add 1,d1
167 calls flush_icache_range
168#endif
1692:
170
171 mov d3,(kgdb_single_step)
172
173 # Restore the return value (the previous thread_struct pointer)
174 mov e4,a0
175 mov a0,d0
176 add 12,sp
177 bra __switch_back
178
179#endif /* CONFIG_KGDB */