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.write32(0x42, 0x0);
assert!(iomem.try_write32(0x42, 0x0).is_ok());
assert!(iomem.try_write32(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 read8(&self, offset: usize) -> u8
pub fn read8(&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_read8(&self, offset: usize) -> Result<u8>
pub fn try_read8(&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 read16(&self, offset: usize) -> u16
pub fn read16(&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_read16(&self, offset: usize) -> Result<u16>
pub fn try_read16(&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 read32(&self, offset: usize) -> u32
pub fn read32(&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_read32(&self, offset: usize) -> Result<u32>
pub fn try_read32(&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 read64(&self, offset: usize) -> u64
pub fn read64(&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_read64(&self, offset: usize) -> Result<u64>
pub fn try_read64(&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 read8_relaxed(&self, offset: usize) -> u8
pub fn read8_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_read8_relaxed(&self, offset: usize) -> Result<u8>
pub fn try_read8_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 read16_relaxed(&self, offset: usize) -> u16
pub fn read16_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_read16_relaxed(&self, offset: usize) -> Result<u16>
pub fn try_read16_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 read32_relaxed(&self, offset: usize) -> u32
pub fn read32_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_read32_relaxed(&self, offset: usize) -> Result<u32>
pub fn try_read32_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 read64_relaxed(&self, offset: usize) -> u64
pub fn read64_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_read64_relaxed(&self, offset: usize) -> Result<u64>
pub fn try_read64_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 write8(&self, value: u8, offset: usize)
pub fn write8(&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_write8(&self, value: u8, offset: usize) -> Result
pub fn try_write8(&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 write16(&self, value: u16, offset: usize)
pub fn write16(&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_write16(&self, value: u16, offset: usize) -> Result
pub fn try_write16(&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 write32(&self, value: u32, offset: usize)
pub fn write32(&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_write32(&self, value: u32, offset: usize) -> Result
pub fn try_write32(&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 write64(&self, value: u64, offset: usize)
pub fn write64(&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_write64(&self, value: u64, offset: usize) -> Result
pub fn try_write64(&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 write8_relaxed(&self, value: u8, offset: usize)
pub fn write8_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_write8_relaxed(&self, value: u8, offset: usize) -> Result
pub fn try_write8_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 write16_relaxed(&self, value: u16, offset: usize)
pub fn write16_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_write16_relaxed(&self, value: u16, offset: usize) -> Result
pub fn try_write16_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 write32_relaxed(&self, value: u32, offset: usize)
pub fn write32_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_write32_relaxed(&self, value: u32, offset: usize) -> Result
pub fn try_write32_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 write64_relaxed(&self, value: u64, offset: usize)
pub fn write64_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_write64_relaxed(&self, value: u64, offset: usize) -> Result
pub fn try_write64_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.