syscall/io/
pio.rs

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