Use SBI calls to reboot or power down the machine when the firmware
authorkettenis <kettenis@openbsd.org>
Fri, 29 Mar 2024 22:11:34 +0000 (22:11 +0000)
committerkettenis <kettenis@openbsd.org>
Fri, 29 Mar 2024 22:11:34 +0000 (22:11 +0000)
supports them.

ok jca@

sys/arch/riscv64/include/sbi.h
sys/arch/riscv64/riscv64/sbi.c

index 802ae7f..e5117ed 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: sbi.h,v 1.5 2022/08/29 02:01:18 jsg Exp $     */
+/*     $OpenBSD: sbi.h,v 1.6 2024/03/29 22:11:34 kettenis Exp $        */
 
 /*-
  * Copyright (c) 2016-2017 Ruslan Bukin <br@bsdpad.com>
 #define         SBI_HSM_STATUS_START_PENDING   2
 #define         SBI_HSM_STATUS_STOP_PENDING    3
 
+/* System Reset Extension */
+#define        SBI_EXT_ID_SRST                 0x53525354
+#define        SBI_SRST_RESET                  0
+#define         SBI_SRST_RESET_SHUTDOWN        0
+#define         SBI_SRST_RESET_COLD_REBOOT     1
+#define         SBI_SRST_RESET_WARM_REBOOT     2
+
 /* Legacy Extensions */
 #define        SBI_SET_TIMER                   0
 #define        SBI_CONSOLE_PUTCHAR             1
index 57b90aa..b7c8690 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: sbi.c,v 1.7 2022/12/06 00:11:23 jca Exp $     */
+/*     $OpenBSD: sbi.c,v 1.8 2024/03/29 22:11:34 kettenis Exp $        */
 
 /*-
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
@@ -35,6 +35,9 @@
 
 #include <dev/cons.h>
 
+extern void (*cpuresetfn)(void);
+extern void (*powerdownfn)(void);
+
 /* SBI Implementation-Specific Definitions */
 #define        OPENSBI_VERSION_MAJOR_OFFSET    16
 #define        OPENSBI_VERSION_MINOR_MASK      0xFFFF
@@ -124,6 +127,20 @@ sbi_hsm_hart_status(u_long hart)
 
 #endif
 
+void
+sbi_reset(void)
+{
+       SBI_CALL2(SBI_EXT_ID_SRST, SBI_SRST_RESET,
+           SBI_SRST_RESET_WARM_REBOOT, 0);
+}
+
+void
+sbi_powerdown(void)
+{
+       SBI_CALL2(SBI_EXT_ID_SRST, SBI_SRST_RESET,
+           SBI_SRST_RESET_SHUTDOWN, 0);
+}
+
 void
 sbi_init(void)
 {
@@ -167,6 +184,15 @@ sbi_init(void)
            "SBI doesn't implement sbi_remote_sfence_vma_asid()");
        KASSERTMSG(sbi_probe_extension(SBI_SHUTDOWN) != 0,
            "SBI doesn't implement sbi_shutdown()");
+
+       /*
+        * Implement reboot and power down if the System Reset
+        * Extension is implemented.
+        */
+       if (sbi_probe_extension(SBI_EXT_ID_SRST) != 0) {
+               cpuresetfn = sbi_reset;
+               powerdownfn = sbi_powerdown;
+       }
 }
 
 /*