xref: /DragonOS/kernel/src/driver/base/map/mod.rs (revision 06d5e247267cb65b84a80f219853ccd0f384b16e)
1ae5ede03SLoGin use core::ops::{Deref, DerefMut};
2b087521eSChiichen 
3*06d5e247SLoGin use super::{
4*06d5e247SLoGin     device::{mkdev, DeviceNumber},
5*06d5e247SLoGin     kobject::KObject,
6*06d5e247SLoGin };
7ae5ede03SLoGin use crate::libs::spinlock::{SpinLock, SpinLockGuard};
80663027bSTingHuang use alloc::{collections::BTreeMap, sync::Arc, vec::Vec};
90663027bSTingHuang 
100663027bSTingHuang const KOBJMAP_HASH_SIZE: usize = 255;
11ae5ede03SLoGin pub(crate) const DEV_MAJOR_HASH_SIZE: usize = 255;
12ae5ede03SLoGin pub(crate) const DEV_MAJOR_MAX: usize = 512;
13ae5ede03SLoGin pub(crate) const MINOR_BITS: usize = 20;
14ae5ede03SLoGin pub(crate) const MINOR_MASK: usize = 1 << MINOR_BITS - 1;
15b087521eSChiichen /* Marks the bottom of the first segment of free char majors */
16ae5ede03SLoGin pub(crate) const DEV_MAJOR_DYN_END: usize = 234;
17b087521eSChiichen /* Marks the top and bottom of the second segment of free char majors */
18ae5ede03SLoGin pub(crate) const DEV_MAJOR_DYN_EXT_START: usize = 511;
19ae5ede03SLoGin pub(crate) const DEV_MAJOR_DYN_EXT_END: usize = 384;
200663027bSTingHuang 
210663027bSTingHuang /// @brief: 字符设备与块设备管理结构体
220663027bSTingHuang #[derive(Debug, Clone)]
230663027bSTingHuang struct Probe(Arc<dyn KObject>);
240663027bSTingHuang 
250663027bSTingHuang impl Probe {
260663027bSTingHuang     /// @brief: 新建probe实例
270663027bSTingHuang     /// @parameter: data: probe实例
280663027bSTingHuang     /// @return: probe实例
290663027bSTingHuang     pub fn new(data: Arc<dyn KObject>) -> Self {
300663027bSTingHuang         Self(data)
310663027bSTingHuang     }
320663027bSTingHuang }
330663027bSTingHuang 
340663027bSTingHuang /// @brief: 字符设备和块设备管理实例(锁)
350663027bSTingHuang #[derive(Debug)]
360663027bSTingHuang pub struct LockedKObjMap(SpinLock<KObjMap>);
370663027bSTingHuang 
380663027bSTingHuang impl Default for LockedKObjMap {
390663027bSTingHuang     fn default() -> Self {
400663027bSTingHuang         Self(SpinLock::new(KObjMap::default()))
410663027bSTingHuang     }
420663027bSTingHuang }
430663027bSTingHuang 
440663027bSTingHuang /// @brief: 字符设备和块设备管理实例
450663027bSTingHuang #[derive(Debug, Clone)]
460663027bSTingHuang struct KObjMap(Vec<BTreeMap<DeviceNumber, Probe>>);
470663027bSTingHuang 
480663027bSTingHuang impl Default for KObjMap {
490663027bSTingHuang     fn default() -> Self {
500663027bSTingHuang         Self(vec![BTreeMap::new(); KOBJMAP_HASH_SIZE])
510663027bSTingHuang     }
520663027bSTingHuang }
530663027bSTingHuang 
540663027bSTingHuang /// @brief: obj设备注册
550663027bSTingHuang /// @parameter: domain: 管理实例
560663027bSTingHuang ///             dev_t: 设备号
570663027bSTingHuang ///             range: 次设备号范围
580663027bSTingHuang ///             data: 设备实例
590663027bSTingHuang /// @return: none
600663027bSTingHuang pub fn kobj_map(
610663027bSTingHuang     domain: Arc<LockedKObjMap>,
620663027bSTingHuang     dev_t: DeviceNumber,
630663027bSTingHuang     range: usize,
640663027bSTingHuang     data: Arc<dyn KObject>,
650663027bSTingHuang ) {
660663027bSTingHuang     if let Some(map) = domain.0.lock().0.get_mut(dev_t.major() % 255) {
670663027bSTingHuang         for i in 0..range {
680663027bSTingHuang             map.insert(
690663027bSTingHuang                 mkdev(dev_t.major(), dev_t.minor() + i),
700663027bSTingHuang                 Probe::new(data.clone()),
710663027bSTingHuang             );
720663027bSTingHuang         }
730663027bSTingHuang     }
740663027bSTingHuang }
750663027bSTingHuang 
760663027bSTingHuang /// @brief: obj设备注销
770663027bSTingHuang /// @parameter: domain: 管理实例
780663027bSTingHuang ///             dev_t: 设备号
790663027bSTingHuang ///             range: 次设备号范围
800663027bSTingHuang /// @return: none
810663027bSTingHuang pub fn kobj_unmap(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber, range: usize) {
820663027bSTingHuang     if let Some(map) = domain.0.lock().0.get_mut(dev_t.major() % 255) {
830663027bSTingHuang         for i in 0..range {
840663027bSTingHuang             let rm_dev_t = &DeviceNumber::new(Into::<usize>::into(dev_t) + i);
850663027bSTingHuang             match map.get(rm_dev_t) {
860663027bSTingHuang                 Some(_) => {
870663027bSTingHuang                     map.remove(rm_dev_t);
880663027bSTingHuang                 }
890663027bSTingHuang                 None => {}
900663027bSTingHuang             }
910663027bSTingHuang         }
920663027bSTingHuang     }
930663027bSTingHuang }
940663027bSTingHuang 
950663027bSTingHuang /// @brief: 设备查找
960663027bSTingHuang /// @parameter: domain: 管理实例
970663027bSTingHuang ///             dev_t: 设备号
980663027bSTingHuang /// @return: 查找成功,返回设备实例,否则返回None
990663027bSTingHuang #[allow(dead_code)]
1000663027bSTingHuang pub fn kobj_lookup(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber) -> Option<Arc<dyn KObject>> {
1010663027bSTingHuang     if let Some(map) = domain.0.lock().0.get(dev_t.major() % 255) {
1020663027bSTingHuang         match map.get(&dev_t) {
1030663027bSTingHuang             Some(value) => {
1040663027bSTingHuang                 return Some(value.0.clone());
1050663027bSTingHuang             }
1060663027bSTingHuang             None => {
1070663027bSTingHuang                 return None;
1080663027bSTingHuang             }
1090663027bSTingHuang         }
1100663027bSTingHuang     }
1110663027bSTingHuang     return None;
1120663027bSTingHuang }
113b087521eSChiichen 
114b087521eSChiichen // 管理字符设备号的map(加锁)
115b087521eSChiichen pub struct LockedDevsMap(SpinLock<DevsMap>);
116b087521eSChiichen 
117b087521eSChiichen impl Default for LockedDevsMap {
118b087521eSChiichen     fn default() -> Self {
119b087521eSChiichen         LockedDevsMap(SpinLock::new(DevsMap::default()))
120b087521eSChiichen     }
121b087521eSChiichen }
122b087521eSChiichen 
123ae5ede03SLoGin impl LockedDevsMap {
124ae5ede03SLoGin     #[inline(always)]
125ae5ede03SLoGin     pub fn lock(&self) -> SpinLockGuard<DevsMap> {
126ae5ede03SLoGin         self.0.lock()
127ae5ede03SLoGin     }
128ae5ede03SLoGin }
129ae5ede03SLoGin 
130b087521eSChiichen // 管理字符设备号的map
131b087521eSChiichen #[derive(Debug)]
132ae5ede03SLoGin pub struct DevsMap(Vec<Vec<DeviceStruct>>);
133b087521eSChiichen 
134b087521eSChiichen impl Default for DevsMap {
135b087521eSChiichen     fn default() -> Self {
136b087521eSChiichen         DevsMap(vec![Vec::new(); DEV_MAJOR_HASH_SIZE])
137b087521eSChiichen     }
138b087521eSChiichen }
139b087521eSChiichen 
140ae5ede03SLoGin impl Deref for DevsMap {
141ae5ede03SLoGin     type Target = Vec<Vec<DeviceStruct>>;
142ae5ede03SLoGin 
143ae5ede03SLoGin     fn deref(&self) -> &Self::Target {
144ae5ede03SLoGin         &self.0
145ae5ede03SLoGin     }
146ae5ede03SLoGin }
147ae5ede03SLoGin 
148ae5ede03SLoGin impl DerefMut for DevsMap {
149ae5ede03SLoGin     fn deref_mut(&mut self) -> &mut Self::Target {
150ae5ede03SLoGin         &mut self.0
151ae5ede03SLoGin     }
152ae5ede03SLoGin }
153ae5ede03SLoGin 
154b087521eSChiichen // 字符设备在系统中的实例,devfs通过该结构与实际字符设备进行联系
155b087521eSChiichen #[allow(dead_code)]
156b087521eSChiichen #[derive(Debug, Clone)]
157b087521eSChiichen pub struct DeviceStruct {
158b087521eSChiichen     dev_t: DeviceNumber, //起始设备号
159b087521eSChiichen     minorct: usize,      // 次设备号数量
160b087521eSChiichen     name: &'static str,  //字符设备名
161b087521eSChiichen }
162b087521eSChiichen 
163b087521eSChiichen impl DeviceStruct {
164b087521eSChiichen     /// @brief: 创建实例
165b087521eSChiichen     /// @parameter: dev_t: 设备号
166b087521eSChiichen     ///             minorct: 次设备号数量
167b087521eSChiichen     ///             name: 字符设备名
168b087521eSChiichen     ///             char: 字符设备实例
169b087521eSChiichen     /// @return: 实例
170b087521eSChiichen     ///
171b087521eSChiichen     #[allow(dead_code)]
172b087521eSChiichen     pub fn new(dev_t: DeviceNumber, minorct: usize, name: &'static str) -> Self {
173b087521eSChiichen         Self {
174b087521eSChiichen             dev_t,
175b087521eSChiichen             minorct,
176b087521eSChiichen             name,
177b087521eSChiichen         }
178b087521eSChiichen     }
179b087521eSChiichen 
180b087521eSChiichen     /// @brief: 获取起始次设备号
181b087521eSChiichen     /// @parameter: None
182b087521eSChiichen     /// @return: 起始设备号
183b087521eSChiichen     ///
184b087521eSChiichen     #[allow(dead_code)]
185b087521eSChiichen     pub fn device_number(&self) -> DeviceNumber {
186b087521eSChiichen         self.dev_t
187b087521eSChiichen     }
188b087521eSChiichen 
189b087521eSChiichen     /// @brief: 获取起始次设备号
190b087521eSChiichen     /// @parameter: None
191b087521eSChiichen     /// @return: 起始设备号
192b087521eSChiichen     ///
193b087521eSChiichen     #[allow(dead_code)]
194b087521eSChiichen     pub fn base_minor(&self) -> usize {
195b087521eSChiichen         self.dev_t.minor()
196b087521eSChiichen     }
197b087521eSChiichen 
198b087521eSChiichen     /// @brief: 获取次设备号数量
199b087521eSChiichen     /// @parameter: None
200b087521eSChiichen     /// @return: 次设备号数量
201b087521eSChiichen     #[allow(dead_code)]
202b087521eSChiichen     pub fn minorct(&self) -> usize {
203b087521eSChiichen         self.minorct
204b087521eSChiichen     }
205b087521eSChiichen }
206