Linux Audio

Check our new training course

Loading...
v4.6
  1/*
  2 * machine_kexec.c for kexec
  3 * Created by <nschichan@corp.free.fr> on Thu Oct 12 15:15:06 2006
  4 *
  5 * This source code is licensed under the GNU General Public License,
  6 * Version 2.  See the file COPYING for more details.
  7 */
  8#include <linux/compiler.h>
  9#include <linux/kexec.h>
 10#include <linux/mm.h>
 11#include <linux/delay.h>
 12
 13#include <asm/cacheflush.h>
 14#include <asm/page.h>
 15
 16extern const unsigned char relocate_new_kernel[];
 17extern const size_t relocate_new_kernel_size;
 18
 19extern unsigned long kexec_start_address;
 20extern unsigned long kexec_indirection_page;
 21
 22int (*_machine_kexec_prepare)(struct kimage *) = NULL;
 23void (*_machine_kexec_shutdown)(void) = NULL;
 24void (*_machine_crash_shutdown)(struct pt_regs *regs) = NULL;
 25#ifdef CONFIG_SMP
 26void (*relocated_kexec_smp_wait) (void *);
 27atomic_t kexec_ready_to_reboot = ATOMIC_INIT(0);
 
 28#endif
 29
 30int
 31machine_kexec_prepare(struct kimage *kimage)
 32{
 33	if (_machine_kexec_prepare)
 34		return _machine_kexec_prepare(kimage);
 35	return 0;
 36}
 37
 38void
 39machine_kexec_cleanup(struct kimage *kimage)
 40{
 41}
 42
 43void
 44machine_shutdown(void)
 45{
 46	if (_machine_kexec_shutdown)
 47		_machine_kexec_shutdown();
 48}
 49
 50void
 51machine_crash_shutdown(struct pt_regs *regs)
 52{
 53	if (_machine_crash_shutdown)
 54		_machine_crash_shutdown(regs);
 55	else
 56		default_machine_crash_shutdown(regs);
 57}
 58
 59typedef void (*noretfun_t)(void) __noreturn;
 60
 61void
 62machine_kexec(struct kimage *image)
 63{
 64	unsigned long reboot_code_buffer;
 65	unsigned long entry;
 66	unsigned long *ptr;
 67
 68	reboot_code_buffer =
 69	  (unsigned long)page_address(image->control_code_page);
 70
 71	kexec_start_address =
 72		(unsigned long) phys_to_virt(image->start);
 73
 74	if (image->type == KEXEC_TYPE_DEFAULT) {
 75		kexec_indirection_page =
 76			(unsigned long) phys_to_virt(image->head & PAGE_MASK);
 77	} else {
 78		kexec_indirection_page = (unsigned long)&image->head;
 79	}
 80
 81	memcpy((void*)reboot_code_buffer, relocate_new_kernel,
 82	       relocate_new_kernel_size);
 83
 84	/*
 85	 * The generic kexec code builds a page list with physical
 86	 * addresses. they are directly accessible through KSEG0 (or
 87	 * CKSEG0 or XPHYS if on 64bit system), hence the
 88	 * phys_to_virt() call.
 89	 */
 90	for (ptr = &image->head; (entry = *ptr) && !(entry &IND_DONE);
 91	     ptr = (entry & IND_INDIRECTION) ?
 92	       phys_to_virt(entry & PAGE_MASK) : ptr + 1) {
 93		if (*ptr & IND_SOURCE || *ptr & IND_INDIRECTION ||
 94		    *ptr & IND_DESTINATION)
 95			*ptr = (unsigned long) phys_to_virt(*ptr);
 96	}
 97
 98	/*
 99	 * we do not want to be bothered.
100	 */
101	local_irq_disable();
102
103	printk("Will call new kernel at %08lx\n", image->start);
104	printk("Bye ...\n");
105	__flush_cache_all();
106#ifdef CONFIG_SMP
107	/* All secondary cpus now may jump to kexec_wait cycle */
108	relocated_kexec_smp_wait = reboot_code_buffer +
109		(void *)(kexec_smp_wait - relocate_new_kernel);
110	smp_wmb();
111	atomic_set(&kexec_ready_to_reboot, 1);
112#endif
113	((noretfun_t) reboot_code_buffer)();
114}
v4.10.11
  1/*
  2 * machine_kexec.c for kexec
  3 * Created by <nschichan@corp.free.fr> on Thu Oct 12 15:15:06 2006
  4 *
  5 * This source code is licensed under the GNU General Public License,
  6 * Version 2.  See the file COPYING for more details.
  7 */
  8#include <linux/compiler.h>
  9#include <linux/kexec.h>
 10#include <linux/mm.h>
 11#include <linux/delay.h>
 12
 13#include <asm/cacheflush.h>
 14#include <asm/page.h>
 15
 16extern const unsigned char relocate_new_kernel[];
 17extern const size_t relocate_new_kernel_size;
 18
 19extern unsigned long kexec_start_address;
 20extern unsigned long kexec_indirection_page;
 21
 22int (*_machine_kexec_prepare)(struct kimage *) = NULL;
 23void (*_machine_kexec_shutdown)(void) = NULL;
 24void (*_machine_crash_shutdown)(struct pt_regs *regs) = NULL;
 25#ifdef CONFIG_SMP
 26void (*relocated_kexec_smp_wait) (void *);
 27atomic_t kexec_ready_to_reboot = ATOMIC_INIT(0);
 28void (*_crash_smp_send_stop)(void) = NULL;
 29#endif
 30
 31int
 32machine_kexec_prepare(struct kimage *kimage)
 33{
 34	if (_machine_kexec_prepare)
 35		return _machine_kexec_prepare(kimage);
 36	return 0;
 37}
 38
 39void
 40machine_kexec_cleanup(struct kimage *kimage)
 41{
 42}
 43
 44void
 45machine_shutdown(void)
 46{
 47	if (_machine_kexec_shutdown)
 48		_machine_kexec_shutdown();
 49}
 50
 51void
 52machine_crash_shutdown(struct pt_regs *regs)
 53{
 54	if (_machine_crash_shutdown)
 55		_machine_crash_shutdown(regs);
 56	else
 57		default_machine_crash_shutdown(regs);
 58}
 59
 60typedef void (*noretfun_t)(void) __noreturn;
 61
 62void
 63machine_kexec(struct kimage *image)
 64{
 65	unsigned long reboot_code_buffer;
 66	unsigned long entry;
 67	unsigned long *ptr;
 68
 69	reboot_code_buffer =
 70	  (unsigned long)page_address(image->control_code_page);
 71
 72	kexec_start_address =
 73		(unsigned long) phys_to_virt(image->start);
 74
 75	if (image->type == KEXEC_TYPE_DEFAULT) {
 76		kexec_indirection_page =
 77			(unsigned long) phys_to_virt(image->head & PAGE_MASK);
 78	} else {
 79		kexec_indirection_page = (unsigned long)&image->head;
 80	}
 81
 82	memcpy((void*)reboot_code_buffer, relocate_new_kernel,
 83	       relocate_new_kernel_size);
 84
 85	/*
 86	 * The generic kexec code builds a page list with physical
 87	 * addresses. they are directly accessible through KSEG0 (or
 88	 * CKSEG0 or XPHYS if on 64bit system), hence the
 89	 * phys_to_virt() call.
 90	 */
 91	for (ptr = &image->head; (entry = *ptr) && !(entry &IND_DONE);
 92	     ptr = (entry & IND_INDIRECTION) ?
 93	       phys_to_virt(entry & PAGE_MASK) : ptr + 1) {
 94		if (*ptr & IND_SOURCE || *ptr & IND_INDIRECTION ||
 95		    *ptr & IND_DESTINATION)
 96			*ptr = (unsigned long) phys_to_virt(*ptr);
 97	}
 98
 99	/*
100	 * we do not want to be bothered.
101	 */
102	local_irq_disable();
103
104	printk("Will call new kernel at %08lx\n", image->start);
105	printk("Bye ...\n");
106	__flush_cache_all();
107#ifdef CONFIG_SMP
108	/* All secondary cpus now may jump to kexec_wait cycle */
109	relocated_kexec_smp_wait = reboot_code_buffer +
110		(void *)(kexec_smp_wait - relocate_new_kernel);
111	smp_wmb();
112	atomic_set(&kexec_ready_to_reboot, 1);
113#endif
114	((noretfun_t) reboot_code_buffer)();
115}