xref: /DragonOS/kernel/src/arch/x86_64/pci/pci.rs (revision 370472f7288b568c7b80815f5b150daf4496446c)
178bf93f0SYJwu2023 use crate::arch::TraitPciArch;
28b3d1688Syuyi2439 use crate::driver::acpi::acpi_manager;
3*370472f7SLoGin use crate::driver::pci::ecam::{pci_ecam_root_info_manager, EcamRootInfo};
478bf93f0SYJwu2023 use crate::driver::pci::pci::{
5*370472f7SLoGin     pci_init, BusDeviceFunction, PciAddr, PciError, PORT_PCI_CONFIG_ADDRESS, PORT_PCI_CONFIG_DATA,
678bf93f0SYJwu2023 };
7cc5feaf6SJomo use crate::include::bindings::bindings::{io_in32, io_out32};
8*370472f7SLoGin use crate::init::initcall::INITCALL_SUBSYS;
9*370472f7SLoGin use crate::kerror;
102dd9f0c7SLoGin use crate::mm::PhysAddr;
1178bf93f0SYJwu2023 
128b3d1688Syuyi2439 use acpi::mcfg::Mcfg;
13*370472f7SLoGin use system_error::SystemError;
14*370472f7SLoGin use unified_init::macros::unified_init;
158b3d1688Syuyi2439 
168b3d1688Syuyi2439 pub struct X86_64PciArch;
1778bf93f0SYJwu2023 impl TraitPciArch for X86_64PciArch {
1878bf93f0SYJwu2023     fn read_config(bus_device_function: &BusDeviceFunction, offset: u8) -> u32 {
1978bf93f0SYJwu2023         // 构造pci配置空间地址
2078bf93f0SYJwu2023         let address = ((bus_device_function.bus as u32) << 16)
2178bf93f0SYJwu2023             | ((bus_device_function.device as u32) << 11)
2278bf93f0SYJwu2023             | ((bus_device_function.function as u32 & 7) << 8)
2378bf93f0SYJwu2023             | (offset & 0xfc) as u32
2478bf93f0SYJwu2023             | (0x80000000);
2578bf93f0SYJwu2023         let ret = unsafe {
2678bf93f0SYJwu2023             io_out32(PORT_PCI_CONFIG_ADDRESS, address);
2778bf93f0SYJwu2023             let temp = io_in32(PORT_PCI_CONFIG_DATA);
2878bf93f0SYJwu2023             temp
2978bf93f0SYJwu2023         };
3078bf93f0SYJwu2023         return ret;
3178bf93f0SYJwu2023     }
3278bf93f0SYJwu2023 
3378bf93f0SYJwu2023     fn write_config(bus_device_function: &BusDeviceFunction, offset: u8, data: u32) {
3478bf93f0SYJwu2023         let address = ((bus_device_function.bus as u32) << 16)
3578bf93f0SYJwu2023             | ((bus_device_function.device as u32) << 11)
3678bf93f0SYJwu2023             | ((bus_device_function.function as u32 & 7) << 8)
3778bf93f0SYJwu2023             | (offset & 0xfc) as u32
3878bf93f0SYJwu2023             | (0x80000000);
3978bf93f0SYJwu2023         unsafe {
4078bf93f0SYJwu2023             io_out32(PORT_PCI_CONFIG_ADDRESS, address);
4178bf93f0SYJwu2023             // 写入数据
4278bf93f0SYJwu2023             io_out32(PORT_PCI_CONFIG_DATA, data);
4378bf93f0SYJwu2023         }
4478bf93f0SYJwu2023     }
4578bf93f0SYJwu2023 
462dd9f0c7SLoGin     fn address_pci_to_physical(pci_address: PciAddr) -> PhysAddr {
472dd9f0c7SLoGin         return PhysAddr::new(pci_address.data());
4878bf93f0SYJwu2023     }
49*370472f7SLoGin }
5078bf93f0SYJwu2023 
51*370472f7SLoGin #[unified_init(INITCALL_SUBSYS)]
52*370472f7SLoGin fn x86_64_pci_init() -> Result<(), SystemError> {
53*370472f7SLoGin     if let Err(e) = discover_ecam_root() {
54*370472f7SLoGin         kerror!("x86_64_pci_init(): discover_ecam_root error: {:?}", e);
55*370472f7SLoGin     }
56*370472f7SLoGin     pci_init();
57*370472f7SLoGin 
58*370472f7SLoGin     return Ok(());
59*370472f7SLoGin }
60*370472f7SLoGin 
61*370472f7SLoGin /// # discover_ecam_root - 发现使用ECAM的PCI root device
62*370472f7SLoGin ///
63*370472f7SLoGin /// 该函数用于从ACPI管理器获取MCFG表,并从中发现使用ECAM的PCI root device。
64*370472f7SLoGin /// 然后,本函数将这些信息添加到pci_ecam_root_info_manager
65*370472f7SLoGin ///
66*370472f7SLoGin /// ## 返回值
67*370472f7SLoGin ///
68*370472f7SLoGin /// - Ok(()): 成功发现并添加了所有ECAM根信息
69*370472f7SLoGin /// - Err(PciError): 在获取ACPI管理器表或发现MCFG表时发生错误
70*370472f7SLoGin fn discover_ecam_root() -> Result<(), PciError> {
71cc5feaf6SJomo     let mcfg = acpi_manager()
728b3d1688Syuyi2439         .tables()
738b3d1688Syuyi2439         .expect("get acpi_manager table error")
74cc5feaf6SJomo         .find_table::<Mcfg>()
75cc5feaf6SJomo         .map_err(|_| PciError::McfgTableNotFound)?;
768b3d1688Syuyi2439     for mcfg_entry in mcfg.entries() {
77*370472f7SLoGin         pci_ecam_root_info_manager().add_ecam_root_info(EcamRootInfo::new(
78*370472f7SLoGin             mcfg_entry.pci_segment_group,
79*370472f7SLoGin             mcfg_entry.bus_number_start,
80*370472f7SLoGin             mcfg_entry.bus_number_end,
81*370472f7SLoGin             PhysAddr::new(mcfg_entry.base_address as usize),
82*370472f7SLoGin         ));
8378bf93f0SYJwu2023     }
84*370472f7SLoGin 
85*370472f7SLoGin     Ok(())
8678bf93f0SYJwu2023 }
87