summaryrefslogtreecommitdiffstats
path: root/third_party/rust/redox_syscall/src/io
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/redox_syscall/src/io')
-rw-r--r--third_party/rust/redox_syscall/src/io/dma.rs76
-rw-r--r--third_party/rust/redox_syscall/src/io/io.rs67
-rw-r--r--third_party/rust/redox_syscall/src/io/mmio.rs31
-rw-r--r--third_party/rust/redox_syscall/src/io/mod.rs11
-rw-r--r--third_party/rust/redox_syscall/src/io/pio.rs89
5 files changed, 274 insertions, 0 deletions
diff --git a/third_party/rust/redox_syscall/src/io/dma.rs b/third_party/rust/redox_syscall/src/io/dma.rs
new file mode 100644
index 0000000000..d5334b843f
--- /dev/null
+++ b/third_party/rust/redox_syscall/src/io/dma.rs
@@ -0,0 +1,76 @@
+use core::{mem, ptr};
+use core::ops::{Deref, DerefMut};
+
+use Result;
+
+struct PhysBox {
+ address: usize,
+ size: usize
+}
+
+impl PhysBox {
+ fn new(size: usize) -> Result<PhysBox> {
+ let address = unsafe { ::physalloc(size)? };
+ Ok(PhysBox {
+ address: address,
+ size: size
+ })
+ }
+}
+
+impl Drop for PhysBox {
+ fn drop(&mut self) {
+ let _ = unsafe { ::physfree(self.address, self.size) };
+ }
+}
+
+pub struct Dma<T> {
+ phys: PhysBox,
+ virt: *mut T
+}
+
+impl<T> Dma<T> {
+ pub fn new(value: T) -> Result<Dma<T>> {
+ let phys = PhysBox::new(mem::size_of::<T>())?;
+ let virt = unsafe { ::physmap(phys.address, phys.size, ::PHYSMAP_WRITE)? } as *mut T;
+ unsafe { ptr::write(virt, value); }
+ Ok(Dma {
+ phys: phys,
+ virt: virt
+ })
+ }
+
+ pub fn zeroed() -> Result<Dma<T>> {
+ let phys = PhysBox::new(mem::size_of::<T>())?;
+ let virt = unsafe { ::physmap(phys.address, phys.size, ::PHYSMAP_WRITE)? } as *mut T;
+ unsafe { ptr::write_bytes(virt as *mut u8, 0, phys.size); }
+ Ok(Dma {
+ phys: phys,
+ virt: virt
+ })
+ }
+
+ pub fn physical(&self) -> usize {
+ self.phys.address
+ }
+}
+
+impl<T> Deref for Dma<T> {
+ type Target = T;
+ fn deref(&self) -> &T {
+ unsafe { &*self.virt }
+ }
+}
+
+impl<T> DerefMut for Dma<T> {
+ fn deref_mut(&mut self) -> &mut T {
+ unsafe { &mut *self.virt }
+ }
+}
+
+impl<T> Drop for Dma<T> {
+ fn drop(&mut self) {
+ unsafe { drop(ptr::read(self.virt)); }
+ let _ = unsafe { ::physunmap(self.virt as usize) };
+ }
+}
diff --git a/third_party/rust/redox_syscall/src/io/io.rs b/third_party/rust/redox_syscall/src/io/io.rs
new file mode 100644
index 0000000000..fb866b581b
--- /dev/null
+++ b/third_party/rust/redox_syscall/src/io/io.rs
@@ -0,0 +1,67 @@
+use core::cmp::PartialEq;
+use core::ops::{BitAnd, BitOr, Not};
+
+pub trait Io {
+ type Value: Copy + PartialEq + BitAnd<Output = Self::Value> + BitOr<Output = Self::Value> + Not<Output = Self::Value>;
+
+ fn read(&self) -> Self::Value;
+ fn write(&mut self, value: Self::Value);
+
+ #[inline(always)]
+ fn readf(&self, flags: Self::Value) -> bool {
+ (self.read() & flags) as Self::Value == flags
+ }
+
+ #[inline(always)]
+ fn writef(&mut self, flags: Self::Value, value: bool) {
+ let tmp: Self::Value = match value {
+ true => self.read() | flags,
+ false => self.read() & !flags,
+ };
+ self.write(tmp);
+ }
+}
+
+pub struct ReadOnly<I: Io> {
+ inner: I
+}
+
+impl<I: Io> ReadOnly<I> {
+ pub const fn new(inner: I) -> ReadOnly<I> {
+ ReadOnly {
+ inner: inner
+ }
+ }
+
+ #[inline(always)]
+ pub fn read(&self) -> I::Value {
+ self.inner.read()
+ }
+
+ #[inline(always)]
+ pub fn readf(&self, flags: I::Value) -> bool {
+ self.inner.readf(flags)
+ }
+}
+
+pub struct WriteOnly<I: Io> {
+ inner: I
+}
+
+impl<I: Io> WriteOnly<I> {
+ pub const fn new(inner: I) -> WriteOnly<I> {
+ WriteOnly {
+ inner: inner
+ }
+ }
+
+ #[inline(always)]
+ pub fn write(&mut self, value: I::Value) {
+ self.inner.write(value)
+ }
+
+ #[inline(always)]
+ pub fn writef(&mut self, flags: I::Value, value: bool) {
+ self.inner.writef(flags, value)
+ }
+}
diff --git a/third_party/rust/redox_syscall/src/io/mmio.rs b/third_party/rust/redox_syscall/src/io/mmio.rs
new file mode 100644
index 0000000000..b8e7727d3c
--- /dev/null
+++ b/third_party/rust/redox_syscall/src/io/mmio.rs
@@ -0,0 +1,31 @@
+use core::ptr::{read_volatile, write_volatile};
+use core::mem::uninitialized;
+use core::ops::{BitAnd, BitOr, Not};
+
+use super::io::Io;
+
+#[repr(packed)]
+pub struct Mmio<T> {
+ value: T,
+}
+
+impl<T> Mmio<T> {
+ /// Create a new Mmio without initializing
+ pub fn new() -> Self {
+ Mmio {
+ value: unsafe { uninitialized() }
+ }
+ }
+}
+
+impl<T> Io for Mmio<T> where T: Copy + PartialEq + BitAnd<Output = T> + BitOr<Output = T> + Not<Output = T> {
+ type Value = T;
+
+ fn read(&self) -> T {
+ unsafe { read_volatile(&self.value) }
+ }
+
+ fn write(&mut self, value: T) {
+ unsafe { write_volatile(&mut self.value, value) };
+ }
+}
diff --git a/third_party/rust/redox_syscall/src/io/mod.rs b/third_party/rust/redox_syscall/src/io/mod.rs
new file mode 100644
index 0000000000..a35456e30a
--- /dev/null
+++ b/third_party/rust/redox_syscall/src/io/mod.rs
@@ -0,0 +1,11 @@
+//! I/O functions
+
+pub use self::dma::*;
+pub use self::io::*;
+pub use self::mmio::*;
+pub use self::pio::*;
+
+mod dma;
+mod io;
+mod mmio;
+mod pio;
diff --git a/third_party/rust/redox_syscall/src/io/pio.rs b/third_party/rust/redox_syscall/src/io/pio.rs
new file mode 100644
index 0000000000..91ae310b62
--- /dev/null
+++ b/third_party/rust/redox_syscall/src/io/pio.rs
@@ -0,0 +1,89 @@
+use core::marker::PhantomData;
+
+use super::io::Io;
+
+/// Generic PIO
+#[derive(Copy, Clone)]
+pub struct Pio<T> {
+ port: u16,
+ value: PhantomData<T>,
+}
+
+impl<T> Pio<T> {
+ /// Create a PIO from a given port
+ pub const fn new(port: u16) -> Self {
+ Pio::<T> {
+ port: port,
+ value: PhantomData,
+ }
+ }
+}
+
+/// Read/Write for byte PIO
+impl Io for Pio<u8> {
+ type Value = u8;
+
+ /// Read
+ #[inline(always)]
+ fn read(&self) -> u8 {
+ let value: u8;
+ unsafe {
+ asm!("in $0, $1" : "={al}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile");
+ }
+ value
+ }
+
+ /// Write
+ #[inline(always)]
+ fn write(&mut self, value: u8) {
+ unsafe {
+ asm!("out $1, $0" : : "{al}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile");
+ }
+ }
+}
+
+/// Read/Write for word PIO
+impl Io for Pio<u16> {
+ type Value = u16;
+
+ /// Read
+ #[inline(always)]
+ fn read(&self) -> u16 {
+ let value: u16;
+ unsafe {
+ asm!("in $0, $1" : "={ax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile");
+ }
+ value
+ }
+
+ /// Write
+ #[inline(always)]
+ fn write(&mut self, value: u16) {
+ unsafe {
+ asm!("out $1, $0" : : "{ax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile");
+ }
+ }
+}
+
+/// Read/Write for doubleword PIO
+impl Io for Pio<u32> {
+ type Value = u32;
+
+ /// Read
+ #[inline(always)]
+ fn read(&self) -> u32 {
+ let value: u32;
+ unsafe {
+ asm!("in $0, $1" : "={eax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile");
+ }
+ value
+ }
+
+ /// Write
+ #[inline(always)]
+ fn write(&mut self, value: u32) {
+ unsafe {
+ asm!("out $1, $0" : : "{eax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile");
+ }
+ }
+}