2016-08-14 17:31:35 +02:00
|
|
|
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
|
2016-08-18 00:26:43 +02:00
|
|
|
pub const fn new(port: u16) -> Self {
|
2016-08-14 17:31:35 +02:00
|
|
|
Pio::<T> {
|
|
|
|
port: port,
|
|
|
|
value: PhantomData,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Read/Write for byte PIO
|
|
|
|
impl Io for Pio<u8> {
|
|
|
|
type Value = u8;
|
|
|
|
|
|
|
|
/// Read
|
2016-09-01 01:45:21 +02:00
|
|
|
#[inline(always)]
|
2016-08-14 17:31:35 +02:00
|
|
|
fn read(&self) -> u8 {
|
2016-09-20 01:19:49 +02:00
|
|
|
let value: u8;
|
|
|
|
unsafe {
|
|
|
|
asm!("in $0, $1" : "={al}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile");
|
|
|
|
}
|
|
|
|
value
|
2016-08-14 17:31:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Write
|
2016-09-01 01:45:21 +02:00
|
|
|
#[inline(always)]
|
2016-08-14 17:31:35 +02:00
|
|
|
fn write(&mut self, value: u8) {
|
2016-09-20 01:19:49 +02:00
|
|
|
unsafe {
|
|
|
|
asm!("out $1, $0" : : "{al}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile");
|
|
|
|
}
|
2016-08-14 17:31:35 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Read/Write for word PIO
|
|
|
|
impl Io for Pio<u16> {
|
|
|
|
type Value = u16;
|
|
|
|
|
|
|
|
/// Read
|
2016-09-01 01:45:21 +02:00
|
|
|
#[inline(always)]
|
2016-08-14 17:31:35 +02:00
|
|
|
fn read(&self) -> u16 {
|
2016-09-20 01:19:49 +02:00
|
|
|
let value: u16;
|
|
|
|
unsafe {
|
|
|
|
asm!("in $0, $1" : "={ax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile");
|
|
|
|
}
|
|
|
|
value
|
2016-08-14 17:31:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Write
|
2016-09-01 01:45:21 +02:00
|
|
|
#[inline(always)]
|
2016-08-14 17:31:35 +02:00
|
|
|
fn write(&mut self, value: u16) {
|
2016-09-20 01:19:49 +02:00
|
|
|
unsafe {
|
|
|
|
asm!("out $1, $0" : : "{ax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile");
|
|
|
|
}
|
2016-08-14 17:31:35 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Read/Write for doubleword PIO
|
|
|
|
impl Io for Pio<u32> {
|
|
|
|
type Value = u32;
|
|
|
|
|
|
|
|
/// Read
|
2016-09-01 01:45:21 +02:00
|
|
|
#[inline(always)]
|
2016-08-14 17:31:35 +02:00
|
|
|
fn read(&self) -> u32 {
|
2016-09-20 01:19:49 +02:00
|
|
|
let value: u32;
|
|
|
|
unsafe {
|
|
|
|
asm!("in $0, $1" : "={eax}"(value) : "{dx}"(self.port) : "memory" : "intel", "volatile");
|
|
|
|
}
|
|
|
|
value
|
2016-08-14 17:31:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Write
|
2016-09-01 01:45:21 +02:00
|
|
|
#[inline(always)]
|
2016-08-14 17:31:35 +02:00
|
|
|
fn write(&mut self, value: u32) {
|
2016-09-20 01:19:49 +02:00
|
|
|
unsafe {
|
|
|
|
asm!("out $1, $0" : : "{eax}"(value), "{dx}"(self.port) : "memory" : "intel", "volatile");
|
|
|
|
}
|
2016-08-14 17:31:35 +02:00
|
|
|
}
|
|
|
|
}
|