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