Struct sbi_spec::binary::SbiRet

source ·
#[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

source

pub const fn success(value: usize) -> Self

Returns success SBI state with given value.

source

pub const fn failed() -> Self

The SBI call request failed for unknown reasons.

source

pub const fn not_supported() -> Self

SBI call failed due to not supported by target ISA, operation type not supported, or target operation type not implemented on purpose.

source

pub const fn invalid_param() -> Self

SBI call failed due to invalid hart mask parameter, invalid target hart id, invalid operation type, or invalid resource index.

source

pub const fn denied() -> Self

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.

source

pub const fn invalid_address() -> Self

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.

source

pub const fn already_available() -> Self

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.

source

pub const fn already_started() -> Self

SBI call failed for the target resource is already started, e.g., target performance counter is started.

source

pub const fn already_stopped() -> Self

SBI call failed for the target resource is already stopped, e.g., target performance counter is stopped.

source

pub const fn no_shmem() -> Self

SBI call failed for shared memory is not available, e.g. nested acceleration shared memory is not available.

source§

impl SbiRet

source

pub const fn into_result(self) -> Result<usize, Error>

Converts to a Result of value and error.

source

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);
source

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);
source

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);
source

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));
source

pub fn map<U, F: FnOnce(usize) -> U>(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));
source

pub fn map_or<U, F: FnOnce(usize) -> U>(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);
source

pub fn map_or_else<U, D: FnOnce(Error) -> U, F: FnOnce(usize) -> U>( 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);
source

pub fn map_err<F, O: FnOnce(Error) -> F>(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()));
source

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`
source

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
source

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`
source

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);
source

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));
source

pub fn and_then<U, F: FnOnce(usize) -> Result<U, Error>>( 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));
source

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));
source

pub fn or_else<F, O: FnOnce(Error) -> Result<usize, F>>( 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));
source

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);
source

pub fn unwrap_or_else<F: FnOnce(Error) -> usize>(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);

Trait Implementations§

source§

impl Clone for SbiRet

source§

fn clone(&self) -> SbiRet

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for SbiRet

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl PartialEq for SbiRet

source§

fn eq(&self, other: &SbiRet) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl Copy for SbiRet

source§

impl Eq for SbiRet

source§

impl StructuralPartialEq for SbiRet

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.