Struct Io

Source
pub struct Io<const SIZE: usize = 0>(/* private fields */);
Expand description

IO-mapped memory, starting at the base address @addr and spanning @maxlen bytes.

The creator (usually a subsystem / bus such as PCI) is responsible for creating the mapping, performing an additional region request etc.

§Invariant

addr is the start and maxsize the length of valid I/O mapped memory region of size maxsize.

§Examples


// See also [`pci::Bar`] for a real example.
struct IoMem<const SIZE: usize>(IoRaw<SIZE>);

impl<const SIZE: usize> IoMem<SIZE> {
    /// # Safety
    ///
    /// [`paddr`, `paddr` + `SIZE`) must be a valid MMIO region that is mappable into the CPUs
    /// virtual address space.
    unsafe fn new(paddr: usize) -> Result<Self>{
        // SAFETY: By the safety requirements of this function [`paddr`, `paddr` + `SIZE`) is
        // valid for `ioremap`.
        let addr = unsafe { bindings::ioremap(paddr as _, SIZE as _) };
        if addr.is_null() {
            return Err(ENOMEM);
        }

        Ok(IoMem(IoRaw::new(addr as _, SIZE)?))
    }
}

impl<const SIZE: usize> Drop for IoMem<SIZE> {
    fn drop(&mut self) {
        // SAFETY: `self.0.addr()` is guaranteed to be properly mapped by `Self::new`.
        unsafe { bindings::iounmap(self.0.addr() as _); };
    }
}

impl<const SIZE: usize> Deref for IoMem<SIZE> {
   type Target = Io<SIZE>;

   fn deref(&self) -> &Self::Target {
        // SAFETY: The memory range stored in `self` has been properly mapped in `Self::new`.
        unsafe { Io::from_raw(&self.0) }
   }
}

// SAFETY: Invalid usage for example purposes.
let iomem = unsafe { IoMem::<{ core::mem::size_of::<u32>() }>::new(0xBAAAAAAD)? };
iomem.writel(0x42, 0x0);
assert!(iomem.try_writel(0x42, 0x0).is_ok());
assert!(iomem.try_writel(0x42, 0x4).is_err());

Implementations§

Source§

impl<const SIZE: usize> Io<SIZE>

Source

pub unsafe fn from_raw(raw: &IoRaw<SIZE>) -> &Self

Converts an IoRaw into an Io instance, providing the accessors to the MMIO mapping.

§Safety

Callers must ensure that addr is the start of a valid I/O mapped memory region of size maxsize.

Source

pub fn addr(&self) -> usize

Returns the base address of this mapping.

Source

pub fn maxsize(&self) -> usize

Returns the maximum size of this mapping.

Source

pub fn readb(&self, offset: usize) -> u8

Read IO data from a given offset known at compile time.

Bound checks are performed on compile time, hence if the offset is not known at compile time, the build will fail.

Source

pub fn try_readb(&self, offset: usize) -> Result<u8>

Read IO data from a given offset.

Bound checks are performed on runtime, it fails if the offset (plus the type size) is out of bounds.

Source

pub fn readw(&self, offset: usize) -> u16

Read IO data from a given offset known at compile time.

Bound checks are performed on compile time, hence if the offset is not known at compile time, the build will fail.

Source

pub fn try_readw(&self, offset: usize) -> Result<u16>

Read IO data from a given offset.

Bound checks are performed on runtime, it fails if the offset (plus the type size) is out of bounds.

Source

pub fn readl(&self, offset: usize) -> u32

Read IO data from a given offset known at compile time.

Bound checks are performed on compile time, hence if the offset is not known at compile time, the build will fail.

Source

pub fn try_readl(&self, offset: usize) -> Result<u32>

Read IO data from a given offset.

Bound checks are performed on runtime, it fails if the offset (plus the type size) is out of bounds.

Source

pub fn readq(&self, offset: usize) -> u64

Read IO data from a given offset known at compile time.

Bound checks are performed on compile time, hence if the offset is not known at compile time, the build will fail.

Source

pub fn try_readq(&self, offset: usize) -> Result<u64>

Read IO data from a given offset.

Bound checks are performed on runtime, it fails if the offset (plus the type size) is out of bounds.

Source

pub fn readb_relaxed(&self, offset: usize) -> u8

Read IO data from a given offset known at compile time.

Bound checks are performed on compile time, hence if the offset is not known at compile time, the build will fail.

Source

pub fn try_readb_relaxed(&self, offset: usize) -> Result<u8>

Read IO data from a given offset.

Bound checks are performed on runtime, it fails if the offset (plus the type size) is out of bounds.

Source

pub fn readw_relaxed(&self, offset: usize) -> u16

Read IO data from a given offset known at compile time.

Bound checks are performed on compile time, hence if the offset is not known at compile time, the build will fail.

Source

pub fn try_readw_relaxed(&self, offset: usize) -> Result<u16>

Read IO data from a given offset.

Bound checks are performed on runtime, it fails if the offset (plus the type size) is out of bounds.

Source

pub fn readl_relaxed(&self, offset: usize) -> u32

Read IO data from a given offset known at compile time.

Bound checks are performed on compile time, hence if the offset is not known at compile time, the build will fail.

Source

pub fn try_readl_relaxed(&self, offset: usize) -> Result<u32>

Read IO data from a given offset.

Bound checks are performed on runtime, it fails if the offset (plus the type size) is out of bounds.

Source

pub fn readq_relaxed(&self, offset: usize) -> u64

Read IO data from a given offset known at compile time.

Bound checks are performed on compile time, hence if the offset is not known at compile time, the build will fail.

Source

pub fn try_readq_relaxed(&self, offset: usize) -> Result<u64>

Read IO data from a given offset.

Bound checks are performed on runtime, it fails if the offset (plus the type size) is out of bounds.

Source

pub fn writeb(&self, value: u8, offset: usize)

Write IO data from a given offset known at compile time.

Bound checks are performed on compile time, hence if the offset is not known at compile time, the build will fail.

Source

pub fn try_writeb(&self, value: u8, offset: usize) -> Result

Write IO data from a given offset.

Bound checks are performed on runtime, it fails if the offset (plus the type size) is out of bounds.

Source

pub fn writew(&self, value: u16, offset: usize)

Write IO data from a given offset known at compile time.

Bound checks are performed on compile time, hence if the offset is not known at compile time, the build will fail.

Source

pub fn try_writew(&self, value: u16, offset: usize) -> Result

Write IO data from a given offset.

Bound checks are performed on runtime, it fails if the offset (plus the type size) is out of bounds.

Source

pub fn writel(&self, value: u32, offset: usize)

Write IO data from a given offset known at compile time.

Bound checks are performed on compile time, hence if the offset is not known at compile time, the build will fail.

Source

pub fn try_writel(&self, value: u32, offset: usize) -> Result

Write IO data from a given offset.

Bound checks are performed on runtime, it fails if the offset (plus the type size) is out of bounds.

Source

pub fn writeq(&self, value: u64, offset: usize)

Write IO data from a given offset known at compile time.

Bound checks are performed on compile time, hence if the offset is not known at compile time, the build will fail.

Source

pub fn try_writeq(&self, value: u64, offset: usize) -> Result

Write IO data from a given offset.

Bound checks are performed on runtime, it fails if the offset (plus the type size) is out of bounds.

Source

pub fn writeb_relaxed(&self, value: u8, offset: usize)

Write IO data from a given offset known at compile time.

Bound checks are performed on compile time, hence if the offset is not known at compile time, the build will fail.

Source

pub fn try_writeb_relaxed(&self, value: u8, offset: usize) -> Result

Write IO data from a given offset.

Bound checks are performed on runtime, it fails if the offset (plus the type size) is out of bounds.

Source

pub fn writew_relaxed(&self, value: u16, offset: usize)

Write IO data from a given offset known at compile time.

Bound checks are performed on compile time, hence if the offset is not known at compile time, the build will fail.

Source

pub fn try_writew_relaxed(&self, value: u16, offset: usize) -> Result

Write IO data from a given offset.

Bound checks are performed on runtime, it fails if the offset (plus the type size) is out of bounds.

Source

pub fn writel_relaxed(&self, value: u32, offset: usize)

Write IO data from a given offset known at compile time.

Bound checks are performed on compile time, hence if the offset is not known at compile time, the build will fail.

Source

pub fn try_writel_relaxed(&self, value: u32, offset: usize) -> Result

Write IO data from a given offset.

Bound checks are performed on runtime, it fails if the offset (plus the type size) is out of bounds.

Source

pub fn writeq_relaxed(&self, value: u64, offset: usize)

Write IO data from a given offset known at compile time.

Bound checks are performed on compile time, hence if the offset is not known at compile time, the build will fail.

Source

pub fn try_writeq_relaxed(&self, value: u64, offset: usize) -> Result

Write IO data from a given offset.

Bound checks are performed on runtime, it fails if the offset (plus the type size) is out of bounds.

Auto Trait Implementations§

§

impl<const SIZE: usize> Freeze for Io<SIZE>

§

impl<const SIZE: usize> RefUnwindSafe for Io<SIZE>

§

impl<const SIZE: usize> Send for Io<SIZE>

§

impl<const SIZE: usize> Sync for Io<SIZE>

§

impl<const SIZE: usize> Unpin for Io<SIZE>

§

impl<const SIZE: usize> UnwindSafe for Io<SIZE>

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, E> Init<T, E> for T

Source§

unsafe fn __init(self, slot: *mut T) -> Result<(), E>

Initializes slot. Read more
Source§

fn chain<F>(self, f: F) -> ChainInit<Self, F, T, E>
where F: FnOnce(&mut T) -> Result<(), E>,

First initializes the value using self then calls the function f with the initialized value. Read more
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, E> PinInit<T, E> for T

Source§

unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E>

Initializes slot. Read more
Source§

fn pin_chain<F>(self, f: F) -> ChainPinInit<Self, F, T, E>
where F: FnOnce(Pin<&mut T>) -> Result<(), E>,

First initializes the value using self then calls the function f with the initialized value. Read more
Source§

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

Source§

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>,

Source§

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.