diff --git a/kernel/comps/pci/src/arch/x86/mod.rs b/kernel/comps/pci/src/arch/x86/mod.rs index 4051b6ea8..3885bfbf7 100644 --- a/kernel/comps/pci/src/arch/x86/mod.rs +++ b/kernel/comps/pci/src/arch/x86/mod.rs @@ -2,23 +2,38 @@ //! PCI bus access -use super::device::io_port::{ReadWriteAccess, WriteOnlyAccess}; -use crate::{bus::pci::PciDeviceLocation, io::IoPort, prelude::*}; +use ostd::{ + arch::device::io_port::{ReadWriteAccess, WriteOnlyAccess}, + io::IoPort, + Error, +}; +use spin::Once; -static PCI_ADDRESS_PORT: IoPort = unsafe { IoPort::new(0x0CF8) }; -static PCI_DATA_PORT: IoPort = unsafe { IoPort::new(0x0CFC) }; +use crate::device_info::PciDeviceLocation; + +static PCI_ADDRESS_PORT: Once> = Once::new(); +static PCI_DATA_PORT: Once> = Once::new(); const BIT32_ALIGN_MASK: u32 = 0xFFFC; -pub(crate) fn write32(location: &PciDeviceLocation, offset: u32, value: u32) -> Result<()> { - PCI_ADDRESS_PORT.write(encode_as_port(location) | (offset & BIT32_ALIGN_MASK)); - PCI_DATA_PORT.write(value.to_le()); +pub(crate) fn write32(location: &PciDeviceLocation, offset: u32, value: u32) -> Result<(), Error> { + PCI_ADDRESS_PORT + .get() + .ok_or(Error::IoError)? + .write(encode_as_port(location) | (offset & BIT32_ALIGN_MASK)); + PCI_DATA_PORT + .get() + .ok_or(Error::IoError)? + .write(value.to_le()); Ok(()) } -pub(crate) fn read32(location: &PciDeviceLocation, offset: u32) -> Result { - PCI_ADDRESS_PORT.write(encode_as_port(location) | (offset & BIT32_ALIGN_MASK)); - Ok(PCI_DATA_PORT.read().to_le()) +pub(crate) fn read32(location: &PciDeviceLocation, offset: u32) -> Result { + PCI_ADDRESS_PORT + .get() + .ok_or(Error::IoError)? + .write(encode_as_port(location) | (offset & BIT32_ALIGN_MASK)); + Ok(PCI_DATA_PORT.get().ok_or(Error::IoError)?.read().to_le()) } /// Encodes the bus, device, and function into a port address for use with the PCI I/O port. @@ -30,14 +45,15 @@ fn encode_as_port(location: &PciDeviceLocation) -> u32 { | (((location.function as u32) & 0b111) << 8) } -pub fn init(){ - // Empty function, consistent with other architecture. -} - pub(crate) fn has_pci_bus() -> bool { true } +pub(crate) fn init() { + PCI_ADDRESS_PORT.call_once(|| IoPort::acquire(0xCF8).unwrap()); + PCI_DATA_PORT.call_once(|| IoPort::acquire(0xCFC).unwrap()); +} + pub(crate) const MSIX_DEFAULT_MSG_ADDR: u32 = 0xFEE0_0000; pub(crate) fn construct_remappable_msix_address(remapping_index: u32) -> u32 {