Skip to main content

strat9_bus_drivers/
registry.rs

1//! Bus driver registry : discovers and instantiates all known bus drivers.
2//!
3//! Each driver implements the `BusDriver` trait and declares one or more
4//! DeviceTree-compatible strings.  The registry attempts to initialise every
5//! driver; those that succeed are made available through the `/bus/` VFS
6//! scheme under their own name (e.g. `/bus/simple-pm-bus/status`).
7//!
8//! On systems that lack DeviceTree (e.g. x86) only generic drivers such as
9//! `SimplePmBus` are expected to succeed.  On ARM / embedded platforms the
10//! SoC-specific drivers will match their corresponding hardware blocks.
11use alloc::{boxed::Box, string::String, vec::Vec};
12use strat9_syscall::call;
13
14use crate::{
15    BusDriver,
16    arm_cci::ArmCci,
17    arm_integrator_lm::ArmIntegratorLm,
18    brcmstb_gisb::{BCM7038_OFFSETS, BrcmstbGisb},
19    bt1_apb::Bt1Apb,
20    bt1_axi::Bt1Axi,
21    da8xx_mstpri::Da8xxMstpri,
22    hisi_lpc::HisiLpc,
23    imx_aipstz::{IMX8MP_DEFAULT_CFG, ImxAipstz},
24    imx_weim::{IMX1_WEIM, ImxWeim},
25    intel_ixp4xx_eb::IntelIxp4xxEb,
26    mips_cdmm::MipsCdmm,
27    moxtet::Moxtet,
28    mvebu_mbus::MvebuMbus,
29    omap_l3_noc::OmapL3Noc,
30    omap_l3_smx::OmapL3Smx,
31    omap_ocp2scp::OmapOcp2Scp,
32    qcom_ebi2::QcomEbi2,
33    qcom_ssc_block_bus::QcomSscBlockBus,
34    simple_pm_bus::SimplePmBus,
35    stm32_etzpc::Stm32Etzpc,
36    stm32_rifsc::Stm32Rifsc,
37    sun50i_de2::Sun50iDe2,
38    sunxi_rsb::SunxiRsb,
39    tegra_aconnect::TegraAconnect,
40    tegra_gmi::TegraGmi,
41    ti_pwmss::TiPwmss,
42    ti_sysc::{REGBITS_OMAP4, TiSysc},
43    ts_nbus::TsNbus,
44    uniphier_system_bus::UniphierSystemBus,
45    vexpress_config::VexpressConfig,
46};
47
48/// Try to probe and init a driver; log and return `(name, driver)` on success.
49fn try_init<D: BusDriver + 'static>(
50    name: &str,
51    mut driver: D,
52) -> Option<(String, Box<dyn BusDriver>)> {
53    if !driver.probe() {
54        let msg = alloc::format!("[bus] {}: probe failed (no hardware detected)\n", name);
55        let _ = call::debug_log(msg.as_bytes());
56        return None;
57    }
58    match driver.init(0) {
59        Ok(()) => {
60            let msg = alloc::format!("[bus] {}: init OK\n", name);
61            let _ = call::debug_log(msg.as_bytes());
62            Some((String::from(name), Box::new(driver)))
63        }
64        Err(e) => {
65            let msg = alloc::format!("[bus] {}: init skipped ({:?})\n", name, e);
66            let _ = call::debug_log(msg.as_bytes());
67            None
68        }
69    }
70}
71
72/// Initialise all known bus drivers and return the ones that succeeded.
73///
74/// Call this once at startup, then pass the result to `BusSchemeServer::new()`.
75pub fn init_all() -> Vec<(String, Box<dyn BusDriver>)> {
76    let mut entries = Vec::new();
77
78    // ===  Generic / fallback =================================================
79    entries.extend(try_init("simple-pm-bus", SimplePmBus::new()));
80    entries.extend(try_init("vexpress-config", VexpressConfig::new()));
81
82    // ===  ARM / CoreLink =================================================
83    entries.extend(try_init("arm-cci", ArmCci::new()));
84    entries.extend(try_init("arm-integrator-lm", ArmIntegratorLm::new()));
85
86    // ===  Broadcom STB ===================================================
87    entries.extend(try_init("brcmstb-gisb", BrcmstbGisb::new(BCM7038_OFFSETS)));
88
89    // ===  Baikal-T1 ======================================================
90    entries.extend(try_init("bt1-apb", Bt1Apb::new()));
91    entries.extend(try_init("bt1-axi", Bt1Axi::new()));
92
93    // ===  Texas Instruments ==============================================
94    entries.extend(try_init("da8xx-mstpri", Da8xxMstpri::new()));
95    entries.extend(try_init("omap-l3-noc", OmapL3Noc::new()));
96    entries.extend(try_init("omap-l3-smx", OmapL3Smx::new()));
97    entries.extend(try_init("omap-ocp2scp", OmapOcp2Scp::new()));
98    entries.extend(try_init("ti-pwmss", TiPwmss::new()));
99    entries.extend(try_init("ti-sysc", TiSysc::new(&REGBITS_OMAP4)));
100
101    // ===  HiSilicon ======================================================
102    entries.extend(try_init("hisi-lpc", HisiLpc::new()));
103
104    // ===  NXP i.MX =======================================================
105    entries.extend(try_init("imx-aipstz", ImxAipstz::new(IMX8MP_DEFAULT_CFG)));
106    entries.extend(try_init("imx-weim", ImxWeim::new(IMX1_WEIM)));
107
108    // ===  Intel IXP4xx ===================================================
109    entries.extend(try_init("intel-ixp4xx-eb", IntelIxp4xxEb::new()));
110
111    // ===  MIPS ===========================================================
112
113    entries.extend(try_init("mips-cdmm", MipsCdmm::new()));
114
115    // ===  CZ.NIC Turris / Moxtet ========================================
116    entries.extend(try_init("moxtet", Moxtet::new()));
117
118    // ===  Marvell MVEBU ================================================
119    entries.extend(try_init("mvebu-mbus", MvebuMbus::new(20, true)));
120
121    // ===  Qualcomm =======================================================
122    entries.extend(try_init("qcom-ebi2", QcomEbi2::new()));
123    entries.extend(try_init("qcom-ssc-block-bus", QcomSscBlockBus::new()));
124
125    // ===  STM32 ==========================================================
126    entries.extend(try_init("stm32-etzpc", Stm32Etzpc::new()));
127    entries.extend(try_init("stm32-rifsc", Stm32Rifsc::new()));
128
129    // ===  Allwinner ======================================================
130    entries.extend(try_init("sun50i-de2", Sun50iDe2::new()));
131    entries.extend(try_init("sunxi-rsb", SunxiRsb::new()));
132
133    // ===  NVIDIA Tegra ===================================================
134    entries.extend(try_init("tegra-aconnect", TegraAconnect::new()));
135    entries.extend(try_init("tegra-gmi", TegraGmi::new()));
136
137    // ===  Technologic Systems ===========================================
138    entries.extend(try_init("ts-nbus", TsNbus::new()));
139
140    // ===  Socionext UniPhier ============================================
141    entries.extend(try_init("uniphier-system-bus", UniphierSystemBus::new()));
142
143    entries
144}