riscv: add SBI system reset extension

The System Reset extension provides functions to shutdown or reboot the
system via SBI firmware. This newly defined extension supersedes the
functionality of the legacy shutdown extension.

Update the SBI code to use the new System Reset extension when
available, and fall back to the legacy one.

Reviewed By:	kp, jhb
MFC after:	3 days
Differential Revision:	https://reviews.freebsd.org/D28226
This commit is contained in:
Danjel Qyteza 2021-01-27 12:28:48 -04:00 committed by Mitchell Horne
parent a6405133b7
commit 9bae4ce661
3 changed files with 39 additions and 11 deletions

View File

@ -99,6 +99,15 @@
#define SBI_HSM_STATUS_START_PENDING 2
#define SBI_HSM_STATUS_STOP_PENDING 3
/* System Reset (SRST) Extension */
#define SBI_EXT_ID_SRST 0x53525354
#define SBI_SRST_SYSTEM_RESET 0
#define SBI_SRST_TYPE_SHUTDOWN 0
#define SBI_SRST_TYPE_COLD_REBOOT 1
#define SBI_SRST_TYPE_WARM_REBOOT 2
#define SBI_SRST_REASON_NONE 0
#define SBI_SRST_REASON_SYSTEM_FAILURE 1
/* Legacy Extensions */
#define SBI_SET_TIMER 0
#define SBI_CONSOLE_PUTCHAR 1
@ -199,6 +208,18 @@ void sbi_hsm_hart_stop(void);
*/
int sbi_hsm_hart_status(u_long hart);
/* System Reset extension functions. */
/*
* Reset the system based on the following 'type' and 'reason' chosen from:
* - SBI_SRST_TYPE_SHUTDOWN
* - SBI_SRST_TYPE_COLD_REBOOT
* - SBI_SRST_TYPE_WARM_REBOOT
* - SBI_SRST_REASON_NONE
* - SBI_SRST_REASON_SYSTEM_FAILURE
*/
void sbi_system_reset(u_long reset_type, u_long reset_reason);
/* Legacy extension functions. */
static __inline void
sbi_console_putchar(int ch)
@ -218,13 +239,6 @@ sbi_console_getchar(void)
return (SBI_CALL0(SBI_CONSOLE_GETCHAR, 0).error);
}
static __inline void
sbi_shutdown(void)
{
(void)SBI_CALL0(SBI_SHUTDOWN, 0);
}
void sbi_print_version(void);
void sbi_init(void);

View File

@ -49,6 +49,7 @@ u_long sbi_impl_version;
static bool has_time_extension = false;
static bool has_ipi_extension = false;
static bool has_rfnc_extension = false;
static bool has_srst_extension = false;
static struct sbi_ret
sbi_get_spec_version(void)
@ -90,7 +91,18 @@ static void
sbi_shutdown_final(void *dummy __unused, int howto)
{
if ((howto & RB_POWEROFF) != 0)
sbi_shutdown();
sbi_system_reset(SBI_SRST_TYPE_SHUTDOWN, SBI_SRST_REASON_NONE);
}
void
sbi_system_reset(u_long reset_type, u_long reset_reason)
{
/* Use the SRST extension, if available. */
if (has_srst_extension) {
(void)SBI_CALL2(SBI_EXT_ID_SRST, SBI_SRST_SYSTEM_RESET,
reset_type, reset_reason);
}
(void)SBI_CALL0(SBI_SHUTDOWN, 0);
}
void
@ -277,6 +289,8 @@ sbi_init(void)
has_ipi_extension = true;
if (sbi_probe_extension(SBI_EXT_ID_RFNC) != 0)
has_rfnc_extension = true;
if (sbi_probe_extension(SBI_EXT_ID_SRST) != 0)
has_srst_extension = true;
/*
* Probe for legacy extensions. We still rely on many of them to be
@ -299,8 +313,8 @@ sbi_init(void)
KASSERT(has_rfnc_extension ||
sbi_probe_extension(SBI_REMOTE_SFENCE_VMA_ASID) != 0,
("SBI doesn't implement sbi_remote_sfence_vma_asid()"));
KASSERT(sbi_probe_extension(SBI_SHUTDOWN) != 0,
("SBI doesn't implement sbi_shutdown()"));
KASSERT(has_srst_extension || sbi_probe_extension(SBI_SHUTDOWN) != 0,
("SBI doesn't implement a shutdown or reset extension"));
}
static void

View File

@ -110,7 +110,7 @@ void
cpu_reset(void)
{
sbi_shutdown();
sbi_system_reset(SBI_SRST_TYPE_COLD_REBOOT, SBI_SRST_REASON_NONE);
while(1);
}