|
@@ -60,6 +60,8 @@ static cpumask_t cpus_in_xmon = CPU_MASK_NONE;
|
|
|
static unsigned long xmon_taken = 1;
|
|
|
static int xmon_owner;
|
|
|
static int xmon_gate;
|
|
|
+#else
|
|
|
+#define xmon_owner 0
|
|
|
#endif /* CONFIG_SMP */
|
|
|
|
|
|
static unsigned long in_xmon __read_mostly = 0;
|
|
@@ -202,7 +204,13 @@ Commands:\n\
|
|
|
di dump instructions\n\
|
|
|
df dump float 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\
|
|
|
e print exception information\n\
|
|
|
f flush cache\n\
|
|
@@ -2009,6 +2017,95 @@ static void xmon_rawdump (unsigned long adrs, long ndump)
|
|
|
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') \
|
|
|
|| ('a' <= (c) && (c) <= 'f') \
|
|
|
|| ('A' <= (c) && (c) <= 'F'))
|
|
@@ -2018,6 +2115,14 @@ dump(void)
|
|
|
int c;
|
|
|
|
|
|
c = inchar();
|
|
|
+
|
|
|
+#ifdef CONFIG_PPC64
|
|
|
+ if (c == 'p') {
|
|
|
+ dump_pacas();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
|
|
|
termch = c;
|
|
|
scanhex((void *)&adrs);
|