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