From 1b6a04ca5504955c571d1c97504fb45ea0befee4 Mon Sep 17 00:00:00 2001 From: Valentin Popov Date: Mon, 8 Jan 2024 01:21:28 +0400 Subject: Initial vendor packages Signed-off-by: Valentin Popov --- vendor/redox_syscall/src/io/mmio.rs | 168 ++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 vendor/redox_syscall/src/io/mmio.rs (limited to 'vendor/redox_syscall/src/io/mmio.rs') diff --git a/vendor/redox_syscall/src/io/mmio.rs b/vendor/redox_syscall/src/io/mmio.rs new file mode 100644 index 0000000..ef8f603 --- /dev/null +++ b/vendor/redox_syscall/src/io/mmio.rs @@ -0,0 +1,168 @@ +use core::mem::MaybeUninit; +use core::ptr; +#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] +use core::ops::{BitAnd, BitOr, Not}; + +use super::io::Io; + +#[repr(packed)] +pub struct Mmio { + value: MaybeUninit, +} + +impl Mmio { + /// Create a new Mmio without initializing + #[deprecated = "unsound because it's possible to read even though it's uninitialized"] + pub fn new() -> Self { + unsafe { Self::uninit() } + } + pub unsafe fn zeroed() -> Self { + Self { + value: MaybeUninit::zeroed(), + } + } + pub unsafe fn uninit() -> Self { + Self { + value: MaybeUninit::uninit(), + } + } + pub const fn from(value: T) -> Self { + Self { + value: MaybeUninit::new(value), + } + } +} + +// Generic implementation (WARNING: requires aligned pointers!) +#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] +impl Io for Mmio where T: Copy + PartialEq + BitAnd + BitOr + Not { + type Value = T; + + fn read(&self) -> T { + unsafe { ptr::read_volatile(ptr::addr_of!(self.value).cast::()) } + } + + fn write(&mut self, value: T) { + unsafe { ptr::write_volatile(ptr::addr_of_mut!(self.value).cast::(), value) }; + } +} + +// x86 u8 implementation +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +impl Io for Mmio { + type Value = u8; + + fn read(&self) -> Self::Value { + unsafe { + let value: Self::Value; + let ptr: *const Self::Value = ptr::addr_of!(self.value).cast::(); + core::arch::asm!( + "mov {}, [{}]", + out(reg_byte) value, + in(reg) ptr + ); + value + } + } + + fn write(&mut self, value: Self::Value) { + unsafe { + let ptr: *mut Self::Value = ptr::addr_of_mut!(self.value).cast::(); + core::arch::asm!( + "mov [{}], {}", + in(reg) ptr, + in(reg_byte) value, + ); + } + } +} + +// x86 u16 implementation +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +impl Io for Mmio { + type Value = u16; + + fn read(&self) -> Self::Value { + unsafe { + let value: Self::Value; + let ptr: *const Self::Value = ptr::addr_of!(self.value).cast::(); + core::arch::asm!( + "mov {:x}, [{}]", + out(reg) value, + in(reg) ptr + ); + value + } + } + + fn write(&mut self, value: Self::Value) { + unsafe { + let ptr: *mut Self::Value = ptr::addr_of_mut!(self.value).cast::(); + core::arch::asm!( + "mov [{}], {:x}", + in(reg) ptr, + in(reg) value, + ); + } + } +} + +// x86 u32 implementation +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +impl Io for Mmio { + type Value = u32; + + fn read(&self) -> Self::Value { + unsafe { + let value: Self::Value; + let ptr: *const Self::Value = ptr::addr_of!(self.value).cast::(); + core::arch::asm!( + "mov {:e}, [{}]", + out(reg) value, + in(reg) ptr + ); + value + } + } + + fn write(&mut self, value: Self::Value) { + unsafe { + let ptr: *mut Self::Value = ptr::addr_of_mut!(self.value).cast::(); + core::arch::asm!( + "mov [{}], {:e}", + in(reg) ptr, + in(reg) value, + ); + } + } +} + +// x86 u64 implementation (x86_64 only) +#[cfg(target_arch = "x86_64")] +impl Io for Mmio { + type Value = u64; + + fn read(&self) -> Self::Value { + unsafe { + let value: Self::Value; + let ptr: *const Self::Value = ptr::addr_of!(self.value).cast::(); + core::arch::asm!( + "mov {:r}, [{}]", + out(reg) value, + in(reg) ptr + ); + value + } + } + + fn write(&mut self, value: Self::Value) { + unsafe { + let ptr: *mut Self::Value = ptr::addr_of_mut!(self.value).cast::(); + core::arch::asm!( + "mov [{}], {:r}", + in(reg) ptr, + in(reg) value, + ); + } + } +} -- cgit v1.2.3