machine_kexec.c 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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/kexec.h>
  9. #include <linux/mm.h>
  10. #include <linux/delay.h>
  11. #include <asm/cacheflush.h>
  12. #include <asm/page.h>
  13. const extern unsigned char relocate_new_kernel[];
  14. const extern unsigned int relocate_new_kernel_size;
  15. extern unsigned long kexec_start_address;
  16. extern unsigned long kexec_indirection_page;
  17. int
  18. machine_kexec_prepare(struct kimage *kimage)
  19. {
  20. return 0;
  21. }
  22. void
  23. machine_kexec_cleanup(struct kimage *kimage)
  24. {
  25. }
  26. void
  27. machine_shutdown(void)
  28. {
  29. }
  30. void
  31. machine_crash_shutdown(struct pt_regs *regs)
  32. {
  33. }
  34. void
  35. machine_kexec(struct kimage *image)
  36. {
  37. unsigned long reboot_code_buffer;
  38. unsigned long entry;
  39. unsigned long *ptr;
  40. reboot_code_buffer =
  41. (unsigned long)page_address(image->control_code_page);
  42. kexec_start_address = image->start;
  43. kexec_indirection_page = phys_to_virt(image->head & PAGE_MASK);
  44. memcpy((void*)reboot_code_buffer, relocate_new_kernel,
  45. relocate_new_kernel_size);
  46. /*
  47. * The generic kexec code builds a page list with physical
  48. * addresses. they are directly accessible through KSEG0 (or
  49. * CKSEG0 or XPHYS if on 64bit system), hence the
  50. * pys_to_virt() call.
  51. */
  52. for (ptr = &image->head; (entry = *ptr) && !(entry &IND_DONE);
  53. ptr = (entry & IND_INDIRECTION) ?
  54. phys_to_virt(entry & PAGE_MASK) : ptr + 1) {
  55. if (*ptr & IND_SOURCE || *ptr & IND_INDIRECTION ||
  56. *ptr & IND_DESTINATION)
  57. *ptr = phys_to_virt(*ptr);
  58. }
  59. /*
  60. * we do not want to be bothered.
  61. */
  62. local_irq_disable();
  63. flush_icache_range(reboot_code_buffer,
  64. reboot_code_buffer + KEXEC_CONTROL_CODE_SIZE);
  65. printk("Will call new kernel at %08x\n", image->start);
  66. printk("Bye ...\n");
  67. flush_cache_all();
  68. ((void (*)(void))reboot_code_buffer)();
  69. }