diff options
Diffstat (limited to 'arch/blackfin/mach-common/entry.S')
-rw-r--r-- | arch/blackfin/mach-common/entry.S | 50 |
1 files changed, 38 insertions, 12 deletions
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index 038f70e0be65..eceb484d90f9 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 | ||
177 | 1: | ||
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 | ||
227 | 1: | ||
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 | |||
210 | ENDPROC(_ex_single_step) | 236 | ENDPROC(_ex_single_step) |
211 | 237 | ||
212 | ENTRY(_bfin_return_from_exception) | 238 | ENTRY(_bfin_return_from_exception) |