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