summaryrefslogtreecommitdiff
path: root/lib/sbi/sbi_system.c
diff options
context:
space:
mode:
authorAnup Patel <anup.patel@wdc.com>2020-01-03 08:47:44 +0300
committerAnup Patel <anup.patel@wdc.com>2020-01-07 09:41:36 +0300
commit15ed1e74526d85f94c2cda338c572e36e249c803 (patch)
treee132b968b341b7324ebfc8e51c0cc366d25ba739 /lib/sbi/sbi_system.c
parentb0c9787435e56550aea4d110dc503ac23f9801a6 (diff)
downloadopensbi-15ed1e74526d85f94c2cda338c572e36e249c803.tar.xz
lib: improve system reboot and shutdown implementation
We improve sbi_system_reboot() an sbi_system_shutdown() by: 1. Calling halt IPI to all harts (except current HART) before calling platform reboot/shutdown hook. 2. Calling sbi_exit() instead of sbi_hang() in-case platform reboot/shutdown hook failed. Signed-off-by: Anup Patel <anup.patel@wdc.com> Reviewed-by: Atish Patra <atish.patra@wdc.com>
Diffstat (limited to 'lib/sbi/sbi_system.c')
-rw-r--r--lib/sbi/sbi_system.c37
1 files changed, 24 insertions, 13 deletions
diff --git a/lib/sbi/sbi_system.c b/lib/sbi/sbi_system.c
index 9ea3c21..d189a89 100644
--- a/lib/sbi/sbi_system.c
+++ b/lib/sbi/sbi_system.c
@@ -12,6 +12,7 @@
#include <sbi/sbi_platform.h>
#include <sbi/sbi_system.h>
#include <sbi/sbi_ipi.h>
+#include <sbi/sbi_init.h>
int sbi_system_early_init(struct sbi_scratch *scratch, bool cold_boot)
{
@@ -33,24 +34,34 @@ void sbi_system_final_exit(struct sbi_scratch *scratch)
sbi_platform_final_exit(sbi_platform_ptr(scratch));
}
-void __attribute__((noreturn))
-sbi_system_reboot(struct sbi_scratch *scratch, u32 type)
-
+void __noreturn sbi_system_reboot(struct sbi_scratch *scratch, u32 type)
{
+ u32 current_hartid_mask = 1UL << sbi_current_hartid();
+
+ /* Send HALT IPI to every hart other than the current hart */
+ sbi_ipi_send_many(scratch,
+ sbi_hart_available_mask() & ~current_hartid_mask,
+ 0, SBI_IPI_EVENT_HALT, NULL);
+
+ /* Platform specific reooot */
sbi_platform_system_reboot(sbi_platform_ptr(scratch), type);
- sbi_hart_hang();
+
+ /* If platform specific reboot did not work then do sbi_exit() */
+ sbi_exit(scratch);
}
-void __attribute__((noreturn))
-sbi_system_shutdown(struct sbi_scratch *scratch, u32 type)
+void __noreturn sbi_system_shutdown(struct sbi_scratch *scratch, u32 type)
{
- /* First try the platform-specific method */
- sbi_platform_system_shutdown(sbi_platform_ptr(scratch), type);
+ u32 current_hartid_mask = 1UL << sbi_current_hartid();
+
+ /* Send HALT IPI to every hart other than the current hart */
+ sbi_ipi_send_many(scratch,
+ sbi_hart_available_mask() & ~current_hartid_mask,
+ 0, SBI_IPI_EVENT_HALT, NULL);
- /* If that fails (or is not implemented) send an IPI on every
- * hart to hang and then hang the current hart */
- sbi_ipi_send_many(scratch, sbi_hart_available_mask(), 0,
- SBI_IPI_EVENT_HALT, NULL);
+ /* Platform specific shutdown */
+ sbi_platform_system_shutdown(sbi_platform_ptr(scratch), type);
- sbi_hart_hang();
+ /* If platform specific shutdown did not work then do sbi_exit() */
+ sbi_exit(scratch);
}