xref: /DragonOS/kernel/src/arch/x86_64/pci/pci.rs (revision cc36cf4a186be834e6c2ab857b9b9501ddb8b1eb)
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 
11 use core::ffi::c_void;
12 use core::ptr::NonNull;
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) -> usize {
44         return 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         let head = NonNull::new(data as *mut acpi_system_description_table_header_t).unwrap();
60         let outcome = unsafe { mcfg_find_segment(head).as_ref() };
61         for segmentgroupconfiguration in outcome {
62             if segmentgroupconfiguration.segement_group_number == segement {
63                 return Ok(PciRoot {
64                     physical_address_base: segmentgroupconfiguration.base_address,
65                     mmio_base: None,
66                     segement_group_number: segement,
67                     bus_begin: segmentgroupconfiguration.bus_begin,
68                     bus_end: segmentgroupconfiguration.bus_end,
69                 });
70             }
71         }
72         return Err(PciError::SegmentNotFound);
73     }
74 }
75