xref: /DragonOS/kernel/src/driver/pci/ecam.rs (revision f9fe30be89e89499aad4ef52b4648986bef5a7d8)
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)]
11 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 {
29     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实例
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