xref: /DragonOS/kernel/src/driver/base/map/mod.rs (revision b5b571e02693d91eb6918d3b7561e088c3e7ee81)
1ae5ede03SLoGin use core::ops::{Deref, DerefMut};
2b087521eSChiichen 
306d5e247SLoGin use super::{
4c566df45SLoGin     device::device_number::{DeviceNumber, Major},
506d5e247SLoGin     kobject::KObject,
606d5e247SLoGin };
7ae5ede03SLoGin use crate::libs::spinlock::{SpinLock, SpinLockGuard};
80663027bSTingHuang use alloc::{collections::BTreeMap, sync::Arc, vec::Vec};
90663027bSTingHuang 
100663027bSTingHuang const KOBJMAP_HASH_SIZE: usize = 255;
11c566df45SLoGin pub(crate) const DEV_MAJOR_HASH_SIZE: u32 = 255;
12c566df45SLoGin pub(crate) const DEV_MAJOR_MAX: Major = Major::new(512);
13c566df45SLoGin 
14b087521eSChiichen /* Marks the bottom of the first segment of free char majors */
15c566df45SLoGin pub(crate) const DEV_MAJOR_DYN_END: Major = Major::new(234);
16b087521eSChiichen /* Marks the top and bottom of the second segment of free char majors */
17c566df45SLoGin pub(crate) const DEV_MAJOR_DYN_EXT_START: Major = Major::new(511);
18c566df45SLoGin pub(crate) const DEV_MAJOR_DYN_EXT_END: Major = Major::new(384);
190663027bSTingHuang 
200663027bSTingHuang /// @brief: 字符设备与块设备管理结构体
210663027bSTingHuang #[derive(Debug, Clone)]
220663027bSTingHuang struct Probe(Arc<dyn KObject>);
230663027bSTingHuang 
240663027bSTingHuang impl Probe {
250663027bSTingHuang     /// @brief: 新建probe实例
260663027bSTingHuang     /// @parameter: data: probe实例
270663027bSTingHuang     /// @return: probe实例
new(data: Arc<dyn KObject>) -> Self280663027bSTingHuang     pub fn new(data: Arc<dyn KObject>) -> Self {
290663027bSTingHuang         Self(data)
300663027bSTingHuang     }
310663027bSTingHuang }
320663027bSTingHuang 
330663027bSTingHuang /// @brief: 字符设备和块设备管理实例(锁)
340663027bSTingHuang #[derive(Debug)]
350663027bSTingHuang pub struct LockedKObjMap(SpinLock<KObjMap>);
360663027bSTingHuang 
370663027bSTingHuang impl Default for LockedKObjMap {
default() -> Self380663027bSTingHuang     fn default() -> Self {
390663027bSTingHuang         Self(SpinLock::new(KObjMap::default()))
400663027bSTingHuang     }
410663027bSTingHuang }
420663027bSTingHuang 
430663027bSTingHuang /// @brief: 字符设备和块设备管理实例
440663027bSTingHuang #[derive(Debug, Clone)]
450663027bSTingHuang struct KObjMap(Vec<BTreeMap<DeviceNumber, Probe>>);
460663027bSTingHuang 
470663027bSTingHuang impl Default for KObjMap {
default() -> Self480663027bSTingHuang     fn default() -> Self {
490663027bSTingHuang         Self(vec![BTreeMap::new(); KOBJMAP_HASH_SIZE])
500663027bSTingHuang     }
510663027bSTingHuang }
520663027bSTingHuang 
530663027bSTingHuang /// @brief: obj设备注册
540663027bSTingHuang /// @parameter: domain: 管理实例
550663027bSTingHuang ///             dev_t: 设备号
560663027bSTingHuang ///             range: 次设备号范围
570663027bSTingHuang ///             data: 设备实例
580663027bSTingHuang /// @return: none
kobj_map( domain: Arc<LockedKObjMap>, dev_t: DeviceNumber, range: usize, data: Arc<dyn KObject>, )590663027bSTingHuang pub fn kobj_map(
600663027bSTingHuang     domain: Arc<LockedKObjMap>,
610663027bSTingHuang     dev_t: DeviceNumber,
620663027bSTingHuang     range: usize,
630663027bSTingHuang     data: Arc<dyn KObject>,
640663027bSTingHuang ) {
65c566df45SLoGin     if let Some(map) = domain
66c566df45SLoGin         .0
67c566df45SLoGin         .lock()
68c566df45SLoGin         .0
69c566df45SLoGin         .get_mut((dev_t.major().data() % 255) as usize)
70c566df45SLoGin     {
710663027bSTingHuang         for i in 0..range {
720663027bSTingHuang             map.insert(
73c566df45SLoGin                 DeviceNumber::new(dev_t.major(), dev_t.minor() + i as u32),
740663027bSTingHuang                 Probe::new(data.clone()),
750663027bSTingHuang             );
760663027bSTingHuang         }
770663027bSTingHuang     }
780663027bSTingHuang }
790663027bSTingHuang 
800663027bSTingHuang /// @brief: obj设备注销
810663027bSTingHuang /// @parameter: domain: 管理实例
820663027bSTingHuang ///             dev_t: 设备号
830663027bSTingHuang ///             range: 次设备号范围
840663027bSTingHuang /// @return: none
kobj_unmap(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber, range: usize)850663027bSTingHuang pub fn kobj_unmap(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber, range: usize) {
86c566df45SLoGin     if let Some(map) = domain
87c566df45SLoGin         .0
88c566df45SLoGin         .lock()
89c566df45SLoGin         .0
90c566df45SLoGin         .get_mut((dev_t.major().data() % 255) as usize)
91c566df45SLoGin     {
920663027bSTingHuang         for i in 0..range {
93c566df45SLoGin             let rm_dev_t = &DeviceNumber::new(dev_t.major(), dev_t.minor() + i as u32);
94*b5b571e0SLoGin             if map.get(rm_dev_t).is_some() {
950663027bSTingHuang                 map.remove(rm_dev_t);
960663027bSTingHuang             }
970663027bSTingHuang         }
980663027bSTingHuang     }
990663027bSTingHuang }
1000663027bSTingHuang 
1010663027bSTingHuang /// @brief: 设备查找
1020663027bSTingHuang /// @parameter: domain: 管理实例
1030663027bSTingHuang ///             dev_t: 设备号
1040663027bSTingHuang /// @return: 查找成功,返回设备实例,否则返回None
1050663027bSTingHuang #[allow(dead_code)]
kobj_lookup(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber) -> Option<Arc<dyn KObject>>1060663027bSTingHuang pub fn kobj_lookup(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber) -> Option<Arc<dyn KObject>> {
107c566df45SLoGin     if let Some(map) = domain.0.lock().0.get((dev_t.major().data() % 255) as usize) {
1080663027bSTingHuang         match map.get(&dev_t) {
1090663027bSTingHuang             Some(value) => {
1100663027bSTingHuang                 return Some(value.0.clone());
1110663027bSTingHuang             }
1120663027bSTingHuang             None => {
1130663027bSTingHuang                 return None;
1140663027bSTingHuang             }
1150663027bSTingHuang         }
1160663027bSTingHuang     }
1170663027bSTingHuang     return None;
1180663027bSTingHuang }
119b087521eSChiichen 
120b087521eSChiichen // 管理字符设备号的map(加锁)
121b087521eSChiichen pub struct LockedDevsMap(SpinLock<DevsMap>);
122b087521eSChiichen 
123b087521eSChiichen impl Default for LockedDevsMap {
default() -> Self124b087521eSChiichen     fn default() -> Self {
125b087521eSChiichen         LockedDevsMap(SpinLock::new(DevsMap::default()))
126b087521eSChiichen     }
127b087521eSChiichen }
128b087521eSChiichen 
129ae5ede03SLoGin impl LockedDevsMap {
130ae5ede03SLoGin     #[inline(always)]
lock(&self) -> SpinLockGuard<DevsMap>131ae5ede03SLoGin     pub fn lock(&self) -> SpinLockGuard<DevsMap> {
132ae5ede03SLoGin         self.0.lock()
133ae5ede03SLoGin     }
134ae5ede03SLoGin }
135ae5ede03SLoGin 
136b087521eSChiichen // 管理字符设备号的map
137b087521eSChiichen #[derive(Debug)]
138ae5ede03SLoGin pub struct DevsMap(Vec<Vec<DeviceStruct>>);
139b087521eSChiichen 
140b087521eSChiichen impl Default for DevsMap {
default() -> Self141b087521eSChiichen     fn default() -> Self {
142c566df45SLoGin         DevsMap(vec![Vec::new(); DEV_MAJOR_HASH_SIZE as usize])
143b087521eSChiichen     }
144b087521eSChiichen }
145b087521eSChiichen 
146ae5ede03SLoGin impl Deref for DevsMap {
147ae5ede03SLoGin     type Target = Vec<Vec<DeviceStruct>>;
148ae5ede03SLoGin 
deref(&self) -> &Self::Target149ae5ede03SLoGin     fn deref(&self) -> &Self::Target {
150ae5ede03SLoGin         &self.0
151ae5ede03SLoGin     }
152ae5ede03SLoGin }
153ae5ede03SLoGin 
154ae5ede03SLoGin impl DerefMut for DevsMap {
deref_mut(&mut self) -> &mut Self::Target155ae5ede03SLoGin     fn deref_mut(&mut self) -> &mut Self::Target {
156ae5ede03SLoGin         &mut self.0
157ae5ede03SLoGin     }
158ae5ede03SLoGin }
159ae5ede03SLoGin 
160b087521eSChiichen // 字符设备在系统中的实例,devfs通过该结构与实际字符设备进行联系
161b087521eSChiichen #[allow(dead_code)]
162b087521eSChiichen #[derive(Debug, Clone)]
163b087521eSChiichen pub struct DeviceStruct {
164b087521eSChiichen     dev_t: DeviceNumber, //起始设备号
165c566df45SLoGin     minorct: u32,        // 次设备号数量
166b087521eSChiichen     name: &'static str,  //字符设备名
167b087521eSChiichen }
168b087521eSChiichen 
169b087521eSChiichen impl DeviceStruct {
170b087521eSChiichen     /// @brief: 创建实例
171b087521eSChiichen     /// @parameter: dev_t: 设备号
172b087521eSChiichen     ///             minorct: 次设备号数量
173b087521eSChiichen     ///             name: 字符设备名
174b087521eSChiichen     ///             char: 字符设备实例
175b087521eSChiichen     /// @return: 实例
176b087521eSChiichen     ///
177b087521eSChiichen     #[allow(dead_code)]
new(dev_t: DeviceNumber, minorct: u32, name: &'static str) -> Self178c566df45SLoGin     pub fn new(dev_t: DeviceNumber, minorct: u32, name: &'static str) -> Self {
179b087521eSChiichen         Self {
180b087521eSChiichen             dev_t,
181b087521eSChiichen             minorct,
182b087521eSChiichen             name,
183b087521eSChiichen         }
184b087521eSChiichen     }
185b087521eSChiichen 
186b087521eSChiichen     /// @brief: 获取起始次设备号
187b087521eSChiichen     /// @parameter: None
188b087521eSChiichen     /// @return: 起始设备号
189b087521eSChiichen     ///
190b087521eSChiichen     #[allow(dead_code)]
device_number(&self) -> DeviceNumber191b087521eSChiichen     pub fn device_number(&self) -> DeviceNumber {
192b087521eSChiichen         self.dev_t
193b087521eSChiichen     }
194b087521eSChiichen 
195b087521eSChiichen     /// @brief: 获取起始次设备号
196b087521eSChiichen     /// @parameter: None
197b087521eSChiichen     /// @return: 起始设备号
198b087521eSChiichen     ///
199b087521eSChiichen     #[allow(dead_code)]
base_minor(&self) -> u32200c566df45SLoGin     pub fn base_minor(&self) -> u32 {
201b087521eSChiichen         self.dev_t.minor()
202b087521eSChiichen     }
203b087521eSChiichen 
204b087521eSChiichen     /// @brief: 获取次设备号数量
205b087521eSChiichen     /// @parameter: None
206b087521eSChiichen     /// @return: 次设备号数量
207b087521eSChiichen     #[allow(dead_code)]
minorct(&self) -> u32208c566df45SLoGin     pub fn minorct(&self) -> u32 {
209b087521eSChiichen         self.minorct
210b087521eSChiichen     }
211b087521eSChiichen }
212