xref: /DragonOS/kernel/src/driver/base/map/mod.rs (revision 77799ccaaca276fe127448d169f0e035837cce44)
1 use core::ops::{Deref, DerefMut};
2 
3 use super::{
4     device::{mkdev, DeviceNumber},
5     kobject::KObject,
6 };
7 use crate::libs::spinlock::{SpinLock, SpinLockGuard};
8 use alloc::{collections::BTreeMap, sync::Arc, vec::Vec};
9 
10 const KOBJMAP_HASH_SIZE: usize = 255;
11 pub(crate) const DEV_MAJOR_HASH_SIZE: usize = 255;
12 pub(crate) const DEV_MAJOR_MAX: usize = 512;
13 pub(crate) const MINOR_BITS: usize = 20;
14 pub(crate) const MINOR_MASK: usize = 1 << MINOR_BITS - 1;
15 /* Marks the bottom of the first segment of free char majors */
16 pub(crate) const DEV_MAJOR_DYN_END: usize = 234;
17 /* Marks the top and bottom of the second segment of free char majors */
18 pub(crate) const DEV_MAJOR_DYN_EXT_START: usize = 511;
19 pub(crate) const DEV_MAJOR_DYN_EXT_END: usize = 384;
20 
21 /// @brief: 字符设备与块设备管理结构体
22 #[derive(Debug, Clone)]
23 struct Probe(Arc<dyn KObject>);
24 
25 impl Probe {
26     /// @brief: 新建probe实例
27     /// @parameter: data: probe实例
28     /// @return: probe实例
29     pub fn new(data: Arc<dyn KObject>) -> Self {
30         Self(data)
31     }
32 }
33 
34 /// @brief: 字符设备和块设备管理实例(锁)
35 #[derive(Debug)]
36 pub struct LockedKObjMap(SpinLock<KObjMap>);
37 
38 impl Default for LockedKObjMap {
39     fn default() -> Self {
40         Self(SpinLock::new(KObjMap::default()))
41     }
42 }
43 
44 /// @brief: 字符设备和块设备管理实例
45 #[derive(Debug, Clone)]
46 struct KObjMap(Vec<BTreeMap<DeviceNumber, Probe>>);
47 
48 impl Default for KObjMap {
49     fn default() -> Self {
50         Self(vec![BTreeMap::new(); KOBJMAP_HASH_SIZE])
51     }
52 }
53 
54 /// @brief: obj设备注册
55 /// @parameter: domain: 管理实例
56 ///             dev_t: 设备号
57 ///             range: 次设备号范围
58 ///             data: 设备实例
59 /// @return: none
60 pub fn kobj_map(
61     domain: Arc<LockedKObjMap>,
62     dev_t: DeviceNumber,
63     range: usize,
64     data: Arc<dyn KObject>,
65 ) {
66     if let Some(map) = domain.0.lock().0.get_mut(dev_t.major() % 255) {
67         for i in 0..range {
68             map.insert(
69                 mkdev(dev_t.major(), dev_t.minor() + i),
70                 Probe::new(data.clone()),
71             );
72         }
73     }
74 }
75 
76 /// @brief: obj设备注销
77 /// @parameter: domain: 管理实例
78 ///             dev_t: 设备号
79 ///             range: 次设备号范围
80 /// @return: none
81 pub fn kobj_unmap(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber, range: usize) {
82     if let Some(map) = domain.0.lock().0.get_mut(dev_t.major() % 255) {
83         for i in 0..range {
84             let rm_dev_t = &DeviceNumber::new(Into::<usize>::into(dev_t) + i);
85             match map.get(rm_dev_t) {
86                 Some(_) => {
87                     map.remove(rm_dev_t);
88                 }
89                 None => {}
90             }
91         }
92     }
93 }
94 
95 /// @brief: 设备查找
96 /// @parameter: domain: 管理实例
97 ///             dev_t: 设备号
98 /// @return: 查找成功,返回设备实例,否则返回None
99 #[allow(dead_code)]
100 pub fn kobj_lookup(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber) -> Option<Arc<dyn KObject>> {
101     if let Some(map) = domain.0.lock().0.get(dev_t.major() % 255) {
102         match map.get(&dev_t) {
103             Some(value) => {
104                 return Some(value.0.clone());
105             }
106             None => {
107                 return None;
108             }
109         }
110     }
111     return None;
112 }
113 
114 // 管理字符设备号的map(加锁)
115 pub struct LockedDevsMap(SpinLock<DevsMap>);
116 
117 impl Default for LockedDevsMap {
118     fn default() -> Self {
119         LockedDevsMap(SpinLock::new(DevsMap::default()))
120     }
121 }
122 
123 impl LockedDevsMap {
124     #[inline(always)]
125     pub fn lock(&self) -> SpinLockGuard<DevsMap> {
126         self.0.lock()
127     }
128 }
129 
130 // 管理字符设备号的map
131 #[derive(Debug)]
132 pub struct DevsMap(Vec<Vec<DeviceStruct>>);
133 
134 impl Default for DevsMap {
135     fn default() -> Self {
136         DevsMap(vec![Vec::new(); DEV_MAJOR_HASH_SIZE])
137     }
138 }
139 
140 impl Deref for DevsMap {
141     type Target = Vec<Vec<DeviceStruct>>;
142 
143     fn deref(&self) -> &Self::Target {
144         &self.0
145     }
146 }
147 
148 impl DerefMut for DevsMap {
149     fn deref_mut(&mut self) -> &mut Self::Target {
150         &mut self.0
151     }
152 }
153 
154 // 字符设备在系统中的实例,devfs通过该结构与实际字符设备进行联系
155 #[allow(dead_code)]
156 #[derive(Debug, Clone)]
157 pub struct DeviceStruct {
158     dev_t: DeviceNumber, //起始设备号
159     minorct: usize,      // 次设备号数量
160     name: &'static str,  //字符设备名
161 }
162 
163 impl DeviceStruct {
164     /// @brief: 创建实例
165     /// @parameter: dev_t: 设备号
166     ///             minorct: 次设备号数量
167     ///             name: 字符设备名
168     ///             char: 字符设备实例
169     /// @return: 实例
170     ///
171     #[allow(dead_code)]
172     pub fn new(dev_t: DeviceNumber, minorct: usize, name: &'static str) -> Self {
173         Self {
174             dev_t,
175             minorct,
176             name,
177         }
178     }
179 
180     /// @brief: 获取起始次设备号
181     /// @parameter: None
182     /// @return: 起始设备号
183     ///
184     #[allow(dead_code)]
185     pub fn device_number(&self) -> DeviceNumber {
186         self.dev_t
187     }
188 
189     /// @brief: 获取起始次设备号
190     /// @parameter: None
191     /// @return: 起始设备号
192     ///
193     #[allow(dead_code)]
194     pub fn base_minor(&self) -> usize {
195         self.dev_t.minor()
196     }
197 
198     /// @brief: 获取次设备号数量
199     /// @parameter: None
200     /// @return: 次设备号数量
201     #[allow(dead_code)]
202     pub fn minorct(&self) -> usize {
203         self.minorct
204     }
205 }
206