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