aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/xmon/xmon.c
diff options
context:
space:
mode:
authorMichael Ellerman <michael@ellerman.id.au>2012-09-13 19:01:31 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-09-18 01:02:36 -0400
commitddadb6b8e88979a00ac44fba9c92896eec113bd1 (patch)
treebd5856386a13028e016d264511664adf3b6832d4 /arch/powerpc/xmon/xmon.c
parentb9ae38aeca2fddbabe2942bee431873a05d21d74 (diff)
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: Michael Ellerman <michael@ellerman.id.au> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/xmon/xmon.c')
-rw-r--r--arch/powerpc/xmon/xmon.c107
1 files changed, 106 insertions, 1 deletions
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 987f441525cb..3a56a639a92e 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -60,6 +60,8 @@ static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
60static unsigned long xmon_taken = 1; 60static unsigned long xmon_taken = 1;
61static int xmon_owner; 61static int xmon_owner;
62static int xmon_gate; 62static int xmon_gate;
63#else
64#define xmon_owner 0
63#endif /* CONFIG_SMP */ 65#endif /* CONFIG_SMP */
64 66
65static unsigned long in_xmon __read_mostly = 0; 67static unsigned long in_xmon __read_mostly = 0;
@@ -202,7 +204,13 @@ Commands:\n\
202 di dump instructions\n\ 204 di dump instructions\n\
203 df dump float values\n\ 205 df dump float values\n\
204 dd dump double values\n\ 206 dd dump double values\n\
205 dl dump the kernel log buffer\n\ 207 dl dump the kernel log buffer\n"
208#ifdef CONFIG_PPC64
209 "\
210 dp[#] dump paca for current cpu, or cpu #\n\
211 dpa dump paca for all possible cpus\n"
212#endif
213 "\
206 dr dump stream of raw bytes\n\ 214 dr dump stream of raw bytes\n\
207 e print exception information\n\ 215 e print exception information\n\
208 f flush cache\n\ 216 f flush cache\n\
@@ -2009,6 +2017,95 @@ static void xmon_rawdump (unsigned long adrs, long ndump)
2009 printf("\n"); 2017 printf("\n");
2010} 2018}
2011 2019
2020#ifdef CONFIG_PPC64
2021static void dump_one_paca(int cpu)
2022{
2023 struct paca_struct *p;
2024
2025 if (setjmp(bus_error_jmp) != 0) {
2026 printf("*** Error dumping paca for cpu 0x%x!\n", cpu);
2027 return;
2028 }
2029
2030 catch_memory_errors = 1;
2031 sync();
2032
2033 p = &paca[cpu];
2034
2035 printf("paca for cpu 0x%x @ %p:\n", cpu, p);
2036
2037 printf(" %-*s = %s\n", 16, "possible", cpu_possible(cpu) ? "yes" : "no");
2038 printf(" %-*s = %s\n", 16, "present", cpu_present(cpu) ? "yes" : "no");
2039 printf(" %-*s = %s\n", 16, "online", cpu_online(cpu) ? "yes" : "no");
2040
2041#define DUMP(paca, name, format) \
2042 printf(" %-*s = %#-*"format"\t(0x%lx)\n", 16, #name, 18, paca->name, \
2043 offsetof(struct paca_struct, name));
2044
2045 DUMP(p, lock_token, "x");
2046 DUMP(p, paca_index, "x");
2047 DUMP(p, kernel_toc, "lx");
2048 DUMP(p, kernelbase, "lx");
2049 DUMP(p, kernel_msr, "lx");
2050#ifdef CONFIG_PPC_STD_MMU_64
2051 DUMP(p, stab_real, "lx");
2052 DUMP(p, stab_addr, "lx");
2053#endif
2054 DUMP(p, emergency_sp, "p");
2055 DUMP(p, data_offset, "lx");
2056 DUMP(p, hw_cpu_id, "x");
2057 DUMP(p, cpu_start, "x");
2058 DUMP(p, kexec_state, "x");
2059 DUMP(p, __current, "p");
2060 DUMP(p, kstack, "lx");
2061 DUMP(p, stab_rr, "lx");
2062 DUMP(p, saved_r1, "lx");
2063 DUMP(p, trap_save, "x");
2064 DUMP(p, soft_enabled, "x");
2065 DUMP(p, irq_happened, "x");
2066 DUMP(p, io_sync, "x");
2067 DUMP(p, irq_work_pending, "x");
2068 DUMP(p, nap_state_lost, "x");
2069
2070#undef DUMP
2071
2072 catch_memory_errors = 0;
2073 sync();
2074}
2075
2076static void dump_all_pacas(void)
2077{
2078 int cpu;
2079
2080 if (num_possible_cpus() == 0) {
2081 printf("No possible cpus, use 'dp #' to dump individual cpus\n");
2082 return;
2083 }
2084
2085 for_each_possible_cpu(cpu)
2086 dump_one_paca(cpu);
2087}
2088
2089static void dump_pacas(void)
2090{
2091 unsigned long num;
2092 int c;
2093
2094 c = inchar();
2095 if (c == 'a') {
2096 dump_all_pacas();
2097 return;
2098 }
2099
2100 termch = c; /* Put c back, it wasn't 'a' */
2101
2102 if (scanhex(&num))
2103 dump_one_paca(num);
2104 else
2105 dump_one_paca(xmon_owner);
2106}
2107#endif
2108
2012#define isxdigit(c) (('0' <= (c) && (c) <= '9') \ 2109#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
2013 || ('a' <= (c) && (c) <= 'f') \ 2110 || ('a' <= (c) && (c) <= 'f') \
2014 || ('A' <= (c) && (c) <= 'F')) 2111 || ('A' <= (c) && (c) <= 'F'))
@@ -2018,6 +2115,14 @@ dump(void)
2018 int c; 2115 int c;
2019 2116
2020 c = inchar(); 2117 c = inchar();
2118
2119#ifdef CONFIG_PPC64
2120 if (c == 'p') {
2121 dump_pacas();
2122 return;
2123 }
2124#endif
2125
2021 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n') 2126 if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
2022 termch = c; 2127 termch = c;
2023 scanhex((void *)&adrs); 2128 scanhex((void *)&adrs);