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