aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin')
-rw-r--r--arch/blackfin/kernel/kgdb.c16
-rw-r--r--arch/blackfin/mach-common/entry.S50
2 files changed, 53 insertions, 13 deletions
diff --git a/arch/blackfin/kernel/kgdb.c b/arch/blackfin/kernel/kgdb.c
index a9c15515bfd..a1f9641a642 100644
--- a/arch/blackfin/kernel/kgdb.c
+++ b/arch/blackfin/kernel/kgdb.c
@@ -203,6 +203,8 @@ struct hw_breakpoint {
203 203
204int kgdb_arch_init(void) 204int kgdb_arch_init(void)
205{ 205{
206 debugger_step = 0;
207
206 kgdb_remove_all_hw_break(); 208 kgdb_remove_all_hw_break();
207 return 0; 209 return 0;
208} 210}
@@ -368,6 +370,7 @@ int kgdb_arch_handle_exception(int exceptionVector, int signo,
368 char *ptr; 370 char *ptr;
369 int newPC; 371 int newPC;
370 int wp_status; 372 int wp_status;
373 int i;
371 374
372 switch (remcom_in_buffer[0]) { 375 switch (remcom_in_buffer[0]) {
373 case 'c': 376 case 'c':
@@ -392,7 +395,18 @@ int kgdb_arch_handle_exception(int exceptionVector, int signo,
392 /* set the trace bit if we're stepping */ 395 /* set the trace bit if we're stepping */
393 if (remcom_in_buffer[0] == 's') { 396 if (remcom_in_buffer[0] == 's') {
394 linux_regs->syscfg |= 0x1; 397 linux_regs->syscfg |= 0x1;
395 debugger_step = 1; 398 debugger_step = linux_regs->ipend;
399 debugger_step >>= 6;
400 for (i = 10; i > 0; i--, debugger_step >>= 1)
401 if (debugger_step & 1)
402 break;
403 /* i indicate event priority of current stopped instruction
404 * user space instruction is 0, IVG15 is 1, IVTMR is 10.
405 * debugger_step > 0 means in single step mode
406 */
407 debugger_step = i + 1;
408 } else {
409 debugger_step = 0;
396 } 410 }
397 411
398 wp_status = bfin_read_WPSTAT(); 412 wp_status = bfin_read_WPSTAT();
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index 038f70e0be6..eceb484d90f 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -158,23 +158,45 @@ ENTRY(_ex_single_step)
158 cc = r7 == r6; 158 cc = r7 == r6;
159 if cc jump _bfin_return_from_exception; 159 if cc jump _bfin_return_from_exception;
160 160
161 /* Don't do single step in hardware exception handler */
162 p5.l = lo(IPEND);
163 p5.h = hi(IPEND);
164 r6 = [p5];
165 cc = bittst(r6, 5);
166 if cc jump _bfin_return_from_exception;
167
168#ifdef CONFIG_KGDB
169 /* skip single step if current interrupt priority is higher than
170 * that of the first instruction, from which gdb starts single step */
171 r6 >>= 6;
172 r7 = 10;
173.Lfind_priority_start:
174 cc = bittst(r6, 0);
175 if cc jump .Lfind_priority_done;
176 r6 >>= 1;
177 r7 += -1;
178 cc = r7 == 0;
179 if cc jump .Lfind_priority_done;
180 jump.s .Lfind_priority_start;
181.Lfind_priority_done:
182 p4.l = _debugger_step;
183 p4.h = _debugger_step;
184 r6 = [p4];
185 cc = r6 == 0;
186 if cc jump .Ldo_single_step;
187 r6 += -1;
188 cc = r6 < r7;
189 if cc jump _bfin_return_from_exception;
190.Ldo_single_step:
191#endif
192
161 /* If we were in user mode, do the single step normally. */ 193 /* If we were in user mode, do the single step normally. */
162 p5.l = lo(IPEND);
163 p5.h = hi(IPEND);
164 r6 = [p5]; 194 r6 = [p5];
165 r7 = 0xffe0 (z); 195 r7 = 0xffe0 (z);
166 r7 = r7 & r6; 196 r7 = r7 & r6;
167 cc = r7 == 0; 197 cc = r7 == 0;
168 if !cc jump 1f; 198 if cc jump 1f;
169
170 /* Single stepping only a single instruction, so clear the trace
171 * bit here. */
172 r7 = syscfg;
173 bitclr (r7, 0);
174 syscfg = R7;
175 jump _ex_trap_c;
176 199
1771:
178 /* 200 /*
179 * We were in an interrupt handler. By convention, all of them save 201 * We were in an interrupt handler. By convention, all of them save
180 * SYSCFG with their first instruction, so by checking whether our 202 * SYSCFG with their first instruction, so by checking whether our
@@ -202,11 +224,15 @@ ENTRY(_ex_single_step)
202 cc = R7 == R6; 224 cc = R7 == R6;
203 if !cc jump _bfin_return_from_exception; 225 if !cc jump _bfin_return_from_exception;
204 226
2271:
228 /* Single stepping only a single instruction, so clear the trace
229 * bit here. */
205 r7 = syscfg; 230 r7 = syscfg;
206 bitclr (r7, 0); 231 bitclr (r7, 0);
207 syscfg = R7; 232 syscfg = R7;
208 233
209 /* Fall through to _bfin_return_from_exception. */ 234 jump _ex_trap_c;
235
210ENDPROC(_ex_single_step) 236ENDPROC(_ex_single_step)
211 237
212ENTRY(_bfin_return_from_exception) 238ENTRY(_bfin_return_from_exception)