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