xref: /DragonOS/kernel/src/arch/x86_64/pci/pci.rs (revision 5c1e552cc7f0a6ad75c8a1fa2928e3b9cc619657)
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         //kdebug!("{}",data);
54         //loop{}
55         let head = NonNull::new(data as *mut acpi_system_description_table_header_t).unwrap();
56         let outcome = unsafe { mcfg_find_segment(head).as_ref() };
57         for segmentgroupconfiguration in outcome {
58             if segmentgroupconfiguration.segement_group_number == segement {
59                 return Ok(PciRoot {
60                     physical_address_base: segmentgroupconfiguration.base_address,
61                     mmio_base: None,
62                     segement_group_number: segement,
63                     bus_begin: segmentgroupconfiguration.bus_begin,
64                     bus_end: segmentgroupconfiguration.bus_end,
65                 });
66             }
67         }
68         return Err(PciError::SegmentNotFound);
69     }
70 }
71