1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * PPC32 code to handle Linux booting another kernel. 4 * 5 * Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com> 6 * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz 7 * Copyright (C) 2005 IBM Corporation. 8 */ 9 10 #include <linux/irq.h> 11 #include <linux/kexec.h> 12 #include <linux/mm.h> 13 #include <linux/string.h> 14 #include <asm/cacheflush.h> 15 #include <asm/hw_irq.h> 16 #include <asm/io.h> 17 18 typedef void (*relocate_new_kernel_t)( 19 unsigned long indirection_page, 20 unsigned long reboot_code_buffer, 21 unsigned long start_address) __noreturn; 22 23 /* 24 * This is a generic machine_kexec function suitable at least for 25 * non-OpenFirmware embedded platforms. 26 * It merely copies the image relocation code to the control page and 27 * jumps to it. 28 * A platform specific function may just call this one. 29 */ 30 void default_machine_kexec(struct kimage *image) 31 { 32 extern const unsigned int relocate_new_kernel_size; 33 unsigned long page_list; 34 unsigned long reboot_code_buffer, reboot_code_buffer_phys; 35 relocate_new_kernel_t rnk; 36 37 /* Interrupts aren't acceptable while we reboot */ 38 local_irq_disable(); 39 40 /* mask each interrupt so we are in a more sane state for the 41 * kexec kernel */ 42 machine_kexec_mask_interrupts(); 43 44 page_list = image->head; 45 46 /* we need both effective and real address here */ 47 reboot_code_buffer = 48 (unsigned long)page_address(image->control_code_page); 49 reboot_code_buffer_phys = virt_to_phys((void *)reboot_code_buffer); 50 51 /* copy our kernel relocation code to the control code page */ 52 memcpy((void *)reboot_code_buffer, relocate_new_kernel, 53 relocate_new_kernel_size); 54 55 flush_icache_range(reboot_code_buffer, 56 reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE); 57 printk(KERN_INFO "Bye!\n"); 58 59 if (!IS_ENABLED(CONFIG_PPC_85xx) && !IS_ENABLED(CONFIG_44x)) 60 relocate_new_kernel(page_list, reboot_code_buffer_phys, image->start); 61 62 /* now call it */ 63 rnk = (relocate_new_kernel_t) reboot_code_buffer; 64 (*rnk)(page_list, reboot_code_buffer_phys, image->start); 65 } 66 67 int machine_kexec_prepare(struct kimage *image) 68 { 69 return 0; 70 } 71