123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907 |
- use core::marker::PhantomData;
- #[derive(Clone, Copy, PartialEq, Eq)]
- #[repr(C)]
- pub struct SbiRet {
-
- pub error: usize,
-
- pub value: usize,
- }
- pub const RET_SUCCESS: usize = 0;
- pub const RET_ERR_FAILED: usize = -1isize as _;
- pub const RET_ERR_NOT_SUPPORTED: usize = -2isize as _;
- pub const RET_ERR_INVALID_PARAM: usize = -3isize as _;
- pub const RET_ERR_DENIED: usize = -4isize as _;
- pub const RET_ERR_INVALID_ADDRESS: usize = -5isize as _;
- pub const RET_ERR_ALREADY_AVAILABLE: usize = -6isize as _;
- pub const RET_ERR_ALREADY_STARTED: usize = -7isize as _;
- pub const RET_ERR_ALREADY_STOPPED: usize = -8isize as _;
- pub const RET_ERR_NO_SHMEM: usize = -9isize as _;
- impl core::fmt::Debug for SbiRet {
- fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
- match self.error {
- RET_SUCCESS => self.value.fmt(f),
- RET_ERR_FAILED => write!(f, "<SBI call failed>"),
- RET_ERR_NOT_SUPPORTED => write!(f, "<SBI feature not supported>"),
- RET_ERR_INVALID_PARAM => write!(f, "<SBI invalid parameter>"),
- RET_ERR_DENIED => write!(f, "<SBI denied>"),
- RET_ERR_INVALID_ADDRESS => write!(f, "<SBI invalid address>"),
- RET_ERR_ALREADY_AVAILABLE => write!(f, "<SBI already available>"),
- RET_ERR_ALREADY_STARTED => write!(f, "<SBI already started>"),
- RET_ERR_ALREADY_STOPPED => write!(f, "<SBI already stopped>"),
- RET_ERR_NO_SHMEM => write!(f, "<SBI shared memory not available>"),
- unknown => write!(f, "[SBI Unknown error: {unknown:#x}]"),
- }
- }
- }
- #[derive(Debug, Clone, Copy, PartialEq, Eq)]
- pub enum Error {
-
- Failed,
-
- NotSupported,
-
- InvalidParam,
-
- Denied,
-
- InvalidAddress,
-
- AlreadyAvailable,
-
- AlreadyStarted,
-
- AlreadyStopped,
-
- NoShmem,
-
- Custom(isize),
- }
- impl SbiRet {
-
- #[inline]
- pub const fn success(value: usize) -> Self {
- Self {
- error: RET_SUCCESS,
- value,
- }
- }
-
- #[inline]
- pub const fn failed() -> Self {
- Self {
- error: RET_ERR_FAILED,
- value: 0,
- }
- }
-
-
-
- #[inline]
- pub const fn not_supported() -> Self {
- Self {
- error: RET_ERR_NOT_SUPPORTED,
- value: 0,
- }
- }
-
-
-
-
- #[inline]
- pub const fn invalid_param() -> Self {
- Self {
- error: RET_ERR_INVALID_PARAM,
- value: 0,
- }
- }
-
-
-
-
-
-
- #[inline]
- pub const fn denied() -> Self {
- Self {
- error: RET_ERR_DENIED,
- value: 0,
- }
- }
-
-
-
- #[inline]
- pub const fn invalid_address() -> Self {
- Self {
- error: RET_ERR_INVALID_ADDRESS,
- value: 0,
- }
- }
-
-
- #[inline]
- pub const fn already_available() -> Self {
- Self {
- error: RET_ERR_ALREADY_AVAILABLE,
- value: 0,
- }
- }
-
-
- #[inline]
- pub const fn already_started() -> Self {
- Self {
- error: RET_ERR_ALREADY_STARTED,
- value: 0,
- }
- }
-
-
- #[inline]
- pub const fn already_stopped() -> Self {
- Self {
- error: RET_ERR_ALREADY_STOPPED,
- value: 0,
- }
- }
-
-
- #[inline]
- pub const fn no_shmem() -> Self {
- Self {
- error: RET_ERR_NO_SHMEM,
- value: 0,
- }
- }
- }
- impl SbiRet {
-
- #[inline]
- pub const fn into_result(self) -> Result<usize, Error> {
- match self.error {
- RET_SUCCESS => Ok(self.value),
- RET_ERR_FAILED => Err(Error::Failed),
- RET_ERR_NOT_SUPPORTED => Err(Error::NotSupported),
- RET_ERR_INVALID_PARAM => Err(Error::InvalidParam),
- RET_ERR_DENIED => Err(Error::Denied),
- RET_ERR_INVALID_ADDRESS => Err(Error::InvalidAddress),
- RET_ERR_ALREADY_AVAILABLE => Err(Error::AlreadyAvailable),
- RET_ERR_ALREADY_STARTED => Err(Error::AlreadyStarted),
- RET_ERR_ALREADY_STOPPED => Err(Error::AlreadyStopped),
- RET_ERR_NO_SHMEM => Err(Error::NoShmem),
- unknown => Err(Error::Custom(unknown as _)),
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #[must_use = "if you intended to assert that this is ok, consider `.unwrap()` instead"]
- #[inline]
- pub const fn is_ok(&self) -> bool {
- matches!(self.error, RET_SUCCESS)
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #[must_use = "if you intended to assert that this is err, consider `.unwrap_err()` instead"]
- #[inline]
- pub const fn is_err(&self) -> bool {
- !self.is_ok()
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #[inline]
- pub fn ok(self) -> Option<usize> {
- self.into_result().ok()
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #[inline]
- pub fn err(self) -> Option<Error> {
- self.into_result().err()
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #[inline]
- pub fn map<U, F: FnOnce(usize) -> U>(self, op: F) -> Result<U, Error> {
- self.into_result().map(op)
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #[inline]
- pub fn map_or<U, F: FnOnce(usize) -> U>(self, default: U, f: F) -> U {
- self.into_result().map_or(default, f)
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #[inline]
- pub fn map_or_else<U, D: FnOnce(Error) -> U, F: FnOnce(usize) -> U>(
- self,
- default: D,
- f: F,
- ) -> U {
- self.into_result().map_or_else(default, f)
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #[inline]
- pub fn map_err<F, O: FnOnce(Error) -> F>(self, op: O) -> Result<usize, F> {
- self.into_result().map_err(op)
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #[inline]
- pub fn expect(self, msg: &str) -> usize {
- self.into_result().expect(msg)
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #[inline]
- pub fn unwrap(self) -> usize {
- self.into_result().unwrap()
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #[inline]
- pub fn expect_err(self, msg: &str) -> Error {
- self.into_result().expect_err(msg)
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #[inline]
- pub fn unwrap_err(self) -> Error {
- self.into_result().unwrap_err()
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #[inline]
- pub fn and(self, res: Result<usize, Error>) -> Result<usize, Error> {
- self.into_result().and(res)
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #[inline]
- pub fn and_then<U, F: FnOnce(usize) -> Result<U, Error>>(self, op: F) -> Result<U, Error> {
- self.into_result().and_then(op)
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #[inline]
- pub fn or<F>(self, res: Result<usize, F>) -> Result<usize, F> {
- self.into_result().or(res)
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #[inline]
- pub fn or_else<F, O: FnOnce(Error) -> Result<usize, F>>(self, op: O) -> Result<usize, F> {
- self.into_result().or_else(op)
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #[inline]
- pub fn unwrap_or(self, default: usize) -> usize {
- self.into_result().unwrap_or(default)
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
- #[inline]
- pub fn unwrap_or_else<F: FnOnce(Error) -> usize>(self, op: F) -> usize {
- self.into_result().unwrap_or_else(op)
- }
- }
- #[derive(Debug, Copy, Clone)]
- pub struct HartMask {
- inner: BitVector,
- }
- impl HartMask {
-
- #[inline]
- pub const fn from_mask_base(hart_mask: usize, hart_mask_base: usize) -> HartMask {
- HartMask {
- inner: BitVector {
- hart_mask,
- hart_mask_base,
- },
- }
- }
-
- #[inline]
- pub const fn into_inner(self) -> (usize, usize) {
- (self.inner.hart_mask, self.inner.hart_mask_base)
- }
-
- #[inline]
- pub const fn has_bit(&self, hart_id: usize) -> bool {
- let BitVector {
- hart_mask,
- hart_mask_base,
- } = self.inner;
- if hart_mask_base == usize::MAX {
-
-
- return true;
- }
- let Some(idx) = hart_id.checked_sub(hart_mask_base) else {
-
- return false;
- };
- if idx >= usize::BITS as usize {
-
- return false;
- }
- hart_mask & (1 << idx) != 0
- }
- }
- #[derive(Debug, Copy, Clone)]
- struct BitVector {
- hart_mask: usize,
- hart_mask_base: usize,
- }
- #[derive(Clone, Copy)]
- pub struct Physical<P> {
- num_bytes: usize,
- phys_addr_lo: usize,
- phys_addr_hi: usize,
- _marker: PhantomData<P>,
- }
- impl<P> Physical<P> {
-
- #[inline]
- pub const fn new(num_bytes: usize, phys_addr_lo: usize, phys_addr_hi: usize) -> Self {
- Self {
- num_bytes,
- phys_addr_lo,
- phys_addr_hi,
- _marker: core::marker::PhantomData,
- }
- }
-
- #[inline]
- pub const fn num_bytes(&self) -> usize {
- self.num_bytes
- }
-
- #[inline]
- pub const fn phys_addr_lo(&self) -> usize {
- self.phys_addr_lo
- }
-
- #[inline]
- pub const fn phys_addr_hi(&self) -> usize {
- self.phys_addr_hi
- }
- }
- pub struct SharedPtr<T> {
- phys_addr_lo: usize,
- phys_addr_hi: usize,
- _marker: PhantomData<*mut T>,
- }
- impl<T> SharedPtr<T> {
-
- #[inline]
- pub const fn new(phys_addr_lo: usize, phys_addr_hi: usize) -> Self {
- Self {
- phys_addr_lo,
- phys_addr_hi,
- _marker: PhantomData,
- }
- }
-
- #[inline]
- pub const fn phys_addr_lo(self) -> usize {
- self.phys_addr_lo
- }
-
- #[inline]
- pub const fn phys_addr_hi(self) -> usize {
- self.phys_addr_hi
- }
- }
- impl<T> Clone for SharedPtr<T> {
- #[inline(always)]
- fn clone(&self) -> Self {
- *self
- }
- }
- impl<T> Copy for SharedPtr<T> {}
- #[cfg(test)]
- mod tests {
- use super::HartMask;
- #[test]
- fn rustsbi_hart_mask() {
- let mask = HartMask::from_mask_base(0b1, 400);
- assert!(!mask.has_bit(0));
- assert!(mask.has_bit(400));
- assert!(!mask.has_bit(401));
- let mask = HartMask::from_mask_base(0b110, 500);
- assert!(!mask.has_bit(0));
- assert!(!mask.has_bit(500));
- assert!(mask.has_bit(501));
- assert!(mask.has_bit(502));
- assert!(!mask.has_bit(500 + (usize::BITS as usize)));
- let max_bit = 1 << (usize::BITS - 1);
- let mask = HartMask::from_mask_base(max_bit, 600);
- assert!(mask.has_bit(600 + (usize::BITS as usize) - 1));
- assert!(!mask.has_bit(600 + (usize::BITS as usize)));
- let mask = HartMask::from_mask_base(0b11, usize::MAX - 1);
- assert!(!mask.has_bit(usize::MAX - 2));
- assert!(mask.has_bit(usize::MAX - 1));
- assert!(mask.has_bit(usize::MAX));
- assert!(!mask.has_bit(0));
-
-
- let mask = HartMask::from_mask_base(0, usize::MAX);
- for i in 0..5 {
- assert!(mask.has_bit(i));
- }
- assert!(mask.has_bit(usize::MAX));
- }
- }
|