0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/kexec.h>
0011 #include <linux/mm.h>
0012 #include <linux/string.h>
0013 #include <asm/cacheflush.h>
0014 #include <asm/hw_irq.h>
0015 #include <asm/io.h>
0016
0017 typedef void (*relocate_new_kernel_t)(
0018 unsigned long indirection_page,
0019 unsigned long reboot_code_buffer,
0020 unsigned long start_address) __noreturn;
0021
0022
0023
0024
0025
0026
0027
0028
0029 void default_machine_kexec(struct kimage *image)
0030 {
0031 extern const unsigned int relocate_new_kernel_size;
0032 unsigned long page_list;
0033 unsigned long reboot_code_buffer, reboot_code_buffer_phys;
0034 relocate_new_kernel_t rnk;
0035
0036
0037 local_irq_disable();
0038
0039
0040
0041 machine_kexec_mask_interrupts();
0042
0043 page_list = image->head;
0044
0045
0046 reboot_code_buffer =
0047 (unsigned long)page_address(image->control_code_page);
0048 reboot_code_buffer_phys = virt_to_phys((void *)reboot_code_buffer);
0049
0050
0051 memcpy((void *)reboot_code_buffer, relocate_new_kernel,
0052 relocate_new_kernel_size);
0053
0054 flush_icache_range(reboot_code_buffer,
0055 reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE);
0056 printk(KERN_INFO "Bye!\n");
0057
0058 if (!IS_ENABLED(CONFIG_FSL_BOOKE) && !IS_ENABLED(CONFIG_44x))
0059 relocate_new_kernel(page_list, reboot_code_buffer_phys, image->start);
0060
0061
0062 rnk = (relocate_new_kernel_t) reboot_code_buffer;
0063 (*rnk)(page_list, reboot_code_buffer_phys, image->start);
0064 }
0065
0066 int machine_kexec_prepare(struct kimage *image)
0067 {
0068 return 0;
0069 }