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