18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * machine_kexec.c - handle transition of Linux booting another kernel
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci#include <linux/compiler.h>
68c2ecf20Sopenharmony_ci#include <linux/kexec.h>
78c2ecf20Sopenharmony_ci#include <linux/mm.h>
88c2ecf20Sopenharmony_ci#include <linux/delay.h>
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <asm/cacheflush.h>
118c2ecf20Sopenharmony_ci#include <asm/page.h>
128c2ecf20Sopenharmony_ci#include <asm/setup.h>
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ciextern const unsigned char relocate_new_kernel[];
158c2ecf20Sopenharmony_ciextern const size_t relocate_new_kernel_size;
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ciint machine_kexec_prepare(struct kimage *kimage)
188c2ecf20Sopenharmony_ci{
198c2ecf20Sopenharmony_ci	return 0;
208c2ecf20Sopenharmony_ci}
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_civoid machine_kexec_cleanup(struct kimage *kimage)
238c2ecf20Sopenharmony_ci{
248c2ecf20Sopenharmony_ci}
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_civoid machine_shutdown(void)
278c2ecf20Sopenharmony_ci{
288c2ecf20Sopenharmony_ci}
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_civoid machine_crash_shutdown(struct pt_regs *regs)
318c2ecf20Sopenharmony_ci{
328c2ecf20Sopenharmony_ci}
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_citypedef void (*relocate_kernel_t)(unsigned long ptr,
358c2ecf20Sopenharmony_ci				  unsigned long start,
368c2ecf20Sopenharmony_ci				  unsigned long cpu_mmu_flags) __noreturn;
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_civoid machine_kexec(struct kimage *image)
398c2ecf20Sopenharmony_ci{
408c2ecf20Sopenharmony_ci	void *reboot_code_buffer;
418c2ecf20Sopenharmony_ci	unsigned long cpu_mmu_flags;
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci	reboot_code_buffer = page_address(image->control_code_page);
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci	memcpy(reboot_code_buffer, relocate_new_kernel,
468c2ecf20Sopenharmony_ci	       relocate_new_kernel_size);
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci	/*
498c2ecf20Sopenharmony_ci	 * we do not want to be bothered.
508c2ecf20Sopenharmony_ci	 */
518c2ecf20Sopenharmony_ci	local_irq_disable();
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci	pr_info("Will call new kernel at 0x%08lx. Bye...\n", image->start);
548c2ecf20Sopenharmony_ci	__flush_cache_all();
558c2ecf20Sopenharmony_ci	cpu_mmu_flags = m68k_cputype | m68k_mmutype << 8;
568c2ecf20Sopenharmony_ci	((relocate_kernel_t) reboot_code_buffer)(image->head & PAGE_MASK,
578c2ecf20Sopenharmony_ci						 image->start,
588c2ecf20Sopenharmony_ci						 cpu_mmu_flags);
598c2ecf20Sopenharmony_ci}
60