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