xref: /DragonOS/kernel/src/driver/base/platform/mod.rs (revision 78bf93f02f84bf5e024ddfb559f040e68ce39ccf)
12a7d773dSTingHuang use super::device::{
2*78bf93f0SYJwu2023     bus::{Bus, BusDriver, BusState, BUS_MANAGER},
32a7d773dSTingHuang     driver::Driver,
4*78bf93f0SYJwu2023     Device, DeviceError, DeviceState, DeviceType, IdTable,
52a7d773dSTingHuang };
6*78bf93f0SYJwu2023 use crate::libs::{mutex::Mutex, rwlock::RwLock};
7*78bf93f0SYJwu2023 use alloc::{
8*78bf93f0SYJwu2023     collections::{BTreeMap, BTreeSet},
9*78bf93f0SYJwu2023     sync::Arc,
10*78bf93f0SYJwu2023     vec::Vec,
11*78bf93f0SYJwu2023 };
12*78bf93f0SYJwu2023 use core::fmt::Debug;
13*78bf93f0SYJwu2023 use lazy_static::lazy_static;
142a7d773dSTingHuang use platform_device::PlatformDevice;
152a7d773dSTingHuang use platform_driver::PlatformDriver;
162a7d773dSTingHuang 
172a7d773dSTingHuang pub mod platform_device;
182a7d773dSTingHuang pub mod platform_driver;
192a7d773dSTingHuang 
202a7d773dSTingHuang /// @brief: platform总线匹配表
212a7d773dSTingHuang ///         总线上的设备和驱动都存在一份匹配表
222a7d773dSTingHuang ///         根据匹配表条目是否匹配来辨识设备和驱动能否进行匹配
232a7d773dSTingHuang #[derive(Debug)]
242a7d773dSTingHuang pub struct CompatibleTable(BTreeSet<&'static str>);
252a7d773dSTingHuang 
262a7d773dSTingHuang /// @brief: 匹配表操作方法集
272a7d773dSTingHuang impl CompatibleTable {
282a7d773dSTingHuang     /// @brief: 创建一个新的匹配表
292a7d773dSTingHuang     /// @parameter id_vec: 匹配条目数组
302a7d773dSTingHuang     /// @return: 匹配表
312a7d773dSTingHuang     #[inline]
322a7d773dSTingHuang     #[allow(dead_code)]
332a7d773dSTingHuang     pub fn new(id_vec: Vec<&'static str>) -> CompatibleTable {
342a7d773dSTingHuang         CompatibleTable(BTreeSet::from_iter(id_vec.iter().cloned()))
352a7d773dSTingHuang     }
362a7d773dSTingHuang 
372a7d773dSTingHuang     /// @brief: 判断两个匹配表是否能够匹配
382a7d773dSTingHuang     /// @parameter other: 其他匹配表
392a7d773dSTingHuang     /// @return: 如果匹配成功,返回true,否则,返回false
402a7d773dSTingHuang     #[allow(dead_code)]
412a7d773dSTingHuang     pub fn matches(&self, other: &CompatibleTable) -> bool {
422a7d773dSTingHuang         for id in &self.0 {
432a7d773dSTingHuang             if other.0.contains(id) {
442a7d773dSTingHuang                 return true;
452a7d773dSTingHuang             }
462a7d773dSTingHuang         }
472a7d773dSTingHuang         return false;
482a7d773dSTingHuang     }
492a7d773dSTingHuang }
502a7d773dSTingHuang 
512a7d773dSTingHuang /// @brief: platform总线驱动
522a7d773dSTingHuang #[derive(Debug)]
532a7d773dSTingHuang pub struct PlatformBusDriver {
542a7d773dSTingHuang     drivers: RwLock<BTreeMap<IdTable, Arc<dyn PlatformDriver>>>, // 总线上所有驱动
552a7d773dSTingHuang     devices: RwLock<BTreeMap<IdTable, Arc<dyn PlatformDevice>>>, // 总线上所有设备
562a7d773dSTingHuang }
572a7d773dSTingHuang 
582a7d773dSTingHuang impl PlatformBusDriver {
592a7d773dSTingHuang     /// @brief: 创建一个platform总线驱动,该驱动用于匹配plaform总线
602a7d773dSTingHuang     /// @parameter: None
612a7d773dSTingHuang     /// @return: platfor总线驱动
622a7d773dSTingHuang     #[inline]
632a7d773dSTingHuang     #[allow(dead_code)]
642a7d773dSTingHuang     pub fn new() -> Self {
652a7d773dSTingHuang         Self {
662a7d773dSTingHuang             drivers: RwLock::new(BTreeMap::new()),
672a7d773dSTingHuang             devices: RwLock::new(BTreeMap::new()),
682a7d773dSTingHuang         }
692a7d773dSTingHuang     }
702a7d773dSTingHuang 
712a7d773dSTingHuang     /// @brief: 获取该驱动的匹配表
722a7d773dSTingHuang     /// @parameter: None
732a7d773dSTingHuang     /// @return: 驱动的匹配表
742a7d773dSTingHuang     #[inline]
752a7d773dSTingHuang     #[allow(dead_code)]
762a7d773dSTingHuang     fn get_compatible_table(&self) -> CompatibleTable {
772a7d773dSTingHuang         CompatibleTable::new(vec!["platform"])
782a7d773dSTingHuang     }
792a7d773dSTingHuang 
802a7d773dSTingHuang     /// @brief: 根据设备标识符获取platform总线上的设备
812a7d773dSTingHuang     /// @parameter id_table: 设备标识符
822a7d773dSTingHuang     /// @return: 总线上的设备
832a7d773dSTingHuang     #[inline]
842a7d773dSTingHuang     #[allow(dead_code)]
852a7d773dSTingHuang     fn get_device(&self, id_table: &IdTable) -> Option<Arc<dyn PlatformDevice>> {
862a7d773dSTingHuang         let device_map = self.devices.read();
872a7d773dSTingHuang         return device_map.get(id_table).cloned();
882a7d773dSTingHuang     }
892a7d773dSTingHuang 
902a7d773dSTingHuang     /// @brief: 根据设备驱动标识符获取platform总线上的驱动
912a7d773dSTingHuang     /// @parameter id_table: 设备驱动标识符
922a7d773dSTingHuang     /// @return: 总线上的驱动
932a7d773dSTingHuang     #[inline]
942a7d773dSTingHuang     #[allow(dead_code)]
952a7d773dSTingHuang     fn get_driver(&self, id_table: &IdTable) -> Option<Arc<dyn PlatformDriver>> {
962a7d773dSTingHuang         let driver_map = self.drivers.read();
972a7d773dSTingHuang         return driver_map.get(id_table).cloned();
982a7d773dSTingHuang     }
992a7d773dSTingHuang 
1002a7d773dSTingHuang     /// @brief: 注册platform类型驱动
1012a7d773dSTingHuang     /// @parameter driver: platform类型驱动,该驱动需要实现PlatformDriver trait
1022a7d773dSTingHuang     /// @return: 注册成功,返回Ok(()),,注册失败,返回BusError类型
1032a7d773dSTingHuang     #[allow(dead_code)]
104*78bf93f0SYJwu2023     fn register_platform_driver(
105*78bf93f0SYJwu2023         &mut self,
106*78bf93f0SYJwu2023         driver: Arc<dyn PlatformDriver>,
107*78bf93f0SYJwu2023     ) -> Result<(), DeviceError> {
1082a7d773dSTingHuang         let id_table = driver.get_id_table();
1092a7d773dSTingHuang 
1102a7d773dSTingHuang         let mut drivers = self.drivers.write();
1112a7d773dSTingHuang         // 如果存在同类型的驱动,返回错误
1122a7d773dSTingHuang         if drivers.contains_key(&id_table) {
1132a7d773dSTingHuang             return Err(DeviceError::DriverExists);
1142a7d773dSTingHuang         } else {
1152a7d773dSTingHuang             drivers.insert(id_table.clone(), driver.clone());
1162a7d773dSTingHuang             return Ok(());
1172a7d773dSTingHuang         }
1182a7d773dSTingHuang     }
1192a7d773dSTingHuang 
1202a7d773dSTingHuang     /// @brief: 卸载platform类型驱动
1212a7d773dSTingHuang     /// @parameter driver: platform类型驱动,该驱动需挂载在plaform总线之上
1222a7d773dSTingHuang     /// @return: None
1232a7d773dSTingHuang     #[allow(dead_code)]
1242a7d773dSTingHuang     #[inline]
1252a7d773dSTingHuang     fn unregister_platform_driver(&mut self, driver: Arc<dyn PlatformDriver>) {
1262a7d773dSTingHuang         let id_table = driver.get_id_table();
1272a7d773dSTingHuang         self.drivers.write().remove(&id_table);
1282a7d773dSTingHuang     }
1292a7d773dSTingHuang 
1302a7d773dSTingHuang     /// @brief: 注册platform类型设备
1312a7d773dSTingHuang     /// @parameter driver: platform类型设备,该驱动需要实现PlatformDevice trait
1322a7d773dSTingHuang     /// @return: 注册成功,返回Ok(()),,注册失败,返回BusError类型
1332a7d773dSTingHuang     #[allow(dead_code)]
134*78bf93f0SYJwu2023     fn register_platform_device(
135*78bf93f0SYJwu2023         &mut self,
136*78bf93f0SYJwu2023         device: Arc<dyn PlatformDevice>,
137*78bf93f0SYJwu2023     ) -> Result<(), DeviceError> {
1382a7d773dSTingHuang         let id_table = device.get_id_table();
1392a7d773dSTingHuang 
1402a7d773dSTingHuang         let mut devices = self.devices.write();
1412a7d773dSTingHuang         if devices.contains_key(&id_table) {
1422a7d773dSTingHuang             return Err(DeviceError::DeviceExists);
1432a7d773dSTingHuang         } else {
1442a7d773dSTingHuang             devices.insert(id_table.clone(), device.clone());
1452a7d773dSTingHuang             return Ok(());
1462a7d773dSTingHuang         }
1472a7d773dSTingHuang     }
1482a7d773dSTingHuang 
1492a7d773dSTingHuang     /// @brief: 卸载platform类型设备
1502a7d773dSTingHuang     /// @parameter device: platform类型设备,该驱设备需挂载在plaform总线之上
1512a7d773dSTingHuang     /// @return: None
1522a7d773dSTingHuang     #[inline]
1532a7d773dSTingHuang     #[allow(dead_code)]
1542a7d773dSTingHuang     fn unregister_platform_device(&mut self, device: Arc<dyn PlatformDevice>) {
1552a7d773dSTingHuang         let id_table = device.get_id_table();
1562a7d773dSTingHuang         self.devices.write().remove(&id_table);
1572a7d773dSTingHuang     }
1582a7d773dSTingHuang 
1592a7d773dSTingHuang     /// @brief: 匹配platform类型驱动
1602a7d773dSTingHuang     /// @parameter driver: platform类型驱动
1612a7d773dSTingHuang     /// @return: 如果匹配成功,返回成功驱动的设备数,否则,返回BusError类型
1622a7d773dSTingHuang     #[allow(dead_code)]
1632a7d773dSTingHuang     fn driver_match_device(&self, driver: Arc<dyn PlatformDriver>) -> Result<i32, DeviceError> {
1642a7d773dSTingHuang         let mut num = 0;
1652a7d773dSTingHuang         let devices = self.devices.read();
1662a7d773dSTingHuang 
1672a7d773dSTingHuang         for (_dev_id_table, device) in devices.iter() {
168*78bf93f0SYJwu2023             if device
169*78bf93f0SYJwu2023                 .get_compatible_table()
170*78bf93f0SYJwu2023                 .matches(&driver.get_compatible_table())
171*78bf93f0SYJwu2023             {
1722a7d773dSTingHuang                 if !device.is_initialized() {
1732a7d773dSTingHuang                     // 设备未初始化,调用驱动probe函数
1742a7d773dSTingHuang                     match driver.probe(device.clone()) {
1752a7d773dSTingHuang                         Ok(()) => {
1762a7d773dSTingHuang                             num = num + 1;
1772a7d773dSTingHuang                             device.set_state(DeviceState::Initialized)
1782a7d773dSTingHuang                         },
1792a7d773dSTingHuang                         // 可以驱动很多设备,一个设备初始化出错即返回
1802a7d773dSTingHuang                         Err(_) => return Err(DeviceError::InitializeFailed),
1812a7d773dSTingHuang                     }
1822a7d773dSTingHuang                 }
1832a7d773dSTingHuang             }
1842a7d773dSTingHuang         }
1852a7d773dSTingHuang         if num == 0 {
1862a7d773dSTingHuang             return Err(DeviceError::NoDeviceForDriver);
1872a7d773dSTingHuang         } else {
1882a7d773dSTingHuang             return Ok(num);
1892a7d773dSTingHuang         }
1902a7d773dSTingHuang     }
1912a7d773dSTingHuang 
1922a7d773dSTingHuang     /// @brief: 匹配platform上的设备
1932a7d773dSTingHuang     /// @parameter driver: platform类型设备
1942a7d773dSTingHuang     /// @return: 如果匹配成功,返回Ok(()),否则,返回BusError类型
1952a7d773dSTingHuang     #[allow(dead_code)]
1962a7d773dSTingHuang     fn device_match_driver(&self, device: Arc<dyn PlatformDevice>) -> Result<(), DeviceError> {
1972a7d773dSTingHuang         let drivers = self.drivers.read();
1982a7d773dSTingHuang         for (_drv_id_table, driver) in &*drivers {
199*78bf93f0SYJwu2023             if driver
200*78bf93f0SYJwu2023                 .get_compatible_table()
201*78bf93f0SYJwu2023                 .matches(&device.get_compatible_table())
202*78bf93f0SYJwu2023             {
2032a7d773dSTingHuang                 match driver.probe(device.clone()) {
2042a7d773dSTingHuang                     Ok(_driver) => {
2052a7d773dSTingHuang                         // 将设备状态置为已初始化
2062a7d773dSTingHuang                         device.set_state(DeviceState::Initialized);
2072a7d773dSTingHuang                         return Ok(());
2082a7d773dSTingHuang                     }
2092a7d773dSTingHuang                     Err(_) => return Err(DeviceError::InitializeFailed),
2102a7d773dSTingHuang                 }
2112a7d773dSTingHuang             }
2122a7d773dSTingHuang         }
2132a7d773dSTingHuang         return Err(DeviceError::NoDriverForDevice);
2142a7d773dSTingHuang     }
2152a7d773dSTingHuang }
2162a7d773dSTingHuang 
2172a7d773dSTingHuang /// @brief: 为PlatformBusDriver实现Driver trait
2182a7d773dSTingHuang impl Driver for PlatformBusDriver {
2192a7d773dSTingHuang     fn get_id_table(&self) -> IdTable {
2202a7d773dSTingHuang         IdTable::new("PlatformBusDriver", 0)
2212a7d773dSTingHuang     }
2222a7d773dSTingHuang }
2232a7d773dSTingHuang 
2242a7d773dSTingHuang /// @brief: 为PlatformBusDriver实现BusDriver trait
2252a7d773dSTingHuang impl BusDriver for PlatformBusDriver {
2262a7d773dSTingHuang     fn is_empty(&self) -> bool {
2272a7d773dSTingHuang         if self.devices.read().is_empty() && self.drivers.read().is_empty() {
2282a7d773dSTingHuang             return true;
2292a7d773dSTingHuang         } else {
2302a7d773dSTingHuang             return false;
2312a7d773dSTingHuang         }
2322a7d773dSTingHuang     }
2332a7d773dSTingHuang }
2342a7d773dSTingHuang 
2352a7d773dSTingHuang /// @brief: platform总线
236*78bf93f0SYJwu2023 #[derive(Debug, Clone)]
2372a7d773dSTingHuang pub struct Platform {
2382a7d773dSTingHuang     state: Arc<Mutex<BusState>>,            // 总线状态
2392a7d773dSTingHuang     driver: Option<Arc<PlatformBusDriver>>, // 总线驱动
2402a7d773dSTingHuang }
2412a7d773dSTingHuang 
2422a7d773dSTingHuang /// @brief: platform方法集
2432a7d773dSTingHuang impl Platform {
2442a7d773dSTingHuang     /// @brief: 创建一个platform总线实例
2452a7d773dSTingHuang     /// @parameter: None
2462a7d773dSTingHuang     /// @return: platform总线实例
2472a7d773dSTingHuang     pub fn new() -> Self {
2482a7d773dSTingHuang         Self {
2492a7d773dSTingHuang             state: Arc::new(Mutex::new(BusState::NotInitialized)),
2502a7d773dSTingHuang             driver: Option::None,
2512a7d773dSTingHuang         }
2522a7d773dSTingHuang     }
2532a7d773dSTingHuang 
2542a7d773dSTingHuang     /// @brief: 获取总线的匹配表
2552a7d773dSTingHuang     /// @parameter: None
2562a7d773dSTingHuang     /// @return: platform总线匹配表
2572a7d773dSTingHuang     #[inline]
2582a7d773dSTingHuang     #[allow(dead_code)]
2592a7d773dSTingHuang     fn get_compatible_table(&self) -> CompatibleTable {
2602a7d773dSTingHuang         CompatibleTable::new(vec!["platform"])
2612a7d773dSTingHuang     }
2622a7d773dSTingHuang 
2632a7d773dSTingHuang     /// @brief: 判断总线是否初始化
2642a7d773dSTingHuang     /// @parameter: None
2652a7d773dSTingHuang     /// @return: 已初始化,返回true,否则,返回false
2662a7d773dSTingHuang     #[inline]
2672a7d773dSTingHuang     #[allow(dead_code)]
2682a7d773dSTingHuang     fn is_initialized(&self) -> bool {
2692a7d773dSTingHuang         let state = self.state.lock();
2702a7d773dSTingHuang         match *state {
2712a7d773dSTingHuang             BusState::Initialized => true,
2722a7d773dSTingHuang             _ => false,
2732a7d773dSTingHuang         }
2742a7d773dSTingHuang     }
2752a7d773dSTingHuang 
2762a7d773dSTingHuang     /// @brief: 设置总线状态
2772a7d773dSTingHuang     /// @parameter set_state: 总线状态BusState
2782a7d773dSTingHuang     /// @return: None
2792a7d773dSTingHuang     #[inline]
2802a7d773dSTingHuang     fn set_state(&self, set_state: BusState) {
2812a7d773dSTingHuang         let mut state = self.state.lock();
2822a7d773dSTingHuang         *state = set_state;
2832a7d773dSTingHuang     }
2842a7d773dSTingHuang 
2852a7d773dSTingHuang     /// @brief: 获取总线状态
2862a7d773dSTingHuang     /// @parameter: None
2872a7d773dSTingHuang     /// @return: 总线状态
2882a7d773dSTingHuang     #[inline]
2892a7d773dSTingHuang     #[allow(dead_code)]
2902a7d773dSTingHuang     fn get_state(&self) -> BusState {
2912a7d773dSTingHuang         let state = self.state.lock();
2922a7d773dSTingHuang         return *state;
2932a7d773dSTingHuang     }
2942a7d773dSTingHuang 
2952a7d773dSTingHuang     /// @brief:
2962a7d773dSTingHuang     /// @parameter: None
2972a7d773dSTingHuang     /// @return: 总线状态
2982a7d773dSTingHuang     #[inline]
2992a7d773dSTingHuang     #[allow(dead_code)]
3002a7d773dSTingHuang     fn set_driver(&mut self, driver: Option<Arc<PlatformBusDriver>>) {
3012a7d773dSTingHuang         self.driver = driver;
3022a7d773dSTingHuang     }
3032a7d773dSTingHuang }
3042a7d773dSTingHuang 
3052a7d773dSTingHuang /// @brief: 为Platform实现Device trait,platform总线也是一种设备,属于总线设备类型
3062a7d773dSTingHuang impl Device for Platform {
3072a7d773dSTingHuang     /// @brief: 获取platform设备类型
3082a7d773dSTingHuang     /// @parameter: None
3092a7d773dSTingHuang     /// @return: Bus类型
3102a7d773dSTingHuang     #[inline]
3112a7d773dSTingHuang     #[allow(dead_code)]
3122a7d773dSTingHuang     fn get_type(&self) -> DeviceType {
3132a7d773dSTingHuang         return DeviceType::Bus;
3142a7d773dSTingHuang     }
3152a7d773dSTingHuang 
3162a7d773dSTingHuang     /// @brief: 获取platform设备标识符
3172a7d773dSTingHuang     /// @parameter: None
3182a7d773dSTingHuang     /// @return: platform总线设备标识符
3192a7d773dSTingHuang     #[inline]
3202a7d773dSTingHuang     #[allow(dead_code)]
3212a7d773dSTingHuang     fn get_id_table(&self) -> IdTable {
3222a7d773dSTingHuang         IdTable::new("platform", 0)
3232a7d773dSTingHuang     }
3242a7d773dSTingHuang }
3252a7d773dSTingHuang 
3262a7d773dSTingHuang /// @brief: 为Platform实现Bus trait,platform总线是一种总线设备
3272a7d773dSTingHuang impl Bus for Platform {}
3282a7d773dSTingHuang 
3292a7d773dSTingHuang lazy_static! {
3302a7d773dSTingHuang     pub static ref BUS_PLATFORM_DRIVER: Arc<PlatformBusDriver> = Arc::new(PlatformBusDriver::new());
3312a7d773dSTingHuang     pub static ref BUS_PLATFORM_DEVICE: Arc<Platform> = Arc::new(Platform::new());
3322a7d773dSTingHuang }
3332a7d773dSTingHuang 
3342a7d773dSTingHuang /// @brief: 初始化platform总线
3352a7d773dSTingHuang /// @parameter: None
3362a7d773dSTingHuang /// @return: None
3372a7d773dSTingHuang #[allow(dead_code)]
3382a7d773dSTingHuang pub fn platform_bus_init() {
339*78bf93f0SYJwu2023     BUS_MANAGER.add_bus_driver(
340*78bf93f0SYJwu2023         BUS_PLATFORM_DRIVER.get_id_table(),
341*78bf93f0SYJwu2023         BUS_PLATFORM_DRIVER.clone(),
342*78bf93f0SYJwu2023     );
343*78bf93f0SYJwu2023     BUS_MANAGER.add_bus(
344*78bf93f0SYJwu2023         BUS_PLATFORM_DEVICE.get_id_table(),
345*78bf93f0SYJwu2023         BUS_PLATFORM_DEVICE.clone(),
346*78bf93f0SYJwu2023     );
3472a7d773dSTingHuang     BUS_PLATFORM_DEVICE.set_state(BusState::Initialized);
3482a7d773dSTingHuang }
3492a7d773dSTingHuang 
3502a7d773dSTingHuang #[no_mangle]
3512a7d773dSTingHuang extern "C" fn c_platform_bus_init() {
352*78bf93f0SYJwu2023     BUS_MANAGER.add_bus_driver(
353*78bf93f0SYJwu2023         BUS_PLATFORM_DRIVER.get_id_table(),
354*78bf93f0SYJwu2023         BUS_PLATFORM_DRIVER.clone(),
355*78bf93f0SYJwu2023     );
356*78bf93f0SYJwu2023     BUS_MANAGER.add_bus(
357*78bf93f0SYJwu2023         BUS_PLATFORM_DEVICE.get_id_table(),
358*78bf93f0SYJwu2023         BUS_PLATFORM_DEVICE.clone(),
359*78bf93f0SYJwu2023     );
3602a7d773dSTingHuang     BUS_PLATFORM_DEVICE.set_state(BusState::Initialized);
3612a7d773dSTingHuang }
362