37,16 → 37,18 |
#include <memstr.h> |
#include <console/kconsole.h> |
#include <console/cmd.h> |
#include <symtab.h> |
#include <print.h> |
#include <panic.h> |
#include <arch.h> |
#include <arch/cp0.h> |
#include <func.h> |
#include <symtab.h> |
|
bpinfo_t breakpoints[BKPOINTS_MAX]; |
SPINLOCK_INITIALIZE(bkpoint_lock); |
|
#ifdef CONFIG_KCONSOLE |
|
static int cmd_print_breakpoints(cmd_arg_t *argv); |
static cmd_info_t bkpts_info = { |
.name = "bkpts", |
123,10 → 125,12 |
{0, 0} /* EndOfTable */ |
}; |
|
|
/** Test, if the given instruction is a jump or branch instruction |
* |
* @param instr Instruction code |
* @return true - it is jump instruction, false otherwise |
* |
*/ |
static bool is_jump(unative_t instr) |
{ |
158,7 → 162,7 |
for (i = 0; i < BKPOINTS_MAX; i++) { |
if (breakpoints[i].address == (uintptr_t)argv->intval) { |
printf("Duplicate breakpoint %d.\n", i); |
spinlock_unlock(&bkpoints_lock); |
spinlock_unlock(&bkpoint_lock); |
return 0; |
} else if (breakpoints[i].address == (uintptr_t)argv->intval + |
sizeof(unative_t) || breakpoints[i].address == |
165,10 → 169,10 |
(uintptr_t)argv->intval - sizeof(unative_t)) { |
printf("Adjacent breakpoints not supported, conflict " |
"with %d.\n", i); |
spinlock_unlock(&bkpoints_lock); |
spinlock_unlock(&bkpoint_lock); |
return 0; |
} |
|
|
} |
|
for (i = 0; i < BKPOINTS_MAX; i++) |
255,8 → 259,9 |
|
for (i = 0; i < BKPOINTS_MAX; i++) |
if (breakpoints[i].address) { |
symbol = get_symtab_entry(breakpoints[i].address); |
|
symbol = symtab_fmt_name_lookup( |
breakpoints[i].address); |
|
printf("%-2u %-5d %#10zx %-6s %-7s %-8s %s\n", i, |
breakpoints[i].counter, breakpoints[i].address, |
((breakpoints[i].flags & BKPOINT_INPROG) ? "true" : |
267,6 → 272,8 |
return 1; |
} |
|
#endif |
|
/** Initialize debugger */ |
void debugger_init() |
{ |
274,22 → 281,24 |
|
for (i = 0; i < BKPOINTS_MAX; i++) |
breakpoints[i].address = NULL; |
|
|
#ifdef CONFIG_KCONSOLE |
cmd_initialize(&bkpts_info); |
if (!cmd_register(&bkpts_info)) |
panic("could not register command %s\n", bkpts_info.name); |
printf("Cannot register command %s\n", bkpts_info.name); |
|
cmd_initialize(&delbkpt_info); |
if (!cmd_register(&delbkpt_info)) |
panic("could not register command %s\n", delbkpt_info.name); |
printf("Cannot register command %s\n", delbkpt_info.name); |
|
cmd_initialize(&addbkpt_info); |
if (!cmd_register(&addbkpt_info)) |
panic("could not register command %s\n", addbkpt_info.name); |
printf("Cannot register command %s\n", addbkpt_info.name); |
|
cmd_initialize(&addbkpte_info); |
if (!cmd_register(&addbkpte_info)) |
panic("could not register command %s\n", addbkpte_info.name); |
printf("Cannot register command %s\n", addbkpte_info.name); |
#endif |
} |
|
/** Handle breakpoint |
308,7 → 317,7 |
|
/* test branch delay slot */ |
if (cp0_cause_read() & 0x80000000) |
panic("Breakpoint in branch delay slot not supported.\n"); |
panic("Breakpoint in branch delay slot not supported."); |
|
spinlock_lock(&bkpoint_lock); |
for (i = 0; i < BKPOINTS_MAX; i++) { |
340,9 → 349,10 |
if (cur->flags & BKPOINT_INPROG) |
printf("Warning: breakpoint recursion\n"); |
|
if (!(cur->flags & BKPOINT_FUNCCALL)) |
if (!(cur->flags & BKPOINT_FUNCCALL)) { |
printf("***Breakpoint %d: %p in %s.\n", i, fireaddr, |
get_symtab_entry(istate->epc)); |
symtab_fmt_name_lookup(istate->epc)); |
} |
|
/* Return first instruction back */ |
((uint32_t *)cur->address)[0] = cur->instruction; |
355,8 → 365,9 |
} |
cur->flags |= BKPOINT_INPROG; |
} else { |
printf("***Breakpoint %p in %s.\n", fireaddr, |
get_symtab_entry(fireaddr)); |
printf("***Breakpoint %d: %p in %s.\n", i, fireaddr, |
symtab_fmt_name_lookup(fireaddr)); |
|
/* Move on to next instruction */ |
istate->epc += 4; |
} |
367,19 → 378,20 |
if (cur->bkfunc) |
cur->bkfunc(cur, istate); |
} else { |
printf("***Type 'exit' to exit kconsole.\n"); |
#ifdef CONFIG_KCONSOLE |
/* This disables all other processors - we are not SMP, |
* actually this gets us to cpu_halt, if scheduler() is run |
* - we generally do not want scheduler to be run from debug, |
* so this is a good idea |
*/ |
atomic_set(&haltstate,1); |
atomic_set(&haltstate, 1); |
spinlock_unlock(&bkpoint_lock); |
|
kconsole("debug"); |
|
|
kconsole("debug", "Debug console ready.\n", false); |
|
spinlock_lock(&bkpoint_lock); |
atomic_set(&haltstate,0); |
atomic_set(&haltstate, 0); |
#endif |
} |
if (cur && cur->address == fireaddr && (cur->flags & BKPOINT_INPROG)) { |
/* Remove one-shot breakpoint */ |