13 #include <linux/kernel.h>
15 #include <linux/reboot.h>
16 #include <linux/kexec.h>
17 #include <linux/export.h>
22 #include <linux/types.h>
24 #include <asm/processor.h>
25 #include <asm/machdep.h>
26 #include <asm/kexec.h>
31 #include <asm/debug.h>
41 #define PRIMARY_TIMEOUT 500
42 #define SECONDARY_TIMEOUT 1000
44 #define IPI_TIMEOUT 10000
45 #define REAL_MODE_TIMEOUT 10000
49 static int time_to_dump;
51 #define CRASH_HANDLER_MAX 3
56 static unsigned long crash_shutdown_buf[
JMP_BUF_LEN];
57 static int crash_shutdown_cpu = -1;
69 void crash_ipi_callback(
struct pt_regs *regs)
81 cpumask_set_cpu(cpu, &cpus_state_saved);
95 ppc_md.kexec_cpu_down(1, 1);
106 static void crash_kexec_prepare_cpus(
int cpu)
115 crash_send_ipi(crash_ipi_callback);
125 while ((
atomic_read(&cpus_in_crash) < ncpus) && (--msecs > 0))
151 old_handler = __debugger;
152 __debugger = handle_fault;
155 if (
setjmp(crash_shutdown_buf) == 0) {
157 "to stop other cpu(s)\n");
171 crash_shutdown_cpu = -1;
172 __debugger = old_handler;
199 crash_ipi_callback(regs);
204 static void crash_kexec_prepare_cpus(
int cpu)
225 #if defined(CONFIG_SMP) && defined(CONFIG_PPC_STD_MMU_64)
226 static void crash_kexec_wait_realmode(
int cpu)
232 for (i=0; i < nr_cpu_ids && msecs > 0; i++) {
236 while (
paca[i].kexec_state < KEXEC_STATE_REAL_MODE) {
247 static inline void crash_kexec_wait_realmode(
int cpu) {}
258 spin_lock(&crash_handlers_lock);
260 if (!crash_shutdown_handles[i]) {
262 crash_shutdown_handles[
i] = handler;
267 if (i == CRASH_HANDLER_MAX) {
269 "not registered.\n");
273 spin_unlock(&crash_handlers_lock);
282 spin_lock(&crash_handlers_lock);
284 if (crash_shutdown_handles[i] == handler)
287 if (i == CRASH_HANDLER_MAX) {
292 for (; crash_shutdown_handles[
i]; i++)
293 crash_shutdown_handles[i] =
294 crash_shutdown_handles[i+1];
298 spin_unlock(&crash_handlers_lock);
330 if (
TRAP(regs) == 0x100)
347 old_handler = __debugger_fault_handler;
348 __debugger_fault_handler = handle_fault;
350 for (i = 0; crash_shutdown_handles[
i]; i++) {
351 if (
setjmp(crash_shutdown_buf) == 0) {
357 asm volatile(
"sync; isync");
359 crash_shutdown_handles[
i]();
360 asm volatile(
"sync; isync");
363 crash_shutdown_cpu = -1;
364 __debugger_fault_handler = old_handler;
366 if (
ppc_md.kexec_cpu_down)
367 ppc_md.kexec_cpu_down(1, 0);