Skip to main content

Io

Trait Io 

Source
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§

Source

fn size(self) -> usize

Returns the size of this I/O region.

Source

fn len<T>(self) -> usize
where Self: Io<'a, Target = [T]>,

Returns the length of the slice in number of elements.

Source

fn is_empty<T>(self) -> bool
where Self: Io<'a, Target = [T]>,

Returns true if the slice has a length of 0.

Source

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()?;
Source

fn read_val(self) -> Self::Target
where Self::Backend: IoCapable<Self::Target>, Self::Target: Sized,

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();
Source

fn write_val(self, value: Self::Target)
where Self::Backend: IoCapable<Self::Target>, Self::Target: Sized,

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);
Source

fn copy_read(self) -> Self::Target
where Self::Backend: IoCopyable, Self::Target: Sized + FromBytes,

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();
Source

fn copy_write(self, value: Self::Target)
where Self::Backend: IoCopyable, Self::Target: Sized + IntoBytes,

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]);
Source

fn copy_from_slice(self, data: &[u8])
where Self::Backend: IoCopyable, Self: Io<'a, Target = [u8]>,

Copy bytes from data to I/O memory.

§Panics

This function will panic if the length of self differs from the length of data, similar to [[u8]::copy_from_slice].

§Examples
// let mmio: Mmio<'_, [u8]>;
mmio.copy_from_slice(&[0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF]);
Source

fn copy_to_slice(self, data: &mut [u8])
where Self::Backend: IoCopyable, Self: Io<'a, Target = [u8]>,

Copy bytes from I/O memory to data.

§Panics

This function will panic if the length of self differs from the length of data, similar to [[u8]::copy_from_slice].

§Examples
// let mmio: Mmio<'_, [u8]>;
let mut buf = [0; 6];
mmio.copy_to_slice(&mut buf);
Source

fn try_read8(self, offset: usize) -> Result<u8>
where usize: IoLoc<Self::Target, u8, IoType = u8>, Self::Backend: IoCapable<u8>,

Fallible 8-bit read with runtime bounds check.

Source

fn try_read16(self, offset: usize) -> Result<u16>
where usize: IoLoc<Self::Target, u16, IoType = u16>, Self::Backend: IoCapable<u16>,

Fallible 16-bit read with runtime bounds check.

Source

fn try_read32(self, offset: usize) -> Result<u32>
where usize: IoLoc<Self::Target, u32, IoType = u32>, Self::Backend: IoCapable<u32>,

Fallible 32-bit read with runtime bounds check.

Source

fn try_read64(self, offset: usize) -> Result<u64>
where usize: IoLoc<Self::Target, u64, IoType = u64>, Self::Backend: IoCapable<u64>,

Fallible 64-bit read with runtime bounds check.

Source

fn try_write8(self, value: u8, offset: usize) -> Result
where usize: IoLoc<Self::Target, u8, IoType = u8>, Self::Backend: IoCapable<u8>,

Fallible 8-bit write with runtime bounds check.

Source

fn try_write16(self, value: u16, offset: usize) -> Result
where usize: IoLoc<Self::Target, u16, IoType = u16>, Self::Backend: IoCapable<u16>,

Fallible 16-bit write with runtime bounds check.

Source

fn try_write32(self, value: u32, offset: usize) -> Result
where usize: IoLoc<Self::Target, u32, IoType = u32>, Self::Backend: IoCapable<u32>,

Fallible 32-bit write with runtime bounds check.

Source

fn try_write64(self, value: u64, offset: usize) -> Result
where usize: IoLoc<Self::Target, u64, IoType = u64>, Self::Backend: IoCapable<u64>,

Fallible 64-bit write with runtime bounds check.

Source

fn read8(self, offset: usize) -> u8
where usize: IoLoc<Self::Target, u8, IoType = u8>, Self::Backend: IoCapable<u8>,

Infallible 8-bit read with compile-time bounds check.

Source

fn read16(self, offset: usize) -> u16
where usize: IoLoc<Self::Target, u16, IoType = u16>, Self::Backend: IoCapable<u16>,

Infallible 16-bit read with compile-time bounds check.

Source

fn read32(self, offset: usize) -> u32
where usize: IoLoc<Self::Target, u32, IoType = u32>, Self::Backend: IoCapable<u32>,

Infallible 32-bit read with compile-time bounds check.

Source

fn read64(self, offset: usize) -> u64
where usize: IoLoc<Self::Target, u64, IoType = u64>, Self::Backend: IoCapable<u64>,

Infallible 64-bit read with compile-time bounds check.

Source

fn write8(self, value: u8, offset: usize)
where usize: IoLoc<Self::Target, u8, IoType = u8>, Self::Backend: IoCapable<u8>,

Infallible 8-bit write with compile-time bounds check.

Source

fn write16(self, value: u16, offset: usize)
where usize: IoLoc<Self::Target, u16, IoType = u16>, Self::Backend: IoCapable<u16>,

Infallible 16-bit write with compile-time bounds check.

Source

fn write32(self, value: u32, offset: usize)
where usize: IoLoc<Self::Target, u32, IoType = u32>, Self::Backend: IoCapable<u32>,

Infallible 32-bit write with compile-time bounds check.

Source

fn write64(self, value: u64, offset: usize)
where usize: IoLoc<Self::Target, u64, IoType = u64>, Self::Backend: IoCapable<u64>,

Infallible 64-bit write with compile-time bounds check.

Source

fn try_read<T, L>(self, location: L) -> Result<T>
where L: IoLoc<Self::Target, T>, Self::Backend: IoCapable<L::IoType>,

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(())
}
Source

fn try_write<T, L>(self, location: L, value: T) -> Result
where L: IoLoc<Self::Target, T>, Self::Backend: IoCapable<L::IoType>,

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(())
}
Source

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>,

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))
}
Source

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,

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
    })
}
Source

fn read<T, L>(self, location: L) -> T
where L: IoLoc<Self::Target, T>, Self::Backend: IoCapable<L::IoType>,

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);
}
Source

fn write<T, L>(self, location: L, value: T)
where L: IoLoc<Self::Target, T>, Self::Backend: IoCapable<L::IoType>,

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);
}
Source

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>,

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));
}
Source

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,

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".

Implementors§

Source§

impl<'a, T: IoBase<'a>> Io<'a> for T