summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/xmon/xmon.c60
1 files changed, 55 insertions, 5 deletions
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index ac17abbe3ef0..be2c12d68785 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -218,7 +218,8 @@ Commands:\n\
#ifdef CONFIG_PPC_CELL
" ss stop execution on all spus\n\
sr restore execution on stopped spus\n\
- sf # dump spu fields for spu # (in hex)\n"
+ sf # dump spu fields for spu # (in hex)\n\
+ sd # dump spu local store for spu # (in hex)\n"
#endif
" S print special registers\n\
t print backtrace\n\
@@ -2651,6 +2652,7 @@ struct spu_info {
struct spu *spu;
u64 saved_mfc_sr1_RW;
u32 saved_spu_runcntl_RW;
+ unsigned long dump_addr;
u8 stopped_ok;
};
@@ -2670,6 +2672,8 @@ void xmon_register_spus(struct list_head *list)
spu_info[spu->number].spu = spu;
spu_info[spu->number].stopped_ok = 0;
+ spu_info[spu->number].dump_addr = (unsigned long)
+ spu_info[spu->number].spu->local_store;
}
}
@@ -2815,9 +2819,43 @@ static void dump_spu_fields(struct spu *spu)
DUMP_FIELD(spu, "0x%p", priv2);
}
+static void dump_spu_ls(unsigned long num)
+{
+ unsigned long offset, addr, ls_addr;
+
+ if (setjmp(bus_error_jmp) == 0) {
+ catch_memory_errors = 1;
+ sync();
+ ls_addr = (unsigned long)spu_info[num].spu->local_store;
+ sync();
+ __delay(200);
+ } else {
+ catch_memory_errors = 0;
+ printf("*** Error: accessing spu info for spu %d\n", num);
+ return;
+ }
+ catch_memory_errors = 0;
+
+ if (scanhex(&offset))
+ addr = ls_addr + offset;
+ else
+ addr = spu_info[num].dump_addr;
+
+ if (addr >= ls_addr + LS_SIZE) {
+ printf("*** Error: address outside of local store\n");
+ return;
+ }
+
+ prdump(addr, 64);
+ addr += 64;
+ last_cmd = "sd\n";
+
+ spu_info[num].dump_addr = addr;
+}
+
static int do_spu_cmd(void)
{
- unsigned long num = 0;
+ static unsigned long num = 0;
int cmd;
cmd = inchar();
@@ -2829,10 +2867,22 @@ static int do_spu_cmd(void)
restart_spus();
break;
case 'f':
- if (scanhex(&num) && num < XMON_NUM_SPUS && spu_info[num].spu)
- dump_spu_fields(spu_info[num].spu);
- else
+ case 'd':
+ scanhex(&num);
+ if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
printf("*** Error: invalid spu number\n");
+ return 0;
+ }
+
+ switch (cmd) {
+ case 'f':
+ dump_spu_fields(spu_info[num].spu);
+ break;
+ default:
+ dump_spu_ls(num);
+ break;
+ }
+
break;
default:
return -1;