xref: /DragonOS/kernel/src/arch/x86_64/pci/pci.rs (revision 4895ff6968ae8f24c7a0d55dce6ae23082d60e3b)
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