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