machine_kexec.c 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. /*
  2. * machine_kexec.c - handle transition of Linux booting another kernel
  3. */
  4. #include <linux/compiler.h>
  5. #include <linux/kexec.h>
  6. #include <linux/mm.h>
  7. #include <linux/delay.h>
  8. #include <asm/cacheflush.h>
  9. #include <asm/page.h>
  10. #include <asm/setup.h>
  11. extern const unsigned char relocate_new_kernel[];
  12. extern const size_t relocate_new_kernel_size;
  13. int machine_kexec_prepare(struct kimage *kimage)
  14. {
  15. return 0;
  16. }
  17. void machine_kexec_cleanup(struct kimage *kimage)
  18. {
  19. }
  20. void machine_shutdown(void)
  21. {
  22. }
  23. void machine_crash_shutdown(struct pt_regs *regs)
  24. {
  25. }
  26. typedef void (*relocate_kernel_t)(unsigned long ptr,
  27. unsigned long start,
  28. unsigned long cpu_mmu_flags) __noreturn;
  29. void machine_kexec(struct kimage *image)
  30. {
  31. void *reboot_code_buffer;
  32. unsigned long cpu_mmu_flags;
  33. reboot_code_buffer = page_address(image->control_code_page);
  34. memcpy(reboot_code_buffer, relocate_new_kernel,
  35. relocate_new_kernel_size);
  36. /*
  37. * we do not want to be bothered.
  38. */
  39. local_irq_disable();
  40. pr_info("Will call new kernel at 0x%08lx. Bye...\n", image->start);
  41. __flush_cache_all();
  42. cpu_mmu_flags = m68k_cputype | m68k_mmutype << 8;
  43. ((relocate_kernel_t) reboot_code_buffer)(image->head & PAGE_MASK,
  44. image->start,
  45. cpu_mmu_flags);
  46. }