xref: /DragonOS/kernel/src/driver/base/platform/mod.rs (revision 8d94ea66a3eb3e02039730c8d08e9bead8c344b8)
1 use super::device::{
2     bus::{bus_driver_register, bus_register, Bus, BusDriver, BusState},
3     driver::Driver,
4     Device, DeviceError, DeviceState, DeviceType, IdTable, KObject,
5 };
6 use crate::{filesystem::vfs::IndexNode, libs::spinlock::SpinLock, syscall::SystemError};
7 use alloc::{
8     collections::{BTreeMap, BTreeSet},
9     sync::Arc,
10     vec::Vec,
11 };
12 use core::fmt::Debug;
13 use platform_device::PlatformDevice;
14 use platform_driver::PlatformDriver;
15 
16 pub mod platform_device;
17 pub mod platform_driver;
18 
19 /// @brief: platform总线匹配表
20 ///         总线上的设备和驱动都存在一份匹配表
21 ///         根据匹配表条目是否匹配来辨识设备和驱动能否进行匹配
22 #[derive(Debug)]
23 pub struct CompatibleTable(BTreeSet<&'static str>);
24 
25 /// @brief: 匹配表操作方法集
26 impl CompatibleTable {
27     /// @brief: 创建一个新的匹配表
28     /// @parameter id_vec: 匹配条目数组
29     /// @return: 匹配表
30     #[inline]
31     #[allow(dead_code)]
32     pub fn new(id_vec: Vec<&'static str>) -> CompatibleTable {
33         CompatibleTable(BTreeSet::from_iter(id_vec.iter().cloned()))
34     }
35 
36     /// @brief: 判断两个匹配表是否能够匹配
37     /// @parameter other: 其他匹配表
38     /// @return: 如果匹配成功,返回true,否则,返回false
39     #[allow(dead_code)]
40     pub fn matches(&self, other: &CompatibleTable) -> bool {
41         for id in &self.0 {
42             if other.0.contains(id) {
43                 return true;
44             }
45         }
46         return false;
47     }
48 }
49 
50 #[derive(Debug)]
51 pub struct LockedPlatformBusDriver(SpinLock<PlatformBusDriver>);
52 
53 impl LockedPlatformBusDriver {
54     /// @brief: 创建一个platform总线加锁驱动,该驱动用于匹配plaform总线
55     /// @parameter: None
56     /// @return: platfor总线驱动
57     #[inline]
58     #[allow(dead_code)]
59     pub fn new() -> LockedPlatformBusDriver {
60         LockedPlatformBusDriver(SpinLock::new(PlatformBusDriver::new()))
61     }
62 
63     /// @brief: 获取该驱动的匹配表
64     /// @parameter: None
65     /// @return: 驱动的匹配表
66     #[inline]
67     #[allow(dead_code)]
68     fn get_compatible_table(&self) -> CompatibleTable {
69         CompatibleTable::new(vec!["platform"])
70     }
71 
72     /// @brief: 根据设备标识符获取platform总线上的设备
73     /// @parameter id_table: 设备标识符
74     /// @return: 总线上的设备
75     #[inline]
76     #[allow(dead_code)]
77     fn get_device(&self, id_table: &IdTable) -> Option<Arc<dyn PlatformDevice>> {
78         let device_map = &self.0.lock().devices;
79         return device_map.get(id_table).cloned();
80     }
81 
82     /// @brief: 根据设备驱动标识符获取platform总线上的驱动
83     /// @parameter id_table: 设备驱动标识符
84     /// @return: 总线上的驱动
85     #[inline]
86     #[allow(dead_code)]
87     fn get_driver(&self, id_table: &IdTable) -> Option<Arc<dyn PlatformDriver>> {
88         let driver_map = &self.0.lock().drivers;
89         return driver_map.get(id_table).cloned();
90     }
91 
92     /// @brief: 注册platform类型驱动
93     /// @parameter driver: platform类型驱动,该驱动需要实现PlatformDriver trait
94     /// @return: 注册成功,返回Ok(()),,注册失败,返回BusError类型
95     #[allow(dead_code)]
96     fn register_platform_driver(&self, driver: Arc<dyn PlatformDriver>) -> Result<(), DeviceError> {
97         let id_table = driver.id_table();
98 
99         let drivers = &mut self.0.lock().drivers;
100         // 如果存在同类型的驱动,返回错误
101         if drivers.contains_key(&id_table) {
102             return Err(DeviceError::DriverExists);
103         } else {
104             drivers.insert(id_table.clone(), driver.clone());
105             return Ok(());
106         }
107     }
108 
109     /// @brief: 卸载platform类型驱动
110     /// @parameter driver: platform类型驱动,该驱动需挂载在plaform总线之上
111     /// @return: None
112     #[allow(dead_code)]
113     #[inline]
114     fn unregister_platform_driver(&mut self, driver: Arc<dyn PlatformDriver>) {
115         let id_table = driver.id_table();
116         self.0.lock().drivers.remove(&id_table);
117     }
118 
119     /// @brief: 注册platform类型设备
120     /// @parameter driver: platform类型设备,该驱动需要实现PlatformDevice trait
121     /// @return: 注册成功,返回Ok(()),,注册失败,返回BusError类型
122     #[allow(dead_code)]
123     fn register_platform_device(
124         &mut self,
125         device: Arc<dyn PlatformDevice>,
126     ) -> Result<(), DeviceError> {
127         let id_table = device.id_table();
128 
129         let devices = &mut self.0.lock().devices;
130         if devices.contains_key(&id_table) {
131             return Err(DeviceError::DeviceExists);
132         } else {
133             devices.insert(id_table.clone(), device.clone());
134             return Ok(());
135         }
136     }
137 
138     /// @brief: 卸载platform类型设备
139     /// @parameter device: platform类型设备,该驱设备需挂载在plaform总线之上
140     /// @return: None
141     #[inline]
142     #[allow(dead_code)]
143     fn unregister_platform_device(&mut self, device: Arc<dyn PlatformDevice>) {
144         let id_table = device.id_table();
145         self.0.lock().devices.remove(&id_table);
146     }
147 
148     /// @brief: 匹配platform类型驱动
149     /// @parameter driver: platform类型驱动
150     /// @return: 如果匹配成功,返回成功驱动的设备数,否则,返回BusError类型
151     #[allow(dead_code)]
152     fn driver_match_device(&self, driver: Arc<dyn PlatformDriver>) -> Result<i32, DeviceError> {
153         let mut num = 0;
154         let devices = &self.0.lock().devices;
155 
156         for (_dev_id_table, device) in devices.iter() {
157             if device
158                 .compatible_table()
159                 .matches(&driver.compatible_table())
160             {
161                 if !device.is_initialized() {
162                     // 设备未初始化,调用驱动probe函数
163                     match driver.probe(device.clone()) {
164                         Ok(()) => {
165                             num = num + 1;
166                             device.set_state(DeviceState::Initialized)
167                         }
168                         // 可以驱动很多设备,一个设备初始化出错即返回
169                         Err(_) => return Err(DeviceError::InitializeFailed),
170                     }
171                 }
172             }
173         }
174         if num == 0 {
175             return Err(DeviceError::NoDeviceForDriver);
176         } else {
177             return Ok(num);
178         }
179     }
180 
181     /// @brief: 匹配platform上的设备
182     /// @parameter driver: platform类型设备
183     /// @return: 如果匹配成功,返回Ok(()),否则,返回BusError类型
184     #[allow(dead_code)]
185     fn device_match_driver(&self, device: Arc<dyn PlatformDevice>) -> Result<(), DeviceError> {
186         let drivers = &mut self.0.lock().drivers;
187         for (_drv_id_table, driver) in drivers.into_iter() {
188             if driver
189                 .compatible_table()
190                 .matches(&device.compatible_table())
191             {
192                 match driver.probe(device.clone()) {
193                     Ok(_driver) => {
194                         // 将设备状态置为已初始化
195                         device.set_state(DeviceState::Initialized);
196                         return Ok(());
197                     }
198                     Err(_) => return Err(DeviceError::InitializeFailed),
199                 }
200             }
201         }
202         return Err(DeviceError::NoDriverForDevice);
203     }
204 }
205 
206 /// @brief: platform总线驱动
207 #[derive(Debug)]
208 pub struct PlatformBusDriver {
209     drivers: BTreeMap<IdTable, Arc<dyn PlatformDriver>>, // 总线上所有驱动
210     devices: BTreeMap<IdTable, Arc<dyn PlatformDevice>>, // 总线上所有设备
211     sys_info: Option<Arc<dyn IndexNode>>,
212 }
213 
214 impl PlatformBusDriver {
215     /// @brief: 创建一个platform总线驱动,该驱动用于匹配plaform总线
216     /// @parameter: None
217     /// @return: platfor总线驱动
218     #[inline]
219     #[allow(dead_code)]
220     pub fn new() -> Self {
221         Self {
222             drivers: BTreeMap::new(),
223             devices: BTreeMap::new(),
224             sys_info: None,
225         }
226     }
227 }
228 
229 /// @brief: 为PlatformBusDriver实现Driver trait
230 impl Driver for LockedPlatformBusDriver {
231     #[inline]
232     fn as_any_ref(&self) -> &dyn core::any::Any {
233         self
234     }
235 
236     #[inline]
237     fn id_table(&self) -> IdTable {
238         IdTable::new("PlatformBusDriver", 0)
239     }
240 
241     #[inline]
242     #[allow(dead_code)]
243     fn sys_info(&self) -> Option<Arc<dyn IndexNode>> {
244         return self.0.lock().sys_info.clone();
245     }
246 
247     #[inline]
248     #[allow(dead_code)]
249     fn set_sys_info(&self, sys_info: Option<Arc<dyn IndexNode>>) {
250         self.0.lock().sys_info = sys_info;
251     }
252 }
253 
254 /// @brief: 为PlatformBusDriver实现BusDriver trait
255 impl BusDriver for LockedPlatformBusDriver {
256     fn is_empty(&self) -> bool {
257         if self.0.lock().devices.is_empty() && self.0.lock().drivers.is_empty() {
258             return true;
259         } else {
260             return false;
261         }
262     }
263 }
264 
265 impl KObject for LockedPlatformBusDriver {}
266 
267 #[derive(Debug)]
268 pub struct LockedPlatform(SpinLock<Platform>);
269 
270 impl LockedPlatform {
271     /// @brief: 创建一个加锁的platform总线实例
272     /// @parameter: None
273     /// @return: platform总线实例
274     pub fn new() -> LockedPlatform {
275         LockedPlatform(SpinLock::new(Platform::new()))
276     }
277 
278     /// @brief: 获取总线的匹配表
279     /// @parameter: None
280     /// @return: platform总线匹配表
281     #[inline]
282     #[allow(dead_code)]
283     fn compatible_table(&self) -> CompatibleTable {
284         CompatibleTable::new(vec!["platform"])
285     }
286 
287     /// @brief: 判断总线是否初始化
288     /// @parameter: None
289     /// @return: 已初始化,返回true,否则,返回false
290     #[inline]
291     #[allow(dead_code)]
292     fn is_initialized(&self) -> bool {
293         let state = self.0.lock().state;
294         match state {
295             BusState::Initialized => true,
296             _ => false,
297         }
298     }
299 
300     /// @brief: 设置总线状态
301     /// @parameter set_state: 总线状态BusState
302     /// @return: None
303     #[inline]
304     fn set_state(&self, set_state: BusState) {
305         let state = &mut self.0.lock().state;
306         *state = set_state;
307     }
308 
309     /// @brief: 获取总线状态
310     /// @parameter: None
311     /// @return: 总线状态
312     #[inline]
313     #[allow(dead_code)]
314     fn get_state(&self) -> BusState {
315         let state = self.0.lock().state;
316         return state;
317     }
318 
319     /// @brief:
320     /// @parameter: None
321     /// @return: 总线状态
322     #[inline]
323     #[allow(dead_code)]
324     fn set_driver(&self, driver: Option<Arc<LockedPlatformBusDriver>>) {
325         self.0.lock().driver = driver;
326     }
327 }
328 
329 /// @brief: platform总线
330 #[derive(Debug, Clone)]
331 pub struct Platform {
332     state: BusState,                              // 总线状态
333     driver: Option<Arc<LockedPlatformBusDriver>>, // 总线驱动
334     sys_info: Option<Arc<dyn IndexNode>>,         // 总线sys information
335 }
336 
337 /// @brief: platform方法集
338 impl Platform {
339     /// @brief: 创建一个platform总线实例
340     /// @parameter: None
341     /// @return: platform总线实例
342     pub fn new() -> Self {
343         Self {
344             state: BusState::NotInitialized,
345             driver: Option::None,
346             sys_info: Option::None,
347         }
348     }
349 }
350 
351 /// @brief: 为Platform实现Device trait,platform总线也是一种设备,属于总线设备类型
352 impl Device for LockedPlatform {
353     #[inline]
354     #[allow(dead_code)]
355     fn dev_type(&self) -> DeviceType {
356         return DeviceType::Bus;
357     }
358 
359     #[inline]
360     #[allow(dead_code)]
361     fn id_table(&self) -> IdTable {
362         IdTable::new("platform", 0)
363     }
364 
365     #[inline]
366     fn set_sys_info(&self, sys_info: Option<Arc<dyn IndexNode>>) {
367         self.0.lock().sys_info = sys_info;
368     }
369 
370     #[inline]
371     #[allow(dead_code)]
372     fn sys_info(&self) -> Option<Arc<dyn IndexNode>> {
373         return self.0.lock().sys_info.clone();
374     }
375 
376     fn as_any_ref(&'static self) -> &'static dyn core::any::Any {
377         self
378     }
379 }
380 
381 /// @brief: 为Platform实现Bus trait,platform总线是一种总线设备
382 impl Bus for LockedPlatform {}
383 
384 impl KObject for LockedPlatform {}
385 
386 /// @brief: 初始化platform总线
387 /// @parameter: None
388 /// @return: None
389 pub fn platform_bus_init() -> Result<(), SystemError> {
390     let platform_driver: Arc<LockedPlatformBusDriver> = Arc::new(LockedPlatformBusDriver::new());
391     let platform_device: Arc<LockedPlatform> = Arc::new(LockedPlatform::new());
392     bus_register(platform_device.clone()).map_err(|e| e.into())?;
393     platform_device.set_state(BusState::Initialized);
394     platform_device.set_driver(Some(platform_driver.clone()));
395     bus_driver_register(platform_driver.clone()).map_err(|e| e.into())?;
396 
397     return Ok(());
398 }
399