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