1 use crate::arch::TraitPciArch; 2 use crate::driver::acpi::acpi_manager; 3 use crate::driver::pci::pci::{ 4 BusDeviceFunction, PciAddr, PciError, PciRoot, SegmentGroupNumber, PORT_PCI_CONFIG_ADDRESS, 5 PORT_PCI_CONFIG_DATA, 6 }; 7 use crate::include::bindings::bindings::{io_in32, io_out32}; 8 use crate::mm::PhysAddr; 9 10 use acpi::mcfg::Mcfg; 11 12 pub struct X86_64PciArch; 13 impl TraitPciArch for X86_64PciArch { 14 fn read_config(bus_device_function: &BusDeviceFunction, offset: u8) -> u32 { 15 // 构造pci配置空间地址 16 let address = ((bus_device_function.bus as u32) << 16) 17 | ((bus_device_function.device as u32) << 11) 18 | ((bus_device_function.function as u32 & 7) << 8) 19 | (offset & 0xfc) as u32 20 | (0x80000000); 21 let ret = unsafe { 22 io_out32(PORT_PCI_CONFIG_ADDRESS, address); 23 let temp = io_in32(PORT_PCI_CONFIG_DATA); 24 temp 25 }; 26 return ret; 27 } 28 29 fn write_config(bus_device_function: &BusDeviceFunction, offset: u8, data: u32) { 30 let address = ((bus_device_function.bus as u32) << 16) 31 | ((bus_device_function.device as u32) << 11) 32 | ((bus_device_function.function as u32 & 7) << 8) 33 | (offset & 0xfc) as u32 34 | (0x80000000); 35 unsafe { 36 io_out32(PORT_PCI_CONFIG_ADDRESS, address); 37 // 写入数据 38 io_out32(PORT_PCI_CONFIG_DATA, data); 39 } 40 } 41 42 fn address_pci_to_physical(pci_address: PciAddr) -> PhysAddr { 43 return PhysAddr::new(pci_address.data()); 44 } 45 46 fn ecam_root(segement: SegmentGroupNumber) -> Result<PciRoot, PciError> { 47 let mcfg = acpi_manager() 48 .tables() 49 .expect("get acpi_manager table error") 50 .find_table::<Mcfg>() 51 .map_err(|_| PciError::McfgTableNotFound)?; 52 for mcfg_entry in mcfg.entries() { 53 if mcfg_entry.pci_segment_group == segement { 54 return Ok(PciRoot { 55 physical_address_base: PhysAddr::new(mcfg_entry.base_address as usize), 56 mmio_guard: None, 57 segement_group_number: segement, 58 bus_begin: mcfg_entry.bus_number_start, 59 bus_end: mcfg_entry.bus_number_end, 60 }); 61 } 62 } 63 return Err(PciError::SegmentNotFound); 64 } 65 } 66