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/kexec.h> 11 #include <linux/mm.h> 12 #include <linux/string.h> 13 #include <asm/cacheflush.h> 14 #include <asm/hw_irq.h> 15 #include <asm/io.h> 16 17 typedef void (*relocate_new_kernel_t)( 18 unsigned long indirection_page, 19 unsigned long reboot_code_buffer, 20 unsigned long start_address) __noreturn; 21 22 /* 23 * This is a generic machine_kexec function suitable at least for 24 * non-OpenFirmware embedded platforms. 25 * It merely copies the image relocation code to the control page and 26 * jumps to it. 27 * A platform specific function may just call this one. 28 */ 29 void default_machine_kexec(struct kimage *image) 30 { 31 extern const unsigned int relocate_new_kernel_size; 32 unsigned long page_list; 33 unsigned long reboot_code_buffer, reboot_code_buffer_phys; 34 relocate_new_kernel_t rnk; 35 36 /* Interrupts aren't acceptable while we reboot */ 37 local_irq_disable(); 38 39 /* mask each interrupt so we are in a more sane state for the 40 * kexec kernel */ 41 machine_kexec_mask_interrupts(); 42 43 page_list = image->head; 44 45 /* we need both effective and real address here */ 46 reboot_code_buffer = 47 (unsigned long)page_address(image->control_code_page); 48 reboot_code_buffer_phys = virt_to_phys((void *)reboot_code_buffer); 49 50 /* copy our kernel relocation code to the control code page */ 51 memcpy((void *)reboot_code_buffer, relocate_new_kernel, 52 relocate_new_kernel_size); 53 54 flush_icache_range(reboot_code_buffer, 55 reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE); 56 printk(KERN_INFO "Bye!\n"); 57 58 if (!IS_ENABLED(CONFIG_PPC_85xx) && !IS_ENABLED(CONFIG_44x)) 59 relocate_new_kernel(page_list, reboot_code_buffer_phys, image->start); 60 61 /* now call it */ 62 rnk = (relocate_new_kernel_t) reboot_code_buffer; 63 (*rnk)(page_list, reboot_code_buffer_phys, image->start); 64 } 65 66 int machine_kexec_prepare(struct kimage *image) 67 { 68 return 0; 69 } 70
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.