Browse Source

pci: 添加pci root manager来管理pci root,并使得riscv能够正常扫描pci设备. (#745)

* pci: 添加pci root manager来管理pci root.
pci: 使得riscv能够正常扫描pci设备.

* doc: 添加注释
LoGin 10 months ago
parent
commit
370472f728

+ 1 - 5
kernel/src/arch/mod.rs

@@ -1,5 +1,5 @@
 use crate::{
-    driver::pci::pci::{BusDeviceFunction, PciAddr, PciError, PciRoot, SegmentGroupNumber},
+    driver::pci::pci::{BusDeviceFunction, PciAddr},
     mm::PhysAddr,
 };
 
@@ -31,8 +31,4 @@ pub trait TraitPciArch {
     /// @param address PCI域地址
     /// @return usize 转换结果
     fn address_pci_to_physical(pci_address: PciAddr) -> PhysAddr;
-    /// @brief 获取Segement的root地址,x86_64架构为acpi mcfg表中读取
-    /// @param segement 组id
-    /// @return  Result<PciRoot, PciError> 转换结果或出错原因
-    fn ecam_root(segement: SegmentGroupNumber) -> Result<PciRoot, PciError>;
 }

+ 24 - 5
kernel/src/arch/riscv64/pci/mod.rs

@@ -1,8 +1,21 @@
+use system_error::SystemError;
+use unified_init::macros::unified_init;
+
 use crate::{
     arch::TraitPciArch,
-    driver::pci::pci::{BusDeviceFunction, PciAddr, PciError, PciRoot, SegmentGroupNumber},
+    driver::{
+        open_firmware::fdt::open_firmware_fdt_driver,
+        pci::pci::{pci_init, BusDeviceFunction, PciAddr, PciError, SegmentGroupNumber},
+    },
+    init::{boot_params, initcall::INITCALL_SUBSYS},
+    kwarn,
+    mm::PhysAddr,
 };
 
+use self::pci_host_ecam::pci_host_ecam_driver_init;
+
+mod pci_host_ecam;
+
 pub struct RiscV64PciArch;
 impl TraitPciArch for RiscV64PciArch {
     fn read_config(bus_device_function: &BusDeviceFunction, offset: u8) -> u32 {
@@ -14,10 +27,16 @@ impl TraitPciArch for RiscV64PciArch {
     }
 
     fn address_pci_to_physical(pci_address: PciAddr) -> crate::mm::PhysAddr {
-        unimplemented!("RiscV64PciArch::address_pci_to_physical")
+        return PhysAddr::new(pci_address.data());
     }
+}
 
-    fn ecam_root(segement: SegmentGroupNumber) -> Result<PciRoot, PciError> {
-        unimplemented!("RiscV64PciArch::ecam_root")
-    }
+#[unified_init(INITCALL_SUBSYS)]
+fn riscv_pci_init() -> Result<(), SystemError> {
+    let fdt = open_firmware_fdt_driver().fdt_ref()?;
+
+    pci_host_ecam_driver_init(&fdt)?;
+    pci_init();
+
+    return Ok(());
 }

+ 73 - 0
kernel/src/arch/riscv64/pci/pci_host_ecam.rs

@@ -0,0 +1,73 @@
+use fdt::{node::FdtNode, Fdt};
+use system_error::SystemError;
+
+use crate::{
+    driver::{
+        open_firmware::fdt::open_firmware_fdt_driver,
+        pci::ecam::{pci_ecam_root_info_manager, EcamRootInfo},
+    },
+    kdebug,
+    mm::PhysAddr,
+};
+
+pub(super) fn pci_host_ecam_driver_init(fdt: &Fdt<'_>) -> Result<(), SystemError> {
+    let do_check = |node: FdtNode| -> Result<(), SystemError> {
+        let reg = node
+            .reg()
+            .ok_or(SystemError::EINVAL)?
+            .next()
+            .ok_or(SystemError::EINVAL)?;
+        let paddr = reg.starting_address as usize;
+        let size = reg.size.unwrap_or(0);
+        let bus_range: &[u8] = node.property("bus-range").ok_or(SystemError::EINVAL)?.value;
+
+        let (bus_begin, bus_end) = match bus_range.len() {
+            8 => (
+                u32::from_be_bytes(bus_range[0..4].try_into().unwrap()),
+                u32::from_be_bytes(bus_range[4..8].try_into().unwrap()),
+            ),
+            _ => panic!("Unexpected bus-range length"),
+        };
+
+        let segement_group_number: &[u8] = node
+            .property("linux,pci-domain")
+            .ok_or(SystemError::EINVAL)?
+            .value;
+
+        let segement_group_number = match segement_group_number.len() {
+            4 => u32::from_be_bytes(segement_group_number[0..4].try_into().unwrap()),
+            _ => panic!("Unexpected linux,pci-domain length"),
+        };
+
+        kdebug!(
+            "pci_host_ecam_driver_init(): {} paddr: {:#x} size: {:#x} bus-range: {}-{} segement_group_number: {}",
+            node.name,
+            paddr,
+            size,
+            bus_begin,
+            bus_end,
+            segement_group_number
+        );
+
+        pci_ecam_root_info_manager().add_ecam_root_info(EcamRootInfo::new(
+            segement_group_number.try_into().unwrap(),
+            bus_begin as u8,
+            bus_end as u8,
+            PhysAddr::new(paddr),
+        ));
+
+        Ok(())
+    };
+
+    for node in open_firmware_fdt_driver().find_node_by_compatible(&fdt, "pci-host-ecam-generic") {
+        if let Err(err) = do_check(node) {
+            kdebug!(
+                "pci_host_ecam_driver_init(): check {} error: {:?}",
+                node.name,
+                err
+            );
+        }
+    }
+
+    return Ok(());
+}

+ 0 - 3
kernel/src/arch/x86_64/init/mod.rs

@@ -5,7 +5,6 @@ use x86::dtables::DescriptorTablePointer;
 
 use crate::{
     arch::{interrupt::trap::arch_trap_init, process::table::TSSManager},
-    driver::pci::pci::pci_init,
     init::init::start_kernel,
     kdebug,
     mm::{MemoryManagementArch, PhysAddr},
@@ -88,8 +87,6 @@ pub fn early_setup_arch() -> Result<(), SystemError> {
 /// 架构相关的初始化
 #[inline(never)]
 pub fn setup_arch() -> Result<(), SystemError> {
-    // todo: 将来pci接入设备驱动模型之后,删掉这里。
-    pci_init();
     return Ok(());
 }
 

+ 41 - 21
kernel/src/arch/x86_64/pci/pci.rs

@@ -1,13 +1,17 @@
 use crate::arch::TraitPciArch;
 use crate::driver::acpi::acpi_manager;
+use crate::driver::pci::ecam::{pci_ecam_root_info_manager, EcamRootInfo};
 use crate::driver::pci::pci::{
-    BusDeviceFunction, PciAddr, PciCam, PciError, PciRoot, SegmentGroupNumber,
-    PORT_PCI_CONFIG_ADDRESS, PORT_PCI_CONFIG_DATA,
+    pci_init, BusDeviceFunction, PciAddr, PciError, PORT_PCI_CONFIG_ADDRESS, PORT_PCI_CONFIG_DATA,
 };
 use crate::include::bindings::bindings::{io_in32, io_out32};
+use crate::init::initcall::INITCALL_SUBSYS;
+use crate::kerror;
 use crate::mm::PhysAddr;
 
 use acpi::mcfg::Mcfg;
+use system_error::SystemError;
+use unified_init::macros::unified_init;
 
 pub struct X86_64PciArch;
 impl TraitPciArch for X86_64PciArch {
@@ -42,25 +46,41 @@ impl TraitPciArch for X86_64PciArch {
     fn address_pci_to_physical(pci_address: PciAddr) -> PhysAddr {
         return PhysAddr::new(pci_address.data());
     }
+}
 
-    fn ecam_root(segement: SegmentGroupNumber) -> Result<PciRoot, PciError> {
-        let mcfg = acpi_manager()
-            .tables()
-            .expect("get acpi_manager table error")
-            .find_table::<Mcfg>()
-            .map_err(|_| PciError::McfgTableNotFound)?;
-        for mcfg_entry in mcfg.entries() {
-            if mcfg_entry.pci_segment_group == segement {
-                return Ok(PciRoot {
-                    physical_address_base: PhysAddr::new(mcfg_entry.base_address as usize),
-                    mmio_guard: None,
-                    segement_group_number: segement,
-                    bus_begin: mcfg_entry.bus_number_start,
-                    bus_end: mcfg_entry.bus_number_end,
-                    cam: PciCam::Ecam,
-                });
-            }
-        }
-        return Err(PciError::SegmentNotFound);
+#[unified_init(INITCALL_SUBSYS)]
+fn x86_64_pci_init() -> Result<(), SystemError> {
+    if let Err(e) = discover_ecam_root() {
+        kerror!("x86_64_pci_init(): discover_ecam_root error: {:?}", e);
     }
+    pci_init();
+
+    return Ok(());
+}
+
+/// # discover_ecam_root - 发现使用ECAM的PCI root device
+///
+/// 该函数用于从ACPI管理器获取MCFG表,并从中发现使用ECAM的PCI root device。
+/// 然后,本函数将这些信息添加到pci_ecam_root_info_manager
+///
+/// ## 返回值
+///
+/// - Ok(()): 成功发现并添加了所有ECAM根信息
+/// - Err(PciError): 在获取ACPI管理器表或发现MCFG表时发生错误
+fn discover_ecam_root() -> Result<(), PciError> {
+    let mcfg = acpi_manager()
+        .tables()
+        .expect("get acpi_manager table error")
+        .find_table::<Mcfg>()
+        .map_err(|_| PciError::McfgTableNotFound)?;
+    for mcfg_entry in mcfg.entries() {
+        pci_ecam_root_info_manager().add_ecam_root_info(EcamRootInfo::new(
+            mcfg_entry.pci_segment_group,
+            mcfg_entry.bus_number_start,
+            mcfg_entry.bus_number_end,
+            PhysAddr::new(mcfg_entry.base_address as usize),
+        ));
+    }
+
+    Ok(())
 }

+ 0 - 5
kernel/src/driver/net/e1000e/e1000e.rs

@@ -587,11 +587,6 @@ impl Drop for E1000EDevice {
     }
 }
 
-#[no_mangle]
-pub extern "C" fn rs_e1000e_init() {
-    e1000e_init();
-}
-
 pub fn e1000e_init() {
     match e1000e_probe() {
         Ok(_code) => {

+ 14 - 0
kernel/src/driver/open_firmware/fdt.rs

@@ -381,6 +381,20 @@ impl OpenFirmwareFdtDriver {
 
         return mem_block_manager().reserve_block(base, size);
     }
+
+    pub fn find_node_by_compatible<'b>(
+        &self,
+        fdt: &'b Fdt<'b>,
+        compatible: &'b str,
+    ) -> impl Iterator<Item = fdt::node::FdtNode<'b, 'b>> + 'b {
+        // compatible = compatible.trim();
+        let r = fdt.all_nodes().filter(move |x| {
+            x.compatible()
+                .is_some_and(|x| x.all().any(|x| x == compatible))
+        });
+
+        return r;
+    }
 }
 
 #[allow(dead_code)]

+ 71 - 0
kernel/src/driver/pci/ecam.rs

@@ -0,0 +1,71 @@
+use crate::mm::PhysAddr;
+
+use super::{
+    pci::{PciCam, SegmentGroupNumber},
+    root::{pci_root_manager, PciRoot},
+};
+
+#[inline(always)]
+pub fn pci_ecam_root_info_manager() -> &'static EcamRootInfoManager {
+    &EcamRootInfoManager
+}
+
+/// Ecam pci root info
+#[derive(Clone, Copy)]
+pub struct EcamRootInfo {
+    pub segement_group_number: SegmentGroupNumber,
+    pub bus_begin: u8,
+    pub bus_end: u8,
+    pub physical_address_base: PhysAddr,
+}
+
+impl EcamRootInfo {
+    pub fn new(
+        segement_group_number: SegmentGroupNumber,
+        bus_begin: u8,
+        bus_end: u8,
+        physical_address_base: PhysAddr,
+    ) -> Self {
+        Self {
+            segement_group_number,
+            bus_begin,
+            bus_end,
+            physical_address_base,
+        }
+    }
+}
+
+pub struct EcamRootInfoManager;
+
+impl EcamRootInfoManager {
+    /// # add_ecam_root_info - 向EcamRootInfoManager添加EcamRootInfo
+    ///
+    /// 将一个新的EcamRootInfo添加到EcamRootInfoManager中。
+    ///
+    /// ## 参数
+    ///
+    /// - `ecam_root_info`: EcamRootInfo - 要添加的EcamRootInfo实例
+    pub fn add_ecam_root_info(&self, ecam_root_info: EcamRootInfo) {
+        if !pci_root_manager().has_root(ecam_root_info.segement_group_number) {
+            let root = PciRoot::new(
+                ecam_root_info.segement_group_number,
+                PciCam::Ecam,
+                ecam_root_info.physical_address_base,
+                ecam_root_info.bus_begin,
+                ecam_root_info.bus_end,
+            );
+
+            if let Err(err) = root {
+                kerror!("add_ecam_root_info(): failed to create PciRoot: {:?}", err);
+                return;
+            }
+
+            pci_root_manager().add_pci_root(root.unwrap());
+        } else {
+            kwarn!(
+                "add_ecam_root_info(): root {} already exists",
+                ecam_root_info.segement_group_number
+            );
+        }
+    }
+}

+ 2 - 0
kernel/src/driver/pci/mod.rs

@@ -1,3 +1,5 @@
+pub mod ecam;
 #[allow(clippy::module_inception)]
 pub mod pci;
 pub mod pci_irq;
+pub mod root;

+ 2 - 165
kernel/src/driver/pci/pci.rs

@@ -2,14 +2,14 @@
 // 目前仅支持单主桥单Segment
 
 use super::pci_irq::{IrqType, PciIrqError};
+use super::root::{pci_root_0, PciRoot};
 use crate::arch::{PciArch, TraitPciArch};
 use crate::exception::IrqNumber;
-use crate::include::bindings::bindings::PAGE_2M_SIZE;
 use crate::libs::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard};
 
 use crate::mm::mmio_buddy::{mmio_pool, MMIOSpaceGuard};
 
-use crate::mm::{PhysAddr, VirtAddr};
+use crate::mm::VirtAddr;
 use crate::{kdebug, kerror, kinfo, kwarn};
 use alloc::sync::Arc;
 use alloc::vec::Vec;
@@ -21,23 +21,8 @@ use core::{
     fmt::{self, Debug, Display, Formatter},
 };
 // PCI_DEVICE_LINKEDLIST 添加了读写锁的全局链表,里面存储了检索到的PCI设备结构体
-// PCI_ROOT_0 Segment为0的全局PciRoot
 lazy_static! {
     pub static ref PCI_DEVICE_LINKEDLIST: PciDeviceLinkedList = PciDeviceLinkedList::new();
-    pub static ref PCI_ROOT_0: Option<PciRoot> = {
-        match PciRoot::new(0, PciCam::Ecam) {
-            Ok(root) => Some(root),
-            Err(err) => {
-                kerror!("Pci_root init failed because of error: {}", err);
-                None
-            }
-        }
-    };
-}
-
-#[inline(always)]
-pub fn pci_root_0() -> &'static PciRoot {
-    PCI_ROOT_0.as_ref().unwrap()
 }
 
 /// PCI域地址
@@ -600,18 +585,6 @@ impl PciDeviceStructure for PciDeviceStructurePciToCardbusBridge {
     }
 }
 
-/// 代表一个PCI segement greoup.
-#[derive(Clone, Debug)]
-pub struct PciRoot {
-    pub physical_address_base: PhysAddr,         //物理地址,acpi获取
-    pub mmio_guard: Option<Arc<MMIOSpaceGuard>>, //映射后的虚拟地址,为方便访问数据这里转化成指针
-    pub segement_group_number: SegmentGroupNumber, //segement greoup的id
-    pub bus_begin: u8,                           //该分组中的最小bus
-    pub bus_end: u8,                             //该分组中的最大bus
-    /// 配置空间访问机制
-    pub cam: PciCam,
-}
-
 /// PCI配置空间访问机制
 ///
 /// 用于访问PCI设备的功能配置空间的一组机制。
@@ -637,142 +610,6 @@ impl PciCam {
     }
 }
 
-///线程间共享需要,该结构体只需要在初始化时写入数据,无需读写锁保证线程安全
-unsafe impl Send for PciRoot {}
-unsafe impl Sync for PciRoot {}
-///实现PciRoot的Display trait,自定义输出
-impl Display for PciRoot {
-    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        write!(
-                f,
-                "PCI Root with segement:{}, bus begin at {}, bus end at {}, physical address at {:?},mapped at {:?}",
-                self.segement_group_number, self.bus_begin, self.bus_end, self.physical_address_base, self.mmio_guard
-            )
-    }
-}
-
-impl PciRoot {
-    /// 此函数用于初始化一个PciRoot结构体实例,
-    /// 该结构体基于ECAM根的物理地址,将其映射到虚拟地址
-    ///
-    /// ## 参数
-    ///
-    /// - segment_group_number: ECAM根的段组号。
-    /// - cam: PCI配置空间访问机制
-    ///
-    /// ## 返回值
-    ///
-    /// - Ok(Self): 初始化成功,返回一个新的结构体实例。
-    /// - Err(PciError): 初始化过程中发生错误,返回错误信息。
-    ///
-    /// ## 副作用
-    ///
-    /// - 成功执行后,结构体的内部状态将被初始化为包含映射后的虚拟地址。
-    pub fn new(segment_group_number: SegmentGroupNumber, cam: PciCam) -> Result<Self, PciError> {
-        assert_eq!(cam, PciCam::Ecam);
-        let mut pci_root = PciArch::ecam_root(segment_group_number)?;
-        pci_root.map()?;
-        Ok(pci_root)
-    }
-    /// @brief  完成物理地址到虚拟地址的映射,并将虚拟地址加入mmio_base变量
-    /// @return 返回错误或Ok(0)
-    fn map(&mut self) -> Result<u8, PciError> {
-        //kdebug!("bus_begin={},bus_end={}", self.bus_begin,self.bus_end);
-        let bus_number = (self.bus_end - self.bus_begin) as u32 + 1;
-        let bus_number_double = (bus_number - 1) / 2 + 1; //一个bus占据1MB空间,计算全部bus占据空间相对于2MB空间的个数
-
-        let size = (bus_number_double as usize) * (PAGE_2M_SIZE as usize);
-        unsafe {
-            let space_guard = mmio_pool()
-                .create_mmio(size)
-                .map_err(|_| PciError::CreateMmioError)?;
-            let space_guard = Arc::new(space_guard);
-            self.mmio_guard = Some(space_guard.clone());
-
-            assert!(space_guard
-                .map_phys(self.physical_address_base, size)
-                .is_ok());
-        }
-        return Ok(0);
-    }
-
-    /// # cam_offset - 获得要操作的寄存器相对于mmio_offset的偏移量
-    ///
-    /// 此函数用于计算一个PCI设备中特定寄存器相对于该设备的MMIO基地址的偏移量。
-    ///
-    /// ## 参数
-    ///
-    /// - `bus_device_function`: BusDeviceFunction,用于标识在同一组中的PCI设备。
-    /// - `register_offset`: u16,寄存器在设备中的偏移量。
-    ///
-    /// ## 返回值
-    ///
-    /// - `u32`: 成功时,返回要操作的寄存器相对于mmio_offset的偏移量。
-    ///
-    /// ## Panic
-    ///
-    /// - 此函数在参数有效性方面进行了断言,如果传入的`bus_device_function`无效,将panic。
-    /// - 此函数计算出的地址需要是字对齐的(即地址与0x3对齐)。如果不是,将panic。
-    fn cam_offset(&self, bus_device_function: BusDeviceFunction, register_offset: u16) -> u32 {
-        assert!(bus_device_function.valid());
-        let bdf = ((bus_device_function.bus - self.bus_begin) as u32) << 8
-            | (bus_device_function.device as u32) << 3
-            | bus_device_function.function as u32;
-        let address =
-            bdf << match self.cam {
-                PciCam::MmioCam => 8,
-                PciCam::Ecam => 12,
-            } | register_offset as u32;
-        // Ensure that address is word-aligned.
-        assert!(address & 0x3 == 0);
-        address
-    }
-    /// @brief 通过bus_device_function和offset读取相应位置寄存器的值(32位)
-    /// @param bus_device_function 在同一个group中pci设备的唯一标识符
-    /// @param register_offset 寄存器在设备中的offset
-    /// @return u32 寄存器读值结果
-    pub fn read_config(&self, bus_device_function: BusDeviceFunction, register_offset: u16) -> u32 {
-        let address = self.cam_offset(bus_device_function, register_offset);
-        unsafe {
-            // Right shift to convert from byte offset to word offset.
-            ((self.mmio_guard.as_ref().unwrap().vaddr().data() as *mut u32)
-                .add((address >> 2) as usize))
-            .read_volatile()
-        }
-    }
-
-    /// @brief 通过bus_device_function和offset写入相应位置寄存器值(32位)
-    /// @param bus_device_function 在同一个group中pci设备的唯一标识符
-    /// @param register_offset 寄存器在设备中的offset
-    /// @param data 要写入的值
-    pub fn write_config(
-        &self,
-        bus_device_function: BusDeviceFunction,
-        register_offset: u16,
-        data: u32,
-    ) {
-        let address = self.cam_offset(bus_device_function, register_offset);
-        // Safe because both the `mmio_base` and the address offset are properly aligned, and the
-        // resulting pointer is within the MMIO range of the CAM.
-        unsafe {
-            // Right shift to convert from byte offset to word offset.
-            ((self.mmio_guard.as_ref().unwrap().vaddr().data() as *mut u32)
-                .add((address >> 2) as usize))
-            .write_volatile(data)
-        }
-    }
-    /// @brief 返回迭代器,遍历pcie设备的external_capabilities
-    pub fn external_capabilities(
-        &self,
-        bus_device_function: BusDeviceFunction,
-    ) -> ExternalCapabilityIterator {
-        ExternalCapabilityIterator {
-            root: self,
-            bus_device_function,
-            next_capability_offset: Some(0x100),
-        }
-    }
-}
 /// Gets the capabilities 'pointer' for the device function, if any.
 /// @brief 获取第一个capability 的offset
 /// @param bus_device_function PCI设备的唯一标识

+ 2 - 1
kernel/src/driver/pci/pci_irq.rs

@@ -8,7 +8,8 @@ use alloc::sync::Arc;
 use alloc::vec::Vec;
 use system_error::SystemError;
 
-use super::pci::{pci_root_0, PciDeviceStructure, PciDeviceStructureGeneralDevice, PciError};
+use super::pci::{PciDeviceStructure, PciDeviceStructureGeneralDevice, PciError};
+use super::root::pci_root_0;
 use crate::arch::msi::{arch_msi_message_address, arch_msi_message_data};
 
 use crate::driver::base::device::DeviceId;

+ 303 - 0
kernel/src/driver/pci/root.rs

@@ -0,0 +1,303 @@
+use core::fmt::Formatter;
+
+use alloc::sync::Arc;
+use hashbrown::HashMap;
+
+use crate::{
+    libs::spinlock::{SpinLock, SpinLockGuard},
+    mm::{
+        mmio_buddy::{mmio_pool, MMIOSpaceGuard},
+        page::PAGE_2M_SIZE,
+        PhysAddr,
+    },
+};
+
+use super::pci::{
+    BusDeviceFunction, ExternalCapabilityIterator, PciCam, PciError, SegmentGroupNumber,
+};
+
+lazy_static! {
+    static ref PCI_ROOT_MANAGER: PciRootManager = PciRootManager::new();
+}
+
+#[inline(always)]
+pub fn pci_root_manager() -> &'static PciRootManager {
+    &PCI_ROOT_MANAGER
+}
+
+/// 代表一个PCI segement greoup.
+#[derive(Clone, Debug)]
+pub struct PciRoot {
+    pub physical_address_base: PhysAddr,          //物理地址,acpi获取
+    pub mmio_guard: Option<Arc<MMIOSpaceGuard>>,  //映射后的虚拟地址,为方便访问数据这里转化成指针
+    pub segment_group_number: SegmentGroupNumber, //segement greoup的id
+    pub bus_begin: u8,                            //该分组中的最小bus
+    pub bus_end: u8,                              //该分组中的最大bus
+    /// 配置空间访问机制
+    pub cam: PciCam,
+}
+
+///线程间共享需要,该结构体只需要在初始化时写入数据,无需读写锁保证线程安全
+unsafe impl Send for PciRoot {}
+unsafe impl Sync for PciRoot {}
+///实现PciRoot的Display trait,自定义输出
+impl core::fmt::Display for PciRoot {
+    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
+        write!(
+                f,
+                "PCI Root with segement:{}, bus begin at {}, bus end at {}, physical address at {:?},mapped at {:?}",
+                self.segment_group_number, self.bus_begin, self.bus_end, self.physical_address_base, self.mmio_guard
+            )
+    }
+}
+
+impl PciRoot {
+    /// 此函数用于初始化一个PciRoot结构体实例,
+    /// 该结构体基于ECAM根的物理地址,将其映射到虚拟地址
+    ///
+    /// ## 参数
+    ///
+    /// - segment_group_number: ECAM根的段组号。
+    /// - cam: PCI配置空间访问机制
+    ///
+    /// ## 返回值
+    ///
+    /// - Ok(Self): 初始化成功,返回一个新的结构体实例。
+    /// - Err(PciError): 初始化过程中发生错误,返回错误信息。
+    ///
+    /// ## 副作用
+    ///
+    /// - 成功执行后,结构体的内部状态将被初始化为包含映射后的虚拟地址。
+    pub fn new(
+        segment_group_number: SegmentGroupNumber,
+        cam: PciCam,
+        phys_base: PhysAddr,
+        bus_begin: u8,
+        bus_end: u8,
+    ) -> Result<Arc<Self>, PciError> {
+        assert_eq!(cam, PciCam::Ecam);
+        let mut pci_root = Self {
+            physical_address_base: phys_base,
+            mmio_guard: None,
+            segment_group_number,
+            bus_begin,
+            bus_end,
+            cam,
+        };
+        pci_root.map()?;
+
+        Ok(Arc::new(pci_root))
+    }
+    /// @brief  完成物理地址到虚拟地址的映射,并将虚拟地址加入mmio_base变量
+    /// @return 返回错误或Ok(0)
+    fn map(&mut self) -> Result<u8, PciError> {
+        //kdebug!("bus_begin={},bus_end={}", self.bus_begin,self.bus_end);
+        let bus_number = (self.bus_end - self.bus_begin) as u32 + 1;
+        let bus_number_double = (bus_number - 1) / 2 + 1; //一个bus占据1MB空间,计算全部bus占据空间相对于2MB空间的个数
+
+        let size = (bus_number_double as usize) * PAGE_2M_SIZE;
+        unsafe {
+            let space_guard = mmio_pool()
+                .create_mmio(size)
+                .map_err(|_| PciError::CreateMmioError)?;
+            let space_guard = Arc::new(space_guard);
+            self.mmio_guard = Some(space_guard.clone());
+
+            assert!(space_guard
+                .map_phys(self.physical_address_base, size)
+                .is_ok());
+        }
+        return Ok(0);
+    }
+
+    /// # cam_offset - 获得要操作的寄存器相对于mmio_offset的偏移量
+    ///
+    /// 此函数用于计算一个PCI设备中特定寄存器相对于该设备的MMIO基地址的偏移量。
+    ///
+    /// ## 参数
+    ///
+    /// - `bus_device_function`: BusDeviceFunction,用于标识在同一组中的PCI设备。
+    /// - `register_offset`: u16,寄存器在设备中的偏移量。
+    ///
+    /// ## 返回值
+    ///
+    /// - `u32`: 成功时,返回要操作的寄存器相对于mmio_offset的偏移量。
+    ///
+    /// ## Panic
+    ///
+    /// - 此函数在参数有效性方面进行了断言,如果传入的`bus_device_function`无效,将panic。
+    /// - 此函数计算出的地址需要是字对齐的(即地址与0x3对齐)。如果不是,将panic。
+    fn cam_offset(&self, bus_device_function: BusDeviceFunction, register_offset: u16) -> u32 {
+        assert!(bus_device_function.valid());
+        let bdf = ((bus_device_function.bus - self.bus_begin) as u32) << 8
+            | (bus_device_function.device as u32) << 3
+            | bus_device_function.function as u32;
+        let address =
+            bdf << match self.cam {
+                PciCam::MmioCam => 8,
+                PciCam::Ecam => 12,
+            } | register_offset as u32;
+        // Ensure that address is word-aligned.
+        assert!(address & 0x3 == 0);
+        address
+    }
+    /// # read_config - 通过bus_device_function和offset读取相应位置寄存器的值(32位)
+    ///
+    /// 此函数用于通过指定的bus_device_function和register_offset读取PCI设备中相应位置的寄存器值。
+    ///
+    /// ## 参数
+    ///
+    /// - `bus_device_function`: 在同一个group中pci设备的唯一标识符
+    /// - `register_offset`: 寄存器在设备中的offset
+    ///
+    /// ## 返回值
+    ///
+    /// - `u32`: 寄存器读值结果
+    pub fn read_config(&self, bus_device_function: BusDeviceFunction, register_offset: u16) -> u32 {
+        let address = self.cam_offset(bus_device_function, register_offset);
+        unsafe {
+            // Right shift to convert from byte offset to word offset.
+            ((self.mmio_guard.as_ref().unwrap().vaddr().data() as *mut u32)
+                .add((address >> 2) as usize))
+            .read_volatile()
+        }
+    }
+
+    /// # write_config - 通过bus_device_function和offset写入相应位置寄存器值(32位)
+    ///
+    /// 此函数用于通过指定的bus_device_function和register_offset,向PCI设备写入一个32位的寄存器值。
+    ///
+    /// ## 参数
+    ///
+    /// - `bus_device_function`: 在同一个group中pci设备的唯一标识符
+    /// - `register_offset`: 寄存器在设备中的offset
+    /// - `data`: 要写入的数据
+    pub fn write_config(
+        &self,
+        bus_device_function: BusDeviceFunction,
+        register_offset: u16,
+        data: u32,
+    ) {
+        let address = self.cam_offset(bus_device_function, register_offset);
+        // Safe because both the `mmio_base` and the address offset are properly aligned, and the
+        // resulting pointer is within the MMIO range of the CAM.
+        unsafe {
+            // Right shift to convert from byte offset to word offset.
+            ((self.mmio_guard.as_ref().unwrap().vaddr().data() as *mut u32)
+                .add((address >> 2) as usize))
+            .write_volatile(data)
+        }
+    }
+    /// 返回迭代器,遍历pcie设备的external_capabilities
+    #[allow(dead_code)]
+    pub fn external_capabilities(
+        &self,
+        bus_device_function: BusDeviceFunction,
+    ) -> ExternalCapabilityIterator {
+        ExternalCapabilityIterator {
+            root: self,
+            bus_device_function,
+            next_capability_offset: Some(0x100),
+        }
+    }
+}
+
+#[inline(always)]
+pub fn pci_root_0() -> Arc<PciRoot> {
+    pci_root_manager().get_pci_root(0).unwrap()
+}
+
+pub struct PciRootManager {
+    inner: SpinLock<InnerPciRootManager>,
+}
+
+struct InnerPciRootManager {
+    pci_root: HashMap<SegmentGroupNumber, Arc<PciRoot>>,
+}
+
+impl PciRootManager {
+    pub fn new() -> Self {
+        Self {
+            inner: SpinLock::new(InnerPciRootManager {
+                pci_root: HashMap::new(),
+            }),
+        }
+    }
+
+    /// # 添加PciRoot - 向PciRootManager中添加一个PciRoot
+    ///
+    /// 向PciRootManager中添加一个新的PciRoot,通过其segment_group_number进行标识。
+    ///
+    /// ## 参数
+    ///
+    /// - `pci_root`: Arc<PciRoot>,要添加的PciRoot的Arc指针
+    pub fn add_pci_root(&self, pci_root: Arc<PciRoot>) {
+        let mut inner = self.inner.lock();
+        inner
+            .pci_root
+            .insert(pci_root.segment_group_number, pci_root);
+    }
+
+    /// # 检查是否存在PciRoot - 检查PciRootManager中是否存在指定segment_group_number的PciRoot
+    ///
+    /// 检查PciRootManager中是否存在segment_group_number对应的PciRoot。
+    ///
+    /// ## 参数
+    ///
+    /// - `segement_group_number`: SegmentGroupNumber,要检查的segment_group_number。
+    ///
+    /// ## 返回值
+    ///
+    /// - `true`: 如果存在对应的PciRoot。
+    /// - `false`: 如果不存在对应的PciRoot。
+    pub fn has_root(&self, segement_group_number: SegmentGroupNumber) -> bool {
+        self.inner
+            .lock()
+            .pci_root
+            .contains_key(&segement_group_number)
+    }
+
+    /// # 获取PciRoot - 从PciRootManager中获取指定segment_group_number的PciRoot
+    ///
+    /// 从PciRootManager中获取segment_group_number对应的PciRoot。
+    ///
+    /// ## 参数
+    ///
+    /// - `segement_group_number`: SegmentGroupNumber,要获取的PciRoot的segment_group_number。
+    ///
+    /// ## 返回值
+    ///
+    /// - `Some(Arc<PciRoot>)`: 如果找到对应的PciRoot,返回其引用。
+    /// - `None`: 如果没有找到对应的PciRoot。
+    pub fn get_pci_root(&self, segement_group_number: SegmentGroupNumber) -> Option<Arc<PciRoot>> {
+        self.inner
+            .lock()
+            .pci_root
+            .get(&segement_group_number)
+            .cloned()
+    }
+
+    /// # PciRoot迭代器 - 创建一个新的PciRoot迭代器
+    ///
+    /// 创建一个新的迭代器,用于遍历PciRootManager中的所有PciRoot。
+    #[allow(dead_code)]
+    pub fn iter(&self) -> PciRootIterator<'_> {
+        PciRootIterator {
+            inner: self.inner.lock(),
+            index: 0,
+        }
+    }
+}
+
+pub struct PciRootIterator<'a> {
+    inner: SpinLockGuard<'a, InnerPciRootManager>,
+    index: usize,
+}
+
+impl<'a> Iterator for PciRootIterator<'a> {
+    type Item = Arc<PciRoot>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        self.inner.pci_root.values().nth(self.index).cloned()
+    }
+}

+ 2 - 1
kernel/src/driver/virtio/transport_pci.rs

@@ -2,11 +2,12 @@
 
 use crate::driver::base::device::DeviceId;
 use crate::driver::pci::pci::{
-    pci_root_0, BusDeviceFunction, PciDeviceStructure, PciDeviceStructureGeneralDevice, PciError,
+    BusDeviceFunction, PciDeviceStructure, PciDeviceStructureGeneralDevice, PciError,
     PciStandardDeviceBar, PCI_CAP_ID_VNDR,
 };
 
 use crate::driver::pci::pci_irq::{IrqCommonMsg, IrqSpecificMsg, PciInterrupt, PciIrqMsg, IRQ};
+use crate::driver::pci::root::pci_root_0;
 use crate::driver::virtio::irq::virtio_irq_manager;
 use crate::exception::irqdata::IrqHandlerData;
 use crate::exception::irqdesc::{IrqHandler, IrqReturn};

+ 2 - 3
kernel/src/mm/mmio_buddy.rs

@@ -3,7 +3,6 @@ use crate::mm::kernel_mapper::KernelMapper;
 use crate::mm::page::{PAGE_1G_SHIFT, PAGE_4K_SHIFT};
 use crate::process::ProcessManager;
 use crate::{
-    include::bindings::bindings::PAGE_4K_SIZE,
     kdebug,
     mm::{MMArch, MemoryManagementArch},
 };
@@ -14,7 +13,7 @@ use core::mem::MaybeUninit;
 use core::sync::atomic::{AtomicBool, Ordering};
 use system_error::SystemError;
 
-use super::page::PageFlags;
+use super::page::{PageFlags, PAGE_4K_SIZE};
 use super::{PhysAddr, VirtAddr};
 
 // 最大的伙伴块的幂
@@ -495,7 +494,7 @@ impl MmioBuddyMemPool {
         // 对齐要申请的空间大小
         // 如果要申请的空间大小小于4k,则分配4k
         if size_exp < PAGE_4K_SHIFT as u32 {
-            new_size = PAGE_4K_SIZE as usize;
+            new_size = PAGE_4K_SIZE;
             size_exp = PAGE_4K_SHIFT as u32;
         } else if (new_size & (!(1 << size_exp))) != 0 {
             // 向左对齐空间大小

+ 3 - 0
kernel/src/mm/page.rs

@@ -27,6 +27,9 @@ pub const PAGE_4K_SHIFT: usize = 12;
 pub const PAGE_2M_SHIFT: usize = 21;
 pub const PAGE_1G_SHIFT: usize = 30;
 
+pub const PAGE_4K_SIZE: usize = 1 << PAGE_4K_SHIFT;
+pub const PAGE_2M_SIZE: usize = 1 << PAGE_2M_SHIFT;
+
 /// 全局物理页信息管理器
 pub static mut PAGE_MANAGER: Option<SpinLock<PageManager>> = None;
 

+ 4 - 5
kernel/src/syscall/mod.rs

@@ -10,7 +10,7 @@ use crate::{
     filesystem::vfs::syscall::{PosixStatfs, PosixStatx},
     ipc::shm::{ShmCtlCmd, ShmFlags, ShmId, ShmKey},
     libs::{futex::constant::FutexFlag, rand::GRandFlags},
-    mm::syscall::MremapFlags,
+    mm::{page::PAGE_4K_SIZE, syscall::MremapFlags},
     net::syscall::MsgHdr,
     process::{
         fork::KernelCloneArgs,
@@ -32,7 +32,6 @@ use crate::{
         syscall::{ModeType, PosixKstat},
         MAX_PATHLEN,
     },
-    include::bindings::bindings::PAGE_4K_SIZE,
     kinfo,
     libs::align::page_align_up,
     mm::{verify_area, MemoryManagementArch, VirtAddr},
@@ -261,8 +260,8 @@ impl Syscall {
                 // 权限校验
                 if frame.is_from_user()
                     && (verify_area(virt_path_ptr, MAX_PATHLEN).is_err()
-                        || verify_area(virt_argv_ptr, PAGE_4K_SIZE as usize).is_err())
-                    || verify_area(virt_env_ptr, PAGE_4K_SIZE as usize).is_err()
+                        || verify_area(virt_argv_ptr, PAGE_4K_SIZE).is_err())
+                    || verify_area(virt_env_ptr, PAGE_4K_SIZE).is_err()
                 {
                     Err(SystemError::EFAULT)
                 } else {
@@ -422,7 +421,7 @@ impl Syscall {
                 let virt_optlen = VirtAddr::new(optlen as usize);
                 let security_check = || {
                     // 验证optval的地址是否合法
-                    if verify_area(virt_optval, PAGE_4K_SIZE as usize).is_err() {
+                    if verify_area(virt_optval, PAGE_4K_SIZE).is_err() {
                         // 地址空间超出了用户空间的范围,不合法
                         return Err(SystemError::EFAULT);
                     }