1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
use super::*; /// Represents an MMIO address that can be safely read, but not written. /// /// Unlike with raw pointers, this type favors unsafe construction and then /// assumes that all usage is safe once the value has been constructed. /// /// The convention is that reading the address will have no side effects. /// However, the register can be changed by non-CPU parts of the hardware, and /// so each time you perform a read the value might have changed. /// /// For addresses where reads have a side effect, other types are used. #[repr(transparent)] #[derive(Debug, Clone, Copy)] pub struct ReadOnlyVolAddr<T> { addr: NonZeroUsize, _marker: PhantomData<T>, } impl<T> ReadOnlyVolAddr<T> { /// Constructs a new address. /// /// ## Safety /// The input must /// * Not be 0 (or _instant_ UB). /// * Be an actual MMIO location for the data type specified (or /// [`read`](RwVolAddr::read) will UB). #[must_use] #[inline(always)] pub(crate) const unsafe fn new(addr: usize) -> Self { Self { addr: NonZeroUsize::new_unchecked(addr), _marker: PhantomData } } /// Reads the current value at the address. #[must_use] #[inline(always)] pub fn read(&self) -> T where T: Copy, { unsafe { read_volatile(self.addr.get() as *const T) } } }