Linux Audio

Check our new training course

Loading...
v5.4
  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
 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}
v6.2
  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
 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}