pub trait Io<'a>: IoBase<'a> {
Show 34 methods
// Provided methods
fn size(self) -> usize { ... }
fn len<T>(self) -> usize
where Self: Io<'a, Target = [T]> { ... }
fn is_empty<T>(self) -> bool
where Self: Io<'a, Target = [T]> { ... }
fn try_cast<U>(self) -> Result<<Self::Backend as IoBackend>::View<'a, U>>
where Self::Target: FromBytes + IntoBytes,
U: FromBytes + IntoBytes { ... }
fn read_val(self) -> Self::Target
where Self::Backend: IoCapable<Self::Target>,
Self::Target: Sized { ... }
fn write_val(self, value: Self::Target)
where Self::Backend: IoCapable<Self::Target>,
Self::Target: Sized { ... }
fn copy_read(self) -> Self::Target
where Self::Backend: IoCopyable,
Self::Target: Sized + FromBytes { ... }
fn copy_write(self, value: Self::Target)
where Self::Backend: IoCopyable,
Self::Target: Sized + IntoBytes { ... }
fn copy_from_slice(self, data: &[u8])
where Self::Backend: IoCopyable,
Self: Io<'a, Target = [u8]> { ... }
fn copy_to_slice(self, data: &mut [u8])
where Self::Backend: IoCopyable,
Self: Io<'a, Target = [u8]> { ... }
fn try_read8(self, offset: usize) -> Result<u8>
where usize: IoLoc<Self::Target, u8, IoType = u8>,
Self::Backend: IoCapable<u8> { ... }
fn try_read16(self, offset: usize) -> Result<u16>
where usize: IoLoc<Self::Target, u16, IoType = u16>,
Self::Backend: IoCapable<u16> { ... }
fn try_read32(self, offset: usize) -> Result<u32>
where usize: IoLoc<Self::Target, u32, IoType = u32>,
Self::Backend: IoCapable<u32> { ... }
fn try_read64(self, offset: usize) -> Result<u64>
where usize: IoLoc<Self::Target, u64, IoType = u64>,
Self::Backend: IoCapable<u64> { ... }
fn try_write8(self, value: u8, offset: usize) -> Result
where usize: IoLoc<Self::Target, u8, IoType = u8>,
Self::Backend: IoCapable<u8> { ... }
fn try_write16(self, value: u16, offset: usize) -> Result
where usize: IoLoc<Self::Target, u16, IoType = u16>,
Self::Backend: IoCapable<u16> { ... }
fn try_write32(self, value: u32, offset: usize) -> Result
where usize: IoLoc<Self::Target, u32, IoType = u32>,
Self::Backend: IoCapable<u32> { ... }
fn try_write64(self, value: u64, offset: usize) -> Result
where usize: IoLoc<Self::Target, u64, IoType = u64>,
Self::Backend: IoCapable<u64> { ... }
fn read8(self, offset: usize) -> u8
where usize: IoLoc<Self::Target, u8, IoType = u8>,
Self::Backend: IoCapable<u8> { ... }
fn read16(self, offset: usize) -> u16
where usize: IoLoc<Self::Target, u16, IoType = u16>,
Self::Backend: IoCapable<u16> { ... }
fn read32(self, offset: usize) -> u32
where usize: IoLoc<Self::Target, u32, IoType = u32>,
Self::Backend: IoCapable<u32> { ... }
fn read64(self, offset: usize) -> u64
where usize: IoLoc<Self::Target, u64, IoType = u64>,
Self::Backend: IoCapable<u64> { ... }
fn write8(self, value: u8, offset: usize)
where usize: IoLoc<Self::Target, u8, IoType = u8>,
Self::Backend: IoCapable<u8> { ... }
fn write16(self, value: u16, offset: usize)
where usize: IoLoc<Self::Target, u16, IoType = u16>,
Self::Backend: IoCapable<u16> { ... }
fn write32(self, value: u32, offset: usize)
where usize: IoLoc<Self::Target, u32, IoType = u32>,
Self::Backend: IoCapable<u32> { ... }
fn write64(self, value: u64, offset: usize)
where usize: IoLoc<Self::Target, u64, IoType = u64>,
Self::Backend: IoCapable<u64> { ... }
fn try_read<T, L>(self, location: L) -> Result<T>
where L: IoLoc<Self::Target, T>,
Self::Backend: IoCapable<L::IoType> { ... }
fn try_write<T, L>(self, location: L, value: T) -> Result
where L: IoLoc<Self::Target, T>,
Self::Backend: IoCapable<L::IoType> { ... }
fn try_write_reg<T, L, V>(self, value: V) -> Result
where L: IoLoc<Self::Target, T>,
V: LocatedRegister<Self::Target, Location = L, Value = T>,
Self::Backend: IoCapable<L::IoType> { ... }
fn try_update<T, L, F>(self, location: L, f: F) -> Result
where L: IoLoc<Self::Target, T>,
Self::Backend: IoCapable<L::IoType>,
F: FnOnce(T) -> T { ... }
fn read<T, L>(self, location: L) -> T
where L: IoLoc<Self::Target, T>,
Self::Backend: IoCapable<L::IoType> { ... }
fn write<T, L>(self, location: L, value: T)
where L: IoLoc<Self::Target, T>,
Self::Backend: IoCapable<L::IoType> { ... }
fn write_reg<T, L, V>(self, value: V)
where L: IoLoc<Self::Target, T>,
V: LocatedRegister<Self::Target, Location = L, Value = T>,
Self::Backend: IoCapable<L::IoType> { ... }
fn update<T, L, F>(self, location: L, f: F)
where L: IoLoc<Self::Target, T>,
Self::Backend: IoCapable<L::IoType>,
F: FnOnce(T) -> T { ... }
}Expand description
Extension trait to provide I/O operation methods to types that implement IoBase.
This trait provides:
- Helper methods for offset validation and address calculation
- Fallible (runtime checked) accessors for different data widths
Which I/O methods are available depends on the associated IoBackend implementation.
Provided Methods§
Sourcefn try_cast<U>(self) -> Result<<Self::Backend as IoBackend>::View<'a, U>>
fn try_cast<U>(self) -> Result<<Self::Backend as IoBackend>::View<'a, U>>
Try to convert into a different typed I/O view.
A runtime check is performed to ensure that the target type is of same or smaller size to
current type, and the current view is properly aligned for the target type. Returns
Err(EINVAL) if the runtime check fails.
§Examples
use kernel::io::{
io_project,
Mmio,
Io,
Region,
};
#[derive(FromBytes, IntoBytes)]
#[repr(C)]
struct MyStruct { field: u32, }
// let mmio: Mmio<'_, Region>;
let whole: Mmio<'_, MyStruct> = mmio.try_cast()?;Sourcefn read_val(self) -> Self::Target
fn read_val(self) -> Self::Target
Read a value from I/O.
This only works for primitives supported by the I/O backend.
§Examples
// let mmio: Mmio<'_, u32>;
let val: u32 = mmio.read_val();Sourcefn write_val(self, value: Self::Target)
fn write_val(self, value: Self::Target)
Write a value to I/O.
This only works for primitives supported by the I/O backend.
§Examples
// let mmio: Mmio<'_, u32>;
mmio.write_val(1u32);Sourcefn copy_read(self) -> Self::Target
fn copy_read(self) -> Self::Target
Copy-read from I/O memory.
This is equivalent to reading from the I/O memory with byte-wise copy, although the actual
implementation might be more efficient. There is no atomicity guarantee. Note that for some
backends (e.g. Mmio), this can read different value compared to read_val as
byte-swapping is not performed.
§Examples
// let mmio: Mmio<'_, [u8; 6]>;
let val: [u8; 6] = mmio.copy_read();Sourcefn copy_write(self, value: Self::Target)
fn copy_write(self, value: Self::Target)
Copy-write to I/O memory.
This is equivalent to writing to the I/O memory with byte-wise copy, although the actual
implementation might be more efficient. There is no atomicity guarantee. Note that for some
backends (e.g. Mmio), this can write different value compared to write_val as
byte-swapping is not performed.
§Examples
// let mmio: Mmio<'_, [u8; 6]>;
mmio.copy_write([0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF]);Sourcefn copy_from_slice(self, data: &[u8])
fn copy_from_slice(self, data: &[u8])
Sourcefn copy_to_slice(self, data: &mut [u8])
fn copy_to_slice(self, data: &mut [u8])
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,
Region,
};
fn do_reads(io: Mmio<'_, Region>) -> 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,
Region,
};
fn do_writes(io: Mmio<'_, Region>) -> 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,
Region,
};
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<'_, Region>) -> 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,
Region,
};
fn do_update(io: Mmio<'_, Region<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,
Region,
};
fn do_reads(io: Mmio<'_, Region<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,
Region,
};
fn do_writes(io: Mmio<'_, Region<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)
fn write_reg<T, L, V>(self, value: V)
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,
Region,
};
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<'_, Region<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,
Region,
};
fn do_update(io: Mmio<'_, Region<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".