srst.rs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. //! Chapter 10. System Reset Extension (EID #0x53525354 "SRST")
  2. use crate::binary::sbi_call_2;
  3. use sbi_spec::{
  4. binary::SbiRet,
  5. srst::{
  6. EID_SRST, RESET_REASON_NO_REASON, RESET_REASON_SYSTEM_FAILURE, RESET_TYPE_COLD_REBOOT,
  7. RESET_TYPE_SHUTDOWN, RESET_TYPE_WARM_REBOOT, SYSTEM_RESET,
  8. },
  9. };
  10. /// Reset the system based on provided `reset_type` and `reset_reason`.
  11. ///
  12. /// This is a synchronous call and does not return if it succeeds.
  13. ///
  14. /// # Warm reboot and cold reboot
  15. ///
  16. /// When supervisor software is running natively, the SBI implementation is machine mode firmware.
  17. /// In this case, shutdown is equivalent to physical power down of the entire system, and
  18. /// cold reboot is equivalent to a physical power cycle of the entire system.
  19. /// Further, warm reboot is equivalent to a power cycle of the main processor and parts of the system
  20. /// but not the entire system.
  21. ///
  22. /// For example, on a server class system with a BMC (board management controller),
  23. /// a warm reboot will not power cycle the BMC whereas a cold reboot will definitely power cycle the BMC.
  24. ///
  25. /// When supervisor software is running inside a virtual machine, the SBI implementation is a hypervisor.
  26. /// The shutdown, cold reboot and warm reboot will behave functionally the same as the native case but might
  27. /// not result in any physical power changes.
  28. ///
  29. /// This function is defined in RISC-V SBI Specification chapter 10.1.
  30. #[inline]
  31. pub fn system_reset<T, R>(reset_type: T, reset_reason: R) -> SbiRet
  32. where
  33. T: ResetType,
  34. R: ResetReason,
  35. {
  36. sbi_call_2(
  37. EID_SRST,
  38. SYSTEM_RESET,
  39. reset_type.raw() as _,
  40. reset_reason.raw() as _,
  41. )
  42. }
  43. /// A valid type for system reset.
  44. pub trait ResetType {
  45. /// Get a raw value to pass to SBI environment.
  46. fn raw(&self) -> u32;
  47. }
  48. #[cfg(feature = "integer-impls")]
  49. impl ResetType for u32 {
  50. #[inline]
  51. fn raw(&self) -> u32 {
  52. *self
  53. }
  54. }
  55. #[cfg(feature = "integer-impls")]
  56. impl ResetType for i32 {
  57. #[inline]
  58. fn raw(&self) -> u32 {
  59. u32::from_ne_bytes(i32::to_ne_bytes(*self))
  60. }
  61. }
  62. /// A valid reason for system reset.
  63. pub trait ResetReason {
  64. /// Get a raw value to pass to SBI environment.
  65. fn raw(&self) -> u32;
  66. }
  67. #[cfg(feature = "integer-impls")]
  68. impl ResetReason for u32 {
  69. #[inline]
  70. fn raw(&self) -> u32 {
  71. *self
  72. }
  73. }
  74. #[cfg(feature = "integer-impls")]
  75. impl ResetReason for i32 {
  76. #[inline]
  77. fn raw(&self) -> u32 {
  78. u32::from_ne_bytes(i32::to_ne_bytes(*self))
  79. }
  80. }
  81. macro_rules! define_reset_param {
  82. ($($struct:ident($value:expr): $trait:ident #[$doc:meta])*) => {
  83. $(
  84. #[derive(Clone, Copy, Debug)]
  85. #[$doc]
  86. pub struct $struct;
  87. impl $trait for $struct {
  88. #[inline]
  89. fn raw(&self) -> u32 {
  90. $value
  91. }
  92. }
  93. )*
  94. };
  95. }
  96. define_reset_param! {
  97. Shutdown(RESET_TYPE_SHUTDOWN): ResetType /// Shutdown as a reset type.
  98. ColdReboot(RESET_TYPE_COLD_REBOOT): ResetType /// Cold reboot as a reset type.
  99. WarmReboot(RESET_TYPE_WARM_REBOOT): ResetType /// Warm reboot as a reset type.
  100. NoReason(RESET_REASON_NO_REASON): ResetReason /// No reason as a reset reason.
  101. SystemFailure(RESET_REASON_SYSTEM_FAILURE): ResetReason /// System failure as a reset reason.
  102. }