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
use super::*;

/// Represents a simple MMIO address that can be written but not read.
///
/// Unlike with raw pointers, this type favors unsafe construction and then
/// assumes that all usage is safe once the value has been constructed.
#[repr(transparent)]
#[derive(Debug, Clone, Copy)]
pub struct WriteOnlyVolAddr<T> {
  addr: NonZeroUsize,
  _marker: PhantomData<T>,
}

impl<T> WriteOnlyVolAddr<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
  ///   [`write`](SimpleVolAddr::write) will UB).
  #[must_use]
  #[inline(always)]
  pub(crate) const unsafe fn new(addr: usize) -> Self {
    Self { addr: NonZeroUsize::new_unchecked(addr), _marker: PhantomData }
  }

  /// Writes a new value to the address.
  #[inline(always)]
  pub fn write(&self, t: T)
  where
    T: Copy,
  {
    unsafe { write_volatile(self.addr.get() as *mut T, t) }
  }
}