^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * machine_kexec.c - handle transition of Linux booting another kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/compiler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/kexec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/cacheflush.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <asm/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <asm/setup.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) extern const unsigned char relocate_new_kernel[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) extern const size_t relocate_new_kernel_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) int machine_kexec_prepare(struct kimage *kimage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) void machine_kexec_cleanup(struct kimage *kimage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) void machine_shutdown(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) void machine_crash_shutdown(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) typedef void (*relocate_kernel_t)(unsigned long ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) unsigned long start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) unsigned long cpu_mmu_flags) __noreturn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) void machine_kexec(struct kimage *image)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) void *reboot_code_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) unsigned long cpu_mmu_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) reboot_code_buffer = page_address(image->control_code_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) memcpy(reboot_code_buffer, relocate_new_kernel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) relocate_new_kernel_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * we do not want to be bothered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) local_irq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) pr_info("Will call new kernel at 0x%08lx. Bye...\n", image->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) __flush_cache_all();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) cpu_mmu_flags = m68k_cputype | m68k_mmutype << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) ((relocate_kernel_t) reboot_code_buffer)(image->head & PAGE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) image->start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) cpu_mmu_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }