Commit da985ddd authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ppc64: xmon breakpoint and single step on LPAR fixes from John Rose

From: Anton Blanchard <anton@samba.org>

Xmon changes to make breakpoints and single-stepping work on pSeries LPARs.
Also changed help text to reflect obsolete cmds.
parent eb55c013
...@@ -37,9 +37,10 @@ ...@@ -37,9 +37,10 @@
#define skipbl xmon_skipbl #define skipbl xmon_skipbl
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
unsigned long cpus_in_xmon = 0; volatile unsigned long cpus_in_xmon = 0;
static unsigned long got_xmon = 0; static unsigned long got_xmon = 0;
static volatile int take_xmon = -1; static volatile int take_xmon = -1;
static volatile int leaving_xmon = 0;
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
static unsigned long adrs; static unsigned long adrs;
...@@ -162,7 +163,6 @@ Commands:\n\ ...@@ -162,7 +163,6 @@ Commands:\n\
mz zero a block of memory\n\ mz zero a block of memory\n\
mx translation information for an effective address\n\ mx translation information for an effective address\n\
mi show information about memory allocation\n\ mi show information about memory allocation\n\
M print System.map\n\
p show the task list\n\ p show the task list\n\
r print registers\n\ r print registers\n\
s single step\n\ s single step\n\
...@@ -227,7 +227,7 @@ void ...@@ -227,7 +227,7 @@ void
xmon(struct pt_regs *excp) xmon(struct pt_regs *excp)
{ {
struct pt_regs regs; struct pt_regs regs;
int cmd; int cmd = 0;
unsigned long msr; unsigned long msr;
if (excp == NULL) { if (excp == NULL) {
...@@ -285,9 +285,15 @@ xmon(struct pt_regs *excp) ...@@ -285,9 +285,15 @@ xmon(struct pt_regs *excp)
xmon_regs[smp_processor_id()] = excp; xmon_regs[smp_processor_id()] = excp;
excprint(excp); excprint(excp);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
if (test_and_set_bit(smp_processor_id(), &cpus_in_xmon)) leaving_xmon = 0;
/* possible race condition here if a CPU is held up and gets
* here while we are exiting */
if (test_and_set_bit(smp_processor_id(), &cpus_in_xmon)) {
/* xmon probably caused an exception itself */
printf("We are already in xmon\n");
for (;;) for (;;)
; ;
}
while (test_and_set_bit(0, &got_xmon)) { while (test_and_set_bit(0, &got_xmon)) {
if (take_xmon == smp_processor_id()) { if (take_xmon == smp_processor_id()) {
take_xmon = -1; take_xmon = -1;
...@@ -304,6 +310,9 @@ xmon(struct pt_regs *excp) ...@@ -304,6 +310,9 @@ xmon(struct pt_regs *excp)
if (cmd == 's') { if (cmd == 's') {
xmon_trace[smp_processor_id()] = SSTEP; xmon_trace[smp_processor_id()] = SSTEP;
excp->msr |= MSR_SE; excp->msr |= MSR_SE;
#ifdef CONFIG_SMP
take_xmon = smp_processor_id();
#endif
} else if (at_breakpoint(excp->nip)) { } else if (at_breakpoint(excp->nip)) {
xmon_trace[smp_processor_id()] = BRSTEP; xmon_trace[smp_processor_id()] = BRSTEP;
excp->msr |= MSR_SE; excp->msr |= MSR_SE;
...@@ -313,6 +322,8 @@ xmon(struct pt_regs *excp) ...@@ -313,6 +322,8 @@ xmon(struct pt_regs *excp)
} }
xmon_regs[smp_processor_id()] = 0; xmon_regs[smp_processor_id()] = 0;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
leaving_xmon = 1;
if (cmd != 's')
clear_bit(0, &got_xmon); clear_bit(0, &got_xmon);
clear_bit(smp_processor_id(), &cpus_in_xmon); clear_bit(smp_processor_id(), &cpus_in_xmon);
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
...@@ -421,8 +432,6 @@ insert_bpts() ...@@ -421,8 +432,6 @@ insert_bpts()
int i; int i;
struct bpt *bp; struct bpt *bp;
if (systemcfg->platform != PLATFORM_PSERIES)
return;
bp = bpts; bp = bpts;
for (i = 0; i < NBPTS; ++i, ++bp) { for (i = 0; i < NBPTS; ++i, ++bp) {
if (!bp->enabled) if (!bp->enabled)
...@@ -450,9 +459,6 @@ remove_bpts() ...@@ -450,9 +459,6 @@ remove_bpts()
struct bpt *bp; struct bpt *bp;
unsigned instr; unsigned instr;
if (systemcfg->platform != PLATFORM_PSERIES)
return;
if ((cur_cpu_spec->cpu_features & CPU_FTR_DABR)) if ((cur_cpu_spec->cpu_features & CPU_FTR_DABR))
set_dabr(0); set_dabr(0);
if ((cur_cpu_spec->cpu_features & CPU_FTR_IABR)) if ((cur_cpu_spec->cpu_features & CPU_FTR_IABR))
...@@ -478,11 +484,15 @@ static char *last_cmd; ...@@ -478,11 +484,15 @@ static char *last_cmd;
static int static int
cmds(struct pt_regs *excp) cmds(struct pt_regs *excp)
{ {
int cmd; int cmd = 0;
last_cmd = NULL; last_cmd = NULL;
for(;;) { for(;;) {
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* Need to check if we should take any commands on
this CPU. */
if (leaving_xmon)
return cmd;
printf("%d:", smp_processor_id()); printf("%d:", smp_processor_id());
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
printf("mon> "); printf("mon> ");
...@@ -832,6 +842,12 @@ bpt_cmds(void) ...@@ -832,6 +842,12 @@ bpt_cmds(void)
} }
break; break;
} }
if (!(systemcfg->platform & PLATFORM_PSERIES)) {
printf("Not supported for this platform\n");
break;
}
bp = at_breakpoint(a); bp = at_breakpoint(a);
if (bp == 0) { if (bp == 0) {
for (bp = bpts; bp < &bpts[NBPTS]; ++bp) for (bp = bpts; bp < &bpts[NBPTS]; ++bp)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment