diff --git a/Kernel/Arch/riscv64/SBI.cpp b/Kernel/Arch/riscv64/SBI.cpp index dcd6902912..d321647bf5 100644 --- a/Kernel/Arch/riscv64/SBI.cpp +++ b/Kernel/Arch/riscv64/SBI.cpp @@ -44,6 +44,22 @@ static SBIErrorOr sbi_ecall1(EID extension_id, u32 function_id, unsigned l return static_cast(a0); } +static SBIErrorOr sbi_ecall2(EID extension_id, u32 function_id, unsigned long arg0, unsigned long arg1) +{ + register unsigned long a0 asm("a0") = arg0; + register unsigned long a1 asm("a1") = arg1; + register unsigned long a6 asm("a6") = function_id; + register unsigned long a7 asm("a7") = to_underlying(extension_id); + asm volatile("ecall" + : "+r"(a0), "+r"(a1) + : "r"(a0), "r"(a1), "r"(a6), "r"(a7) + : "memory"); + if (a0 == to_underlying(SBIError::Success)) + return static_cast(a1); + + return static_cast(a0); +} + namespace Base { SBIErrorOr get_spec_version() @@ -145,6 +161,20 @@ SBIErrorOr set_timer(u64 stime_value) } +namespace SystemReset { + +SBIError system_reset(ResetType reset_type, ResetReason reset_reason) +{ + auto const res = SBI::sbi_ecall2(EID::SystemReset, to_underlying(FID::SystemReset), to_underlying(reset_type), to_underlying(reset_reason)); + + // This SBI call shold only return if it didn't succeed + VERIFY(res.is_error()); + + return res.error(); +} + +} + namespace DBCN { SBIErrorOr debug_console_write_byte(u8 byte) diff --git a/Kernel/Arch/riscv64/SBI.h b/Kernel/Arch/riscv64/SBI.h index 20fad2f3fe..98c5776fd3 100644 --- a/Kernel/Arch/riscv64/SBI.h +++ b/Kernel/Arch/riscv64/SBI.h @@ -46,6 +46,8 @@ enum class EID : i32 { Base = 0x10, // Debug Console Extension ("DBCN") DebugConsole = 0x4442434E, + // System Reset Extension ("SRST") + SystemReset = 0x53525354, // Timer Extension ("TIME") Timer = 0x54494D45, }; @@ -155,6 +157,32 @@ SBIErrorOr set_timer(u64 stime_value); } +// Chapter 10. System Reset Extension (EID #0x53525354 "SRST") +// Since SBI v0.2 +namespace SystemReset { + +enum class FID : i32 { + SystemReset = 0, +}; + +enum class ResetType : u32 { + Shutdown = 0x0, + ColdReboot = 0x1, + WarmReboot = 0x2, +}; + +enum class ResetReason : u32 { + NoReason = 0x0, + SystemFailure = 0x1, +}; + +// System reset (FID #0) +// Reset the system based on provided reset_type and reset_reason. This is a synchronous call and +// does not return if it succeeds. +SBIError system_reset(ResetType reset_type, ResetReason reset_reason); + +} + // Chapter 12. Debug Console Extension (EID #0x4442434E "DBCN") // Since SBI v2.0 namespace DBCN {