1 /* 2 * machine_kexec.c - handle transition of Linux booting another kernel 3 */ 4 5 #include <linux/mm.h> 6 #include <linux/kexec.h> 7 #include <linux/delay.h> 8 #include <linux/reboot.h> 9 #include <linux/io.h> 10 #include <linux/irq.h> 11 #include <asm/pgtable.h> 12 #include <asm/pgalloc.h> 13 #include <asm/mmu_context.h> 14 #include <asm/cacheflush.h> 15 #include <asm/mach-types.h> 16 #include <asm/system_misc.h> 17 18 extern const unsigned char relocate_new_kernel[]; 19 extern const unsigned int relocate_new_kernel_size; 20 21 extern unsigned long kexec_start_address; 22 extern unsigned long kexec_indirection_page; 23 extern unsigned long kexec_mach_type; 24 extern unsigned long kexec_boot_atags; 25 26 static atomic_t waiting_for_crash_ipi; 27 28 /* 29 * Provide a dummy crash_notes definition while crash dump arrives to arm. 30 * This prevents breakage of crash_notes attribute in kernel/ksysfs.c. 31 */ 32 33 int machine_kexec_prepare(struct kimage *image) 34 { 35 return 0; 36 } 37 38 void machine_kexec_cleanup(struct kimage *image) 39 { 40 } 41 42 void machine_crash_nonpanic_core(void *unused) 43 { 44 struct pt_regs regs; 45 46 crash_setup_regs(®s, NULL); 47 printk(KERN_DEBUG "CPU %u will stop doing anything useful since another CPU has crashed\n", 48 smp_processor_id()); 49 crash_save_cpu(®s, smp_processor_id()); 50 flush_cache_all(); 51 52 atomic_dec(&waiting_for_crash_ipi); 53 while (1) 54 cpu_relax(); 55 } 56 57 static void machine_kexec_mask_interrupts(void) 58 { 59 unsigned int i; 60 struct irq_desc *desc; 61 62 for_each_irq_desc(i, desc) { 63 struct irq_chip *chip; 64 65 chip = irq_desc_get_chip(desc); 66 if (!chip) 67 continue; 68 69 if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data)) 70 chip->irq_eoi(&desc->irq_data); 71 72 if (chip->irq_mask) 73 chip->irq_mask(&desc->irq_data); 74 75 if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data)) 76 chip->irq_disable(&desc->irq_data); 77 } 78 } 79 80 void machine_crash_shutdown(struct pt_regs *regs) 81 { 82 unsigned long msecs; 83 84 local_irq_disable(); 85 86 atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); 87 smp_call_function(machine_crash_nonpanic_core, NULL, false); 88 msecs = 1000; /* Wait at most a second for the other cpus to stop */ 89 while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) { 90 mdelay(1); 91 msecs--; 92 } 93 if (atomic_read(&waiting_for_crash_ipi) > 0) 94 printk(KERN_WARNING "Non-crashing CPUs did not react to IPI\n"); 95 96 crash_save_cpu(regs, smp_processor_id()); 97 machine_kexec_mask_interrupts(); 98 99 printk(KERN_INFO "Loading crashdump kernel...\n"); 100 } 101 102 /* 103 * Function pointer to optional machine-specific reinitialization 104 */ 105 void (*kexec_reinit)(void); 106 107 void machine_kexec(struct kimage *image) 108 { 109 unsigned long page_list; 110 unsigned long reboot_code_buffer_phys; 111 void *reboot_code_buffer; 112 113 114 page_list = image->head & PAGE_MASK; 115 116 /* we need both effective and real address here */ 117 reboot_code_buffer_phys = 118 page_to_pfn(image->control_code_page) << PAGE_SHIFT; 119 reboot_code_buffer = page_address(image->control_code_page); 120 121 /* Prepare parameters for reboot_code_buffer*/ 122 kexec_start_address = image->start; 123 kexec_indirection_page = page_list; 124 kexec_mach_type = machine_arch_type; 125 kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET; 126 127 /* copy our kernel relocation code to the control code page */ 128 memcpy(reboot_code_buffer, 129 relocate_new_kernel, relocate_new_kernel_size); 130 131 132 flush_icache_range((unsigned long) reboot_code_buffer, 133 (unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE); 134 printk(KERN_INFO "Bye!\n"); 135 136 if (kexec_reinit) 137 kexec_reinit(); 138 139 soft_restart(reboot_code_buffer_phys); 140 } 141