reboot.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 1996-2000 Russell King - Converted to ARM.
  4. * Original Copyright (C) 1995 Linus Torvalds
  5. */
  6. #include <linux/cpu.h>
  7. #include <linux/delay.h>
  8. #include <linux/reboot.h>
  9. #include <asm/cacheflush.h>
  10. #include <asm/idmap.h>
  11. #include <asm/virt.h>
  12. #include <asm/system_misc.h>
  13. #include "reboot.h"
  14. typedef void (*phys_reset_t)(unsigned long, bool);
  15. /*
  16. * Function pointers to optional machine specific functions
  17. */
  18. void (*pm_power_off)(void);
  19. EXPORT_SYMBOL(pm_power_off);
  20. /*
  21. * A temporary stack to use for CPU reset. This is static so that we
  22. * don't clobber it with the identity mapping. When running with this
  23. * stack, any references to the current task *will not work* so you
  24. * should really do as little as possible before jumping to your reset
  25. * code.
  26. */
  27. static u64 soft_restart_stack[16];
  28. static void __soft_restart(void *addr)
  29. {
  30. phys_reset_t phys_reset;
  31. /* Take out a flat memory mapping. */
  32. setup_mm_for_reboot();
  33. /* Clean and invalidate caches */
  34. flush_cache_all();
  35. /* Turn off caching */
  36. cpu_proc_fin();
  37. /* Push out any further dirty data, and ensure cache is empty */
  38. flush_cache_all();
  39. /* Switch to the identity mapping. */
  40. phys_reset = (phys_reset_t)virt_to_idmap(cpu_reset);
  41. /* original stub should be restored by kvm */
  42. phys_reset((unsigned long)addr, is_hyp_mode_available());
  43. /* Should never get here. */
  44. BUG();
  45. }
  46. void _soft_restart(unsigned long addr, bool disable_l2)
  47. {
  48. u64 *stack = soft_restart_stack + ARRAY_SIZE(soft_restart_stack);
  49. /* Disable interrupts first */
  50. raw_local_irq_disable();
  51. local_fiq_disable();
  52. /* Disable the L2 if we're the last man standing. */
  53. if (disable_l2)
  54. outer_disable();
  55. /* Change to the new stack and continue with the reset. */
  56. call_with_stack(__soft_restart, (void *)addr, (void *)stack);
  57. /* Should never get here. */
  58. BUG();
  59. }
  60. void soft_restart(unsigned long addr)
  61. {
  62. _soft_restart(addr, num_online_cpus() == 1);
  63. }
  64. /*
  65. * Called by kexec, immediately prior to machine_kexec().
  66. *
  67. * This must completely disable all secondary CPUs; simply causing those CPUs
  68. * to execute e.g. a RAM-based pin loop is not sufficient. This allows the
  69. * kexec'd kernel to use any and all RAM as it sees fit, without having to
  70. * avoid any code or data used by any SW CPU pin loop. The CPU hotplug
  71. * functionality embodied in smp_shutdown_nonboot_cpus() to achieve this.
  72. */
  73. void machine_shutdown(void)
  74. {
  75. smp_shutdown_nonboot_cpus(reboot_cpu);
  76. }
  77. /*
  78. * Halting simply requires that the secondary CPUs stop performing any
  79. * activity (executing tasks, handling interrupts). smp_send_stop()
  80. * achieves this.
  81. */
  82. void machine_halt(void)
  83. {
  84. local_irq_disable();
  85. smp_send_stop();
  86. while (1);
  87. }
  88. /*
  89. * Power-off simply requires that the secondary CPUs stop performing any
  90. * activity (executing tasks, handling interrupts). smp_send_stop()
  91. * achieves this. When the system power is turned off, it will take all CPUs
  92. * with it.
  93. */
  94. void machine_power_off(void)
  95. {
  96. local_irq_disable();
  97. smp_send_stop();
  98. do_kernel_power_off();
  99. }
  100. /*
  101. * Restart requires that the secondary CPUs stop performing any activity
  102. * while the primary CPU resets the system. Systems with a single CPU can
  103. * use soft_restart() as their machine descriptor's .restart hook, since that
  104. * will cause the only available CPU to reset. Systems with multiple CPUs must
  105. * provide a HW restart implementation, to ensure that all CPUs reset at once.
  106. * This is required so that any code running after reset on the primary CPU
  107. * doesn't have to co-ordinate with other CPUs to ensure they aren't still
  108. * executing pre-reset code, and using RAM that the primary CPU's code wishes
  109. * to use. Implementing such co-ordination would be essentially impossible.
  110. */
  111. void machine_restart(char *cmd)
  112. {
  113. local_irq_disable();
  114. smp_send_stop();
  115. do_kernel_restart(cmd);
  116. /* Give a grace period for failure to restart of 1s */
  117. mdelay(1000);
  118. /* Whoops - the platform was unable to reboot. Tell the user! */
  119. printk("Reboot failed -- System halted\n");
  120. while (1);
  121. }