xref: /openbmc/linux/arch/parisc/kernel/kexec.c (revision cc719a9c)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 #include <linux/kernel.h>
4 #include <linux/console.h>
5 #include <linux/kexec.h>
6 #include <linux/delay.h>
7 #include <linux/reboot.h>
8 
9 #include <asm/cacheflush.h>
10 #include <asm/sections.h>
11 
12 extern void relocate_new_kernel(unsigned long head,
13 				unsigned long start,
14 				unsigned long phys);
15 
16 extern const unsigned int relocate_new_kernel_size;
17 extern unsigned int kexec_initrd_start_offset;
18 extern unsigned int kexec_initrd_end_offset;
19 extern unsigned int kexec_cmdline_offset;
20 extern unsigned int kexec_free_mem_offset;
21 
kexec_show_segment_info(const struct kimage * kimage,unsigned long n)22 static void kexec_show_segment_info(const struct kimage *kimage,
23 				    unsigned long n)
24 {
25 	pr_debug("    segment[%lu]: %016lx - %016lx, 0x%lx bytes, %lu pages\n",
26 			n,
27 			kimage->segment[n].mem,
28 			kimage->segment[n].mem + kimage->segment[n].memsz,
29 			(unsigned long)kimage->segment[n].memsz,
30 			(unsigned long)kimage->segment[n].memsz /  PAGE_SIZE);
31 }
32 
kexec_image_info(const struct kimage * kimage)33 static void kexec_image_info(const struct kimage *kimage)
34 {
35 	unsigned long i;
36 
37 	pr_debug("kexec kimage info:\n");
38 	pr_debug("  type:        %d\n", kimage->type);
39 	pr_debug("  start:       %lx\n", kimage->start);
40 	pr_debug("  head:        %lx\n", kimage->head);
41 	pr_debug("  nr_segments: %lu\n", kimage->nr_segments);
42 
43 	for (i = 0; i < kimage->nr_segments; i++)
44 		kexec_show_segment_info(kimage, i);
45 
46 #ifdef CONFIG_KEXEC_FILE
47 	if (kimage->file_mode) {
48 		pr_debug("cmdline: %.*s\n", (int)kimage->cmdline_buf_len,
49 			 kimage->cmdline_buf);
50 	}
51 #endif
52 }
53 
machine_kexec_cleanup(struct kimage * kimage)54 void machine_kexec_cleanup(struct kimage *kimage)
55 {
56 }
57 
machine_crash_shutdown(struct pt_regs * regs)58 void machine_crash_shutdown(struct pt_regs *regs)
59 {
60 }
61 
machine_shutdown(void)62 void machine_shutdown(void)
63 {
64 	smp_send_stop();
65 	while (num_online_cpus() > 1) {
66 		cpu_relax();
67 		mdelay(1);
68 	}
69 }
70 
machine_kexec(struct kimage * image)71 void machine_kexec(struct kimage *image)
72 {
73 #ifdef CONFIG_64BIT
74 	Elf64_Fdesc desc;
75 #endif
76 	void (*reloc)(unsigned long head,
77 		      unsigned long start,
78 		      unsigned long phys);
79 
80 	unsigned long phys = page_to_phys(image->control_code_page);
81 	void *virt = (void *)__fix_to_virt(FIX_TEXT_KEXEC);
82 	struct kimage_arch *arch = &image->arch;
83 
84 	set_fixmap(FIX_TEXT_KEXEC, phys);
85 
86 	flush_cache_all();
87 
88 #ifdef CONFIG_64BIT
89 	reloc = (void *)&desc;
90 	desc.addr = (long long)virt;
91 #else
92 	reloc = (void *)virt;
93 #endif
94 
95 	memcpy(virt, dereference_function_descriptor(relocate_new_kernel),
96 		relocate_new_kernel_size);
97 
98 	*(unsigned long *)(virt + kexec_cmdline_offset) = arch->cmdline;
99 	*(unsigned long *)(virt + kexec_initrd_start_offset) = arch->initrd_start;
100 	*(unsigned long *)(virt + kexec_initrd_end_offset) = arch->initrd_end;
101 	*(unsigned long *)(virt + kexec_free_mem_offset) = PAGE0->mem_free;
102 
103 	flush_cache_all();
104 	flush_tlb_all();
105 	local_irq_disable();
106 
107 	reloc(image->head & PAGE_MASK, image->start, phys);
108 }
109 
machine_kexec_prepare(struct kimage * image)110 int machine_kexec_prepare(struct kimage *image)
111 {
112 	kexec_image_info(image);
113 	return 0;
114 }
115