pub trait Io {
Show 27 methods
// Required methods
fn addr(&self) -> usize;
fn maxsize(&self) -> usize;
// Provided methods
fn io_addr<U>(&self, offset: usize) -> Result<usize> { ... }
fn try_read8(&self, offset: usize) -> Result<u8>
where Self: IoCapable<u8> { ... }
fn try_read16(&self, offset: usize) -> Result<u16>
where Self: IoCapable<u16> { ... }
fn try_read32(&self, offset: usize) -> Result<u32>
where Self: IoCapable<u32> { ... }
fn try_read64(&self, offset: usize) -> Result<u64>
where Self: IoCapable<u64> { ... }
fn try_write8(&self, value: u8, offset: usize) -> Result
where Self: IoCapable<u8> { ... }
fn try_write16(&self, value: u16, offset: usize) -> Result
where Self: IoCapable<u16> { ... }
fn try_write32(&self, value: u32, offset: usize) -> Result
where Self: IoCapable<u32> { ... }
fn try_write64(&self, value: u64, offset: usize) -> Result
where Self: IoCapable<u64> { ... }
fn read8(&self, offset: usize) -> u8
where Self: IoKnownSize + IoCapable<u8> { ... }
fn read16(&self, offset: usize) -> u16
where Self: IoKnownSize + IoCapable<u16> { ... }
fn read32(&self, offset: usize) -> u32
where Self: IoKnownSize + IoCapable<u32> { ... }
fn read64(&self, offset: usize) -> u64
where Self: IoKnownSize + IoCapable<u64> { ... }
fn write8(&self, value: u8, offset: usize)
where Self: IoKnownSize + IoCapable<u8> { ... }
fn write16(&self, value: u16, offset: usize)
where Self: IoKnownSize + IoCapable<u16> { ... }
fn write32(&self, value: u32, offset: usize)
where Self: IoKnownSize + IoCapable<u32> { ... }
fn write64(&self, value: u64, offset: usize)
where Self: IoKnownSize + IoCapable<u64> { ... }
fn try_read<T, L>(&self, location: L) -> Result<T>
where L: IoLoc<T>,
Self: IoCapable<L::IoType> { ... }
fn try_write<T, L>(&self, location: L, value: T) -> Result
where L: IoLoc<T>,
Self: IoCapable<L::IoType> { ... }
fn try_write_reg<T, L, V>(&self, value: V) -> Result
where L: IoLoc<T>,
V: LocatedRegister<Location = L, Value = T>,
Self: IoCapable<L::IoType> { ... }
fn try_update<T, L, F>(&self, location: L, f: F) -> Result
where L: IoLoc<T>,
Self: IoCapable<L::IoType>,
F: FnOnce(T) -> T { ... }
fn read<T, L>(&self, location: L) -> T
where L: IoLoc<T>,
Self: IoKnownSize + IoCapable<L::IoType> { ... }
fn write<T, L>(&self, location: L, value: T)
where L: IoLoc<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> { ... }
fn update<T, L, F>(&self, location: L, f: F)
where L: IoLoc<T>,
Self: IoKnownSize + IoCapable<L::IoType> + Sized,
F: FnOnce(T) -> T { ... }
}Expand description
Types implementing this trait (e.g. MMIO BARs or PCI config regions) can perform I/O operations on regions of memory.
This is an abstract representation to be implemented by arbitrary I/O backends (e.g. MMIO, PCI config space, etc.).
The Io trait provides:
- Base address and size information
- Helper methods for offset validation and address calculation
- Fallible (runtime checked) accessors for different data widths
Which I/O methods are available depends on which IoCapable<T> traits
are implemented for the type.
§Examples
For MMIO regions, all widths (u8, u16, u32, and u64 on 64-bit systems) are typically supported. For PCI configuration space, u8, u16, and u32 are supported but u64 is not.
Required Methods§
Provided Methods§
Sourcefn 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.
Sourcefn try_read8(&self, offset: usize) -> Result<u8>
fn try_read8(&self, offset: usize) -> Result<u8>
Fallible 8-bit read with runtime bounds check.
Sourcefn try_read16(&self, offset: usize) -> Result<u16>
fn try_read16(&self, offset: usize) -> Result<u16>
Fallible 16-bit read with runtime bounds check.
Sourcefn try_read32(&self, offset: usize) -> Result<u32>
fn try_read32(&self, offset: usize) -> Result<u32>
Fallible 32-bit read with runtime bounds check.
Sourcefn try_read64(&self, offset: usize) -> Result<u64>
fn try_read64(&self, offset: usize) -> Result<u64>
Fallible 64-bit read with runtime bounds check.
Sourcefn 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.
Sourcefn 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.
Sourcefn 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.
Sourcefn 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.
Sourcefn write8(&self, value: u8, offset: usize)
fn write8(&self, value: u8, offset: usize)
Infallible 8-bit write with compile-time bounds check.
Sourcefn write16(&self, value: u16, offset: usize)
fn write16(&self, value: u16, offset: usize)
Infallible 16-bit write with compile-time bounds check.
Sourcefn write32(&self, value: u32, offset: usize)
fn write32(&self, value: u32, offset: usize)
Infallible 32-bit write with compile-time bounds check.
Sourcefn write64(&self, value: u64, offset: usize)
fn write64(&self, value: u64, offset: usize)
Infallible 64-bit write with compile-time bounds check.
Sourcefn 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.
§Examples
Read a primitive type from an I/O address:
use kernel::io::{
Io,
Mmio,
};
fn do_reads(io: &Mmio) -> Result {
// 32-bit read from address `0x10`.
let v: u32 = io.try_read(0x10)?;
// 8-bit read from address `0xfff`.
let v: u8 = io.try_read(0xfff)?;
Ok(())
}Sourcefn 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.
§Examples
Write a primitive type to an I/O address:
use kernel::io::{
Io,
Mmio,
};
fn do_writes(io: &Mmio) -> Result {
// 32-bit write of value `1` at address `0x10`.
io.try_write(0x10, 1u32)?;
// 8-bit write of value `0xff` at address `0xfff`.
io.try_write(0xfff, 0xffu8)?;
Ok(())
}Sourcefn 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.
§Examples
Tuples carrying a location and a value can be used with this method:
use kernel::io::{
register,
Io,
Mmio,
};
register! {
VERSION(u32) @ 0x100 {
15:8 major;
7:0 minor;
}
}
impl VERSION {
fn new(major: u8, minor: u8) -> Self {
VERSION::zeroed().with_major(major).with_minor(minor)
}
}
fn do_write_reg(io: &Mmio) -> Result {
io.try_write_reg(VERSION::new(1, 0))
}Sourcefn 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.
Note: this does not perform any synchronization. The caller is responsible for ensuring exclusive access if required.
§Examples
Read the u32 value at address 0x10, increment it, and store the updated value back:
use kernel::io::{
Io,
Mmio,
};
fn do_update(io: &Mmio<0x1000>) -> Result {
io.try_update(0x10, |v: u32| {
v + 1
})
}Sourcefn read<T, L>(&self, location: L) -> T
fn read<T, L>(&self, location: L) -> T
Generic infallible read with compile-time bounds check.
§Examples
Read a primitive type from an I/O address:
use kernel::io::{
Io,
Mmio,
};
fn do_reads(io: &Mmio<0x1000>) {
// 32-bit read from address `0x10`.
let v: u32 = io.read(0x10);
// 8-bit read from the top of the I/O space.
let v: u8 = io.read(0xfff);
}Sourcefn 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.
§Examples
Write a primitive type to an I/O address:
use kernel::io::{
Io,
Mmio,
};
fn do_writes(io: &Mmio<0x1000>) {
// 32-bit write of value `1` at address `0x10`.
io.write(0x10, 1u32);
// 8-bit write of value `0xff` at the top of the I/O space.
io.write(0xfff, 0xffu8);
}Sourcefn 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.
§Examples
Tuples carrying a location and a value can be used with this method:
use kernel::io::{
register,
Io,
Mmio,
};
register! {
VERSION(u32) @ 0x100 {
15:8 major;
7:0 minor;
}
}
impl VERSION {
fn new(major: u8, minor: u8) -> Self {
VERSION::zeroed().with_major(major).with_minor(minor)
}
}
fn do_write_reg(io: &Mmio<0x1000>) {
io.write_reg(VERSION::new(1, 0));
}Sourcefn update<T, L, F>(&self, location: L, f: F)
fn update<T, L, F>(&self, location: L, f: F)
Generic infallible update with compile-time bounds check.
Note: this does not perform any synchronization. The caller is responsible for ensuring exclusive access if required.
§Examples
Read the u32 value at address 0x10, increment it, and store the updated value back:
use kernel::io::{
Io,
Mmio,
};
fn do_update(io: &Mmio<0x1000>) {
io.update(0x10, |v: u32| {
v + 1
})
}Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.