|
@@ -1,6 +1,6 @@
|
|
|
use crate::{
|
|
|
- spec::binary::SbiRet, Console, Fence, HartMask, Hsm, Ipi, Pmu, Reset, Timer, IMPL_ID_RUSTSBI,
|
|
|
- RUSTSBI_VERSION, SBI_SPEC_MAJOR, SBI_SPEC_MINOR,
|
|
|
+ spec::binary::SbiRet, Console, Fence, HartMask, Hsm, Ipi, Pmu, Reset, Susp, Timer,
|
|
|
+ IMPL_ID_RUSTSBI, RUSTSBI_VERSION, SBI_SPEC_MAJOR, SBI_SPEC_MINOR,
|
|
|
};
|
|
|
use core::convert::Infallible;
|
|
|
#[cfg(feature = "machine")]
|
|
@@ -12,7 +12,7 @@ use spec::binary::Physical;
|
|
|
/// By now RustSBI supports to run instance based interface on systems has environment pointer width
|
|
|
/// that is the same as supervisor pointer width.
|
|
|
#[derive(Clone, Debug)]
|
|
|
-pub struct RustSBI<T, I, R, H, S, P, C> {
|
|
|
+pub struct RustSBI<T, I, R, H, S, P, C, SU> {
|
|
|
timer: Option<T>,
|
|
|
ipi: Option<I>,
|
|
|
rfnc: Option<R>,
|
|
@@ -20,6 +20,7 @@ pub struct RustSBI<T, I, R, H, S, P, C> {
|
|
|
srst: Option<S>,
|
|
|
pmu: Option<P>,
|
|
|
dbcn: Option<C>,
|
|
|
+ susp: Option<SU>,
|
|
|
#[cfg(not(feature = "machine"))]
|
|
|
info: MachineInfo,
|
|
|
}
|
|
@@ -38,13 +39,22 @@ pub struct MachineInfo {
|
|
|
pub mimpid: usize,
|
|
|
}
|
|
|
|
|
|
-impl<T: Timer, I: Ipi, R: Fence, H: Hsm, S: Reset, P: Pmu, C: Console>
|
|
|
- RustSBI<T, I, R, H, S, P, C>
|
|
|
+impl<T: Timer, I: Ipi, R: Fence, H: Hsm, S: Reset, P: Pmu, C: Console, SU: Susp>
|
|
|
+ RustSBI<T, I, R, H, S, P, C, SU>
|
|
|
{
|
|
|
/// Create RustSBI instance on current machine environment for all the SBI extensions
|
|
|
#[cfg(feature = "machine")]
|
|
|
#[inline]
|
|
|
- pub const fn new_machine(timer: T, ipi: I, rfnc: R, hsm: H, srst: S, pmu: P, dbcn: C) -> Self {
|
|
|
+ pub const fn new_machine(
|
|
|
+ timer: T,
|
|
|
+ ipi: I,
|
|
|
+ rfnc: R,
|
|
|
+ hsm: H,
|
|
|
+ srst: S,
|
|
|
+ pmu: P,
|
|
|
+ dbcn: C,
|
|
|
+ susp: SU,
|
|
|
+ ) -> Self {
|
|
|
Self {
|
|
|
timer: Some(timer),
|
|
|
ipi: Some(ipi),
|
|
@@ -53,6 +63,7 @@ impl<T: Timer, I: Ipi, R: Fence, H: Hsm, S: Reset, P: Pmu, C: Console>
|
|
|
srst: Some(srst),
|
|
|
pmu: Some(pmu),
|
|
|
dbcn: Some(dbcn),
|
|
|
+ susp: Some(susp),
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -68,6 +79,7 @@ impl<T: Timer, I: Ipi, R: Fence, H: Hsm, S: Reset, P: Pmu, C: Console>
|
|
|
srst: S,
|
|
|
pmu: P,
|
|
|
dbcn: C,
|
|
|
+ susp: SU,
|
|
|
info: MachineInfo,
|
|
|
) -> Self {
|
|
|
Self {
|
|
@@ -78,6 +90,7 @@ impl<T: Timer, I: Ipi, R: Fence, H: Hsm, S: Reset, P: Pmu, C: Console>
|
|
|
srst: Some(srst),
|
|
|
pmu: Some(pmu),
|
|
|
dbcn: Some(dbcn),
|
|
|
+ susp: Some(susp),
|
|
|
info,
|
|
|
}
|
|
|
}
|
|
@@ -292,6 +305,19 @@ impl<T: Timer, I: Ipi, R: Fence, H: Hsm, S: Reset, P: Pmu, C: Console>
|
|
|
_ => SbiRet::not_supported(),
|
|
|
}
|
|
|
}
|
|
|
+ spec::susp::EID_SUSP => {
|
|
|
+ let Some(susp) = &mut self.susp else {
|
|
|
+ return SbiRet::not_supported();
|
|
|
+ };
|
|
|
+ let [param0, param1, param2] = [param[0], param[1], param[2]];
|
|
|
+ match function {
|
|
|
+ spec::susp::SUSPEND => match u32::try_from(param0) {
|
|
|
+ Ok(sleep_type) => susp.system_suspend(sleep_type, param1, param2),
|
|
|
+ _ => SbiRet::invalid_param(),
|
|
|
+ },
|
|
|
+ _ => SbiRet::not_supported(),
|
|
|
+ }
|
|
|
+ }
|
|
|
_ => SbiRet::not_supported(),
|
|
|
}
|
|
|
}
|
|
@@ -324,17 +350,35 @@ const fn concat_u32(h: usize, l: usize) -> u64 {
|
|
|
}
|
|
|
|
|
|
/// Structure to build a RustSBI instance
|
|
|
-pub struct Builder<T, I, R, H, S, P, C> {
|
|
|
- inner: RustSBI<T, I, R, H, S, P, C>,
|
|
|
+pub struct Builder<T, I, R, H, S, P, C, SU> {
|
|
|
+ inner: RustSBI<T, I, R, H, S, P, C, SU>,
|
|
|
}
|
|
|
|
|
|
-impl Builder<Infallible, Infallible, Infallible, Infallible, Infallible, Infallible, Infallible> {
|
|
|
+impl
|
|
|
+ Builder<
|
|
|
+ Infallible,
|
|
|
+ Infallible,
|
|
|
+ Infallible,
|
|
|
+ Infallible,
|
|
|
+ Infallible,
|
|
|
+ Infallible,
|
|
|
+ Infallible,
|
|
|
+ Infallible,
|
|
|
+ >
|
|
|
+{
|
|
|
/// Create a new `Builder` from current machine environment
|
|
|
#[inline]
|
|
|
#[cfg(feature = "machine")]
|
|
|
- pub const fn new_machine(
|
|
|
- ) -> Builder<Infallible, Infallible, Infallible, Infallible, Infallible, Infallible, Infallible>
|
|
|
- {
|
|
|
+ pub const fn new_machine() -> Builder<
|
|
|
+ Infallible,
|
|
|
+ Infallible,
|
|
|
+ Infallible,
|
|
|
+ Infallible,
|
|
|
+ Infallible,
|
|
|
+ Infallible,
|
|
|
+ Infallible,
|
|
|
+ Infallible,
|
|
|
+ > {
|
|
|
Builder {
|
|
|
inner: RustSBI {
|
|
|
timer: None,
|
|
@@ -344,6 +388,7 @@ impl Builder<Infallible, Infallible, Infallible, Infallible, Infallible, Infalli
|
|
|
srst: None,
|
|
|
pmu: None,
|
|
|
dbcn: None,
|
|
|
+ susp: None,
|
|
|
},
|
|
|
}
|
|
|
}
|
|
@@ -353,8 +398,16 @@ impl Builder<Infallible, Infallible, Infallible, Infallible, Infallible, Infalli
|
|
|
#[cfg(not(feature = "machine"))]
|
|
|
pub const fn with_machine_info(
|
|
|
info: MachineInfo,
|
|
|
- ) -> Builder<Infallible, Infallible, Infallible, Infallible, Infallible, Infallible, Infallible>
|
|
|
- {
|
|
|
+ ) -> Builder<
|
|
|
+ Infallible,
|
|
|
+ Infallible,
|
|
|
+ Infallible,
|
|
|
+ Infallible,
|
|
|
+ Infallible,
|
|
|
+ Infallible,
|
|
|
+ Infallible,
|
|
|
+ Infallible,
|
|
|
+ > {
|
|
|
Builder {
|
|
|
inner: RustSBI {
|
|
|
timer: None,
|
|
@@ -364,6 +417,7 @@ impl Builder<Infallible, Infallible, Infallible, Infallible, Infallible, Infalli
|
|
|
srst: None,
|
|
|
pmu: None,
|
|
|
dbcn: None,
|
|
|
+ susp: None,
|
|
|
info,
|
|
|
},
|
|
|
}
|
|
@@ -376,10 +430,10 @@ impl Builder<Infallible, Infallible, Infallible, Infallible, Infallible, Infalli
|
|
|
|
|
|
// fixme: struct `Infallible` should be replaced to never type once it's stablized
|
|
|
|
|
|
-impl<T, I, R, H, S, P, C> Builder<T, I, R, H, S, P, C> {
|
|
|
+impl<T, I, R, H, S, P, C, SU> Builder<T, I, R, H, S, P, C, SU> {
|
|
|
/// Add Timer programmer extension to RustSBI
|
|
|
#[inline]
|
|
|
- pub fn with_timer<T2: Timer>(self, timer: T2) -> Builder<T2, I, R, H, S, P, C> {
|
|
|
+ pub fn with_timer<T2: Timer>(self, timer: T2) -> Builder<T2, I, R, H, S, P, C, SU> {
|
|
|
Builder {
|
|
|
inner: RustSBI {
|
|
|
timer: Some(timer),
|
|
@@ -389,6 +443,7 @@ impl<T, I, R, H, S, P, C> Builder<T, I, R, H, S, P, C> {
|
|
|
srst: self.inner.srst,
|
|
|
pmu: self.inner.pmu,
|
|
|
dbcn: self.inner.dbcn,
|
|
|
+ susp: self.inner.susp,
|
|
|
#[cfg(not(feature = "machine"))]
|
|
|
info: self.inner.info,
|
|
|
},
|
|
@@ -397,7 +452,7 @@ impl<T, I, R, H, S, P, C> Builder<T, I, R, H, S, P, C> {
|
|
|
|
|
|
/// Add Inter-processor Interrupt extension to RustSBI
|
|
|
#[inline]
|
|
|
- pub fn with_ipi<I2: Ipi>(self, ipi: I2) -> Builder<T, I2, R, H, S, P, C> {
|
|
|
+ pub fn with_ipi<I2: Ipi>(self, ipi: I2) -> Builder<T, I2, R, H, S, P, C, SU> {
|
|
|
Builder {
|
|
|
inner: RustSBI {
|
|
|
timer: self.inner.timer,
|
|
@@ -407,6 +462,7 @@ impl<T, I, R, H, S, P, C> Builder<T, I, R, H, S, P, C> {
|
|
|
srst: self.inner.srst,
|
|
|
pmu: self.inner.pmu,
|
|
|
dbcn: self.inner.dbcn,
|
|
|
+ susp: self.inner.susp,
|
|
|
#[cfg(not(feature = "machine"))]
|
|
|
info: self.inner.info,
|
|
|
},
|
|
@@ -415,7 +471,7 @@ impl<T, I, R, H, S, P, C> Builder<T, I, R, H, S, P, C> {
|
|
|
|
|
|
/// Add Remote Fence extension to RustSBI
|
|
|
#[inline]
|
|
|
- pub fn with_fence<R2: Fence>(self, fence: R2) -> Builder<T, I, R2, H, S, P, C> {
|
|
|
+ pub fn with_fence<R2: Fence>(self, fence: R2) -> Builder<T, I, R2, H, S, P, C, SU> {
|
|
|
Builder {
|
|
|
inner: RustSBI {
|
|
|
timer: self.inner.timer,
|
|
@@ -425,6 +481,7 @@ impl<T, I, R, H, S, P, C> Builder<T, I, R, H, S, P, C> {
|
|
|
srst: self.inner.srst,
|
|
|
pmu: self.inner.pmu,
|
|
|
dbcn: self.inner.dbcn,
|
|
|
+ susp: self.inner.susp,
|
|
|
#[cfg(not(feature = "machine"))]
|
|
|
info: self.inner.info,
|
|
|
},
|
|
@@ -433,7 +490,7 @@ impl<T, I, R, H, S, P, C> Builder<T, I, R, H, S, P, C> {
|
|
|
|
|
|
/// Add Hart State Monitor extension to RustSBI
|
|
|
#[inline]
|
|
|
- pub fn with_hsm<H2: Hsm>(self, hsm: H2) -> Builder<T, I, R, H2, S, P, C> {
|
|
|
+ pub fn with_hsm<H2: Hsm>(self, hsm: H2) -> Builder<T, I, R, H2, S, P, C, SU> {
|
|
|
Builder {
|
|
|
inner: RustSBI {
|
|
|
timer: self.inner.timer,
|
|
@@ -443,6 +500,7 @@ impl<T, I, R, H, S, P, C> Builder<T, I, R, H, S, P, C> {
|
|
|
srst: self.inner.srst,
|
|
|
pmu: self.inner.pmu,
|
|
|
dbcn: self.inner.dbcn,
|
|
|
+ susp: self.inner.susp,
|
|
|
#[cfg(not(feature = "machine"))]
|
|
|
info: self.inner.info,
|
|
|
},
|
|
@@ -451,7 +509,7 @@ impl<T, I, R, H, S, P, C> Builder<T, I, R, H, S, P, C> {
|
|
|
|
|
|
/// Add System Reset extension to RustSBI
|
|
|
#[inline]
|
|
|
- pub fn with_reset<S2: Reset>(self, reset: S2) -> Builder<T, I, R, H, S2, P, C> {
|
|
|
+ pub fn with_reset<S2: Reset>(self, reset: S2) -> Builder<T, I, R, H, S2, P, C, SU> {
|
|
|
Builder {
|
|
|
inner: RustSBI {
|
|
|
timer: self.inner.timer,
|
|
@@ -461,6 +519,7 @@ impl<T, I, R, H, S, P, C> Builder<T, I, R, H, S, P, C> {
|
|
|
srst: Some(reset),
|
|
|
pmu: self.inner.pmu,
|
|
|
dbcn: self.inner.dbcn,
|
|
|
+ susp: self.inner.susp,
|
|
|
#[cfg(not(feature = "machine"))]
|
|
|
info: self.inner.info,
|
|
|
},
|
|
@@ -469,7 +528,7 @@ impl<T, I, R, H, S, P, C> Builder<T, I, R, H, S, P, C> {
|
|
|
|
|
|
/// Add Performance Monitor Unit extension to RustSBI
|
|
|
#[inline]
|
|
|
- pub fn with_pmu<P2: Pmu>(self, pmu: P2) -> Builder<T, I, R, H, S, P2, C> {
|
|
|
+ pub fn with_pmu<P2: Pmu>(self, pmu: P2) -> Builder<T, I, R, H, S, P2, C, SU> {
|
|
|
Builder {
|
|
|
inner: RustSBI {
|
|
|
timer: self.inner.timer,
|
|
@@ -479,6 +538,7 @@ impl<T, I, R, H, S, P, C> Builder<T, I, R, H, S, P, C> {
|
|
|
srst: self.inner.srst,
|
|
|
pmu: Some(pmu),
|
|
|
dbcn: self.inner.dbcn,
|
|
|
+ susp: self.inner.susp,
|
|
|
#[cfg(not(feature = "machine"))]
|
|
|
info: self.inner.info,
|
|
|
},
|
|
@@ -486,7 +546,7 @@ impl<T, I, R, H, S, P, C> Builder<T, I, R, H, S, P, C> {
|
|
|
}
|
|
|
/// Add Debug Console extension to RustSBI
|
|
|
#[inline]
|
|
|
- pub fn with_console<C2: Console>(self, console: C2) -> Builder<T, I, R, H, S, P, C2> {
|
|
|
+ pub fn with_console<C2: Console>(self, console: C2) -> Builder<T, I, R, H, S, P, C2, SU> {
|
|
|
Builder {
|
|
|
inner: RustSBI {
|
|
|
timer: self.inner.timer,
|
|
@@ -496,6 +556,25 @@ impl<T, I, R, H, S, P, C> Builder<T, I, R, H, S, P, C> {
|
|
|
srst: self.inner.srst,
|
|
|
pmu: self.inner.pmu,
|
|
|
dbcn: Some(console),
|
|
|
+ susp: self.inner.susp,
|
|
|
+ #[cfg(not(feature = "machine"))]
|
|
|
+ info: self.inner.info,
|
|
|
+ },
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /// Add System Suspend extension to RustSBI
|
|
|
+ #[inline]
|
|
|
+ pub fn with_susp<SU2: Susp>(self, susp: SU2) -> Builder<T, I, R, H, S, P, C, SU2> {
|
|
|
+ Builder {
|
|
|
+ inner: RustSBI {
|
|
|
+ timer: self.inner.timer,
|
|
|
+ ipi: self.inner.ipi,
|
|
|
+ rfnc: self.inner.rfnc,
|
|
|
+ hsm: self.inner.hsm,
|
|
|
+ srst: self.inner.srst,
|
|
|
+ pmu: self.inner.pmu,
|
|
|
+ dbcn: self.inner.dbcn,
|
|
|
+ susp: Some(susp),
|
|
|
#[cfg(not(feature = "machine"))]
|
|
|
info: self.inner.info,
|
|
|
},
|
|
@@ -504,7 +583,7 @@ impl<T, I, R, H, S, P, C> Builder<T, I, R, H, S, P, C> {
|
|
|
|
|
|
/// Build the target RustSBI instance
|
|
|
#[inline]
|
|
|
- pub fn build(self) -> RustSBI<T, I, R, H, S, P, C> {
|
|
|
+ pub fn build(self) -> RustSBI<T, I, R, H, S, P, C, SU> {
|
|
|
self.inner
|
|
|
}
|
|
|
}
|
|
@@ -625,3 +704,9 @@ impl Console for Infallible {
|
|
|
unreachable!()
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+impl Susp for Infallible {
|
|
|
+ fn system_suspend(&self, _: u32, _: usize, _: usize) -> SbiRet {
|
|
|
+ unreachable!()
|
|
|
+ }
|
|
|
+}
|