I'm trying to implement a trait to access CPU registers and get/set their distinct fields.
pub trait ReadWrite<T: Copy> {
// #[inline]
fn get(&self) -> T;
// #[inline]
fn set(&self, value: T);
#[inline]
fn get_field(&self, field_attr: (u8, u8)) -> T {
let mask = ((1 << field_attr.1) - 1) << field_attr.0;
(self.get() & mask) >> field_attr.0
}
}
And I define registers as
pub struct MpidrEl1;
pub mod mpidr_el1 {
pub enum Field {
Aff0,
Aff1,
Aff2,
MT,
U,
Aff3
}
}
impl ReadWrite<u64> for MpidrEl1 {
#[inline]
fn get(&self) -> u64 {
let r: u64;
unsafe {
asm!("mrs $0, mpidr_el1":"=r"(r):::"volatile")
}
r
}
#[inline]
fn set(&self, value: u64) {
unsafe {
asm!("msr mpidr_el1, $0"::"r"(value)::"volatile")
}
}
fn field_attr(field: mpidr_el1::Field) -> (u8, u8) {
match field {
mpidr_el1::Field::Aff0 => (0, 8),
mpidr_el1::Field::Aff1 => (8, 8),
mpidr_el1::Field::Aff2 => (16, 8),
mpidr_el1::Field::MT => (24, 1),
mpidr_el1::Field::U => (30, 1),
mpidr_el1::Field::Aff3 => (32, 8)
}
}
}
First, when I tried to complile I was getting an error:
|
33 | (self.get() & mask) >> field_attr.0
| ---------- ^ ---- {integer}
| |
| T
|
= note: `T` might need a bound for `std::ops::BitAnd`
Okay, I added
use core::ops::BitAnd;
pub trait ReadWrite<T: Copy + BitAnd> {
// . . .
}
This has caused the next errors:
error[E0308]: mismatched types
--> lib/register/src/cpu.rs:33:23
|
33 | (self.get() & mask) >> field_attr.0
| ^^^^ expected type parameter, found integer
|
= note: expected type `T`
found type `{integer}`
= help: type parameters must be constrained to match other types
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
error[E0369]: binary operation `>>` cannot be applied to type `<T as core::ops::BitAnd>::Output`
--> lib/register/src/cpu.rs:33:29
|
33 | (self.get() & mask) >> field_attr.0
| ------------------- ^^ ------------ u8
| |
| <T as core::ops::BitAnd>::Output
|
= note: an implementation of `std::ops::Shr` might be missing for `<T as core::ops::BitAnd>::Output`
Adding core::ops::{Shl, Shr}
didn't help. Error says:
binary operation `>>` cannot be applied to type `<T as core::ops::BitAnd>::Output`
Well, I don't understand where it takes me and how to resolve it. I tought integer types implement all that bitwise operations by default. But I guess the problem is that T
generic is not treated as integer only type. Could you please explain why it doesn't work and the proper way of doing such things?
Thanks in advance!