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
12extern void relocate_new_kernel(unsigned long head,
13 unsigned long start,
14 unsigned long phys);
15
16extern const unsigned int relocate_new_kernel_size;
17extern unsigned int kexec_initrd_start_offset;
18extern unsigned int kexec_initrd_end_offset;
19extern unsigned int kexec_cmdline_offset;
20extern unsigned int kexec_free_mem_offset;
21
22static 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
33static 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, n: 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
54void machine_kexec_cleanup(struct kimage *kimage)
55{
56}
57
58void machine_crash_shutdown(struct pt_regs *regs)
59{
60}
61
62void machine_shutdown(void)
63{
64 smp_send_stop();
65 while (num_online_cpus() > 1) {
66 cpu_relax();
67 mdelay(1);
68 }
69}
70
71void 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
110int machine_kexec_prepare(struct kimage *image)
111{
112 kexec_image_info(kimage: image);
113 return 0;
114}
115

source code of linux/arch/parisc/kernel/kexec.c