From c587e4a6a4d808fd2a1c4e7fb2d5a3a31e300d23 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Tue, 6 Feb 2007 21:29:00 +0100 Subject: [ARM] 4137/1: Add kexec support Add kexec support to ARM. Improvements like commandline handling could be made but this patch gives basic functional support. It uses the next available syscall number, 347. Once the syscall number is known, userspace support will be finalised/submitted to kexec-tools, various patches already exist. Originally based on a patch by Maxim Syrchin but updated and forward ported by various people. Signed-off-by: Richard Purdie Signed-off-by: Russell King --- arch/arm/kernel/machine_kexec.c | 78 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 arch/arm/kernel/machine_kexec.c (limited to 'arch/arm/kernel/machine_kexec.c') diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c new file mode 100644 index 000000000000..863c66454f2b --- /dev/null +++ b/arch/arm/kernel/machine_kexec.c @@ -0,0 +1,78 @@ +/* + * machine_kexec.c - handle transition of Linux booting another kernel + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const extern unsigned char relocate_new_kernel[]; +const extern unsigned int relocate_new_kernel_size; + +extern void setup_mm_for_reboot(char mode); + +extern unsigned long kexec_start_address; +extern unsigned long kexec_indirection_page; +extern unsigned long kexec_mach_type; + +/* + * Provide a dummy crash_notes definition while crash dump arrives to arm. + * This prevents breakage of crash_notes attribute in kernel/ksysfs.c. + */ + +int machine_kexec_prepare(struct kimage *image) +{ + return 0; +} + +void machine_kexec_cleanup(struct kimage *image) +{ +} + +void machine_shutdown(void) +{ +} + +void machine_crash_shutdown(struct pt_regs *regs) +{ +} + +void machine_kexec(struct kimage *image) +{ + unsigned long page_list; + unsigned long reboot_code_buffer_phys; + void *reboot_code_buffer; + + + page_list = image->head & PAGE_MASK; + + /* we need both effective and real address here */ + reboot_code_buffer_phys = + page_to_pfn(image->control_code_page) << PAGE_SHIFT; + reboot_code_buffer = page_address(image->control_code_page); + + /* Prepare parameters for reboot_code_buffer*/ + kexec_start_address = image->start; + kexec_indirection_page = page_list; + kexec_mach_type = machine_arch_type; + + /* copy our kernel relocation code to the control code page */ + memcpy(reboot_code_buffer, + relocate_new_kernel, relocate_new_kernel_size); + + + flush_icache_range((unsigned long) reboot_code_buffer, + (unsigned long) reboot_code_buffer + KEXEC_CONTROL_CODE_SIZE); + printk(KERN_INFO "Bye!\n"); + + cpu_proc_fin(); + setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/ + cpu_reset(reboot_code_buffer_phys); +} -- cgit v1.2.1