xref: /DragonOS/kernel/src/arch/riscv64/pci/pci_host_ecam.rs (revision 370472f7288b568c7b80815f5b150daf4496446c)
1*370472f7SLoGin use fdt::{node::FdtNode, Fdt};
2*370472f7SLoGin use system_error::SystemError;
3*370472f7SLoGin 
4*370472f7SLoGin use crate::{
5*370472f7SLoGin     driver::{
6*370472f7SLoGin         open_firmware::fdt::open_firmware_fdt_driver,
7*370472f7SLoGin         pci::ecam::{pci_ecam_root_info_manager, EcamRootInfo},
8*370472f7SLoGin     },
9*370472f7SLoGin     kdebug,
10*370472f7SLoGin     mm::PhysAddr,
11*370472f7SLoGin };
12*370472f7SLoGin 
13*370472f7SLoGin pub(super) fn pci_host_ecam_driver_init(fdt: &Fdt<'_>) -> Result<(), SystemError> {
14*370472f7SLoGin     let do_check = |node: FdtNode| -> Result<(), SystemError> {
15*370472f7SLoGin         let reg = node
16*370472f7SLoGin             .reg()
17*370472f7SLoGin             .ok_or(SystemError::EINVAL)?
18*370472f7SLoGin             .next()
19*370472f7SLoGin             .ok_or(SystemError::EINVAL)?;
20*370472f7SLoGin         let paddr = reg.starting_address as usize;
21*370472f7SLoGin         let size = reg.size.unwrap_or(0);
22*370472f7SLoGin         let bus_range: &[u8] = node.property("bus-range").ok_or(SystemError::EINVAL)?.value;
23*370472f7SLoGin 
24*370472f7SLoGin         let (bus_begin, bus_end) = match bus_range.len() {
25*370472f7SLoGin             8 => (
26*370472f7SLoGin                 u32::from_be_bytes(bus_range[0..4].try_into().unwrap()),
27*370472f7SLoGin                 u32::from_be_bytes(bus_range[4..8].try_into().unwrap()),
28*370472f7SLoGin             ),
29*370472f7SLoGin             _ => panic!("Unexpected bus-range length"),
30*370472f7SLoGin         };
31*370472f7SLoGin 
32*370472f7SLoGin         let segement_group_number: &[u8] = node
33*370472f7SLoGin             .property("linux,pci-domain")
34*370472f7SLoGin             .ok_or(SystemError::EINVAL)?
35*370472f7SLoGin             .value;
36*370472f7SLoGin 
37*370472f7SLoGin         let segement_group_number = match segement_group_number.len() {
38*370472f7SLoGin             4 => u32::from_be_bytes(segement_group_number[0..4].try_into().unwrap()),
39*370472f7SLoGin             _ => panic!("Unexpected linux,pci-domain length"),
40*370472f7SLoGin         };
41*370472f7SLoGin 
42*370472f7SLoGin         kdebug!(
43*370472f7SLoGin             "pci_host_ecam_driver_init(): {} paddr: {:#x} size: {:#x} bus-range: {}-{} segement_group_number: {}",
44*370472f7SLoGin             node.name,
45*370472f7SLoGin             paddr,
46*370472f7SLoGin             size,
47*370472f7SLoGin             bus_begin,
48*370472f7SLoGin             bus_end,
49*370472f7SLoGin             segement_group_number
50*370472f7SLoGin         );
51*370472f7SLoGin 
52*370472f7SLoGin         pci_ecam_root_info_manager().add_ecam_root_info(EcamRootInfo::new(
53*370472f7SLoGin             segement_group_number.try_into().unwrap(),
54*370472f7SLoGin             bus_begin as u8,
55*370472f7SLoGin             bus_end as u8,
56*370472f7SLoGin             PhysAddr::new(paddr),
57*370472f7SLoGin         ));
58*370472f7SLoGin 
59*370472f7SLoGin         Ok(())
60*370472f7SLoGin     };
61*370472f7SLoGin 
62*370472f7SLoGin     for node in open_firmware_fdt_driver().find_node_by_compatible(&fdt, "pci-host-ecam-generic") {
63*370472f7SLoGin         if let Err(err) = do_check(node) {
64*370472f7SLoGin             kdebug!(
65*370472f7SLoGin                 "pci_host_ecam_driver_init(): check {} error: {:?}",
66*370472f7SLoGin                 node.name,
67*370472f7SLoGin                 err
68*370472f7SLoGin             );
69*370472f7SLoGin         }
70*370472f7SLoGin     }
71*370472f7SLoGin 
72*370472f7SLoGin     return Ok(());
73*370472f7SLoGin }
74