1370472f7SLoGin use fdt::{node::FdtNode, Fdt};
2*2eab6dd7S曾俊 use log::debug;
3370472f7SLoGin use system_error::SystemError;
4370472f7SLoGin
5370472f7SLoGin use crate::{
6370472f7SLoGin driver::{
7370472f7SLoGin open_firmware::fdt::open_firmware_fdt_driver,
8370472f7SLoGin pci::ecam::{pci_ecam_root_info_manager, EcamRootInfo},
9370472f7SLoGin },
10370472f7SLoGin mm::PhysAddr,
11370472f7SLoGin };
12370472f7SLoGin
pci_host_ecam_driver_init(fdt: &Fdt<'_>) -> Result<(), SystemError>13370472f7SLoGin pub(super) fn pci_host_ecam_driver_init(fdt: &Fdt<'_>) -> Result<(), SystemError> {
14370472f7SLoGin let do_check = |node: FdtNode| -> Result<(), SystemError> {
15370472f7SLoGin let reg = node
16370472f7SLoGin .reg()
17370472f7SLoGin .ok_or(SystemError::EINVAL)?
18370472f7SLoGin .next()
19370472f7SLoGin .ok_or(SystemError::EINVAL)?;
20370472f7SLoGin let paddr = reg.starting_address as usize;
21370472f7SLoGin let size = reg.size.unwrap_or(0);
22370472f7SLoGin let bus_range: &[u8] = node.property("bus-range").ok_or(SystemError::EINVAL)?.value;
23370472f7SLoGin
24370472f7SLoGin let (bus_begin, bus_end) = match bus_range.len() {
25370472f7SLoGin 8 => (
26370472f7SLoGin u32::from_be_bytes(bus_range[0..4].try_into().unwrap()),
27370472f7SLoGin u32::from_be_bytes(bus_range[4..8].try_into().unwrap()),
28370472f7SLoGin ),
29370472f7SLoGin _ => panic!("Unexpected bus-range length"),
30370472f7SLoGin };
31370472f7SLoGin
32370472f7SLoGin let segement_group_number: &[u8] = node
33370472f7SLoGin .property("linux,pci-domain")
34370472f7SLoGin .ok_or(SystemError::EINVAL)?
35370472f7SLoGin .value;
36370472f7SLoGin
37370472f7SLoGin let segement_group_number = match segement_group_number.len() {
38370472f7SLoGin 4 => u32::from_be_bytes(segement_group_number[0..4].try_into().unwrap()),
39370472f7SLoGin _ => panic!("Unexpected linux,pci-domain length"),
40370472f7SLoGin };
41370472f7SLoGin
42*2eab6dd7S曾俊 debug!(
43370472f7SLoGin "pci_host_ecam_driver_init(): {} paddr: {:#x} size: {:#x} bus-range: {}-{} segement_group_number: {}",
44370472f7SLoGin node.name,
45370472f7SLoGin paddr,
46370472f7SLoGin size,
47370472f7SLoGin bus_begin,
48370472f7SLoGin bus_end,
49370472f7SLoGin segement_group_number
50370472f7SLoGin );
51370472f7SLoGin
52370472f7SLoGin pci_ecam_root_info_manager().add_ecam_root_info(EcamRootInfo::new(
53370472f7SLoGin segement_group_number.try_into().unwrap(),
54370472f7SLoGin bus_begin as u8,
55370472f7SLoGin bus_end as u8,
56370472f7SLoGin PhysAddr::new(paddr),
57370472f7SLoGin ));
58370472f7SLoGin
59370472f7SLoGin Ok(())
60370472f7SLoGin };
61370472f7SLoGin
62370472f7SLoGin for node in open_firmware_fdt_driver().find_node_by_compatible(&fdt, "pci-host-ecam-generic") {
63370472f7SLoGin if let Err(err) = do_check(node) {
64*2eab6dd7S曾俊 debug!(
65370472f7SLoGin "pci_host_ecam_driver_init(): check {} error: {:?}",
66*2eab6dd7S曾俊 node.name, err
67370472f7SLoGin );
68370472f7SLoGin }
69370472f7SLoGin }
70370472f7SLoGin
71370472f7SLoGin return Ok(());
72370472f7SLoGin }
73