xref: /DragonOS/kernel/src/arch/x86_64/pci/pci.rs (revision 8b3d1688daac2aaf4e87403ecda5467a01464f81)
178bf93f0SYJwu2023 use crate::arch::TraitPciArch;
2*8b3d1688Syuyi2439 use crate::driver::acpi::acpi_manager;
378bf93f0SYJwu2023 use crate::driver::pci::pci::{
45c1e552cSYJwu2023     BusDeviceFunction, PciAddr, PciError, PciRoot, SegmentGroupNumber, PORT_PCI_CONFIG_ADDRESS,
578bf93f0SYJwu2023     PORT_PCI_CONFIG_DATA,
678bf93f0SYJwu2023 };
7*8b3d1688Syuyi2439 use crate::include::bindings::bindings::{acpi_get_MCFG, acpi_iter_SDT, io_in32, io_out32};
82dd9f0c7SLoGin use crate::mm::PhysAddr;
978bf93f0SYJwu2023 
10*8b3d1688Syuyi2439 use acpi::mcfg::Mcfg;
1178bf93f0SYJwu2023 use core::ffi::c_void;
12*8b3d1688Syuyi2439 
13*8b3d1688Syuyi2439 pub struct X86_64PciArch;
1478bf93f0SYJwu2023 impl TraitPciArch for X86_64PciArch {
1578bf93f0SYJwu2023     fn read_config(bus_device_function: &BusDeviceFunction, offset: u8) -> u32 {
1678bf93f0SYJwu2023         // 构造pci配置空间地址
1778bf93f0SYJwu2023         let address = ((bus_device_function.bus as u32) << 16)
1878bf93f0SYJwu2023             | ((bus_device_function.device as u32) << 11)
1978bf93f0SYJwu2023             | ((bus_device_function.function as u32 & 7) << 8)
2078bf93f0SYJwu2023             | (offset & 0xfc) as u32
2178bf93f0SYJwu2023             | (0x80000000);
2278bf93f0SYJwu2023         let ret = unsafe {
2378bf93f0SYJwu2023             io_out32(PORT_PCI_CONFIG_ADDRESS, address);
2478bf93f0SYJwu2023             let temp = io_in32(PORT_PCI_CONFIG_DATA);
2578bf93f0SYJwu2023             temp
2678bf93f0SYJwu2023         };
2778bf93f0SYJwu2023         return ret;
2878bf93f0SYJwu2023     }
2978bf93f0SYJwu2023 
3078bf93f0SYJwu2023     fn write_config(bus_device_function: &BusDeviceFunction, offset: u8, data: u32) {
3178bf93f0SYJwu2023         let address = ((bus_device_function.bus as u32) << 16)
3278bf93f0SYJwu2023             | ((bus_device_function.device as u32) << 11)
3378bf93f0SYJwu2023             | ((bus_device_function.function as u32 & 7) << 8)
3478bf93f0SYJwu2023             | (offset & 0xfc) as u32
3578bf93f0SYJwu2023             | (0x80000000);
3678bf93f0SYJwu2023         unsafe {
3778bf93f0SYJwu2023             io_out32(PORT_PCI_CONFIG_ADDRESS, address);
3878bf93f0SYJwu2023             // 写入数据
3978bf93f0SYJwu2023             io_out32(PORT_PCI_CONFIG_DATA, data);
4078bf93f0SYJwu2023         }
4178bf93f0SYJwu2023     }
4278bf93f0SYJwu2023 
432dd9f0c7SLoGin     fn address_pci_to_physical(pci_address: PciAddr) -> PhysAddr {
442dd9f0c7SLoGin         return PhysAddr::new(pci_address.data());
4578bf93f0SYJwu2023     }
4678bf93f0SYJwu2023 
4778bf93f0SYJwu2023     fn ecam_root(segement: SegmentGroupNumber) -> Result<PciRoot, PciError> {
4878bf93f0SYJwu2023         let mut data: usize = 0;
4978bf93f0SYJwu2023         let data_point = &mut data;
5078bf93f0SYJwu2023         unsafe {
5178bf93f0SYJwu2023             acpi_iter_SDT(Some(acpi_get_MCFG), data_point as *mut usize as *mut c_void);
5278bf93f0SYJwu2023         };
53cc36cf4aSYJwu2023         // 防止无PCIE的机器找不到MCFG Table导致的错误
54cc36cf4aSYJwu2023         if data == 0 {
55cc36cf4aSYJwu2023             return Err(PciError::McfgTableNotFound);
56cc36cf4aSYJwu2023         }
5778bf93f0SYJwu2023         //kdebug!("{}",data);
5878bf93f0SYJwu2023         //loop{}
59*8b3d1688Syuyi2439 
60*8b3d1688Syuyi2439         let binding = acpi_manager()
61*8b3d1688Syuyi2439             .tables()
62*8b3d1688Syuyi2439             .expect("get acpi_manager table error")
63*8b3d1688Syuyi2439             .find_table::<Mcfg>();
64*8b3d1688Syuyi2439         if let Ok(mcfg) = binding {
65*8b3d1688Syuyi2439             for mcfg_entry in mcfg.entries() {
66*8b3d1688Syuyi2439                 if mcfg_entry.pci_segment_group == segement {
6778bf93f0SYJwu2023                     return Ok(PciRoot {
68*8b3d1688Syuyi2439                         physical_address_base: PhysAddr::new(mcfg_entry.base_address as usize),
692dd9f0c7SLoGin                         mmio_guard: None,
7078bf93f0SYJwu2023                         segement_group_number: segement,
71*8b3d1688Syuyi2439                         bus_begin: mcfg_entry.bus_number_start,
72*8b3d1688Syuyi2439                         bus_end: mcfg_entry.bus_number_end,
7378bf93f0SYJwu2023                     });
7478bf93f0SYJwu2023                 }
7578bf93f0SYJwu2023             }
76*8b3d1688Syuyi2439         }
7778bf93f0SYJwu2023         return Err(PciError::SegmentNotFound);
7878bf93f0SYJwu2023     }
7978bf93f0SYJwu2023 }
80