#[repr(C)]pub struct SbiRet {
pub error: usize,
pub value: usize,
}
Expand description
SBI functions return type.
SBI functions must return a pair of values in a0 and a1, with a0 returning an error code. This is analogous to returning the C structure
SbiRet
.
Note: if this structure is used in function return on conventional
Rust code, it would not require pinning memory representation as
extern C. The repr(C)
is set in case that some users want to use
this structure in FFI code.
Fields§
§error: usize
Error number.
value: usize
Result value.
Implementations§
source§impl SbiRet
impl SbiRet
sourcepub const fn not_supported() -> SbiRet
pub const fn not_supported() -> SbiRet
SBI call failed due to not supported by target ISA, operation type not supported, or target operation type not implemented on purpose.
sourcepub const fn invalid_param() -> SbiRet
pub const fn invalid_param() -> SbiRet
SBI call failed due to invalid hart mask parameter, invalid target hart id, invalid operation type, or invalid resource index.
sourcepub const fn denied() -> SbiRet
pub const fn denied() -> SbiRet
SBI call denied.
As the time this document was written, there is currently no function in SBI standard that returns this error. However, custom extensions or future standard functions may return this error if appropriate.
sourcepub const fn invalid_address() -> SbiRet
pub const fn invalid_address() -> SbiRet
SBI call failed for invalid mask start address, not a valid physical address parameter, or the target address is prohibited by PMP to run in supervisor mode.
sourcepub const fn already_available() -> SbiRet
pub const fn already_available() -> SbiRet
SBI call failed for the target resource is already available, e.g., the target hart is already started when caller still requests it to start.
sourcepub const fn already_started() -> SbiRet
pub const fn already_started() -> SbiRet
SBI call failed for the target resource is already started, e.g., target performance counter is started.
sourcepub const fn already_stopped() -> SbiRet
pub const fn already_stopped() -> SbiRet
SBI call failed for the target resource is already stopped, e.g., target performance counter is stopped.
source§impl SbiRet
impl SbiRet
sourcepub const fn into_result(self) -> Result<usize, Error>
pub const fn into_result(self) -> Result<usize, Error>
Converts to a Result
of value and error.
sourcepub const fn is_ok(&self) -> bool
pub const fn is_ok(&self) -> bool
Returns true
if current SBI return succeeded.
§Examples
Basic usage:
let x = SbiRet::success(0);
assert_eq!(x.is_ok(), true);
let x = SbiRet::failed();
assert_eq!(x.is_ok(), false);
sourcepub const fn is_err(&self) -> bool
pub const fn is_err(&self) -> bool
Returns true
if current SBI return is an error.
§Examples
Basic usage:
let x = SbiRet::success(0);
assert_eq!(x.is_err(), false);
let x = SbiRet::not_supported();
assert_eq!(x.is_err(), true);
sourcepub fn ok(self) -> Option<usize>
pub fn ok(self) -> Option<usize>
Converts from SbiRet
to Option<usize>
.
Converts self
into an Option<usize>
, consuming self
,
and discarding the error, if any.
§Examples
Basic usage:
let x = SbiRet::success(2);
assert_eq!(x.ok(), Some(2));
let x = SbiRet::invalid_param();
assert_eq!(x.ok(), None);
sourcepub fn err(self) -> Option<Error>
pub fn err(self) -> Option<Error>
Converts from SbiRet
to Option<Error>
.
Converts self
into an Option<Error>
, consuming self
,
and discarding the success value, if any.
§Examples
Basic usage:
let x = SbiRet::success(2);
assert_eq!(x.err(), None);
let x = SbiRet::denied();
assert_eq!(x.err(), Some(Error::Denied));
sourcepub fn map<U, F>(self, op: F) -> Result<U, Error>
pub fn map<U, F>(self, op: F) -> Result<U, Error>
Maps a SbiRet
to Result<U, Error>
by applying a function to a
contained success value, leaving an error value untouched.
This function can be used to compose the results of two functions.
§Examples
Gets detail of a PMU counter and judge if it is a firmware counter.
// We assume that counter index 42 is a firmware counter.
let counter_idx = 42;
// Masks PMU counter type by setting highest bit in `usize`.
const TYPE_MASK: usize = 1 << (size_of::<usize>() - 1);
// Highest bit of returned `counter_info` represents whether it's
// a firmware counter or a hardware counter.
let is_firmware_counter = sbi_rt::pmu_counter_get_info(counter_idx)
.map(|counter_info| counter_info & TYPE_MASK != 0);
// If that bit is set, it is a firmware counter.
assert_eq!(is_firmware_counter, Ok(true));
sourcepub fn map_or<U, F>(self, default: U, f: F) -> U
pub fn map_or<U, F>(self, default: U, f: F) -> U
Returns the provided default (if error), or applies a function to the contained value (if success).
Arguments passed to map_or
are eagerly evaluated;
if you are passing the result of a function call,
it is recommended to use map_or_else
,
which is lazily evaluated.
§Examples
let x = SbiRet::success(3);
assert_eq!(x.map_or(42, |v| v & 0b1), 1);
let x = SbiRet::invalid_address();
assert_eq!(x.map_or(42, |v| v & 0b1), 42);
sourcepub fn map_or_else<U, D, F>(self, default: D, f: F) -> U
pub fn map_or_else<U, D, F>(self, default: D, f: F) -> U
Maps a SbiRet
to usize
value by applying fallback function default
to
a contained error, or function f
to a contained success value.
This function can be used to unpack a successful result while handling an error.
§Examples
Basic usage:
let k = 21;
let x = SbiRet::success(3);
assert_eq!(x.map_or_else(|e| k * 2, |v| v & 0b1), 1);
let x = SbiRet::already_available();
assert_eq!(x.map_or_else(|e| k * 2, |v| v & 0b1), 42);
sourcepub fn map_err<F, O>(self, op: O) -> Result<usize, F>
pub fn map_err<F, O>(self, op: O) -> Result<usize, F>
Maps a SbiRet
to Result<T, F>
by applying a function to a
contained error as Error
struct, leaving success value untouched.
This function can be used to pass through a successful result while handling an error.
§Examples
Basic usage:
fn stringify(x: Error) -> String {
if x == Error::AlreadyStarted {
"error: already started!".to_string()
} else {
"error: other error!".to_string()
}
}
let x = SbiRet::success(2);
assert_eq!(x.map_err(stringify), Ok(2));
let x = SbiRet::already_started();
assert_eq!(x.map_err(stringify), Err("error: already started!".to_string()));
sourcepub fn expect(self, msg: &str) -> usize
pub fn expect(self, msg: &str) -> usize
Returns the contained success value, consuming the self
value.
§Panics
Panics if self is an SBI error with a panic message including the passed message, and the content of the SBI state.
§Examples
Basic usage:
let x = SbiRet::already_stopped();
x.expect("Testing expect"); // panics with `Testing expect`
sourcepub fn unwrap(self) -> usize
pub fn unwrap(self) -> usize
Returns the contained success value, consuming the self
value.
§Panics
Panics if self is an SBI error, with a panic message provided by the
SBI error converted into Error
struct.
§Examples
Basic usage:
let x = SbiRet::success(2);
assert_eq!(x.unwrap(), 2);
let x = SbiRet::failed();
x.unwrap(); // panics
sourcepub fn expect_err(self, msg: &str) -> Error
pub fn expect_err(self, msg: &str) -> Error
Returns the contained error as Error
struct, consuming the self
value.
§Panics
Panics if the self is SBI success value, with a panic message including the passed message, and the content of the success value.
§Examples
Basic usage:
let x = SbiRet::success(10);
x.expect_err("Testing expect_err"); // panics with `Testing expect_err`
sourcepub fn unwrap_err(self) -> Error
pub fn unwrap_err(self) -> Error
Returns the contained error as Error
struct, consuming the self
value.
§Panics
Panics if the self is SBI success value, with a custom panic message provided by the success value.
§Examples
let x = SbiRet::success(2);
x.unwrap_err(); // panics with `2`
let x = SbiRet::not_supported();
assert_eq!(x.unwrap_err(), Error::NotSupported);
sourcepub fn and(self, res: Result<usize, Error>) -> Result<usize, Error>
pub fn and(self, res: Result<usize, Error>) -> Result<usize, Error>
Returns res
if self is success value, otherwise otherwise returns the contained error
of self
as Error
struct.
Arguments passed to and
are eagerly evaluated; if you are passing the
result of a function call, it is recommended to use and_then
, which is
lazily evaluated.
§Examples
Basic usage:
let x = SbiRet::success(2);
let y = SbiRet::invalid_param().into_result();
assert_eq!(x.and(y), Err(Error::InvalidParam));
let x = SbiRet::denied();
let y = SbiRet::success(3).into_result();
assert_eq!(x.and(y), Err(Error::Denied));
let x = SbiRet::invalid_address();
let y = SbiRet::already_available().into_result();
assert_eq!(x.and(y), Err(Error::InvalidAddress));
let x = SbiRet::success(4);
let y = SbiRet::success(5).into_result();
assert_eq!(x.and(y), Ok(5));
sourcepub fn and_then<U, F>(self, op: F) -> Result<U, Error>
pub fn and_then<U, F>(self, op: F) -> Result<U, Error>
Calls op
if self is success value, otherwise returns the contained error
as Error
struct.
This function can be used for control flow based on SbiRet
values.
§Examples
fn sq_then_to_string(x: usize) -> Result<String, Error> {
x.checked_mul(x).map(|sq| sq.to_string()).ok_or(Error::Failed)
}
assert_eq!(SbiRet::success(2).and_then(sq_then_to_string), Ok(4.to_string()));
assert_eq!(SbiRet::success(1_000_000_000_000).and_then(sq_then_to_string), Err(Error::Failed));
assert_eq!(SbiRet::invalid_param().and_then(sq_then_to_string), Err(Error::InvalidParam));
sourcepub fn or<F>(self, res: Result<usize, F>) -> Result<usize, F>
pub fn or<F>(self, res: Result<usize, F>) -> Result<usize, F>
Returns res
if self is SBI error, otherwise returns the success value of self
.
Arguments passed to or
are eagerly evaluated; if you are passing the
result of a function call, it is recommended to use or_else
, which is
lazily evaluated.
§Examples
Basic usage:
let x = SbiRet::success(2);
let y = SbiRet::invalid_param().into_result();
assert_eq!(x.or(y), Ok(2));
let x = SbiRet::denied();
let y = SbiRet::success(3).into_result();
assert_eq!(x.or(y), Ok(3));
let x = SbiRet::invalid_address();
let y = SbiRet::already_available().into_result();
assert_eq!(x.or(y), Err(Error::AlreadyAvailable));
let x = SbiRet::success(4);
let y = SbiRet::success(100).into_result();
assert_eq!(x.or(y), Ok(4));
sourcepub fn or_else<F, O>(self, op: O) -> Result<usize, F>
pub fn or_else<F, O>(self, op: O) -> Result<usize, F>
Calls op
if self is SBI error, otherwise returns the success value of self
.
This function can be used for control flow based on result values.
§Examples
Basic usage:
fn is_failed(x: Error) -> Result<usize, bool> { Err(x == Error::Failed) }
assert_eq!(SbiRet::success(2).or_else(is_failed), Ok(2));
assert_eq!(SbiRet::failed().or_else(is_failed), Err(true));
sourcepub fn unwrap_or(self, default: usize) -> usize
pub fn unwrap_or(self, default: usize) -> usize
Returns the contained success value or a provided default.
Arguments passed to unwrap_or
are eagerly evaluated; if you are passing
the result of a function call, it is recommended to use unwrap_or_else
,
which is lazily evaluated.
§Examples
Basic usage:
let default = 2;
let x = SbiRet::success(9);
assert_eq!(x.unwrap_or(default), 9);
let x = SbiRet::invalid_param();
assert_eq!(x.unwrap_or(default), default);
sourcepub fn unwrap_or_else<F>(self, op: F) -> usize
pub fn unwrap_or_else<F>(self, op: F) -> usize
Returns the contained success value or computes it from a closure.
§Examples
Basic usage:
fn invalid_use_zero(x: Error) -> usize { if x == Error::InvalidParam { 0 } else { 3 } }
assert_eq!(SbiRet::success(2).unwrap_or_else(invalid_use_zero), 2);
assert_eq!(SbiRet::invalid_param().unwrap_or_else(invalid_use_zero), 0);