linux/arch/parisc/kernel/kexec.c
<<
>>
Prefs
   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}
 113