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