Skip to main content

Io

Trait Io 

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

Source

fn addr(&self) -> usize

Returns the base address of this mapping.

Source

fn maxsize(&self) -> usize

Returns the maximum size of this mapping.

Provided Methods§

Source

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>
where Self: IoCapable<u8>,

Fallible 8-bit read with runtime bounds check.

Source

fn try_read16(&self, offset: usize) -> Result<u16>
where Self: IoCapable<u16>,

Fallible 16-bit read with runtime bounds check.

Source

fn try_read32(&self, offset: usize) -> Result<u32>
where Self: IoCapable<u32>,

Fallible 32-bit read with runtime bounds check.

Source

fn try_read64(&self, offset: usize) -> Result<u64>
where Self: IoCapable<u64>,

Fallible 64-bit read with runtime bounds check.

Source

fn try_write8(&self, value: u8, offset: usize) -> Result
where Self: IoCapable<u8>,

Fallible 8-bit write with runtime bounds check.

Source

fn try_write16(&self, value: u16, offset: usize) -> Result
where Self: IoCapable<u16>,

Fallible 16-bit write with runtime bounds check.

Source

fn try_write32(&self, value: u32, offset: usize) -> Result
where Self: IoCapable<u32>,

Fallible 32-bit write with runtime bounds check.

Source

fn try_write64(&self, value: u64, offset: usize) -> Result
where Self: IoCapable<u64>,

Fallible 64-bit write with runtime bounds check.

Source

fn read8(&self, offset: usize) -> u8
where Self: IoKnownSize + IoCapable<u8>,

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

Source

fn read16(&self, offset: usize) -> u16
where Self: IoKnownSize + IoCapable<u16>,

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

Source

fn read32(&self, offset: usize) -> u32
where Self: IoKnownSize + IoCapable<u32>,

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

Source

fn read64(&self, offset: usize) -> u64
where Self: IoKnownSize + IoCapable<u64>,

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

Source

fn write8(&self, value: u8, offset: usize)
where Self: IoKnownSize + IoCapable<u8>,

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

Source

fn write16(&self, value: u16, offset: usize)
where Self: IoKnownSize + IoCapable<u16>,

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

Source

fn write32(&self, value: u32, offset: usize)
where Self: IoKnownSize + IoCapable<u32>,

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

Source

fn write64(&self, value: u64, offset: usize)
where Self: IoKnownSize + 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<T>, Self: 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,
};

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

fn try_write<T, L>(&self, location: L, value: T) -> Result
where L: IoLoc<T>, Self: 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,
};

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

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

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

fn try_update<T, L, F>(&self, location: L, f: F) -> Result
where L: IoLoc<T>, Self: 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,
};

fn do_update(io: &Mmio<0x1000>) -> Result {
    io.try_update(0x10, |v: u32| {
        v + 1
    })
}
Source

fn read<T, L>(&self, location: L) -> T
where L: IoLoc<T>, Self: IoKnownSize + 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,
};

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

fn write<T, L>(&self, location: L, value: T)
where L: IoLoc<T>, Self: IoKnownSize + 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,
};

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

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

fn update<T, L, F>(&self, location: L, f: F)
where L: IoLoc<T>, Self: IoKnownSize + IoCapable<L::IoType> + Sized, 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,
};

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.

Implementors§

Source§

impl<'a, S: ConfigSpaceKind> Io for ConfigSpace<'a, S>

Source§

impl<const SIZE: usize> Io for Mmio<SIZE>

Source§

impl<const SIZE: usize> Io for RelaxedMmio<SIZE>