Change IoPort to architecture-independent

This commit is contained in:
Yuke Peng 2025-03-30 15:52:21 +08:00 committed by Tate, Hongliang Tian
parent 85d4cdbbb0
commit f89b248f3b
9 changed files with 69 additions and 118 deletions

View File

@ -32,53 +32,3 @@ impl PortRead for u16 {}
impl PortWrite for u16 {}
impl PortRead for u32 {}
impl PortWrite for u32 {}
/// An I/O port, representing a specific address in the I/O address of x86.
///
/// The following code shows and example to read and write u32 value to an I/O port:
///
/// ```rust
/// static PORT: IoPort<u32, ReadWriteAccess> = unsafe { IoPort::new(0x12) };
///
/// fn port_value_increase(){
/// PORT.write(PORT.read() + 1)
/// }
/// ```
///
pub struct IoPort<T, A> {
port: u16,
value_marker: PhantomData<T>,
access_marker: PhantomData<A>,
}
impl<T, A> IoPort<T, A> {
/// Create an I/O port.
///
/// # Safety
///
/// This function is marked unsafe as creating an I/O port is considered
/// a privileged operation.
pub const unsafe fn new(port: u16) -> Self {
Self {
port,
value_marker: PhantomData,
access_marker: PhantomData,
}
}
}
impl<T: PortRead, A: IoPortReadAccess> IoPort<T, A> {
/// Reads from the I/O port
#[inline]
pub fn read(&self) -> T {
unsafe { PortRead::read_from_port(self.port) }
}
}
impl<T: PortWrite, A: IoPortWriteAccess> IoPort<T, A> {
/// Writes to the I/O port
#[inline]
pub fn write(&self, value: T) {
unsafe { PortWrite::write_to_port(self.port, value) }
}
}

View File

@ -12,8 +12,7 @@
use acpi::fadt::Fadt;
use x86_64::instructions::port::{ReadOnlyAccess, WriteOnlyAccess};
use super::io_port::IoPort;
use crate::arch::x86::kernel::acpi::get_acpi_tables;
use crate::{arch::x86::kernel::acpi::get_acpi_tables, io::IoPort};
/// CMOS address I/O port
pub static CMOS_ADDRESS: IoPort<u8, WriteOnlyAccess> = unsafe { IoPort::new(0x70) };

View File

@ -2,8 +2,6 @@
//! I/O port access.
use core::marker::PhantomData;
pub use x86_64::{
instructions::port::{
PortReadAccess as IoPortReadAccess, PortWriteAccess as IoPortWriteAccess, ReadOnlyAccess,
@ -11,53 +9,3 @@ pub use x86_64::{
},
structures::port::{PortRead, PortWrite},
};
/// An I/O port, representing a specific address in the I/O address of x86.
///
/// The following code shows and example to read and write u32 value to an I/O port:
///
/// ```rust
/// static PORT: IoPort<u32, ReadWriteAccess> = unsafe { IoPort::new(0x12) };
///
/// fn port_value_increase(){
/// PORT.write(PORT.read() + 1)
/// }
/// ```
///
pub struct IoPort<T, A> {
port: u16,
value_marker: PhantomData<T>,
access_marker: PhantomData<A>,
}
impl<T, A> IoPort<T, A> {
/// Creates an I/O port.
///
/// # Safety
///
/// This function is marked unsafe as creating an I/O port is considered
/// a privileged operation.
pub const unsafe fn new(port: u16) -> Self {
Self {
port,
value_marker: PhantomData,
access_marker: PhantomData,
}
}
}
impl<T: PortRead, A: IoPortReadAccess> IoPort<T, A> {
/// Reads from the I/O port
#[inline]
pub fn read(&self) -> T {
unsafe { PortRead::read_from_port(self.port) }
}
}
impl<T: PortWrite, A: IoPortWriteAccess> IoPort<T, A> {
/// Writes to the I/O port
#[inline]
pub fn write(&self, value: T) {
unsafe { PortWrite::write_to_port(self.port, value) }
}
}

View File

@ -4,8 +4,10 @@
#![expect(dead_code)]
use crate::arch::x86::device::io_port::{IoPort, ReadWriteAccess, WriteOnlyAccess};
use crate::{
arch::x86::device::io_port::{ReadWriteAccess, WriteOnlyAccess},
io::IoPort,
};
/// A serial port.
///
/// Serial ports are a legacy communications port common on IBM-PC compatible computers.

View File

@ -6,10 +6,7 @@ use core::sync::atomic::{AtomicBool, AtomicU8, Ordering::Relaxed};
use log::info;
use crate::{
arch::x86::device::io_port::{IoPort, WriteOnlyAccess},
trap::IrqLine,
};
use crate::{arch::x86::device::io_port::WriteOnlyAccess, io::IoPort, trap::IrqLine};
static MASTER_CMD: IoPort<u8, WriteOnlyAccess> = unsafe { IoPort::new(0x20) };
static MASTER_DATA: IoPort<u8, WriteOnlyAccess> = unsafe { IoPort::new(0x21) };

View File

@ -2,8 +2,8 @@
//! PCI bus access
use super::device::io_port::{IoPort, ReadWriteAccess, WriteOnlyAccess};
use crate::{bus::pci::PciDeviceLocation, prelude::*};
use super::device::io_port::{ReadWriteAccess, WriteOnlyAccess};
use crate::{bus::pci::PciDeviceLocation, io::IoPort, prelude::*};
static PCI_ADDRESS_PORT: IoPort<u32, WriteOnlyAccess> = unsafe { IoPort::new(0x0CF8) };
static PCI_DATA_PORT: IoPort<u32, ReadWriteAccess> = unsafe { IoPort::new(0x0CFC) };

View File

@ -10,11 +10,8 @@
//!
use crate::{
arch::{
kernel::IO_APIC,
timer::TIMER_FREQ,
x86::device::io_port::{IoPort, WriteOnlyAccess},
},
arch::{kernel::IO_APIC, timer::TIMER_FREQ, x86::device::io_port::WriteOnlyAccess},
io::IoPort,
trap::IrqLine,
};

View File

@ -0,0 +1,57 @@
// SPDX-License-Identifier: MPL-2.0
//! I/O port and its allocator that allocates port I/O (PIO) to device drivers.
use core::marker::PhantomData;
use crate::arch::device::io_port::{IoPortReadAccess, IoPortWriteAccess, PortRead, PortWrite};
/// An I/O port, representing a specific address in the I/O address of x86.
///
/// The following code shows and example to read and write u32 value to an I/O port:
///
/// ```rust
/// static PORT: IoPort<u32, ReadWriteAccess> = unsafe { IoPort::new(0x12) };
///
/// fn port_value_increase(){
/// PORT.write(PORT.read() + 1)
/// }
/// ```
///
pub struct IoPort<T, A> {
port: u16,
value_marker: PhantomData<T>,
access_marker: PhantomData<A>,
}
impl<T, A> IoPort<T, A> {
/// Create an I/O port.
///
/// # Safety
///
/// This function is marked unsafe as creating an I/O port is considered
/// a privileged operation.
pub const unsafe fn new(port: u16) -> Self {
Self {
port,
value_marker: PhantomData,
access_marker: PhantomData,
}
}
}
impl<T: PortRead, A: IoPortReadAccess> IoPort<T, A> {
/// Reads from the I/O port
#[inline]
pub fn read(&self) -> T {
unsafe { PortRead::read_from_port(self.port) }
}
}
impl<T: PortWrite, A: IoPortWriteAccess> IoPort<T, A> {
/// Writes to the I/O port
#[inline]
pub fn write(&self, value: T) {
unsafe { PortWrite::write_to_port(self.port, value) }
}
}

View File

@ -8,9 +8,10 @@
//! - `IoPort` for port I/O (PIO).
mod io_mem;
mod io_port;
pub use self::io_mem::IoMem;
pub(crate) use self::io_mem::IoMemAllocatorBuilder;
pub use self::{io_mem::IoMem, io_port::IoPort};
/// Initializes the static allocator based on builder.
///