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