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