mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-19 12:36:46 +00:00
Change IoPort to architecture-independent
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
85d4cdbbb0
commit
f89b248f3b
@ -32,53 +32,3 @@ impl PortRead for u16 {}
|
|||||||
impl PortWrite for u16 {}
|
impl PortWrite for u16 {}
|
||||||
impl PortRead for u32 {}
|
impl PortRead for u32 {}
|
||||||
impl PortWrite 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) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -12,8 +12,7 @@
|
|||||||
use acpi::fadt::Fadt;
|
use acpi::fadt::Fadt;
|
||||||
use x86_64::instructions::port::{ReadOnlyAccess, WriteOnlyAccess};
|
use x86_64::instructions::port::{ReadOnlyAccess, WriteOnlyAccess};
|
||||||
|
|
||||||
use super::io_port::IoPort;
|
use crate::{arch::x86::kernel::acpi::get_acpi_tables, io::IoPort};
|
||||||
use crate::arch::x86::kernel::acpi::get_acpi_tables;
|
|
||||||
|
|
||||||
/// CMOS address I/O port
|
/// CMOS address I/O port
|
||||||
pub static CMOS_ADDRESS: IoPort<u8, WriteOnlyAccess> = unsafe { IoPort::new(0x70) };
|
pub static CMOS_ADDRESS: IoPort<u8, WriteOnlyAccess> = unsafe { IoPort::new(0x70) };
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
//! I/O port access.
|
//! I/O port access.
|
||||||
|
|
||||||
use core::marker::PhantomData;
|
|
||||||
|
|
||||||
pub use x86_64::{
|
pub use x86_64::{
|
||||||
instructions::port::{
|
instructions::port::{
|
||||||
PortReadAccess as IoPortReadAccess, PortWriteAccess as IoPortWriteAccess, ReadOnlyAccess,
|
PortReadAccess as IoPortReadAccess, PortWriteAccess as IoPortWriteAccess, ReadOnlyAccess,
|
||||||
@ -11,53 +9,3 @@ pub use x86_64::{
|
|||||||
},
|
},
|
||||||
structures::port::{PortRead, PortWrite},
|
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) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -4,8 +4,10 @@
|
|||||||
|
|
||||||
#![expect(dead_code)]
|
#![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.
|
/// A serial port.
|
||||||
///
|
///
|
||||||
/// Serial ports are a legacy communications port common on IBM-PC compatible computers.
|
/// Serial ports are a legacy communications port common on IBM-PC compatible computers.
|
||||||
|
@ -6,10 +6,7 @@ use core::sync::atomic::{AtomicBool, AtomicU8, Ordering::Relaxed};
|
|||||||
|
|
||||||
use log::info;
|
use log::info;
|
||||||
|
|
||||||
use crate::{
|
use crate::{arch::x86::device::io_port::WriteOnlyAccess, io::IoPort, trap::IrqLine};
|
||||||
arch::x86::device::io_port::{IoPort, WriteOnlyAccess},
|
|
||||||
trap::IrqLine,
|
|
||||||
};
|
|
||||||
|
|
||||||
static MASTER_CMD: IoPort<u8, WriteOnlyAccess> = unsafe { IoPort::new(0x20) };
|
static MASTER_CMD: IoPort<u8, WriteOnlyAccess> = unsafe { IoPort::new(0x20) };
|
||||||
static MASTER_DATA: IoPort<u8, WriteOnlyAccess> = unsafe { IoPort::new(0x21) };
|
static MASTER_DATA: IoPort<u8, WriteOnlyAccess> = unsafe { IoPort::new(0x21) };
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
//! PCI bus access
|
//! PCI bus access
|
||||||
|
|
||||||
use super::device::io_port::{IoPort, ReadWriteAccess, WriteOnlyAccess};
|
use super::device::io_port::{ReadWriteAccess, WriteOnlyAccess};
|
||||||
use crate::{bus::pci::PciDeviceLocation, prelude::*};
|
use crate::{bus::pci::PciDeviceLocation, io::IoPort, prelude::*};
|
||||||
|
|
||||||
static PCI_ADDRESS_PORT: IoPort<u32, WriteOnlyAccess> = unsafe { IoPort::new(0x0CF8) };
|
static PCI_ADDRESS_PORT: IoPort<u32, WriteOnlyAccess> = unsafe { IoPort::new(0x0CF8) };
|
||||||
static PCI_DATA_PORT: IoPort<u32, ReadWriteAccess> = unsafe { IoPort::new(0x0CFC) };
|
static PCI_DATA_PORT: IoPort<u32, ReadWriteAccess> = unsafe { IoPort::new(0x0CFC) };
|
||||||
|
@ -10,11 +10,8 @@
|
|||||||
//!
|
//!
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::{
|
arch::{kernel::IO_APIC, timer::TIMER_FREQ, x86::device::io_port::WriteOnlyAccess},
|
||||||
kernel::IO_APIC,
|
io::IoPort,
|
||||||
timer::TIMER_FREQ,
|
|
||||||
x86::device::io_port::{IoPort, WriteOnlyAccess},
|
|
||||||
},
|
|
||||||
trap::IrqLine,
|
trap::IrqLine,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
57
ostd/src/io/io_port/mod.rs
Normal file
57
ostd/src/io/io_port/mod.rs
Normal 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) }
|
||||||
|
}
|
||||||
|
}
|
@ -8,9 +8,10 @@
|
|||||||
//! - `IoPort` for port I/O (PIO).
|
//! - `IoPort` for port I/O (PIO).
|
||||||
|
|
||||||
mod io_mem;
|
mod io_mem;
|
||||||
|
mod io_port;
|
||||||
|
|
||||||
pub use self::io_mem::IoMem;
|
|
||||||
pub(crate) use self::io_mem::IoMemAllocatorBuilder;
|
pub(crate) use self::io_mem::IoMemAllocatorBuilder;
|
||||||
|
pub use self::{io_mem::IoMem, io_port::IoPort};
|
||||||
|
|
||||||
/// Initializes the static allocator based on builder.
|
/// Initializes the static allocator based on builder.
|
||||||
///
|
///
|
||||||
|
Reference in New Issue
Block a user