Crate rumio[−][src]
rumio
Control your MMIO and CPU registers without pain.
Documentation | Crate | Examples
This crate provides various macros to generate a nice API for MMIO blocks
and CPU registers. It's mainly meant as a replacement for the register
crate
to provide a better API and make the work easier.
Usage
For more updated and larger examples take a look at the tests.
Defining CPU registers
The CPU registers are only useful for control registers which store their data using bitfields. For example the Control-Status-Register of the RISC-V architecture.
#![feature(asm)] mod mstatus { use rumio::cpu::{RegisterRead, RegisterWrite}; // first we need to define a register, and a way to read/write to it. // we will use the `mstatus` CSR from the RISC-V architecture as an example struct Mstatus; // the `usize` argument indicates the underyling value of the register. impl RegisterRead<usize> for Mstatus { #[inline] fn read() -> usize { let val; unsafe { asm!("csrr {}, mstatus", out(reg) val) } val } } impl RegisterWrite<usize> for Mstatus { #[inline] fn write(val: usize) { unsafe { asm!("csrw mstatus, {}", in(reg) val) } } #[inline] fn set(mask: usize) { // `impl_cpu_set` and `impl_cpu_clear` can generated `set` and `clear` // by performing a read, setting the bits and then write the value again. rumio::impl_cpu_set!(Self, mask); } #[inline] fn clear(mask: usize) { rumio::impl_cpu_clear!(Self, mask); } } // now define the different bits and fields of this register rumio::define_cpu_register! { Mstatus as usize => /// Globally enables interrupts in U-Mode. rw UIE: 0, /// Globally enables interrupts in S-Mode. rw SIE: 1, /// Globally enables interrupts in M-Mode. rw MIE: 3, /// The privilege mode a trap in M-Mode was taken from. r MPP: 11..12 = enum PrivilegeMode [ User = 0b00, Supervisor = 0b01, Machine = 0b11, ], /// This is not an actual flag of the `mstatus` register, but /// we add it here for showing the usage of `flags` rw FLAGS: 13..16 = flags CpuFlags [ A = 0b0001, B = 0b0010, C = 0b0100, D = 0b1000, ], } } // the generated api then can be used like this. // to explore the full api generated by this macro, check the `example_generated` // module on docs.rs, and check the examples (the tests are the examples) mstatus::modify(mstatus::UIE::SET | mstatus::SIE::SET | mstatus::MIE::SET); println!("Trap was taken from {:?}", mstatus::MPP::get());
Defining MMIO registers
// define one MMIO register whose base type is `u16` and name is `Reg`. rumio::define_mmio_register! { Reg: u16 { rw MODE: 0..1 = enum Mode [ A = 0b00, B = 0b01, C = 0b10, D = 0b11, ], r FOO: 2, rw BAR: 3, rw BAZ: 4, rw FLAGS: 5..8 = flags Flags [ A = 0b0001, B = 0b0010, C = 0b0100, D = 0b1000, ], } } rumio::define_mmio_struct! { pub struct Device { 0x00 => one: Reg, 0x08 => two: Reg, } } // create a new `Device` at address `0xF00D_BABE let mmio = unsafe { Device::new(0xF00D_BABE) }; // access the `one` register let one = mmio.one(); // now `one` can be used similarly to the cpu register one.MODE().set(Mode::B); one.FLAGS().set(Flags::B | Flags::C); one.modify(Mode::A | BAR::SET);
License
Licensed under either Apache License or the MIT license.
Modules
cpu | Traits for accessing CPU registers. |
example_generated | This module shows examples of the generated code by the macros. |
mmio | Abstractions for MMIO regions. |
perm | Marker trait and structs for providing type-safe permissions. |
Macros
define_cpu_register | Define abstractions for a CPU register. |
define_mmio_register | Define abstractions for a single register inside an MMIO block. |
define_mmio_struct | Creates a struct which represents the MMIO block and all their registers. |
impl_cpu_clear | Provide a simple implementation for the |
impl_cpu_set | Provide a simple implementation for the |
Structs
Field | Specifies a specific bit mask inside a register. |
Value | A value that can be applied to any register using
the |
Traits
Int | Represents any type that can be used as the underlying value for a register or bitfield. |
Functions
get_bits | Obtain the bits that are in the inclusive range of |
set_bits | Sets the range (inclusive) of bits, given by the |