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