pub struct Mmio<const SIZE: usize = 0>(/* private fields */);Expand description
IO-mapped memory region.
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
use kernel::{
bindings,
ffi::c_void,
io::{
Io,
IoKnownSize,
Mmio,
MmioRaw,
PhysAddr,
},
};
use core::ops::Deref;
// See also `pci::Bar` for a real example.
struct IoMem<const SIZE: usize>(MmioRaw<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 PhysAddr, SIZE) };
if addr.is_null() {
return Err(ENOMEM);
}
Ok(IoMem(MmioRaw::new(addr as usize, 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 *mut c_void); };
}
}
impl<const SIZE: usize> Deref for IoMem<SIZE> {
type Target = Mmio<SIZE>;
fn deref(&self) -> &Self::Target {
// SAFETY: The memory range stored in `self` has been properly mapped in `Self::new`.
unsafe { Mmio::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> Mmio<SIZE>
impl<const SIZE: usize> Mmio<SIZE>
Sourcepub fn relaxed(&self) -> &RelaxedMmio<SIZE>
pub fn relaxed(&self) -> &RelaxedMmio<SIZE>
Returns a RelaxedMmio reference that performs relaxed I/O operations.
Relaxed accessors do not provide ordering guarantees with respect to DMA or memory accesses and can be used when such ordering is not required.
§Examples
use kernel::io::{
Io,
Mmio,
RelaxedMmio,
};
fn do_io(io: &Mmio<0x100>) {
// The access is performed using `readl_relaxed` instead of `readl`.
let v = io.relaxed().read32(0x10);
}
Trait Implementations§
Source§impl<const SIZE: usize> Io for Mmio<SIZE>
impl<const SIZE: usize> Io for Mmio<SIZE>
Source§fn io_addr<U>(&self, offset: usize) -> Result<usize>
fn io_addr<U>(&self, offset: usize) -> Result<usize>
Returns the absolute I/O address for a given
offset,
performing runtime bound checks.Source§fn try_read8(&self, offset: usize) -> Result<u8>
fn try_read8(&self, offset: usize) -> Result<u8>
Fallible 8-bit read with runtime bounds check.
Source§fn try_read16(&self, offset: usize) -> Result<u16>
fn try_read16(&self, offset: usize) -> Result<u16>
Fallible 16-bit read with runtime bounds check.
Source§fn try_read32(&self, offset: usize) -> Result<u32>
fn try_read32(&self, offset: usize) -> Result<u32>
Fallible 32-bit read with runtime bounds check.
Source§fn try_read64(&self, offset: usize) -> Result<u64>
fn try_read64(&self, offset: usize) -> Result<u64>
Fallible 64-bit read with runtime bounds check.
Source§fn try_write8(&self, value: u8, offset: usize) -> Result
fn try_write8(&self, value: u8, offset: usize) -> Result
Fallible 8-bit write with runtime bounds check.
Source§fn try_write16(&self, value: u16, offset: usize) -> Result
fn try_write16(&self, value: u16, offset: usize) -> Result
Fallible 16-bit write with runtime bounds check.
Source§fn try_write32(&self, value: u32, offset: usize) -> Result
fn try_write32(&self, value: u32, offset: usize) -> Result
Fallible 32-bit write with runtime bounds check.
Source§fn try_write64(&self, value: u64, offset: usize) -> Result
fn try_write64(&self, value: u64, offset: usize) -> Result
Fallible 64-bit write with runtime bounds check.
Source§fn write8(&self, value: u8, offset: usize)
fn write8(&self, value: u8, offset: usize)
Infallible 8-bit write with compile-time bounds check.
Source§fn write16(&self, value: u16, offset: usize)
fn write16(&self, value: u16, offset: usize)
Infallible 16-bit write with compile-time bounds check.
Source§fn write32(&self, value: u32, offset: usize)
fn write32(&self, value: u32, offset: usize)
Infallible 32-bit write with compile-time bounds check.
Source§fn write64(&self, value: u64, offset: usize)
fn write64(&self, value: u64, offset: usize)
Infallible 64-bit write with compile-time bounds check.
Source§fn try_read<T, L>(&self, location: L) -> Result<T>
fn try_read<T, L>(&self, location: L) -> Result<T>
Generic fallible read with runtime bounds check. Read more
Source§fn try_write<T, L>(&self, location: L, value: T) -> Result
fn try_write<T, L>(&self, location: L, value: T) -> Result
Generic fallible write with runtime bounds check. Read more
Source§fn try_write_reg<T, L, V>(&self, value: V) -> Result
fn try_write_reg<T, L, V>(&self, value: V) -> Result
Generic fallible write of a fully-located register value. Read more
Source§fn try_update<T, L, F>(&self, location: L, f: F) -> Result
fn try_update<T, L, F>(&self, location: L, f: F) -> Result
Generic fallible update with runtime bounds check. Read more
Source§fn read<T, L>(&self, location: L) -> T
fn read<T, L>(&self, location: L) -> T
Generic infallible read with compile-time bounds check. Read more
Source§fn write<T, L>(&self, location: L, value: T)
fn write<T, L>(&self, location: L, value: T)
Generic infallible write with compile-time bounds check. Read more
Source§fn write_reg<T, L, V>(&self, value: V)where
L: IoLoc<T>,
V: LocatedRegister<Location = L, Value = T>,
Self: IoKnownSize + IoCapable<L::IoType>,
fn write_reg<T, L, V>(&self, value: V)where
L: IoLoc<T>,
V: LocatedRegister<Location = L, Value = T>,
Self: IoKnownSize + IoCapable<L::IoType>,
Generic infallible write of a fully-located register value. Read more
Auto Trait Implementations§
impl<const SIZE: usize> Freeze for Mmio<SIZE>
impl<const SIZE: usize> RefUnwindSafe for Mmio<SIZE>
impl<const SIZE: usize> Send for Mmio<SIZE>
impl<const SIZE: usize> Sync for Mmio<SIZE>
impl<const SIZE: usize> Unpin for Mmio<SIZE>
impl<const SIZE: usize> UnsafeUnpin for Mmio<SIZE>
impl<const SIZE: usize> UnwindSafe for Mmio<SIZE>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> PinInit<T> for T
impl<T> PinInit<T> for T
Source§unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), Infallible>
unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), Infallible>
Initializes
slot. Read more