xref: /linux/arch/powerpc/platforms/pseries/kexec.c (revision c537b994505099b7197e7d3125b942ecbcc51eb6)
1 /*
2  *  Copyright 2006 Michael Ellerman, IBM Corporation
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version
7  * 2 of the License, or (at your option) any later version.
8  */
9 
10 #include <asm/machdep.h>
11 #include <asm/page.h>
12 #include <asm/firmware.h>
13 #include <asm/kexec.h>
14 #include <asm/mpic.h>
15 
16 #include "pseries.h"
17 #include "xics.h"
18 #include "plpar_wrappers.h"
19 
20 static void pseries_kexec_cpu_down(int crash_shutdown, int secondary)
21 {
22 	/* Don't risk a hypervisor call if we're crashing */
23 	if (firmware_has_feature(FW_FEATURE_SPLPAR) && !crash_shutdown) {
24 		unsigned long addr;
25 
26 		addr = __pa(get_slb_shadow());
27 		if (unregister_slb_shadow(hard_smp_processor_id(), addr))
28 			printk("SLB shadow buffer deregistration of "
29 			       "cpu %u (hw_cpu_id %d) failed\n",
30 			       smp_processor_id(),
31 			       hard_smp_processor_id());
32 
33 		addr = __pa(get_lppaca());
34 		if (unregister_vpa(hard_smp_processor_id(), addr)) {
35 			printk("VPA deregistration of cpu %u (hw_cpu_id %d) "
36 					"failed\n", smp_processor_id(),
37 					hard_smp_processor_id());
38 		}
39 	}
40 }
41 
42 static void pseries_kexec_cpu_down_mpic(int crash_shutdown, int secondary)
43 {
44 	pseries_kexec_cpu_down(crash_shutdown, secondary);
45 	mpic_teardown_this_cpu(secondary);
46 }
47 
48 void __init setup_kexec_cpu_down_mpic(void)
49 {
50 	ppc_md.kexec_cpu_down = pseries_kexec_cpu_down_mpic;
51 }
52 
53 static void pseries_kexec_cpu_down_xics(int crash_shutdown, int secondary)
54 {
55 	pseries_kexec_cpu_down(crash_shutdown, secondary);
56 	xics_teardown_cpu(secondary);
57 }
58 
59 void __init setup_kexec_cpu_down_xics(void)
60 {
61 	ppc_md.kexec_cpu_down = pseries_kexec_cpu_down_xics;
62 }
63 
64 static int __init pseries_kexec_setup(void)
65 {
66 	ppc_md.machine_kexec = default_machine_kexec;
67 	ppc_md.machine_kexec_prepare = default_machine_kexec_prepare;
68 	ppc_md.machine_crash_shutdown = default_machine_crash_shutdown;
69 
70 	return 0;
71 }
72 __initcall(pseries_kexec_setup);
73