1 use core::ptr::{read_volatile, write_volatile};
2 use core::mem::MaybeUninit;
3 use core::ops::{BitAnd, BitOr, Not};
4 
5 use super::io::Io;
6 
7 #[repr(packed)]
8 pub struct Mmio<T> {
9     value: MaybeUninit<T>,
10 }
11 
12 impl<T> Mmio<T> {
13     /// Create a new Mmio without initializing
14     #[deprecated = "unsound because it's possible to read even though it's uninitialized"]
new() -> Self15     pub fn new() -> Self {
16         unsafe { Self::uninit() }
17     }
zeroed() -> Self18     pub unsafe fn zeroed() -> Self {
19         Self {
20             value: MaybeUninit::zeroed(),
21         }
22     }
uninit() -> Self23     pub unsafe fn uninit() -> Self {
24         Self {
25             value: MaybeUninit::uninit(),
26         }
27     }
from(value: T) -> Self28     pub const fn from(value: T) -> Self {
29         Self {
30             value: MaybeUninit::new(value),
31         }
32     }
33 }
34 
35 impl<T> Io for Mmio<T> where T: Copy + PartialEq + BitAnd<Output = T> + BitOr<Output = T> + Not<Output = T> {
36     type Value = T;
37 
read(&self) -> T38     fn read(&self) -> T {
39         unsafe { read_volatile(self.value.as_ptr()) }
40     }
41 
write(&mut self, value: T)42     fn write(&mut self, value: T) {
43         unsafe { write_volatile(self.value.as_mut_ptr(), value) };
44     }
45 }
46