Rev 2787 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2787 | Rev 3424 | ||
---|---|---|---|
Line 31... | Line 31... | ||
31 | */ |
31 | */ |
32 | /** @file |
32 | /** @file |
33 | */ |
33 | */ |
34 | 34 | ||
35 | #include <arch/debugger.h> |
35 | #include <arch/debugger.h> |
- | 36 | #include <arch/barrier.h> |
|
36 | #include <memstr.h> |
37 | #include <memstr.h> |
37 | #include <console/kconsole.h> |
38 | #include <console/kconsole.h> |
38 | #include <console/cmd.h> |
39 | #include <console/cmd.h> |
39 | #include <symtab.h> |
40 | #include <symtab.h> |
40 | #include <print.h> |
41 | #include <print.h> |
Line 70... | Line 71... | ||
70 | static cmd_arg_t add_argv = { |
71 | static cmd_arg_t add_argv = { |
71 | .type = ARG_TYPE_INT |
72 | .type = ARG_TYPE_INT |
72 | }; |
73 | }; |
73 | static cmd_info_t addbkpt_info = { |
74 | static cmd_info_t addbkpt_info = { |
74 | .name = "addbkpt", |
75 | .name = "addbkpt", |
75 | .description = "addbkpt <&symbol> - new bkpoint. Break on J/Branch insts unsupported.", |
76 | .description = "addbkpt <&symbol> - new bkpoint. Break on J/Branch " |
- | 77 | "insts unsupported.", |
|
76 | .func = cmd_add_breakpoint, |
78 | .func = cmd_add_breakpoint, |
77 | .argc = 1, |
79 | .argc = 1, |
78 | .argv = &add_argv |
80 | .argv = &add_argv |
79 | }; |
81 | }; |
80 | 82 | ||
Line 82... | Line 84... | ||
82 | { .type = ARG_TYPE_INT }, |
84 | { .type = ARG_TYPE_INT }, |
83 | { .type = ARG_TYPE_INT } |
85 | { .type = ARG_TYPE_INT } |
84 | }; |
86 | }; |
85 | static cmd_info_t addbkpte_info = { |
87 | static cmd_info_t addbkpte_info = { |
86 | .name = "addbkpte", |
88 | .name = "addbkpte", |
87 | .description = "addebkpte <&symbol> <&func> - new bkpoint. Call func(or Nothing if 0).", |
89 | .description = "addebkpte <&symbol> <&func> - new bkpoint. Call " |
- | 90 | "func(or Nothing if 0).", |
|
88 | .func = cmd_add_breakpoint, |
91 | .func = cmd_add_breakpoint, |
89 | .argc = 2, |
92 | .argc = 2, |
90 | .argv = adde_argv |
93 | .argv = adde_argv |
91 | }; |
94 | }; |
92 | 95 | ||
Line 155... | Line 158... | ||
155 | for (i=0; i<BKPOINTS_MAX; i++) { |
158 | for (i = 0; i < BKPOINTS_MAX; i++) { |
156 | if (breakpoints[i].address == (uintptr_t)argv->intval) { |
159 | if (breakpoints[i].address == (uintptr_t)argv->intval) { |
157 | printf("Duplicate breakpoint %d.\n", i); |
160 | printf("Duplicate breakpoint %d.\n", i); |
158 | spinlock_unlock(&bkpoints_lock); |
161 | spinlock_unlock(&bkpoints_lock); |
159 | return 0; |
162 | return 0; |
160 | } else if (breakpoints[i].address == (uintptr_t)argv->intval + sizeof(unative_t) || \ |
163 | } else if (breakpoints[i].address == (uintptr_t)argv->intval + |
- | 164 | sizeof(unative_t) || breakpoints[i].address == |
|
161 | breakpoints[i].address == (uintptr_t)argv->intval - sizeof(unative_t)) { |
165 | (uintptr_t)argv->intval - sizeof(unative_t)) { |
162 | printf("Adjacent breakpoints not supported, conflict with %d.\n", i); |
166 | printf("Adjacent breakpoints not supported, conflict " |
- | 167 | "with %d.\n", i); |
|
163 | spinlock_unlock(&bkpoints_lock); |
168 | spinlock_unlock(&bkpoints_lock); |
164 | return 0; |
169 | return 0; |
165 | } |
170 | } |
166 | 171 | ||
167 | } |
172 | } |
Line 191... | Line 196... | ||
191 | cur->flags |= BKPOINT_ONESHOT; |
196 | cur->flags |= BKPOINT_ONESHOT; |
192 | cur->counter = 0; |
197 | cur->counter = 0; |
193 | 198 | ||
194 | /* Set breakpoint */ |
199 | /* Set breakpoint */ |
195 | *((unative_t *)cur->address) = 0x0d; |
200 | *((unative_t *)cur->address) = 0x0d; |
- | 201 | smc_coherence(cur->address); |
|
196 | 202 | ||
197 | spinlock_unlock(&bkpoint_lock); |
203 | spinlock_unlock(&bkpoint_lock); |
198 | interrupts_restore(ipl); |
204 | interrupts_restore(ipl); |
199 | 205 | ||
200 | return 1; |
206 | return 1; |
201 | } |
207 | } |
202 | 208 | ||
203 | - | ||
204 | - | ||
205 | /** Remove breakpoint from table */ |
209 | /** Remove breakpoint from table */ |
206 | int cmd_del_breakpoint(cmd_arg_t *argv) |
210 | int cmd_del_breakpoint(cmd_arg_t *argv) |
207 | { |
211 | { |
208 | bpinfo_t *cur; |
212 | bpinfo_t *cur; |
209 | ipl_t ipl; |
213 | ipl_t ipl; |
Line 227... | Line 231... | ||
227 | spinlock_unlock(&bkpoint_lock); |
231 | spinlock_unlock(&bkpoint_lock); |
228 | interrupts_restore(ipl); |
232 | interrupts_restore(ipl); |
229 | return 0; |
233 | return 0; |
230 | } |
234 | } |
231 | ((uint32_t *)cur->address)[0] = cur->instruction; |
235 | ((uint32_t *)cur->address)[0] = cur->instruction; |
- | 236 | smc_coherence(((uint32_t *)cur->address)[0]); |
|
232 | ((uint32_t *)cur->address)[1] = cur->nextinstruction; |
237 | ((uint32_t *)cur->address)[1] = cur->nextinstruction; |
- | 238 | smc_coherence(((uint32_t *)cur->address)[1]); |
|
233 | 239 | ||
234 | cur->address = NULL; |
240 | cur->address = NULL; |
235 | 241 | ||
236 | spinlock_unlock(&bkpoint_lock); |
242 | spinlock_unlock(&bkpoint_lock); |
237 | interrupts_restore(ipl); |
243 | interrupts_restore(ipl); |
Line 251... | Line 257... | ||
251 | if (breakpoints[i].address) { |
257 | if (breakpoints[i].address) { |
252 | symbol = get_symtab_entry(breakpoints[i].address); |
258 | symbol = get_symtab_entry(breakpoints[i].address); |
253 | 259 | ||
254 | printf("%-2u %-5d %#10zx %-6s %-7s %-8s %s\n", i, |
260 | printf("%-2u %-5d %#10zx %-6s %-7s %-8s %s\n", i, |
255 | breakpoints[i].counter, breakpoints[i].address, |
261 | breakpoints[i].counter, breakpoints[i].address, |
256 | ((breakpoints[i].flags & BKPOINT_INPROG) ? "true" : "false"), |
262 | ((breakpoints[i].flags & BKPOINT_INPROG) ? "true" : |
257 | ((breakpoints[i].flags & BKPOINT_ONESHOT) ? "true" : "false"), |
263 | "false"), ((breakpoints[i].flags & BKPOINT_ONESHOT) |
- | 264 | ? "true" : "false"), ((breakpoints[i].flags & |
|
258 | ((breakpoints[i].flags & BKPOINT_FUNCCALL) ? "true" : "false"), |
265 | BKPOINT_FUNCCALL) ? "true" : "false"), symbol); |
259 | symbol); |
- | |
260 | } |
266 | } |
261 | return 1; |
267 | return 1; |
262 | } |
268 | } |
263 | 269 | ||
264 | /** Initialize debugger */ |
270 | /** Initialize debugger */ |
Line 305... | Line 311... | ||
305 | panic("Breakpoint in branch delay slot not supported.\n"); |
311 | panic("Breakpoint in branch delay slot not supported.\n"); |
306 | 312 | ||
307 | spinlock_lock(&bkpoint_lock); |
313 | spinlock_lock(&bkpoint_lock); |
308 | for (i=0; i<BKPOINTS_MAX; i++) { |
314 | for (i = 0; i < BKPOINTS_MAX; i++) { |
309 | /* Normal breakpoint */ |
315 | /* Normal breakpoint */ |
310 | if (fireaddr == breakpoints[i].address \ |
316 | if (fireaddr == breakpoints[i].address && |
311 | && !(breakpoints[i].flags & BKPOINT_REINST)) { |
317 | !(breakpoints[i].flags & BKPOINT_REINST)) { |
312 | cur = &breakpoints[i]; |
318 | cur = &breakpoints[i]; |
313 | break; |
319 | break; |
314 | } |
320 | } |
315 | /* Reinst only breakpoint */ |
321 | /* Reinst only breakpoint */ |
316 | if ((breakpoints[i].flags & BKPOINT_REINST) \ |
322 | if ((breakpoints[i].flags & BKPOINT_REINST) && |
317 | && (fireaddr ==breakpoints[i].address+sizeof(unative_t))) { |
323 | (fireaddr == breakpoints[i].address + sizeof(unative_t))) { |
318 | cur = &breakpoints[i]; |
324 | cur = &breakpoints[i]; |
319 | break; |
325 | break; |
320 | } |
326 | } |
321 | } |
327 | } |
322 | if (cur) { |
328 | if (cur) { |
323 | if (cur->flags & BKPOINT_REINST) { |
329 | if (cur->flags & BKPOINT_REINST) { |
324 | /* Set breakpoint on first instruction */ |
330 | /* Set breakpoint on first instruction */ |
325 | ((uint32_t *)cur->address)[0] = 0x0d; |
331 | ((uint32_t *)cur->address)[0] = 0x0d; |
- | 332 | smc_coherence(((uint32_t *)cur->address)[0]); |
|
326 | /* Return back the second */ |
333 | /* Return back the second */ |
327 | ((uint32_t *)cur->address)[1] = cur->nextinstruction; |
334 | ((uint32_t *)cur->address)[1] = cur->nextinstruction; |
- | 335 | smc_coherence(((uint32_t *)cur->address)[1]); |
|
328 | cur->flags &= ~BKPOINT_REINST; |
336 | cur->flags &= ~BKPOINT_REINST; |
329 | spinlock_unlock(&bkpoint_lock); |
337 | spinlock_unlock(&bkpoint_lock); |
330 | return; |
338 | return; |
331 | } |
339 | } |
332 | if (cur->flags & BKPOINT_INPROG) |
340 | if (cur->flags & BKPOINT_INPROG) |
333 | printf("Warning: breakpoint recursion\n"); |
341 | printf("Warning: breakpoint recursion\n"); |
334 | 342 | ||
335 | if (!(cur->flags & BKPOINT_FUNCCALL)) |
343 | if (!(cur->flags & BKPOINT_FUNCCALL)) |
336 | printf("***Breakpoint %d: %p in %s.\n", i, |
344 | printf("***Breakpoint %d: %p in %s.\n", i, fireaddr, |
337 | fireaddr, get_symtab_entry(istate->epc)); |
345 | get_symtab_entry(istate->epc)); |
338 | 346 | ||
339 | /* Return first instruction back */ |
347 | /* Return first instruction back */ |
340 | ((uint32_t *)cur->address)[0] = cur->instruction; |
348 | ((uint32_t *)cur->address)[0] = cur->instruction; |
- | 349 | smc_coherence(cur->address); |
|
341 | 350 | ||
342 | if (! (cur->flags & BKPOINT_ONESHOT)) { |
351 | if (! (cur->flags & BKPOINT_ONESHOT)) { |
343 | /* Set Breakpoint on next instruction */ |
352 | /* Set Breakpoint on next instruction */ |
344 | ((uint32_t *)cur->address)[1] = 0x0d; |
353 | ((uint32_t *)cur->address)[1] = 0x0d; |
345 | cur->flags |= BKPOINT_REINST; |
354 | cur->flags |= BKPOINT_REINST; |