1 use crate::arch::TraitPciArch; 2 use crate::driver::acpi::acpi_manager; 3 use crate::driver::pci::ecam::{pci_ecam_root_info_manager, EcamRootInfo}; 4 use crate::driver::pci::pci::{ 5 pci_init, BusDeviceFunction, PciAddr, PciError, PORT_PCI_CONFIG_ADDRESS, PORT_PCI_CONFIG_DATA, 6 }; 7 use crate::include::bindings::bindings::{io_in32, io_out32}; 8 use crate::init::initcall::INITCALL_SUBSYS; 9 10 use crate::mm::PhysAddr; 11 12 use acpi::mcfg::Mcfg; 13 use log::error; 14 use system_error::SystemError; 15 use unified_init::macros::unified_init; 16 17 pub struct X86_64PciArch; 18 impl TraitPciArch for X86_64PciArch { 19 fn read_config(bus_device_function: &BusDeviceFunction, offset: u8) -> u32 { 20 // 构造pci配置空间地址 21 let address = ((bus_device_function.bus as u32) << 16) 22 | ((bus_device_function.device as u32) << 11) 23 | ((bus_device_function.function as u32 & 7) << 8) 24 | (offset & 0xfc) as u32 25 | (0x80000000); 26 let ret = unsafe { 27 io_out32(PORT_PCI_CONFIG_ADDRESS, address); 28 let temp = io_in32(PORT_PCI_CONFIG_DATA); 29 temp 30 }; 31 return ret; 32 } 33 34 fn write_config(bus_device_function: &BusDeviceFunction, offset: u8, data: u32) { 35 let address = ((bus_device_function.bus as u32) << 16) 36 | ((bus_device_function.device as u32) << 11) 37 | ((bus_device_function.function as u32 & 7) << 8) 38 | (offset & 0xfc) as u32 39 | (0x80000000); 40 unsafe { 41 io_out32(PORT_PCI_CONFIG_ADDRESS, address); 42 // 写入数据 43 io_out32(PORT_PCI_CONFIG_DATA, data); 44 } 45 } 46 47 fn address_pci_to_physical(pci_address: PciAddr) -> PhysAddr { 48 return PhysAddr::new(pci_address.data()); 49 } 50 } 51 52 #[unified_init(INITCALL_SUBSYS)] 53 fn x86_64_pci_init() -> Result<(), SystemError> { 54 if let Err(e) = discover_ecam_root() { 55 error!("x86_64_pci_init(): discover_ecam_root error: {:?}", e); 56 } 57 pci_init(); 58 59 return Ok(()); 60 } 61 62 /// # discover_ecam_root - 发现使用ECAM的PCI root device 63 /// 64 /// 该函数用于从ACPI管理器获取MCFG表,并从中发现使用ECAM的PCI root device。 65 /// 然后,本函数将这些信息添加到pci_ecam_root_info_manager 66 /// 67 /// ## 返回值 68 /// 69 /// - Ok(()): 成功发现并添加了所有ECAM根信息 70 /// - Err(PciError): 在获取ACPI管理器表或发现MCFG表时发生错误 71 fn discover_ecam_root() -> Result<(), PciError> { 72 let mcfg = acpi_manager() 73 .tables() 74 .expect("get acpi_manager table error") 75 .find_table::<Mcfg>() 76 .map_err(|_| PciError::McfgTableNotFound)?; 77 for mcfg_entry in mcfg.entries() { 78 pci_ecam_root_info_manager().add_ecam_root_info(EcamRootInfo::new( 79 mcfg_entry.pci_segment_group, 80 mcfg_entry.bus_number_start, 81 mcfg_entry.bus_number_end, 82 PhysAddr::new(mcfg_entry.base_address as usize), 83 )); 84 } 85 86 Ok(()) 87 } 88