Commit a8984970 authored by Michael Ellerman's avatar Michael Ellerman Committed by Paul Mackerras

[POWERPC] add support for dumping spu info from xmon

This patch adds a command to xmon for dumping information about
spu structs. The command is 'sf' for "spu fields" perhaps, and
takes the spu number as an argument. This is the same value as the
spu->number field, or the "phys-id" value of a context when it is
bound to a physical spu.

We try to catch memory errors as we dump each field, hopefully this
will make the command reasonably robust, but YMMV. If people see a
need we can easily add more fields to the dump in future.

Output looks something like this:

0:mon> sf 0
Dumping spu fields at address c00000001ffd9e80:
  number                  = 0x0
  name                    = spe
  devnode->full_name      = /cpus/PowerPC,BE@0/spes/spe@0
  nid                     = 0x0
  local_store_phys        = 0x20000000000
  local_store             = 0xd0000800801e0000
  ls_size                 = 0x0
  isrc                    = 0x4
  node                    = 0x0
  flags                   = 0x0
  dar                     = 0x0
  dsisr                   = 0x0
  class_0_pending         = 0
  irqs[0]                 = 0x16
  irqs[1]                 = 0x17
  irqs[2]                 = 0x24
  slb_replace             = 0x0
  pid                     = 0
  prio                    = 0
  mm                      = 0x0000000000000000
  ctx                     = 0x0000000000000000
  rq                      = 0x0000000000000000
  timestamp               = 0x0000000000000000
  problem_phys            = 0x20000040000
  problem                 = 0xd000080080220000
  problem->spu_runcntl_RW = 0x0
  problem->spu_status_R   = 0x0
  problem->spu_npc_RW     = 0x0
  priv1                   = 0xd000080080240000
  priv1->mfc_sr1_RW       = 0x33
  priv2                   = 0xd000080080250000
Signed-off-by: default avatarMichael Ellerman <michael@ellerman.id.au>
Signed-off-by: default avatarArnd Bergmann <arnd.bergmann@de.ibm.com>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent ff8a8f25
...@@ -216,7 +216,8 @@ Commands:\n\ ...@@ -216,7 +216,8 @@ Commands:\n\
s single step\n" s single step\n"
#ifdef CONFIG_PPC_CELL #ifdef CONFIG_PPC_CELL
" ss stop execution on all spus\n\ " ss stop execution on all spus\n\
sr restore execution on stopped spus\n" sr restore execution on stopped spus\n\
sf # dump spu fields for spu # (in hex)\n"
#endif #endif
" S print special registers\n\ " S print special registers\n\
t print backtrace\n\ t print backtrace\n\
...@@ -2744,8 +2745,66 @@ static void restart_spus(void) ...@@ -2744,8 +2745,66 @@ static void restart_spus(void)
} }
} }
#define DUMP_WIDTH 23
#define DUMP_FIELD(obj, format, field) \
do { \
if (setjmp(bus_error_jmp) == 0) { \
catch_memory_errors = 1; \
sync(); \
printf(" %-*s = "format"\n", DUMP_WIDTH, \
#field, obj->field); \
sync(); \
__delay(200); \
} else { \
catch_memory_errors = 0; \
printf(" %-*s = *** Error reading field.\n", \
DUMP_WIDTH, #field); \
} \
catch_memory_errors = 0; \
} while (0)
static void dump_spu_fields(struct spu *spu)
{
printf("Dumping spu fields at address %p:\n", spu);
DUMP_FIELD(spu, "0x%x", number);
DUMP_FIELD(spu, "%s", name);
DUMP_FIELD(spu, "%s", devnode->full_name);
DUMP_FIELD(spu, "0x%x", nid);
DUMP_FIELD(spu, "0x%lx", local_store_phys);
DUMP_FIELD(spu, "0x%p", local_store);
DUMP_FIELD(spu, "0x%lx", ls_size);
DUMP_FIELD(spu, "0x%x", node);
DUMP_FIELD(spu, "0x%lx", flags);
DUMP_FIELD(spu, "0x%lx", dar);
DUMP_FIELD(spu, "0x%lx", dsisr);
DUMP_FIELD(spu, "%d", class_0_pending);
DUMP_FIELD(spu, "0x%lx", irqs[0]);
DUMP_FIELD(spu, "0x%lx", irqs[1]);
DUMP_FIELD(spu, "0x%lx", irqs[2]);
DUMP_FIELD(spu, "0x%x", slb_replace);
DUMP_FIELD(spu, "%d", pid);
DUMP_FIELD(spu, "%d", prio);
DUMP_FIELD(spu, "0x%p", mm);
DUMP_FIELD(spu, "0x%p", ctx);
DUMP_FIELD(spu, "0x%p", rq);
DUMP_FIELD(spu, "0x%p", timestamp);
DUMP_FIELD(spu, "0x%lx", problem_phys);
DUMP_FIELD(spu, "0x%p", problem);
DUMP_FIELD(spu, "0x%x", problem->spu_runcntl_RW);
DUMP_FIELD(spu, "0x%x", problem->spu_status_R);
DUMP_FIELD(spu, "0x%x", problem->spu_npc_RW);
DUMP_FIELD(spu, "0x%p", priv1);
if (spu->priv1)
DUMP_FIELD(spu, "0x%lx", priv1->mfc_sr1_RW);
DUMP_FIELD(spu, "0x%p", priv2);
}
static int do_spu_cmd(void) static int do_spu_cmd(void)
{ {
unsigned long num = 0;
int cmd; int cmd;
cmd = inchar(); cmd = inchar();
...@@ -2756,6 +2815,12 @@ static int do_spu_cmd(void) ...@@ -2756,6 +2815,12 @@ static int do_spu_cmd(void)
case 'r': case 'r':
restart_spus(); restart_spus();
break; break;
case 'f':
if (scanhex(&num) && num < XMON_NUM_SPUS && spu_info[num].spu)
dump_spu_fields(spu_info[num].spu);
else
printf("*** Error: invalid spu number\n");
break;
default: default:
return -1; return -1;
} }
......
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