forked from Mirrors/opensbi
		
	lib: sbi: Implement System Reset (SRST) SBI extension
The SBI SRST extension has been accepted and merged in the latest SBI v0.3-draft specification. (Refer, https://github.com/riscv/riscv-sbi-doc) It allows to S-mode software to request system shutdown, cold reboot, and warm reboot. This patch implements SBI SRST extension as a replacement of the legacy sbi_shutdown() call of SBI v0.1 specification. Signed-off-by: Anup Patel <anup.patel@wdc.com> Reviewed-by: Atish Patra <atish.patra@wdc.com>
This commit is contained in:
		@@ -37,6 +37,7 @@ extern struct sbi_ecall_extension ecall_rfence;
 | 
			
		||||
extern struct sbi_ecall_extension ecall_ipi;
 | 
			
		||||
extern struct sbi_ecall_extension ecall_vendor;
 | 
			
		||||
extern struct sbi_ecall_extension ecall_hsm;
 | 
			
		||||
extern struct sbi_ecall_extension ecall_srst;
 | 
			
		||||
 | 
			
		||||
u16 sbi_ecall_version_major(void);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -167,6 +167,9 @@ int sbi_ecall_init(void)
 | 
			
		||||
	if (ret)
 | 
			
		||||
		return ret;
 | 
			
		||||
	ret = sbi_ecall_register_extension(&ecall_hsm);
 | 
			
		||||
	if (ret)
 | 
			
		||||
		return ret;
 | 
			
		||||
	ret = sbi_ecall_register_extension(&ecall_srst);
 | 
			
		||||
	if (ret)
 | 
			
		||||
		return ret;
 | 
			
		||||
	ret = sbi_ecall_register_extension(&ecall_legacy);
 | 
			
		||||
 
 | 
			
		||||
@@ -14,6 +14,7 @@
 | 
			
		||||
#include <sbi/sbi_error.h>
 | 
			
		||||
#include <sbi/sbi_hart.h>
 | 
			
		||||
#include <sbi/sbi_ipi.h>
 | 
			
		||||
#include <sbi/sbi_system.h>
 | 
			
		||||
#include <sbi/sbi_timer.h>
 | 
			
		||||
#include <sbi/sbi_tlb.h>
 | 
			
		||||
 | 
			
		||||
@@ -127,3 +128,62 @@ struct sbi_ecall_extension ecall_ipi = {
 | 
			
		||||
	.extid_end = SBI_EXT_IPI,
 | 
			
		||||
	.handle = sbi_ecall_ipi_handler,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int sbi_ecall_srst_handler(unsigned long extid, unsigned long funcid,
 | 
			
		||||
				  unsigned long *args, unsigned long *out_val,
 | 
			
		||||
				  struct sbi_trap_info *out_trap)
 | 
			
		||||
{
 | 
			
		||||
	if (funcid == SBI_EXT_SRST_RESET) {
 | 
			
		||||
		if ((((u32)-1U) <= ((u64)args[0])) ||
 | 
			
		||||
		    (((u32)-1U) <= ((u64)args[1])))
 | 
			
		||||
			return SBI_EINVAL;
 | 
			
		||||
 | 
			
		||||
		switch (args[0]) {
 | 
			
		||||
		case SBI_SRST_RESET_TYPE_SHUTDOWN:
 | 
			
		||||
		case SBI_SRST_RESET_TYPE_COLD_REBOOT:
 | 
			
		||||
		case SBI_SRST_RESET_TYPE_WARM_REBOOT:
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			return SBI_ENOTSUPP;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		switch (args[1]) {
 | 
			
		||||
		case SBI_SRST_RESET_REASON_NONE:
 | 
			
		||||
		case SBI_SRST_RESET_REASON_SYSFAIL:
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			return SBI_ENOTSUPP;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (sbi_system_reset_supported(args[0], args[1]))
 | 
			
		||||
			sbi_system_reset(args[0], args[1]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return SBI_ENOTSUPP;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int sbi_ecall_srst_probe(unsigned long extid, unsigned long *out_val)
 | 
			
		||||
{
 | 
			
		||||
	u32 type, count = 0;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * At least one standard reset types should be supported by
 | 
			
		||||
	 * the platform for SBI SRST extension to be usable.
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	for (type = 0; type <= SBI_SRST_RESET_TYPE_LAST; type++) {
 | 
			
		||||
		if (sbi_system_reset_supported(type,
 | 
			
		||||
					SBI_SRST_RESET_REASON_NONE))
 | 
			
		||||
			count++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*out_val = (count) ? 1 : 0;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct sbi_ecall_extension ecall_srst = {
 | 
			
		||||
	.extid_start = SBI_EXT_SRST,
 | 
			
		||||
	.extid_end = SBI_EXT_SRST,
 | 
			
		||||
	.handle = sbi_ecall_srst_handler,
 | 
			
		||||
	.probe = sbi_ecall_srst_probe,
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user