Commit ddadb6b8 authored by Michael Ellerman's avatar Michael Ellerman Committed by Benjamin Herrenschmidt

powerpc: Add an xmon command to dump one or all pacas

This was originally motivated by a desire to see the mapping between
logical and hardware cpu numbers.

But it seemed that it made more sense to just add a command to dump
(most of) the paca.

With no arguments "dp" will dump the paca for the current cpu.

It also takes an argument, eg. "dp 3" which is the logical cpu number
in hex. This form does not check if the cpu is possible, but displays
the paca regardless, as well as the cpu's state in the possible, present
and online masks.

Thirdly, "dpa" will display the paca for all possible cpus. If there are
no possible cpus, like early in boot, it will tell you that.

Sample output, number in brackets is the offset into the struct:

2:mon> dp 3
paca for cpu 0x3 @ c00000000ff20a80:
 possible         = yes
 present          = yes
 online           = yes
 lock_token       = 0x8000            	(0x8)
 paca_index       = 0x3               	(0xa)
 kernel_toc       = 0xc00000000144f990	(0x10)
 kernelbase       = 0xc000000000000000	(0x18)
 kernel_msr       = 0xb000000000001032	(0x20)
 stab_real        = 0x0               	(0x28)
 stab_addr        = 0x0               	(0x30)
 emergency_sp     = 0xc00000003ffe4000	(0x38)
 data_offset      = 0xa40000          	(0x40)
 hw_cpu_id        = 0x9               	(0x50)
 cpu_start        = 0x1               	(0x52)
 kexec_state      = 0x0               	(0x53)
 __current        = 0xc00000007e568680	(0x218)
 kstack           = 0xc00000007e5a3e30	(0x220)
 stab_rr          = 0x1a              	(0x228)
 saved_r1         = 0xc00000007e7cb450	(0x230)
 trap_save        = 0x0               	(0x240)
 soft_enabled     = 0x0               	(0x242)
 irq_happened     = 0x0               	(0x243)
 io_sync          = 0x0               	(0x244)
 irq_work_pending = 0x0               	(0x245)
 nap_state_lost   = 0x0               	(0x246)
Signed-off-by: default avatarMichael Ellerman <michael@ellerman.id.au>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent b9ae38ae
...@@ -60,6 +60,8 @@ static cpumask_t cpus_in_xmon = CPU_MASK_NONE; ...@@ -60,6 +60,8 @@ static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
static unsigned long xmon_taken = 1; static unsigned long xmon_taken = 1;
static int xmon_owner; static int xmon_owner;
static int xmon_gate; static int xmon_gate;
#else
#define xmon_owner 0
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
static unsigned long in_xmon __read_mostly = 0; static unsigned long in_xmon __read_mostly = 0;
...@@ -202,7 +204,13 @@ Commands:\n\ ...@@ -202,7 +204,13 @@ Commands:\n\
di dump instructions\n\ di dump instructions\n\
df dump float values\n\ df dump float values\n\
dd dump double values\n\ dd dump double values\n\
dl dump the kernel log buffer\n\ dl dump the kernel log buffer\n"
#ifdef CONFIG_PPC64
"\
dp[#] dump paca for current cpu, or cpu #\n\
dpa dump paca for all possible cpus\n"
#endif
"\
dr dump stream of raw bytes\n\ dr dump stream of raw bytes\n\
e print exception information\n\ e print exception information\n\
f flush cache\n\ f flush cache\n\
...@@ -2009,6 +2017,95 @@ static void xmon_rawdump (unsigned long adrs, long ndump) ...@@ -2009,6 +2017,95 @@ static void xmon_rawdump (unsigned long adrs, long ndump)
printf("\n"); printf("\n");
} }
#ifdef CONFIG_PPC64
static void dump_one_paca(int cpu)
{
struct paca_struct *p;
if (setjmp(bus_error_jmp) != 0) {
printf("*** Error dumping paca for cpu 0x%x!\n", cpu);
return;
}
catch_memory_errors = 1;
sync();
p = &paca[cpu];
printf("paca for cpu 0x%x @ %p:\n", cpu, p);
printf(" %-*s = %s\n", 16, "possible", cpu_possible(cpu) ? "yes" : "no");
printf(" %-*s = %s\n", 16, "present", cpu_present(cpu) ? "yes" : "no");
printf(" %-*s = %s\n", 16, "online", cpu_online(cpu) ? "yes" : "no");
#define DUMP(paca, name, format) \
printf(" %-*s = %#-*"format"\t(0x%lx)\n", 16, #name, 18, paca->name, \
offsetof(struct paca_struct, name));
DUMP(p, lock_token, "x");
DUMP(p, paca_index, "x");
DUMP(p, kernel_toc, "lx");
DUMP(p, kernelbase, "lx");
DUMP(p, kernel_msr, "lx");
#ifdef CONFIG_PPC_STD_MMU_64
DUMP(p, stab_real, "lx");
DUMP(p, stab_addr, "lx");
#endif
DUMP(p, emergency_sp, "p");
DUMP(p, data_offset, "lx");
DUMP(p, hw_cpu_id, "x");
DUMP(p, cpu_start, "x");
DUMP(p, kexec_state, "x");
DUMP(p, __current, "p");
DUMP(p, kstack, "lx");
DUMP(p, stab_rr, "lx");
DUMP(p, saved_r1, "lx");
DUMP(p, trap_save, "x");
DUMP(p, soft_enabled, "x");
DUMP(p, irq_happened, "x");
DUMP(p, io_sync, "x");
DUMP(p, irq_work_pending, "x");
DUMP(p, nap_state_lost, "x");
#undef DUMP
catch_memory_errors = 0;
sync();
}
static void dump_all_pacas(void)
{
int cpu;
if (num_possible_cpus() == 0) {
printf("No possible cpus, use 'dp #' to dump individual cpus\n");
return;
}
for_each_possible_cpu(cpu)
dump_one_paca(cpu);
}
static void dump_pacas(void)
{
unsigned long num;
int c;
c = inchar();
if (c == 'a') {
dump_all_pacas();
return;
}
termch = c; /* Put c back, it wasn't 'a' */
if (scanhex(&num))
dump_one_paca(num);
else
dump_one_paca(xmon_owner);
}
#endif
#define isxdigit(c) (('0' <= (c) && (c) <= '9') \ #define isxdigit(c) (('0' <= (c) && (c) <= '9') \
|| ('a' <= (c) && (c) <= 'f') \ || ('a' <= (c) && (c) <= 'f') \
|| ('A' <= (c) && (c) <= 'F')) || ('A' <= (c) && (c) <= 'F'))
...@@ -2018,6 +2115,14 @@ dump(void) ...@@ -2018,6 +2115,14 @@ dump(void)
int c; int c;
c = inchar(); c = inchar();
#ifdef CONFIG_PPC64
if (c == 'p') {
dump_pacas();
return;
}
#endif
if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n') if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
termch = c; termch = c;
scanhex((void *)&adrs); scanhex((void *)&adrs);
......
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