regmap_support/
lib.rs

1//use mockall::predicate::*;
2//use mockall::*;
3//use modular_bitfield::prelude::*;
4use std::convert::TryInto;
5use std::result::Result;
6
7//#[automock]
8pub trait RegmapAccessor<T> {
9    type Error;
10
11    fn peek(&mut self, addr: T) -> Result<T, Self::Error>;
12    fn poke(&mut self, addr: T, data: T) -> Result<(), Self::Error>;
13}
14
15/*#[automock]
16pub trait RegmapAccessor64Bit {
17    type Error;
18
19    fn peek64(&mut self, addr: u64) -> u64;
20    fn poke64(&mut self, addr: u64, data: u64);
21}*/
22
23/*#[automock]
24pub trait RegmapAccessor<T: Copy> {
25    fn peek(&mut self, addr: T) -> T;
26    fn poke(&mut self, addr: T, data: T);
27}*/
28
29pub struct MemoryAccessor {
30    base: *mut u8,
31}
32
33impl MemoryAccessor {
34    pub fn new(base: usize) -> MemoryAccessor {
35        MemoryAccessor {
36            base: base as *mut u8,
37        }
38    }
39}
40
41impl RegmapAccessor<u32> for MemoryAccessor {
42    type Error = ();
43
44    fn peek(&mut self, addr: u32) -> Result<u32, Self::Error> {
45        unsafe {
46            let ptr = self.base.offset(
47                addr.try_into()
48                    .expect("Couldn't convert offset into isize in peek32"),
49            ) as *mut u32;
50            Ok(*ptr)
51        }
52    }
53
54    fn poke(&mut self, addr: u32, data: u32) -> Result<(), Self::Error> {
55        unsafe {
56            let ptr = self.base.offset(
57                addr.try_into()
58                    .expect("Couldn't convert offset into isize in poke32"),
59            ) as *mut u32;
60            *ptr = data;
61        }
62        Ok(())
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::{MemoryAccessor, RegmapAccessor32Bit};
69    use std::convert::TryInto;
70
71    #[test]
72    fn can_peek() {
73        let mut backing = vec![0u8; 1024];
74        backing[12] = 5;
75        let mut accessor = MemoryAccessor::new(backing.as_ptr() as usize);
76        assert_eq!(accessor.peek32(12), 5);
77    }
78
79    #[test]
80    fn can_poke() {
81        let backing = vec![0u8; 1024];
82        let mut accessor = MemoryAccessor::new(backing.as_ptr() as usize);
83        accessor.poke32(40, 0x12345678);
84        assert_eq!(backing[40 + 0], 0x78);
85        assert_eq!(backing[40 + 1], 0x56);
86        assert_eq!(backing[40 + 2], 0x34);
87        assert_eq!(backing[40 + 3], 0x12);
88    }
89}