aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2024-10-22 15:13:59 +0100
committerMichael Brown <mcb30@ipxe.org>2024-10-22 15:13:59 +0100
commit21940425c4b50e2b8f0a2ccf1db2c86873c28462 (patch)
tree12ff34049e8f8a51817ea5ad3cba6a64bf56d5b4
parentb23204b383cdea4ad64276991b55d8019fee3265 (diff)
downloadipxe-21940425c4b50e2b8f0a2ccf1db2c86873c28462.tar.gz
[riscv] Add support for reboot and power off via SBI
Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/arch/riscv/include/bits/errfile.h2
-rw-r--r--src/arch/riscv/include/bits/reboot.h14
-rw-r--r--src/arch/riscv/include/ipxe/sbi.h10
-rw-r--r--src/arch/riscv/include/ipxe/sbi_reboot.h18
-rw-r--r--src/arch/riscv/interface/sbi/sbi_reboot.c76
5 files changed, 120 insertions, 0 deletions
diff --git a/src/arch/riscv/include/bits/errfile.h b/src/arch/riscv/include/bits/errfile.h
index 2b1202147..e97c71a37 100644
--- a/src/arch/riscv/include/bits/errfile.h
+++ b/src/arch/riscv/include/bits/errfile.h
@@ -14,6 +14,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
* @{
*/
+#define ERRFILE_sbi_reboot ( ERRFILE_ARCH | ERRFILE_CORE | 0x00000000 )
+
/** @} */
#endif /* _BITS_ERRFILE_H */
diff --git a/src/arch/riscv/include/bits/reboot.h b/src/arch/riscv/include/bits/reboot.h
new file mode 100644
index 000000000..01272483b
--- /dev/null
+++ b/src/arch/riscv/include/bits/reboot.h
@@ -0,0 +1,14 @@
+#ifndef _BITS_REBOOT_H
+#define _BITS_REBOOT_H
+
+/** @file
+ *
+ * RISCV-specific reboot API implementations
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/sbi_reboot.h>
+
+#endif /* _BITS_REBOOT_H */
diff --git a/src/arch/riscv/include/ipxe/sbi.h b/src/arch/riscv/include/ipxe/sbi.h
index 529f1d0c9..44685cc87 100644
--- a/src/arch/riscv/include/ipxe/sbi.h
+++ b/src/arch/riscv/include/ipxe/sbi.h
@@ -148,6 +148,16 @@ sbi_ecall_3 ( int eid, int fid, unsigned long p0, unsigned long p1,
return ret;
}
+/** Convert an SBI error code to an iPXE status code */
+#define ESBI( error ) EPLATFORM ( EINFO_EPLATFORM, error )
+
+/** System reset extension */
+#define SBI_SRST SBI_EID ( 'S', 'R', 'S', 'T' )
+#define SBI_SRST_SYSTEM_RESET 0x00 /**< Reset system */
+#define SBI_RESET_SHUTDOWN 0x00000000 /**< Shutdown */
+#define SBI_RESET_COLD 0x00000001 /**< Cold reboot */
+#define SBI_RESET_WARM 0x00000002 /**< Warm reboot */
+
/** Debug console extension */
#define SBI_DBCN SBI_EID ( 'D', 'B', 'C', 'N' )
#define SBI_DBCN_WRITE 0x00 /**< Console Write */
diff --git a/src/arch/riscv/include/ipxe/sbi_reboot.h b/src/arch/riscv/include/ipxe/sbi_reboot.h
new file mode 100644
index 000000000..e8d6e82bf
--- /dev/null
+++ b/src/arch/riscv/include/ipxe/sbi_reboot.h
@@ -0,0 +1,18 @@
+#ifndef _IPXE_BIOS_REBOOT_H
+#define _IPXE_BIOS_REBOOT_H
+
+/** @file
+ *
+ * Supervisor Binary Interface (SBI) reboot mechanism
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#ifdef REBOOT_SBI
+#define REBOOT_PREFIX_sbi
+#else
+#define REBOOT_PREFIX_sbi __sbi_
+#endif
+
+#endif /* _IPXE_BIOS_REBOOT_H */
diff --git a/src/arch/riscv/interface/sbi/sbi_reboot.c b/src/arch/riscv/interface/sbi/sbi_reboot.c
new file mode 100644
index 000000000..64365b0d3
--- /dev/null
+++ b/src/arch/riscv/interface/sbi/sbi_reboot.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+/** @file
+ *
+ * Supervisor Binary Interface (SBI) reboot mechanism
+ *
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <ipxe/sbi.h>
+#include <ipxe/reboot.h>
+
+/**
+ * Reboot system
+ *
+ * @v warm Perform a warm reboot
+ */
+static void sbi_reboot ( int warm ) {
+ struct sbi_return ret;
+ int rc;
+
+ /* Reboot system */
+ ret = sbi_ecall_2 ( SBI_SRST, SBI_SRST_SYSTEM_RESET,
+ ( warm ? SBI_RESET_WARM : SBI_RESET_COLD ), 0 );
+
+ /* Any return is an error */
+ rc = -ESBI ( ret.error );
+ DBGC ( SBI_SRST, "SBI %s reset failed: %s\n",
+ ( warm ? "warm" : "cold" ), strerror ( rc ) );
+}
+
+/**
+ * Power off system
+ *
+ * @ret rc Return status code
+ */
+static int sbi_poweroff ( void ) {
+ struct sbi_return ret;
+ int rc;
+
+ /* Shut down system */
+ ret = sbi_ecall_2 ( SBI_SRST, SBI_SRST_SYSTEM_RESET,
+ SBI_RESET_SHUTDOWN, 0 );
+
+ /* Any return is an error */
+ rc = -ESBI ( ret.error );
+ DBGC ( SBI_SRST, "SBI shutdown failed: %s\n", strerror ( rc ) );
+ return rc;
+}
+
+PROVIDE_REBOOT ( sbi, reboot, sbi_reboot );
+PROVIDE_REBOOT ( sbi, poweroff, sbi_poweroff );