mirror of https://gitee.com/openkylin/linux.git
powerpc/watchpoint/xmon: Support 2nd DAWR
Add support for 2nd DAWR in xmon. With this, we can have two simultaneous breakpoints from xmon. Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Reviewed-by: Michael Neuling <mikey@neuling.org> Link: https://lore.kernel.org/r/20200514111741.97993-17-ravi.bangoria@linux.ibm.com
This commit is contained in:
parent
514db915e7
commit
30df74d67d
|
@ -112,7 +112,7 @@ struct bpt {
|
|||
#define BP_DABR 4
|
||||
|
||||
static struct bpt bpts[NBPTS];
|
||||
static struct bpt dabr;
|
||||
static struct bpt dabr[HBP_NUM_MAX];
|
||||
static struct bpt *iabr;
|
||||
static unsigned bpinstr = 0x7fe00008; /* trap */
|
||||
|
||||
|
@ -784,10 +784,17 @@ static int xmon_sstep(struct pt_regs *regs)
|
|||
|
||||
static int xmon_break_match(struct pt_regs *regs)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
|
||||
return 0;
|
||||
if (dabr.enabled == 0)
|
||||
return 0;
|
||||
for (i = 0; i < nr_wp_slots(); i++) {
|
||||
if (dabr[i].enabled)
|
||||
goto found;
|
||||
}
|
||||
return 0;
|
||||
|
||||
found:
|
||||
xmon_core(regs, 0);
|
||||
return 1;
|
||||
}
|
||||
|
@ -948,13 +955,16 @@ static void insert_bpts(void)
|
|||
|
||||
static void insert_cpu_bpts(void)
|
||||
{
|
||||
int i;
|
||||
struct arch_hw_breakpoint brk;
|
||||
|
||||
if (dabr.enabled) {
|
||||
brk.address = dabr.address;
|
||||
brk.type = (dabr.enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
|
||||
brk.len = DABR_MAX_LEN;
|
||||
__set_breakpoint(0, &brk);
|
||||
for (i = 0; i < nr_wp_slots(); i++) {
|
||||
if (dabr[i].enabled) {
|
||||
brk.address = dabr[i].address;
|
||||
brk.type = (dabr[i].enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
|
||||
brk.len = 8;
|
||||
__set_breakpoint(i, &brk);
|
||||
}
|
||||
}
|
||||
|
||||
if (iabr)
|
||||
|
@ -1366,6 +1376,35 @@ static long check_bp_loc(unsigned long addr)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int find_free_data_bpt(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nr_wp_slots(); i++) {
|
||||
if (!dabr[i].enabled)
|
||||
return i;
|
||||
}
|
||||
printf("Couldn't find free breakpoint register\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void print_data_bpts(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nr_wp_slots(); i++) {
|
||||
if (!dabr[i].enabled)
|
||||
continue;
|
||||
|
||||
printf(" data "REG" [", dabr[i].address);
|
||||
if (dabr[i].enabled & 1)
|
||||
printf("r");
|
||||
if (dabr[i].enabled & 2)
|
||||
printf("w");
|
||||
printf("]\n");
|
||||
}
|
||||
}
|
||||
|
||||
static char *breakpoint_help_string =
|
||||
"Breakpoint command usage:\n"
|
||||
"b show breakpoints\n"
|
||||
|
@ -1399,10 +1438,9 @@ bpt_cmds(void)
|
|||
printf("Hardware data breakpoint not supported on this cpu\n");
|
||||
break;
|
||||
}
|
||||
if (dabr.enabled) {
|
||||
printf("Couldn't find free breakpoint register\n");
|
||||
i = find_free_data_bpt();
|
||||
if (i < 0)
|
||||
break;
|
||||
}
|
||||
mode = 7;
|
||||
cmd = inchar();
|
||||
if (cmd == 'r')
|
||||
|
@ -1411,15 +1449,15 @@ bpt_cmds(void)
|
|||
mode = 6;
|
||||
else
|
||||
termch = cmd;
|
||||
dabr.address = 0;
|
||||
dabr.enabled = 0;
|
||||
if (scanhex(&dabr.address)) {
|
||||
if (!is_kernel_addr(dabr.address)) {
|
||||
dabr[i].address = 0;
|
||||
dabr[i].enabled = 0;
|
||||
if (scanhex(&dabr[i].address)) {
|
||||
if (!is_kernel_addr(dabr[i].address)) {
|
||||
printf(badaddr);
|
||||
break;
|
||||
}
|
||||
dabr.address &= ~HW_BRK_TYPE_DABR;
|
||||
dabr.enabled = mode | BP_DABR;
|
||||
dabr[i].address &= ~HW_BRK_TYPE_DABR;
|
||||
dabr[i].enabled = mode | BP_DABR;
|
||||
}
|
||||
|
||||
force_enable_xmon();
|
||||
|
@ -1458,7 +1496,9 @@ bpt_cmds(void)
|
|||
for (i = 0; i < NBPTS; ++i)
|
||||
bpts[i].enabled = 0;
|
||||
iabr = NULL;
|
||||
dabr.enabled = 0;
|
||||
for (i = 0; i < nr_wp_slots(); i++)
|
||||
dabr[i].enabled = 0;
|
||||
|
||||
printf("All breakpoints cleared\n");
|
||||
break;
|
||||
}
|
||||
|
@ -1492,14 +1532,7 @@ bpt_cmds(void)
|
|||
if (xmon_is_ro || !scanhex(&a)) {
|
||||
/* print all breakpoints */
|
||||
printf(" type address\n");
|
||||
if (dabr.enabled) {
|
||||
printf(" data "REG" [", dabr.address);
|
||||
if (dabr.enabled & 1)
|
||||
printf("r");
|
||||
if (dabr.enabled & 2)
|
||||
printf("w");
|
||||
printf("]\n");
|
||||
}
|
||||
print_data_bpts();
|
||||
for (bp = bpts; bp < &bpts[NBPTS]; ++bp) {
|
||||
if (!bp->enabled)
|
||||
continue;
|
||||
|
@ -1959,8 +1992,13 @@ static void dump_207_sprs(void)
|
|||
|
||||
printf("hfscr = %.16lx dhdes = %.16lx rpr = %.16lx\n",
|
||||
mfspr(SPRN_HFSCR), mfspr(SPRN_DHDES), mfspr(SPRN_RPR));
|
||||
printf("dawr = %.16lx dawrx = %.16lx ciabr = %.16lx\n",
|
||||
mfspr(SPRN_DAWR0), mfspr(SPRN_DAWRX0), mfspr(SPRN_CIABR));
|
||||
printf("dawr0 = %.16lx dawrx0 = %.16lx\n",
|
||||
mfspr(SPRN_DAWR0), mfspr(SPRN_DAWRX0));
|
||||
if (nr_wp_slots() > 1) {
|
||||
printf("dawr1 = %.16lx dawrx1 = %.16lx\n",
|
||||
mfspr(SPRN_DAWR1), mfspr(SPRN_DAWRX1));
|
||||
}
|
||||
printf("ciabr = %.16lx\n", mfspr(SPRN_CIABR));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -3909,10 +3947,9 @@ static void clear_all_bpt(void)
|
|||
bpts[i].enabled = 0;
|
||||
|
||||
/* Clear any data or iabr breakpoints */
|
||||
if (iabr || dabr.enabled) {
|
||||
iabr = NULL;
|
||||
dabr.enabled = 0;
|
||||
}
|
||||
iabr = NULL;
|
||||
for (i = 0; i < nr_wp_slots(); i++)
|
||||
dabr[i].enabled = 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
|
|
Loading…
Reference in New Issue