xref: /DragonOS/kernel/src/driver/pci/ecam.rs (revision bde08cded6c6cbcaf00f6191fe257ae27e5db073)
12eab6dd7S曾俊 use log::{error, warn};
22eab6dd7S曾俊 
3370472f7SLoGin use crate::mm::PhysAddr;
4370472f7SLoGin 
5370472f7SLoGin use super::{
6370472f7SLoGin     pci::{PciCam, SegmentGroupNumber},
7370472f7SLoGin     root::{pci_root_manager, PciRoot},
8370472f7SLoGin };
9370472f7SLoGin 
10370472f7SLoGin #[inline(always)]
pci_ecam_root_info_manager() -> &'static EcamRootInfoManager11370472f7SLoGin pub fn pci_ecam_root_info_manager() -> &'static EcamRootInfoManager {
12370472f7SLoGin     &EcamRootInfoManager
13370472f7SLoGin }
14370472f7SLoGin 
15370472f7SLoGin /// Ecam pci root info
16*bde08cdeSMingtao Huang #[derive(Clone, Debug, Copy)]
17370472f7SLoGin pub struct EcamRootInfo {
18*bde08cdeSMingtao Huang     /// 段组号
19*bde08cdeSMingtao Huang     pub segment_group_number: SegmentGroupNumber,
20*bde08cdeSMingtao Huang     /// 该分组中的最小bus
21370472f7SLoGin     pub bus_begin: u8,
22*bde08cdeSMingtao Huang     /// 该分组中的最大bus
23370472f7SLoGin     pub bus_end: u8,
24*bde08cdeSMingtao Huang     /// 物理基地址
25370472f7SLoGin     pub physical_address_base: PhysAddr,
26370472f7SLoGin }
27370472f7SLoGin 
28370472f7SLoGin impl EcamRootInfo {
new( segment_group_number: SegmentGroupNumber, bus_begin: u8, bus_end: u8, physical_address_base: PhysAddr, ) -> Self29370472f7SLoGin     pub fn new(
30*bde08cdeSMingtao Huang         segment_group_number: SegmentGroupNumber,
31370472f7SLoGin         bus_begin: u8,
32370472f7SLoGin         bus_end: u8,
33370472f7SLoGin         physical_address_base: PhysAddr,
34370472f7SLoGin     ) -> Self {
35*bde08cdeSMingtao Huang         let ecam_root_info = Self {
36*bde08cdeSMingtao Huang             segment_group_number,
37370472f7SLoGin             bus_begin,
38370472f7SLoGin             bus_end,
39370472f7SLoGin             physical_address_base,
40*bde08cdeSMingtao Huang         };
41*bde08cdeSMingtao Huang         return ecam_root_info;
42370472f7SLoGin     }
43370472f7SLoGin }
44370472f7SLoGin 
45370472f7SLoGin pub struct EcamRootInfoManager;
46370472f7SLoGin 
47370472f7SLoGin impl EcamRootInfoManager {
48370472f7SLoGin     /// # add_ecam_root_info - 向EcamRootInfoManager添加EcamRootInfo
49370472f7SLoGin     ///
50370472f7SLoGin     /// 将一个新的EcamRootInfo添加到EcamRootInfoManager中。
51370472f7SLoGin     ///
52370472f7SLoGin     /// ## 参数
53370472f7SLoGin     ///
54370472f7SLoGin     /// - `ecam_root_info`: EcamRootInfo - 要添加的EcamRootInfo实例
add_ecam_root_info(&self, ecam_root_info: EcamRootInfo)55370472f7SLoGin     pub fn add_ecam_root_info(&self, ecam_root_info: EcamRootInfo) {
56*bde08cdeSMingtao Huang         if !pci_root_manager().has_root(ecam_root_info.segment_group_number) {
57370472f7SLoGin             let root = PciRoot::new(
58*bde08cdeSMingtao Huang                 Some(ecam_root_info),
59370472f7SLoGin                 PciCam::Ecam,
60370472f7SLoGin                 ecam_root_info.bus_begin,
61370472f7SLoGin                 ecam_root_info.bus_end,
62370472f7SLoGin             );
63370472f7SLoGin 
64370472f7SLoGin             if let Err(err) = root {
652eab6dd7S曾俊                 error!("add_ecam_root_info(): failed to create PciRoot: {:?}", err);
66370472f7SLoGin                 return;
67370472f7SLoGin             }
68370472f7SLoGin 
69370472f7SLoGin             pci_root_manager().add_pci_root(root.unwrap());
70370472f7SLoGin         } else {
712eab6dd7S曾俊             warn!(
72370472f7SLoGin                 "add_ecam_root_info(): root {} already exists",
73*bde08cdeSMingtao Huang                 ecam_root_info.segment_group_number
74370472f7SLoGin             );
75370472f7SLoGin         }
76370472f7SLoGin     }
77370472f7SLoGin }
78