1 use core::marker::PhantomData; 2 3 use super::io::Io; 4 5 /// Generic PIO 6 #[derive(Copy, Clone)] 7 pub struct Pio<T> { 8 port: u16, 9 value: PhantomData<T>, 10 } 11 12 impl<T> Pio<T> { 13 /// Create a PIO from a given port new(port: u16) -> Self14 pub const fn new(port: u16) -> Self { 15 Pio::<T> { 16 port: port, 17 value: PhantomData, 18 } 19 } 20 } 21 22 /// Read/Write for byte PIO 23 impl Io for Pio<u8> { 24 type Value = u8; 25 26 /// Read 27 #[inline(always)] read(&self) -> u828 fn read(&self) -> u8 { 29 let value: u8; 30 unsafe { 31 llvm_asm!("in $0, $1" : "={al}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile"); 32 } 33 value 34 } 35 36 /// Write 37 #[inline(always)] write(&mut self, value: u8)38 fn write(&mut self, value: u8) { 39 unsafe { 40 llvm_asm!("out $1, $0" : : "{al}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile"); 41 } 42 } 43 } 44 45 /// Read/Write for word PIO 46 impl Io for Pio<u16> { 47 type Value = u16; 48 49 /// Read 50 #[inline(always)] read(&self) -> u1651 fn read(&self) -> u16 { 52 let value: u16; 53 unsafe { 54 llvm_asm!("in $0, $1" : "={ax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile"); 55 } 56 value 57 } 58 59 /// Write 60 #[inline(always)] write(&mut self, value: u16)61 fn write(&mut self, value: u16) { 62 unsafe { 63 llvm_asm!("out $1, $0" : : "{ax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile"); 64 } 65 } 66 } 67 68 /// Read/Write for doubleword PIO 69 impl Io for Pio<u32> { 70 type Value = u32; 71 72 /// Read 73 #[inline(always)] read(&self) -> u3274 fn read(&self) -> u32 { 75 let value: u32; 76 unsafe { 77 llvm_asm!("in $0, $1" : "={eax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile"); 78 } 79 value 80 } 81 82 /// Write 83 #[inline(always)] write(&mut self, value: u32)84 fn write(&mut self, value: u32) { 85 unsafe { 86 llvm_asm!("out $1, $0" : : "{eax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile"); 87 } 88 } 89 } 90