xref: /DragonOS/kernel/src/driver/tty/tty_driver.rs (revision 338f6903262c5031abad3c8e361813355a27fcdb)
1 use core::{fmt::Debug, sync::atomic::Ordering};
2 
3 use alloc::{string::String, sync::Arc, vec::Vec};
4 use hashbrown::HashMap;
5 use system_error::SystemError;
6 
7 use crate::{
8     driver::{
9         base::{
10             char::CharDevOps,
11             device::{
12                 device_number::{DeviceNumber, Major},
13                 driver::Driver,
14             },
15             kobject::KObject,
16         },
17         tty::tty_port::TtyPortState,
18     },
19     libs::spinlock::SpinLock,
20 };
21 
22 use super::{
23     termios::Termios,
24     tty_core::{TtyCore, TtyCoreData},
25     tty_ldisc::TtyLdiscManager,
26     tty_port::TTY_PORTS,
27     virtual_terminal::virtual_console::CURRENT_VCNUM,
28 };
29 
30 lazy_static! {
31     static ref TTY_DRIVERS: SpinLock<Vec<Arc<TtyDriver>>> = SpinLock::new(Vec::new());
32 }
33 
34 pub struct TtyDriverManager;
35 impl TtyDriverManager {
36     pub fn lookup_tty_driver(dev_num: DeviceNumber) -> Option<(usize, Arc<TtyDriver>)> {
37         let drivers_guard = TTY_DRIVERS.lock();
38         for (index, driver) in drivers_guard.iter().enumerate() {
39             let base = DeviceNumber::new(driver.major, driver.minor_start);
40             if dev_num < base || dev_num.data() > base.data() + driver.device_count {
41                 continue;
42             }
43             return Some((index, driver.clone()));
44         }
45 
46         None
47     }
48 
49     /// ## 注册驱动
50     pub fn tty_register_driver(mut driver: TtyDriver) -> Result<(), SystemError> {
51         // 查看是否注册设备号
52         if driver.major == Major::UNNAMED_MAJOR {
53             let dev_num = CharDevOps::alloc_chardev_region(
54                 driver.minor_start,
55                 driver.device_count,
56                 driver.name,
57             )?;
58             driver.major = dev_num.major();
59             driver.minor_start = dev_num.minor();
60         } else {
61             let dev_num = DeviceNumber::new(driver.major, driver.minor_start);
62             CharDevOps::register_chardev_region(dev_num, driver.device_count, driver.name)?;
63         }
64 
65         driver.flags |= TtyDriverFlag::TTY_DRIVER_INSTALLED;
66 
67         // 加入全局TtyDriver表
68         TTY_DRIVERS.lock().push(Arc::new(driver));
69 
70         // TODO: 加入procfs?
71 
72         Ok(())
73     }
74 }
75 
76 #[allow(dead_code)]
77 #[derive(Debug)]
78 #[cast_to([sync] Driver)]
79 pub struct TtyDriver {
80     /// /proc/tty中使用的驱动程序名称
81     driver_name: String,
82     /// 用于构造/dev节点名称,例如name设置为tty,则按照name_base分配节点tty0,tty1等
83     name: &'static str,
84     /// 命名基数
85     name_base: usize,
86     /// 主设备号
87     major: Major,
88     /// 起始次设备号
89     minor_start: u32,
90     /// 最多支持的tty数量
91     device_count: u32,
92     /// tty驱动程序类型
93     tty_driver_type: TtyDriverType,
94     /// 驱动程序子类型
95     tty_driver_sub_type: TtyDriverSubType,
96     /// 每个tty的默认termios
97     init_termios: Termios,
98     /// 懒加载termios,在tty设备关闭时,会将termios按照设备的index保存进这个集合,以便下次打开使用
99     saved_termios: Vec<Termios>,
100     /// 驱动程序标志
101     flags: TtyDriverFlag,
102     /// pty链接此driver的入口
103     pty: Option<Arc<TtyDriver>>,
104     /// 具体类型的tty驱动方法
105     driver_funcs: Arc<dyn TtyOperation>,
106     /// 管理的tty设备列表
107     ttys: SpinLock<HashMap<usize, Arc<TtyCore>>>,
108     // procfs入口?
109 }
110 
111 impl TtyDriver {
112     pub fn new(
113         count: u32,
114         node_name: &'static str,
115         node_name_base: usize,
116         major: Major,
117         minor_start: u32,
118         tty_driver_type: TtyDriverType,
119         default_termios: Termios,
120         driver_funcs: Arc<dyn TtyOperation>,
121     ) -> Self {
122         TtyDriver {
123             driver_name: Default::default(),
124             name: node_name,
125             name_base: node_name_base,
126             major,
127             minor_start,
128             device_count: count,
129             tty_driver_type,
130             tty_driver_sub_type: Default::default(),
131             init_termios: default_termios,
132             flags: TtyDriverFlag::empty(),
133             pty: Default::default(),
134             driver_funcs,
135             ttys: SpinLock::new(HashMap::new()),
136             saved_termios: Vec::with_capacity(count as usize),
137         }
138     }
139 
140     pub fn tty_line_name(&self, index: usize) -> String {
141         if self
142             .flags
143             .contains(TtyDriverFlag::TTY_DRIVER_UNNUMBERED_NODE)
144         {
145             return format!("{}", self.name);
146         } else {
147             return format!("{}{}", self.name, index + self.name_base);
148         }
149     }
150 
151     pub fn add_tty(&self, tty_core: Arc<TtyCore>) {
152         self.ttys.lock().insert(tty_core.core().index(), tty_core);
153     }
154 
155     #[inline]
156     pub fn driver_funcs(&self) -> Arc<dyn TtyOperation> {
157         self.driver_funcs.clone()
158     }
159 
160     #[inline]
161     pub fn flags(&self) -> TtyDriverFlag {
162         self.flags
163     }
164 
165     #[inline]
166     fn lockup_tty(&self, index: usize) -> Option<Arc<TtyCore>> {
167         let device_guard = self.ttys.lock();
168         return match device_guard.get(&index) {
169             Some(tty) => Some(tty.clone()),
170             None => None,
171         };
172     }
173 
174     fn standard_install(&self, tty_core: Arc<TtyCore>) -> Result<(), SystemError> {
175         let tty = tty_core.core();
176         let tty_index = tty.index();
177         // 初始化termios
178         if !self.flags.contains(TtyDriverFlag::TTY_DRIVER_RESET_TERMIOS) {
179             // 先查看是否有已经保存的termios
180             if let Some(t) = self.saved_termios.get(tty_index) {
181                 let mut termios = t.clone();
182                 termios.line = self.init_termios.line;
183                 tty.set_termios(termios);
184             }
185         }
186         // TODO:设置termios波特率?
187 
188         tty.add_count();
189 
190         self.ttys.lock().insert(tty_index, tty_core);
191 
192         Ok(())
193     }
194 
195     fn driver_install_tty(driver: Arc<TtyDriver>, tty: Arc<TtyCore>) -> Result<(), SystemError> {
196         let res = tty.install(driver.clone(), tty.clone());
197 
198         if res.is_err() {
199             let err = res.unwrap_err();
200             if err == SystemError::ENOSYS {
201                 return driver.standard_install(tty);
202             } else {
203                 return Err(err);
204             }
205         }
206 
207         driver.add_tty(tty);
208 
209         Ok(())
210     }
211 
212     fn init_tty_device(driver: Arc<TtyDriver>, index: usize) -> Result<Arc<TtyCore>, SystemError> {
213         let tty = TtyCore::new(driver.clone(), index);
214 
215         Self::driver_install_tty(driver.clone(), tty.clone())?;
216 
217         let core = tty.core();
218 
219         if core.port().is_none() {
220             TTY_PORTS[core.index()].setup_tty(Arc::downgrade(&tty));
221             tty.set_port(TTY_PORTS[core.index()].clone());
222         }
223 
224         TtyLdiscManager::ldisc_setup(tty.clone(), None)?;
225 
226         Ok(tty)
227     }
228 
229     /// ## 通过设备号找到对应驱动并且初始化Tty
230     pub fn open_tty(dev_num: DeviceNumber) -> Result<Arc<TtyCore>, SystemError> {
231         let (index, driver) =
232             TtyDriverManager::lookup_tty_driver(dev_num).ok_or(SystemError::ENODEV)?;
233 
234         let tty = match driver.lockup_tty(index) {
235             Some(tty) => {
236                 // TODO: 暂时这么写,因为还没写TtyPort
237                 if tty.core().port().is_none() {
238                     kwarn!("{} port is None", tty.core().name());
239                 } else {
240                     if tty.core().port().unwrap().state() == TtyPortState::KOPENED {
241                         return Err(SystemError::EBUSY);
242                     }
243                 }
244 
245                 tty.reopen()?;
246                 tty
247             }
248             None => Self::init_tty_device(driver, index)?,
249         };
250 
251         CURRENT_VCNUM.store(index as isize, Ordering::SeqCst);
252 
253         return Ok(tty);
254     }
255 
256     pub fn tty_driver_type(&self) -> TtyDriverType {
257         self.tty_driver_type
258     }
259 
260     pub fn tty_driver_sub_type(&self) -> TtyDriverSubType {
261         self.tty_driver_sub_type
262     }
263 
264     pub fn init_termios(&self) -> Termios {
265         self.init_termios
266     }
267 }
268 
269 impl KObject for TtyDriver {
270     fn as_any_ref(&self) -> &dyn core::any::Any {
271         todo!()
272     }
273 
274     fn set_inode(&self, _inode: Option<alloc::sync::Arc<crate::filesystem::kernfs::KernFSInode>>) {
275         todo!()
276     }
277 
278     fn inode(&self) -> Option<alloc::sync::Arc<crate::filesystem::kernfs::KernFSInode>> {
279         todo!()
280     }
281 
282     fn parent(&self) -> Option<alloc::sync::Weak<dyn KObject>> {
283         todo!()
284     }
285 
286     fn set_parent(&self, _parent: Option<alloc::sync::Weak<dyn KObject>>) {
287         todo!()
288     }
289 
290     fn kset(&self) -> Option<alloc::sync::Arc<crate::driver::base::kset::KSet>> {
291         todo!()
292     }
293 
294     fn set_kset(&self, _kset: Option<alloc::sync::Arc<crate::driver::base::kset::KSet>>) {
295         todo!()
296     }
297 
298     fn kobj_type(&self) -> Option<&'static dyn crate::driver::base::kobject::KObjType> {
299         todo!()
300     }
301 
302     fn set_kobj_type(&self, _ktype: Option<&'static dyn crate::driver::base::kobject::KObjType>) {
303         todo!()
304     }
305 
306     fn name(&self) -> alloc::string::String {
307         todo!()
308     }
309 
310     fn set_name(&self, _name: alloc::string::String) {
311         todo!()
312     }
313 
314     fn kobj_state(
315         &self,
316     ) -> crate::libs::rwlock::RwLockReadGuard<crate::driver::base::kobject::KObjectState> {
317         todo!()
318     }
319 
320     fn kobj_state_mut(
321         &self,
322     ) -> crate::libs::rwlock::RwLockWriteGuard<crate::driver::base::kobject::KObjectState> {
323         todo!()
324     }
325 
326     fn set_kobj_state(&self, _state: crate::driver::base::kobject::KObjectState) {
327         todo!()
328     }
329 }
330 
331 impl Driver for TtyDriver {
332     fn id_table(&self) -> Option<crate::driver::base::device::IdTable> {
333         todo!()
334     }
335 
336     fn devices(
337         &self,
338     ) -> alloc::vec::Vec<alloc::sync::Arc<dyn crate::driver::base::device::Device>> {
339         todo!()
340     }
341 
342     fn add_device(&self, _device: alloc::sync::Arc<dyn crate::driver::base::device::Device>) {
343         todo!()
344     }
345 
346     fn delete_device(&self, _device: &alloc::sync::Arc<dyn crate::driver::base::device::Device>) {
347         todo!()
348     }
349 
350     fn set_bus(&self, _bus: Option<alloc::sync::Weak<dyn crate::driver::base::device::bus::Bus>>) {
351         todo!()
352     }
353 }
354 
355 pub trait TtyOperation: Sync + Send + Debug {
356     fn install(&self, _driver: Arc<TtyDriver>, _tty: Arc<TtyCore>) -> Result<(), SystemError> {
357         return Err(SystemError::ENOSYS);
358     }
359 
360     fn open(&self, tty: &TtyCoreData) -> Result<(), SystemError>;
361 
362     /// ## 获取可写字符数
363     fn write_room(&self, _tty: &TtyCoreData) -> usize {
364         // 默认
365         2048
366     }
367 
368     fn write(&self, tty: &TtyCoreData, buf: &[u8], nr: usize) -> Result<usize, SystemError>;
369 
370     fn flush_chars(&self, tty: &TtyCoreData);
371 
372     fn put_char(&self, tty: &TtyCoreData, ch: u8) -> Result<(), SystemError>;
373 
374     fn start(&self, _tty: &TtyCoreData) -> Result<(), SystemError> {
375         Err(SystemError::ENOSYS)
376     }
377 
378     fn stop(&self, _tty: &TtyCoreData) -> Result<(), SystemError> {
379         Err(SystemError::ENOSYS)
380     }
381 
382     fn flush_buffer(&self, _tty: &TtyCoreData) -> Result<(), SystemError> {
383         Err(SystemError::ENOSYS)
384     }
385 
386     fn ioctl(&self, tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<(), SystemError>;
387 
388     fn chars_in_buffer(&self) -> usize {
389         0
390     }
391 
392     fn set_termios(&self, _tty: Arc<TtyCore>, _old_termios: Termios) -> Result<(), SystemError> {
393         Err(SystemError::ENOSYS)
394     }
395 }
396 
397 #[allow(dead_code)]
398 #[derive(Debug, PartialEq, Copy, Clone)]
399 pub enum TtyDriverType {
400     System,
401     Console,
402     Serial,
403     Pty,
404     Scc,
405     Syscons,
406 }
407 
408 #[allow(dead_code)]
409 #[derive(Debug, PartialEq, Copy, Clone)]
410 pub enum TtyDriverSubType {
411     Undefined,
412     Tty,
413     Console,
414     Syscons,
415     Sysptmx,
416     PtyMaster,
417     PtySlave,
418     SerialNormal,
419 }
420 
421 impl Default for TtyDriverSubType {
422     fn default() -> Self {
423         Self::Undefined
424     }
425 }
426 
427 bitflags! {
428     pub struct TtyDriverFlag: u32 {
429         /// 表示 tty 驱动程序已安装
430         const TTY_DRIVER_INSTALLED		= 0x0001;
431         /// 请求 tty 层在最后一个进程关闭设备时重置 termios 设置
432         const TTY_DRIVER_RESET_TERMIOS	= 0x0002;
433         /// 表示驱动程序将保证在设置了该标志的 tty 上不设置任何特殊字符处理标志(原模式)
434         const TTY_DRIVER_REAL_RAW		    = 0x0004;
435 
436         /// 以下四个标志位为内存分配相关,目前设计无需使用
437         const TTY_DRIVER_DYNAMIC_DEV		= 0x0008;
438         const TTY_DRIVER_DEVPTS_MEM		= 0x0010;
439         const TTY_DRIVER_HARDWARE_BREAK	= 0x0020;
440         const TTY_DRIVER_DYNAMIC_ALLOC	= 0x0040;
441 
442         /// 表示不创建带有编号的 /dev 节点。
443         /// 例如,创建 /dev/ttyprintk 而不是 /dev/ttyprintk0。仅在为单个 tty 设备分配驱动程序时适用。
444         const TTY_DRIVER_UNNUMBERED_NODE	= 0x0080;
445     }
446 }
447