xref: /DragonOS/kernel/src/driver/base/platform/mod.rs (revision b087521e07f601b30e3d48df788fcc2f09f19566)
12a7d773dSTingHuang use super::device::{
2e0de0fd6STingHuang     bus::{bus_driver_register, bus_register, Bus, BusDriver, BusState},
3*b087521eSChiichen     driver::DriverError,
4*b087521eSChiichen     Device, DeviceError, DeviceNumber, DevicePrivateData, DeviceResource, DeviceType, IdTable,
5*b087521eSChiichen     KObject,
62a7d773dSTingHuang };
7*b087521eSChiichen use crate::{
8*b087521eSChiichen     driver::Driver, filesystem::vfs::IndexNode, libs::spinlock::SpinLock, syscall::SystemError,
9*b087521eSChiichen };
1078bf93f0SYJwu2023 use alloc::{
1178bf93f0SYJwu2023     collections::{BTreeMap, BTreeSet},
12*b087521eSChiichen     string::ToString,
1378bf93f0SYJwu2023     sync::Arc,
1478bf93f0SYJwu2023     vec::Vec,
1578bf93f0SYJwu2023 };
1678bf93f0SYJwu2023 use core::fmt::Debug;
172a7d773dSTingHuang use platform_device::PlatformDevice;
182a7d773dSTingHuang use platform_driver::PlatformDriver;
192a7d773dSTingHuang 
202a7d773dSTingHuang pub mod platform_device;
212a7d773dSTingHuang pub mod platform_driver;
222a7d773dSTingHuang 
232a7d773dSTingHuang /// @brief: platform总线匹配表
242a7d773dSTingHuang ///         总线上的设备和驱动都存在一份匹配表
252a7d773dSTingHuang ///         根据匹配表条目是否匹配来辨识设备和驱动能否进行匹配
26*b087521eSChiichen #[derive(Debug, Clone)]
272a7d773dSTingHuang pub struct CompatibleTable(BTreeSet<&'static str>);
282a7d773dSTingHuang 
292a7d773dSTingHuang /// @brief: 匹配表操作方法集
302a7d773dSTingHuang impl CompatibleTable {
312a7d773dSTingHuang     /// @brief: 创建一个新的匹配表
322a7d773dSTingHuang     /// @parameter id_vec: 匹配条目数组
332a7d773dSTingHuang     /// @return: 匹配表
342a7d773dSTingHuang     #[inline]
352a7d773dSTingHuang     #[allow(dead_code)]
362a7d773dSTingHuang     pub fn new(id_vec: Vec<&'static str>) -> CompatibleTable {
372a7d773dSTingHuang         CompatibleTable(BTreeSet::from_iter(id_vec.iter().cloned()))
382a7d773dSTingHuang     }
392a7d773dSTingHuang 
402a7d773dSTingHuang     /// @brief: 判断两个匹配表是否能够匹配
412a7d773dSTingHuang     /// @parameter other: 其他匹配表
422a7d773dSTingHuang     /// @return: 如果匹配成功,返回true,否则,返回false
432a7d773dSTingHuang     #[allow(dead_code)]
442a7d773dSTingHuang     pub fn matches(&self, other: &CompatibleTable) -> bool {
45*b087521eSChiichen         self.0.intersection(&other.0).next().is_some()
462a7d773dSTingHuang     }
47*b087521eSChiichen 
48*b087521eSChiichen     /// @brief: 添加一组匹配条目
49*b087521eSChiichen     /// @param:
50*b087521eSChiichen     #[allow(dead_code)]
51*b087521eSChiichen     pub fn add_device(&mut self, devices: Vec<&'static str>) {
52*b087521eSChiichen         for str in devices {
53*b087521eSChiichen             self.0.insert(str);
542a7d773dSTingHuang         }
552a7d773dSTingHuang     }
562a7d773dSTingHuang }
572a7d773dSTingHuang 
582a7d773dSTingHuang #[derive(Debug)]
59e0de0fd6STingHuang pub struct LockedPlatformBusDriver(SpinLock<PlatformBusDriver>);
602a7d773dSTingHuang 
61e0de0fd6STingHuang impl LockedPlatformBusDriver {
62e0de0fd6STingHuang     /// @brief: 创建一个platform总线加锁驱动,该驱动用于匹配plaform总线
632a7d773dSTingHuang     /// @parameter: None
642a7d773dSTingHuang     /// @return: platfor总线驱动
652a7d773dSTingHuang     #[inline]
662a7d773dSTingHuang     #[allow(dead_code)]
67e0de0fd6STingHuang     pub fn new() -> LockedPlatformBusDriver {
68e0de0fd6STingHuang         LockedPlatformBusDriver(SpinLock::new(PlatformBusDriver::new()))
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>> {
86e0de0fd6STingHuang         let device_map = &self.0.lock().devices;
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>> {
96e0de0fd6STingHuang         let driver_map = &self.0.lock().drivers;
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)]
104e0de0fd6STingHuang     fn register_platform_driver(&self, driver: Arc<dyn PlatformDriver>) -> Result<(), DeviceError> {
1050663027bSTingHuang         let id_table = driver.id_table();
1062a7d773dSTingHuang 
107e0de0fd6STingHuang         let drivers = &mut self.0.lock().drivers;
1082a7d773dSTingHuang         // 如果存在同类型的驱动,返回错误
1092a7d773dSTingHuang         if drivers.contains_key(&id_table) {
1102a7d773dSTingHuang             return Err(DeviceError::DriverExists);
1112a7d773dSTingHuang         } else {
1122a7d773dSTingHuang             drivers.insert(id_table.clone(), driver.clone());
1132a7d773dSTingHuang             return Ok(());
1142a7d773dSTingHuang         }
1152a7d773dSTingHuang     }
1162a7d773dSTingHuang 
1172a7d773dSTingHuang     /// @brief: 卸载platform类型驱动
1182a7d773dSTingHuang     /// @parameter driver: platform类型驱动,该驱动需挂载在plaform总线之上
1192a7d773dSTingHuang     /// @return: None
1202a7d773dSTingHuang     #[allow(dead_code)]
1212a7d773dSTingHuang     #[inline]
122*b087521eSChiichen     fn unregister_platform_driver(
123*b087521eSChiichen         &mut self,
124*b087521eSChiichen         driver: Arc<dyn PlatformDriver>,
125*b087521eSChiichen     ) -> Result<(), DeviceError> {
1260663027bSTingHuang         let id_table = driver.id_table();
127e0de0fd6STingHuang         self.0.lock().drivers.remove(&id_table);
128*b087521eSChiichen         return Ok(());
1292a7d773dSTingHuang     }
1302a7d773dSTingHuang 
1312a7d773dSTingHuang     /// @brief: 注册platform类型设备
1322a7d773dSTingHuang     /// @parameter driver: platform类型设备,该驱动需要实现PlatformDevice trait
1332a7d773dSTingHuang     /// @return: 注册成功,返回Ok(()),,注册失败,返回BusError类型
1342a7d773dSTingHuang     #[allow(dead_code)]
13578bf93f0SYJwu2023     fn register_platform_device(
13678bf93f0SYJwu2023         &mut self,
13778bf93f0SYJwu2023         device: Arc<dyn PlatformDevice>,
13878bf93f0SYJwu2023     ) -> Result<(), DeviceError> {
1390663027bSTingHuang         let id_table = device.id_table();
1402a7d773dSTingHuang 
141e0de0fd6STingHuang         let devices = &mut self.0.lock().devices;
1422a7d773dSTingHuang         if devices.contains_key(&id_table) {
1432a7d773dSTingHuang             return Err(DeviceError::DeviceExists);
1442a7d773dSTingHuang         } else {
1452a7d773dSTingHuang             devices.insert(id_table.clone(), device.clone());
1462a7d773dSTingHuang             return Ok(());
1472a7d773dSTingHuang         }
1482a7d773dSTingHuang     }
1492a7d773dSTingHuang 
1502a7d773dSTingHuang     /// @brief: 卸载platform类型设备
1512a7d773dSTingHuang     /// @parameter device: platform类型设备,该驱设备需挂载在plaform总线之上
1522a7d773dSTingHuang     /// @return: None
1532a7d773dSTingHuang     #[inline]
1542a7d773dSTingHuang     #[allow(dead_code)]
1552a7d773dSTingHuang     fn unregister_platform_device(&mut self, device: Arc<dyn PlatformDevice>) {
1560663027bSTingHuang         let id_table = device.id_table();
157e0de0fd6STingHuang         self.0.lock().devices.remove(&id_table);
1582a7d773dSTingHuang     }
1592a7d773dSTingHuang }
1602a7d773dSTingHuang 
161e0de0fd6STingHuang /// @brief: platform总线驱动
162e0de0fd6STingHuang #[derive(Debug)]
163e0de0fd6STingHuang pub struct PlatformBusDriver {
164e0de0fd6STingHuang     drivers: BTreeMap<IdTable, Arc<dyn PlatformDriver>>, // 总线上所有驱动
165e0de0fd6STingHuang     devices: BTreeMap<IdTable, Arc<dyn PlatformDevice>>, // 总线上所有设备
166e0de0fd6STingHuang     sys_info: Option<Arc<dyn IndexNode>>,
167e0de0fd6STingHuang }
168e0de0fd6STingHuang 
169e0de0fd6STingHuang impl PlatformBusDriver {
170e0de0fd6STingHuang     /// @brief: 创建一个platform总线驱动,该驱动用于匹配plaform总线
171e0de0fd6STingHuang     /// @parameter: None
172e0de0fd6STingHuang     /// @return: platfor总线驱动
173e0de0fd6STingHuang     #[inline]
174e0de0fd6STingHuang     #[allow(dead_code)]
175e0de0fd6STingHuang     pub fn new() -> Self {
176e0de0fd6STingHuang         Self {
177e0de0fd6STingHuang             drivers: BTreeMap::new(),
178e0de0fd6STingHuang             devices: BTreeMap::new(),
179e0de0fd6STingHuang             sys_info: None,
180e0de0fd6STingHuang         }
181e0de0fd6STingHuang     }
182e0de0fd6STingHuang }
183e0de0fd6STingHuang 
1842a7d773dSTingHuang /// @brief: 为PlatformBusDriver实现Driver trait
185e0de0fd6STingHuang impl Driver for LockedPlatformBusDriver {
186e0de0fd6STingHuang     #[inline]
187e0de0fd6STingHuang     fn as_any_ref(&self) -> &dyn core::any::Any {
188e0de0fd6STingHuang         self
189e0de0fd6STingHuang     }
190e0de0fd6STingHuang 
191e0de0fd6STingHuang     #[inline]
1920663027bSTingHuang     fn id_table(&self) -> IdTable {
193*b087521eSChiichen         return IdTable::new("PlatformBusDriver".to_string(), DeviceNumber::new(0));
1942a7d773dSTingHuang     }
195e0de0fd6STingHuang 
196e0de0fd6STingHuang     #[inline]
197e0de0fd6STingHuang     #[allow(dead_code)]
198e0de0fd6STingHuang     fn sys_info(&self) -> Option<Arc<dyn IndexNode>> {
199e0de0fd6STingHuang         return self.0.lock().sys_info.clone();
200e0de0fd6STingHuang     }
201e0de0fd6STingHuang 
202e0de0fd6STingHuang     #[inline]
203e0de0fd6STingHuang     #[allow(dead_code)]
204e0de0fd6STingHuang     fn set_sys_info(&self, sys_info: Option<Arc<dyn IndexNode>>) {
205e0de0fd6STingHuang         self.0.lock().sys_info = sys_info;
206e0de0fd6STingHuang     }
207*b087521eSChiichen 
208*b087521eSChiichen     fn probe(&self, _data: &DevicePrivateData) -> Result<(), DriverError> {
209*b087521eSChiichen         todo!()
210*b087521eSChiichen     }
211*b087521eSChiichen 
212*b087521eSChiichen     fn load(
213*b087521eSChiichen         &self,
214*b087521eSChiichen         _data: DevicePrivateData,
215*b087521eSChiichen         _resource: Option<DeviceResource>,
216*b087521eSChiichen     ) -> Result<Arc<dyn Device>, DriverError> {
217*b087521eSChiichen         todo!()
218*b087521eSChiichen     }
2192a7d773dSTingHuang }
2202a7d773dSTingHuang 
2212a7d773dSTingHuang /// @brief: 为PlatformBusDriver实现BusDriver trait
222e0de0fd6STingHuang impl BusDriver for LockedPlatformBusDriver {
2232a7d773dSTingHuang     fn is_empty(&self) -> bool {
224e0de0fd6STingHuang         if self.0.lock().devices.is_empty() && self.0.lock().drivers.is_empty() {
2252a7d773dSTingHuang             return true;
2262a7d773dSTingHuang         } else {
2272a7d773dSTingHuang             return false;
2282a7d773dSTingHuang         }
2292a7d773dSTingHuang     }
2302a7d773dSTingHuang }
2312a7d773dSTingHuang 
2320663027bSTingHuang impl KObject for LockedPlatformBusDriver {}
2330663027bSTingHuang 
234e0de0fd6STingHuang #[derive(Debug)]
235e0de0fd6STingHuang pub struct LockedPlatform(SpinLock<Platform>);
2362a7d773dSTingHuang 
237e0de0fd6STingHuang impl LockedPlatform {
238e0de0fd6STingHuang     /// @brief: 创建一个加锁的platform总线实例
2392a7d773dSTingHuang     /// @parameter: None
2402a7d773dSTingHuang     /// @return: platform总线实例
241*b087521eSChiichen     pub fn new(data: DevicePrivateData) -> LockedPlatform {
242*b087521eSChiichen         LockedPlatform(SpinLock::new(Platform::new(data)))
2432a7d773dSTingHuang     }
2442a7d773dSTingHuang 
2452a7d773dSTingHuang     /// @brief: 获取总线的匹配表
2462a7d773dSTingHuang     /// @parameter: None
2472a7d773dSTingHuang     /// @return: platform总线匹配表
2482a7d773dSTingHuang     #[inline]
2492a7d773dSTingHuang     #[allow(dead_code)]
2500663027bSTingHuang     fn compatible_table(&self) -> CompatibleTable {
2512a7d773dSTingHuang         CompatibleTable::new(vec!["platform"])
2522a7d773dSTingHuang     }
2532a7d773dSTingHuang 
2542a7d773dSTingHuang     /// @brief: 判断总线是否初始化
2552a7d773dSTingHuang     /// @parameter: None
2562a7d773dSTingHuang     /// @return: 已初始化,返回true,否则,返回false
2572a7d773dSTingHuang     #[inline]
2582a7d773dSTingHuang     #[allow(dead_code)]
2592a7d773dSTingHuang     fn is_initialized(&self) -> bool {
260e0de0fd6STingHuang         let state = self.0.lock().state;
261e0de0fd6STingHuang         match state {
2622a7d773dSTingHuang             BusState::Initialized => true,
2632a7d773dSTingHuang             _ => false,
2642a7d773dSTingHuang         }
2652a7d773dSTingHuang     }
2662a7d773dSTingHuang 
2672a7d773dSTingHuang     /// @brief: 设置总线状态
2682a7d773dSTingHuang     /// @parameter set_state: 总线状态BusState
2692a7d773dSTingHuang     /// @return: None
2702a7d773dSTingHuang     #[inline]
2712a7d773dSTingHuang     fn set_state(&self, set_state: BusState) {
272e0de0fd6STingHuang         let state = &mut self.0.lock().state;
2732a7d773dSTingHuang         *state = set_state;
2742a7d773dSTingHuang     }
2752a7d773dSTingHuang 
2762a7d773dSTingHuang     /// @brief: 获取总线状态
2772a7d773dSTingHuang     /// @parameter: None
2782a7d773dSTingHuang     /// @return: 总线状态
2792a7d773dSTingHuang     #[inline]
2802a7d773dSTingHuang     #[allow(dead_code)]
2812a7d773dSTingHuang     fn get_state(&self) -> BusState {
282e0de0fd6STingHuang         let state = self.0.lock().state;
283e0de0fd6STingHuang         return state;
2842a7d773dSTingHuang     }
2852a7d773dSTingHuang 
286*b087521eSChiichen     // /// @brief:
287*b087521eSChiichen     // /// @parameter: None
288*b087521eSChiichen     // /// @return: 总线状态
289*b087521eSChiichen     // #[inline]
290*b087521eSChiichen     // #[allow(dead_code)]
291*b087521eSChiichen     // fn set_driver(&self, driver: Option<Arc<LockedPlatformBusDriver>>) {
292*b087521eSChiichen     //     self.0.lock().driver = driver;
293*b087521eSChiichen     // }
294e0de0fd6STingHuang }
295e0de0fd6STingHuang 
296e0de0fd6STingHuang /// @brief: platform总线
297e0de0fd6STingHuang #[derive(Debug, Clone)]
298e0de0fd6STingHuang pub struct Platform {
299*b087521eSChiichen     _data: DevicePrivateData,
300e0de0fd6STingHuang     state: BusState,                      // 总线状态
301e0de0fd6STingHuang     sys_info: Option<Arc<dyn IndexNode>>, // 总线sys information
302e0de0fd6STingHuang }
303e0de0fd6STingHuang 
304e0de0fd6STingHuang /// @brief: platform方法集
305e0de0fd6STingHuang impl Platform {
306e0de0fd6STingHuang     /// @brief: 创建一个platform总线实例
307e0de0fd6STingHuang     /// @parameter: None
308e0de0fd6STingHuang     /// @return: platform总线实例
309*b087521eSChiichen     pub fn new(_data: DevicePrivateData) -> Self {
310e0de0fd6STingHuang         Self {
311*b087521eSChiichen             _data,
312e0de0fd6STingHuang             state: BusState::NotInitialized,
313e0de0fd6STingHuang             sys_info: Option::None,
314e0de0fd6STingHuang         }
3152a7d773dSTingHuang     }
3162a7d773dSTingHuang }
3172a7d773dSTingHuang 
3182a7d773dSTingHuang /// @brief: 为Platform实现Device trait,platform总线也是一种设备,属于总线设备类型
319e0de0fd6STingHuang impl Device for LockedPlatform {
3202a7d773dSTingHuang     #[inline]
3212a7d773dSTingHuang     #[allow(dead_code)]
3220663027bSTingHuang     fn dev_type(&self) -> DeviceType {
3232a7d773dSTingHuang         return DeviceType::Bus;
3242a7d773dSTingHuang     }
3252a7d773dSTingHuang 
3262a7d773dSTingHuang     #[inline]
3272a7d773dSTingHuang     #[allow(dead_code)]
3280663027bSTingHuang     fn id_table(&self) -> IdTable {
329*b087521eSChiichen         IdTable::new("platform".to_string(), DeviceNumber::new(0))
3302a7d773dSTingHuang     }
331e0de0fd6STingHuang 
332e0de0fd6STingHuang     #[inline]
333e0de0fd6STingHuang     fn set_sys_info(&self, sys_info: Option<Arc<dyn IndexNode>>) {
334e0de0fd6STingHuang         self.0.lock().sys_info = sys_info;
335e0de0fd6STingHuang     }
336e0de0fd6STingHuang 
337e0de0fd6STingHuang     #[inline]
338e0de0fd6STingHuang     #[allow(dead_code)]
339e0de0fd6STingHuang     fn sys_info(&self) -> Option<Arc<dyn IndexNode>> {
340e0de0fd6STingHuang         return self.0.lock().sys_info.clone();
341e0de0fd6STingHuang     }
3420663027bSTingHuang 
343*b087521eSChiichen     fn as_any_ref(&self) -> &dyn core::any::Any {
3440663027bSTingHuang         self
3450663027bSTingHuang     }
3462a7d773dSTingHuang }
3472a7d773dSTingHuang 
3482a7d773dSTingHuang /// @brief: 为Platform实现Bus trait,platform总线是一种总线设备
349e0de0fd6STingHuang impl Bus for LockedPlatform {}
3502a7d773dSTingHuang 
3510663027bSTingHuang impl KObject for LockedPlatform {}
3520663027bSTingHuang 
3532a7d773dSTingHuang /// @brief: 初始化platform总线
3542a7d773dSTingHuang /// @parameter: None
3552a7d773dSTingHuang /// @return: None
356e0de0fd6STingHuang pub fn platform_bus_init() -> Result<(), SystemError> {
357e0de0fd6STingHuang     let platform_driver: Arc<LockedPlatformBusDriver> = Arc::new(LockedPlatformBusDriver::new());
358*b087521eSChiichen     let platform_device: Arc<LockedPlatform> =
359*b087521eSChiichen         Arc::new(LockedPlatform::new(DevicePrivateData::new(
360*b087521eSChiichen             IdTable::new("platform".to_string(), DeviceNumber::new(0)),
361*b087521eSChiichen             None,
362*b087521eSChiichen             CompatibleTable::new(vec!["platform"]),
363*b087521eSChiichen             BusState::NotInitialized.into(),
364*b087521eSChiichen         )));
365e0de0fd6STingHuang     bus_register(platform_device.clone()).map_err(|e| e.into())?;
366e0de0fd6STingHuang     platform_device.set_state(BusState::Initialized);
367*b087521eSChiichen     //platform_device.set_driver(Some(platform_driver.clone()));
368e0de0fd6STingHuang     bus_driver_register(platform_driver.clone()).map_err(|e| e.into())?;
3692a7d773dSTingHuang 
370e0de0fd6STingHuang     return Ok(());
3712a7d773dSTingHuang }
372