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