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