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>
impl<const SIZE: usize> Io<SIZE>
Sourcepub unsafe fn from_raw(raw: &IoRaw<SIZE>) -> &Self
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
.
Sourcepub fn readb(&self, offset: usize) -> u8
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.
Sourcepub fn try_readb(&self, offset: usize) -> Result<u8>
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.
Sourcepub fn readw(&self, offset: usize) -> u16
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.
Sourcepub fn try_readw(&self, offset: usize) -> Result<u16>
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.
Sourcepub fn readl(&self, offset: usize) -> u32
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.
Sourcepub fn try_readl(&self, offset: usize) -> Result<u32>
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.
Sourcepub fn readq(&self, offset: usize) -> u64
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.
Sourcepub fn try_readq(&self, offset: usize) -> Result<u64>
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.
Sourcepub fn readb_relaxed(&self, offset: usize) -> u8
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.
Sourcepub fn try_readb_relaxed(&self, offset: usize) -> Result<u8>
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.
Sourcepub fn readw_relaxed(&self, offset: usize) -> u16
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.
Sourcepub fn try_readw_relaxed(&self, offset: usize) -> Result<u16>
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.
Sourcepub fn readl_relaxed(&self, offset: usize) -> u32
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.
Sourcepub fn try_readl_relaxed(&self, offset: usize) -> Result<u32>
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.
Sourcepub fn readq_relaxed(&self, offset: usize) -> u64
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.
Sourcepub fn try_readq_relaxed(&self, offset: usize) -> Result<u64>
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.
Sourcepub fn writeb(&self, value: u8, offset: usize)
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.
Sourcepub fn try_writeb(&self, value: u8, offset: usize) -> Result
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.
Sourcepub fn writew(&self, value: u16, offset: usize)
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.
Sourcepub fn try_writew(&self, value: u16, offset: usize) -> Result
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.
Sourcepub fn writel(&self, value: u32, offset: usize)
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.
Sourcepub fn try_writel(&self, value: u32, offset: usize) -> Result
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.
Sourcepub fn writeq(&self, value: u64, offset: usize)
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.
Sourcepub fn try_writeq(&self, value: u64, offset: usize) -> Result
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.
Sourcepub fn writeb_relaxed(&self, value: u8, offset: usize)
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.
Sourcepub fn try_writeb_relaxed(&self, value: u8, offset: usize) -> Result
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.
Sourcepub fn writew_relaxed(&self, value: u16, offset: usize)
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.
Sourcepub fn try_writew_relaxed(&self, value: u16, offset: usize) -> Result
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.
Sourcepub fn writel_relaxed(&self, value: u32, offset: usize)
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.
Sourcepub fn try_writel_relaxed(&self, value: u32, offset: usize) -> Result
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.
Sourcepub fn writeq_relaxed(&self, value: u64, offset: usize)
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.
Sourcepub fn try_writeq_relaxed(&self, value: u64, offset: usize) -> Result
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.