1 use log::{error, warn};
2
3 use crate::mm::PhysAddr;
4
5 use super::{
6 pci::{PciCam, SegmentGroupNumber},
7 root::{pci_root_manager, PciRoot},
8 };
9
10 #[inline(always)]
pci_ecam_root_info_manager() -> &'static EcamRootInfoManager11 pub fn pci_ecam_root_info_manager() -> &'static EcamRootInfoManager {
12 &EcamRootInfoManager
13 }
14
15 /// Ecam pci root info
16 #[derive(Clone, Debug, Copy)]
17 pub struct EcamRootInfo {
18 /// 段组号
19 pub segment_group_number: SegmentGroupNumber,
20 /// 该分组中的最小bus
21 pub bus_begin: u8,
22 /// 该分组中的最大bus
23 pub bus_end: u8,
24 /// 物理基地址
25 pub physical_address_base: PhysAddr,
26 }
27
28 impl EcamRootInfo {
new( segment_group_number: SegmentGroupNumber, bus_begin: u8, bus_end: u8, physical_address_base: PhysAddr, ) -> Self29 pub fn new(
30 segment_group_number: SegmentGroupNumber,
31 bus_begin: u8,
32 bus_end: u8,
33 physical_address_base: PhysAddr,
34 ) -> Self {
35 let ecam_root_info = Self {
36 segment_group_number,
37 bus_begin,
38 bus_end,
39 physical_address_base,
40 };
41 return ecam_root_info;
42 }
43 }
44
45 pub struct EcamRootInfoManager;
46
47 impl EcamRootInfoManager {
48 /// # add_ecam_root_info - 向EcamRootInfoManager添加EcamRootInfo
49 ///
50 /// 将一个新的EcamRootInfo添加到EcamRootInfoManager中。
51 ///
52 /// ## 参数
53 ///
54 /// - `ecam_root_info`: EcamRootInfo - 要添加的EcamRootInfo实例
add_ecam_root_info(&self, ecam_root_info: EcamRootInfo)55 pub fn add_ecam_root_info(&self, ecam_root_info: EcamRootInfo) {
56 if !pci_root_manager().has_root(ecam_root_info.segment_group_number) {
57 let root = PciRoot::new(
58 Some(ecam_root_info),
59 PciCam::Ecam,
60 ecam_root_info.bus_begin,
61 ecam_root_info.bus_end,
62 );
63
64 if let Err(err) = root {
65 error!("add_ecam_root_info(): failed to create PciRoot: {:?}", err);
66 return;
67 }
68
69 pci_root_manager().add_pci_root(root.unwrap());
70 } else {
71 warn!(
72 "add_ecam_root_info(): root {} already exists",
73 ecam_root_info.segment_group_number
74 );
75 }
76 }
77 }
78