Created
March 19, 2019 05:12
-
-
Save RKennedy9064/3446beb0057b4f5f271b3606f5c6ddc6 to your computer and use it in GitHub Desktop.
A basic implementation of moving separating PortReadWrite into 2 traits and making PortReadWrite a combination of those traits.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use core::marker::PhantomData; | |
pub use crate::structures::port::{PortRead, PortWrite, PortReadWrite}; | |
impl PortRead for u8 { | |
#[inline] | |
unsafe fn read_from_port(port: u16) -> u8 { | |
let value: u8; | |
asm!("inb %dx, %al" : "={al}"(value) : "{dx}"(port) :: "volatile"); | |
value | |
} | |
} | |
impl PortRead for u16 { | |
#[inline] | |
unsafe fn read_from_port(port: u16) -> u16 { | |
let value: u16; | |
asm!("inw %dx, %ax" : "={ax}"(value) : "{dx}"(port) :: "volatile"); | |
value | |
} | |
} | |
impl PortRead for u32 { | |
#[inline] | |
unsafe fn read_from_port(port: u16) -> u32 { | |
let value: u32; | |
asm!("inl %dx, %eax" : "={eax}"(value) : "{dx}"(port) :: "volatile"); | |
value | |
} | |
} | |
impl PortWrite for u8 { | |
#[inline] | |
unsafe fn write_to_port(port: u16, value: u8) { | |
asm!("outb %al, %dx" :: "{dx}"(port), "{al}"(value) :: "volatile"); | |
} | |
} | |
impl PortWrite for u16 { | |
#[inline] | |
unsafe fn write_to_port(port: u16, value: u16) { | |
asm!("outw %ax, %dx" :: "{dx}"(port), "{ax}"(value) :: "volatile"); | |
} | |
} | |
impl PortWrite for u32 { | |
#[inline] | |
unsafe fn write_to_port(port: u16, value: u32) { | |
asm!("outl %eax, %dx" :: "{dx}"(port), "{eax}"(value) :: "volatile"); | |
} | |
} | |
impl PortReadWrite for u8 {} | |
impl PortReadWrite for u16 {} | |
impl PortReadWrite for u32 {} | |
#[derive(Debug, Clone, PartialEq, Eq)] | |
pub struct ReadonlyPort<T: PortRead> { | |
port: u16, | |
phantom: PhantomData<T>, | |
} | |
impl<T: PortRead> ReadonlyPort<T> { | |
/// Creates a readonly I/O port with the given port number. | |
pub const fn new(port: u16) -> ReadonlyPort<T> { | |
ReadonlyPort { | |
port: port, | |
phantom: PhantomData, | |
} | |
} | |
#[inline] | |
pub unsafe fn read(&self) -> T { | |
T::read_from_port(self.port) | |
} | |
} | |
#[derive(Debug, Clone, PartialEq, Eq)] | |
pub struct WriteOnlyPort<T: PortWrite> { | |
port: u16, | |
phantom: PhantomData<T>, | |
} | |
impl<T: PortWrite> WriteOnlyPort<T> { | |
/// Creates a write only I/O port with the given port number. | |
pub const fn new(port: u16) -> WriteOnlyPort<T> { | |
WriteOnlyPort { | |
port: port, | |
phantom: PhantomData, | |
} | |
} | |
#[inline] | |
pub unsafe fn write(&mut self, value: T) { | |
T::write_to_port(self.port, value) | |
} | |
} | |
#[derive(Debug, Clone, PartialEq, Eq)] | |
pub struct Port<T: PortReadWrite> { | |
port: u16, | |
phantom: PhantomData<T>, | |
} | |
impl<T: PortReadWrite> Port<T> { | |
/// Creates a read/write I/O port with the given port number. | |
pub const fn new(port: u16) -> Port<T> { | |
Port { | |
port: port, | |
phantom: PhantomData, | |
} | |
} | |
#[inline] | |
pub unsafe fn read(&self) -> T { | |
T::read_from_port(self.port) | |
} | |
#[inline] | |
pub unsafe fn write(&mut self, value: T) { | |
T::write_to_port(self.port, value) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pub trait PortRead { | |
unsafe fn read_from_port(port: u16) -> Self; | |
} | |
pub trait PortWrite { | |
unsafe fn write_to_port(port: u16, value: Self); | |
} | |
pub trait PortReadWrite: PortRead + PortWrite {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct GeneralRegisters { | |
input_status_0: ReadonlyPort<u8>, | |
input_status_1_mono: ReadonlyPort<u8>, | |
input_status_1_color: ReadonlyPort<u8>, | |
feature_control_read: ReadonlyPort<u8>, | |
feature_control_mono_write: WriteOnlyPort<u8>, | |
feature_control_color_write: WriteOnlyPort<u8>, | |
miscellaneous_output_read: ReadonlyPort<u8>, | |
miscellaneous_output_write: WriteOnlyPort<u8>, | |
test_port: Port<u8>, | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment