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::{acpi_get_MCFG, acpi_iter_SDT, io_in32, io_out32}; 8 use crate::mm::PhysAddr; 9 10 use acpi::mcfg::Mcfg; 11 use core::ffi::c_void; 12 13 pub struct X86_64PciArch; 14 impl TraitPciArch for X86_64PciArch { 15 fn read_config(bus_device_function: &BusDeviceFunction, offset: u8) -> u32 { 16 // 构造pci配置空间地址 17 let address = ((bus_device_function.bus as u32) << 16) 18 | ((bus_device_function.device as u32) << 11) 19 | ((bus_device_function.function as u32 & 7) << 8) 20 | (offset & 0xfc) as u32 21 | (0x80000000); 22 let ret = unsafe { 23 io_out32(PORT_PCI_CONFIG_ADDRESS, address); 24 let temp = io_in32(PORT_PCI_CONFIG_DATA); 25 temp 26 }; 27 return ret; 28 } 29 30 fn write_config(bus_device_function: &BusDeviceFunction, offset: u8, data: u32) { 31 let address = ((bus_device_function.bus as u32) << 16) 32 | ((bus_device_function.device as u32) << 11) 33 | ((bus_device_function.function as u32 & 7) << 8) 34 | (offset & 0xfc) as u32 35 | (0x80000000); 36 unsafe { 37 io_out32(PORT_PCI_CONFIG_ADDRESS, address); 38 // 写入数据 39 io_out32(PORT_PCI_CONFIG_DATA, data); 40 } 41 } 42 43 fn address_pci_to_physical(pci_address: PciAddr) -> PhysAddr { 44 return PhysAddr::new(pci_address.data()); 45 } 46 47 fn ecam_root(segement: SegmentGroupNumber) -> Result<PciRoot, PciError> { 48 let mut data: usize = 0; 49 let data_point = &mut data; 50 unsafe { 51 acpi_iter_SDT(Some(acpi_get_MCFG), data_point as *mut usize as *mut c_void); 52 }; 53 // 防止无PCIE的机器找不到MCFG Table导致的错误 54 if data == 0 { 55 return Err(PciError::McfgTableNotFound); 56 } 57 //kdebug!("{}",data); 58 //loop{} 59 60 let binding = acpi_manager() 61 .tables() 62 .expect("get acpi_manager table error") 63 .find_table::<Mcfg>(); 64 if let Ok(mcfg) = binding { 65 for mcfg_entry in mcfg.entries() { 66 if mcfg_entry.pci_segment_group == segement { 67 return Ok(PciRoot { 68 physical_address_base: PhysAddr::new(mcfg_entry.base_address as usize), 69 mmio_guard: None, 70 segement_group_number: segement, 71 bus_begin: mcfg_entry.bus_number_start, 72 bus_end: mcfg_entry.bus_number_end, 73 }); 74 } 75 } 76 } 77 return Err(PciError::SegmentNotFound); 78 } 79 } 80