xref: /DragonOS/kernel/src/driver/tty/pty/mod.rs (revision dfe53cf087ef4c7b6db63d992906b062dc63e93f)
1*dfe53cf0SGnoCiYeH use alloc::{
2*dfe53cf0SGnoCiYeH     string::{String, ToString},
3*dfe53cf0SGnoCiYeH     sync::Arc,
4*dfe53cf0SGnoCiYeH };
5*dfe53cf0SGnoCiYeH use system_error::SystemError;
6*dfe53cf0SGnoCiYeH use unified_init::macros::unified_init;
7*dfe53cf0SGnoCiYeH 
8*dfe53cf0SGnoCiYeH use crate::{
9*dfe53cf0SGnoCiYeH     driver::base::device::{
10*dfe53cf0SGnoCiYeH         device_number::{DeviceNumber, Major},
11*dfe53cf0SGnoCiYeH         device_register, IdTable,
12*dfe53cf0SGnoCiYeH     },
13*dfe53cf0SGnoCiYeH     filesystem::devfs::devfs_register,
14*dfe53cf0SGnoCiYeH     init::initcall::INITCALL_DEVICE,
15*dfe53cf0SGnoCiYeH     libs::lazy_init::Lazy,
16*dfe53cf0SGnoCiYeH     mm::VirtAddr,
17*dfe53cf0SGnoCiYeH     syscall::user_access::{UserBufferReader, UserBufferWriter},
18*dfe53cf0SGnoCiYeH };
19*dfe53cf0SGnoCiYeH 
20*dfe53cf0SGnoCiYeH use self::unix98pty::{Unix98PtyDriverInner, NR_UNIX98_PTY_MAX};
21*dfe53cf0SGnoCiYeH 
22*dfe53cf0SGnoCiYeH use super::{
23*dfe53cf0SGnoCiYeH     termios::{ControlMode, InputMode, LocalMode, OutputMode, TTY_STD_TERMIOS},
24*dfe53cf0SGnoCiYeH     tty_core::{TtyCore, TtyCoreData, TtyFlag, TtyPacketStatus},
25*dfe53cf0SGnoCiYeH     tty_device::{TtyDevice, TtyType},
26*dfe53cf0SGnoCiYeH     tty_driver::{TtyDriver, TtyDriverManager, TtyDriverSubType, TtyDriverType, TTY_DRIVERS},
27*dfe53cf0SGnoCiYeH     tty_port::{DefaultTtyPort, TtyPort},
28*dfe53cf0SGnoCiYeH };
29*dfe53cf0SGnoCiYeH 
30*dfe53cf0SGnoCiYeH pub mod unix98pty;
31*dfe53cf0SGnoCiYeH 
32*dfe53cf0SGnoCiYeH static PTM_DRIVER: Lazy<Arc<TtyDriver>> = Lazy::new();
33*dfe53cf0SGnoCiYeH static PTS_DRIVER: Lazy<Arc<TtyDriver>> = Lazy::new();
34*dfe53cf0SGnoCiYeH 
ptm_driver() -> Arc<TtyDriver>35*dfe53cf0SGnoCiYeH pub(super) fn ptm_driver() -> Arc<TtyDriver> {
36*dfe53cf0SGnoCiYeH     PTM_DRIVER.ensure();
37*dfe53cf0SGnoCiYeH     PTM_DRIVER.get().clone()
38*dfe53cf0SGnoCiYeH }
39*dfe53cf0SGnoCiYeH 
pts_driver() -> Arc<TtyDriver>40*dfe53cf0SGnoCiYeH pub(super) fn pts_driver() -> Arc<TtyDriver> {
41*dfe53cf0SGnoCiYeH     PTS_DRIVER.ensure();
42*dfe53cf0SGnoCiYeH     PTS_DRIVER.get().clone()
43*dfe53cf0SGnoCiYeH }
44*dfe53cf0SGnoCiYeH 
45*dfe53cf0SGnoCiYeH // lazy_static! {
46*dfe53cf0SGnoCiYeH //     pub static ref PTM_DRIVER: Arc<TtyDriver> = {
47*dfe53cf0SGnoCiYeH //         let mut ptm_driver = TtyDriver::new(
48*dfe53cf0SGnoCiYeH //             NR_UNIX98_PTY_MAX,
49*dfe53cf0SGnoCiYeH //             "ptm",
50*dfe53cf0SGnoCiYeH //             0,
51*dfe53cf0SGnoCiYeH //             Major::UNIX98_PTY_MASTER_MAJOR,
52*dfe53cf0SGnoCiYeH //             0,
53*dfe53cf0SGnoCiYeH //             TtyDriverType::Pty,
54*dfe53cf0SGnoCiYeH //             *TTY_STD_TERMIOS,
55*dfe53cf0SGnoCiYeH //             Arc::new(Unix98PtyDriverInner::new()),
56*dfe53cf0SGnoCiYeH //         );
57*dfe53cf0SGnoCiYeH 
58*dfe53cf0SGnoCiYeH //         ptm_driver.set_subtype(TtyDriverSubType::PtyMaster);
59*dfe53cf0SGnoCiYeH //         let term = ptm_driver.init_termios_mut();
60*dfe53cf0SGnoCiYeH //         term.input_mode = InputMode::empty();
61*dfe53cf0SGnoCiYeH //         term.output_mode = OutputMode::empty();
62*dfe53cf0SGnoCiYeH //         term.control_mode = ControlMode::B38400 | ControlMode::CS8 | ControlMode::CREAD;
63*dfe53cf0SGnoCiYeH //         term.local_mode = LocalMode::empty();
64*dfe53cf0SGnoCiYeH //         term.input_speed = 38400;
65*dfe53cf0SGnoCiYeH //         term.output_speed = 38400;
66*dfe53cf0SGnoCiYeH //         TtyDriverManager::tty_register_driver(ptm_driver).unwrap()
67*dfe53cf0SGnoCiYeH //     };
68*dfe53cf0SGnoCiYeH //     pub static ref PTS_DRIVER: Arc<TtyDriver> = {
69*dfe53cf0SGnoCiYeH //         let mut pts_driver = TtyDriver::new(
70*dfe53cf0SGnoCiYeH //             NR_UNIX98_PTY_MAX,
71*dfe53cf0SGnoCiYeH //             "pts",
72*dfe53cf0SGnoCiYeH //             0,
73*dfe53cf0SGnoCiYeH //             Major::UNIX98_PTY_SLAVE_MAJOR,
74*dfe53cf0SGnoCiYeH //             0,
75*dfe53cf0SGnoCiYeH //             TtyDriverType::Pty,
76*dfe53cf0SGnoCiYeH //             *TTY_STD_TERMIOS,
77*dfe53cf0SGnoCiYeH //             Arc::new(Unix98PtyDriverInner::new()),
78*dfe53cf0SGnoCiYeH //         );
79*dfe53cf0SGnoCiYeH 
80*dfe53cf0SGnoCiYeH //         pts_driver.set_subtype(TtyDriverSubType::PtySlave);
81*dfe53cf0SGnoCiYeH //         let term = pts_driver.init_termios_mut();
82*dfe53cf0SGnoCiYeH //         term.input_mode = InputMode::empty();
83*dfe53cf0SGnoCiYeH //         term.output_mode = OutputMode::empty();
84*dfe53cf0SGnoCiYeH //         term.control_mode = ControlMode::B38400 | ControlMode::CS8 | ControlMode::CREAD;
85*dfe53cf0SGnoCiYeH //         term.local_mode = LocalMode::empty();
86*dfe53cf0SGnoCiYeH //         term.input_speed = 38400;
87*dfe53cf0SGnoCiYeH //         term.output_speed = 38400;
88*dfe53cf0SGnoCiYeH //         TtyDriverManager::tty_register_driver(pts_driver).unwrap()
89*dfe53cf0SGnoCiYeH //     };
90*dfe53cf0SGnoCiYeH // }
91*dfe53cf0SGnoCiYeH 
92*dfe53cf0SGnoCiYeH pub struct PtyCommon;
93*dfe53cf0SGnoCiYeH 
94*dfe53cf0SGnoCiYeH impl PtyCommon {
pty_common_install( driver: Arc<TtyDriver>, tty: Arc<TtyCore>, legacy: bool, ) -> Result<(), SystemError>95*dfe53cf0SGnoCiYeH     pub fn pty_common_install(
96*dfe53cf0SGnoCiYeH         driver: Arc<TtyDriver>,
97*dfe53cf0SGnoCiYeH         tty: Arc<TtyCore>,
98*dfe53cf0SGnoCiYeH         legacy: bool,
99*dfe53cf0SGnoCiYeH     ) -> Result<(), SystemError> {
100*dfe53cf0SGnoCiYeH         let core = tty.core();
101*dfe53cf0SGnoCiYeH         let other_driver = driver.other_pty_driver().unwrap();
102*dfe53cf0SGnoCiYeH         let other_tty = TtyCore::new(other_driver.clone(), core.index());
103*dfe53cf0SGnoCiYeH         other_driver.add_tty(other_tty.clone());
104*dfe53cf0SGnoCiYeH 
105*dfe53cf0SGnoCiYeH         let port0: Arc<dyn TtyPort> = Arc::new(DefaultTtyPort::new());
106*dfe53cf0SGnoCiYeH         let port1: Arc<dyn TtyPort> = Arc::new(DefaultTtyPort::new());
107*dfe53cf0SGnoCiYeH 
108*dfe53cf0SGnoCiYeH         let o_core = other_tty.core();
109*dfe53cf0SGnoCiYeH 
110*dfe53cf0SGnoCiYeH         if legacy {
111*dfe53cf0SGnoCiYeH             core.init_termios();
112*dfe53cf0SGnoCiYeH             o_core.init_termios();
113*dfe53cf0SGnoCiYeH 
114*dfe53cf0SGnoCiYeH             driver
115*dfe53cf0SGnoCiYeH                 .other_pty_driver()
116*dfe53cf0SGnoCiYeH                 .unwrap()
117*dfe53cf0SGnoCiYeH                 .ttys()
118*dfe53cf0SGnoCiYeH                 .insert(core.index(), other_tty.clone());
119*dfe53cf0SGnoCiYeH             driver.ttys().insert(core.index(), tty.clone());
120*dfe53cf0SGnoCiYeH         } else {
121*dfe53cf0SGnoCiYeH             *core.termios_write() = driver.init_termios();
122*dfe53cf0SGnoCiYeH             *o_core.termios_write() = driver.other_pty_driver().unwrap().init_termios();
123*dfe53cf0SGnoCiYeH         }
124*dfe53cf0SGnoCiYeH 
125*dfe53cf0SGnoCiYeH         core.set_link(Arc::downgrade(&other_tty));
126*dfe53cf0SGnoCiYeH         o_core.set_link(Arc::downgrade(&tty));
127*dfe53cf0SGnoCiYeH 
128*dfe53cf0SGnoCiYeH         port0.setup_internal_tty(Arc::downgrade(&other_tty));
129*dfe53cf0SGnoCiYeH         port1.setup_internal_tty(Arc::downgrade(&tty));
130*dfe53cf0SGnoCiYeH         other_tty.set_port(port0);
131*dfe53cf0SGnoCiYeH         tty.set_port(port1);
132*dfe53cf0SGnoCiYeH 
133*dfe53cf0SGnoCiYeH         core.add_count();
134*dfe53cf0SGnoCiYeH         o_core.add_count();
135*dfe53cf0SGnoCiYeH 
136*dfe53cf0SGnoCiYeH         // 将pts加入pts Driver管理队列
137*dfe53cf0SGnoCiYeH         PTS_DRIVER.ttys().insert(core.index(), other_tty);
138*dfe53cf0SGnoCiYeH 
139*dfe53cf0SGnoCiYeH         Ok(())
140*dfe53cf0SGnoCiYeH     }
141*dfe53cf0SGnoCiYeH 
pty_common_open(core: &TtyCoreData) -> Result<(), SystemError>142*dfe53cf0SGnoCiYeH     pub fn pty_common_open(core: &TtyCoreData) -> Result<(), SystemError> {
143*dfe53cf0SGnoCiYeH         if let Some(link) = core.link() {
144*dfe53cf0SGnoCiYeH             let link_core = link.core();
145*dfe53cf0SGnoCiYeH 
146*dfe53cf0SGnoCiYeH             if core.flags().contains(TtyFlag::OTHER_CLOSED) {
147*dfe53cf0SGnoCiYeH                 core.flags_write().insert(TtyFlag::IO_ERROR);
148*dfe53cf0SGnoCiYeH                 return Err(SystemError::EIO);
149*dfe53cf0SGnoCiYeH             }
150*dfe53cf0SGnoCiYeH 
151*dfe53cf0SGnoCiYeH             if link_core.flags().contains(TtyFlag::PTY_LOCK) {
152*dfe53cf0SGnoCiYeH                 core.flags_write().insert(TtyFlag::IO_ERROR);
153*dfe53cf0SGnoCiYeH                 return Err(SystemError::EIO);
154*dfe53cf0SGnoCiYeH             }
155*dfe53cf0SGnoCiYeH 
156*dfe53cf0SGnoCiYeH             if core.driver().tty_driver_sub_type() == TtyDriverSubType::PtySlave
157*dfe53cf0SGnoCiYeH                 && link_core.count() != 1
158*dfe53cf0SGnoCiYeH             {
159*dfe53cf0SGnoCiYeH                 // 只能有一个master,如果当前为slave,则link的count必须为1
160*dfe53cf0SGnoCiYeH                 core.flags_write().insert(TtyFlag::IO_ERROR);
161*dfe53cf0SGnoCiYeH                 return Err(SystemError::EIO);
162*dfe53cf0SGnoCiYeH             }
163*dfe53cf0SGnoCiYeH 
164*dfe53cf0SGnoCiYeH             core.flags_write().remove(TtyFlag::IO_ERROR);
165*dfe53cf0SGnoCiYeH             link_core.flags_write().remove(TtyFlag::OTHER_CLOSED);
166*dfe53cf0SGnoCiYeH             core.flags_write().insert(TtyFlag::THROTTLED);
167*dfe53cf0SGnoCiYeH 
168*dfe53cf0SGnoCiYeH             return Ok(());
169*dfe53cf0SGnoCiYeH         }
170*dfe53cf0SGnoCiYeH         return Err(SystemError::ENODEV);
171*dfe53cf0SGnoCiYeH     }
172*dfe53cf0SGnoCiYeH 
pty_set_lock(tty: &TtyCoreData, arg: VirtAddr) -> Result<(), SystemError>173*dfe53cf0SGnoCiYeH     pub fn pty_set_lock(tty: &TtyCoreData, arg: VirtAddr) -> Result<(), SystemError> {
174*dfe53cf0SGnoCiYeH         let user_reader =
175*dfe53cf0SGnoCiYeH             UserBufferReader::new(arg.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?;
176*dfe53cf0SGnoCiYeH 
177*dfe53cf0SGnoCiYeH         if *user_reader.read_one_from_user::<i32>(0)? != 0 {
178*dfe53cf0SGnoCiYeH             tty.flags_write().insert(TtyFlag::PTY_LOCK);
179*dfe53cf0SGnoCiYeH         } else {
180*dfe53cf0SGnoCiYeH             tty.flags_write().remove(TtyFlag::PTY_LOCK);
181*dfe53cf0SGnoCiYeH         }
182*dfe53cf0SGnoCiYeH 
183*dfe53cf0SGnoCiYeH         Ok(())
184*dfe53cf0SGnoCiYeH     }
185*dfe53cf0SGnoCiYeH 
pty_get_lock(tty: &TtyCoreData, arg: VirtAddr) -> Result<(), SystemError>186*dfe53cf0SGnoCiYeH     pub fn pty_get_lock(tty: &TtyCoreData, arg: VirtAddr) -> Result<(), SystemError> {
187*dfe53cf0SGnoCiYeH         let mut user_writer =
188*dfe53cf0SGnoCiYeH             UserBufferWriter::new(arg.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?;
189*dfe53cf0SGnoCiYeH         user_writer.copy_one_to_user(&tty.flags().contains(TtyFlag::PTY_LOCK), 0)?;
190*dfe53cf0SGnoCiYeH         Ok(())
191*dfe53cf0SGnoCiYeH     }
192*dfe53cf0SGnoCiYeH 
pty_set_packet_mode(tty: &TtyCoreData, arg: VirtAddr) -> Result<(), SystemError>193*dfe53cf0SGnoCiYeH     pub fn pty_set_packet_mode(tty: &TtyCoreData, arg: VirtAddr) -> Result<(), SystemError> {
194*dfe53cf0SGnoCiYeH         let user_reader =
195*dfe53cf0SGnoCiYeH             UserBufferReader::new(arg.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?;
196*dfe53cf0SGnoCiYeH 
197*dfe53cf0SGnoCiYeH         let mut ctrl = tty.contorl_info_irqsave();
198*dfe53cf0SGnoCiYeH         if *user_reader.read_one_from_user::<i32>(0)? != 0 {
199*dfe53cf0SGnoCiYeH             if !ctrl.packet {
200*dfe53cf0SGnoCiYeH                 tty.link().unwrap().core().contorl_info_irqsave().pktstatus =
201*dfe53cf0SGnoCiYeH                     TtyPacketStatus::empty();
202*dfe53cf0SGnoCiYeH                 ctrl.packet = true;
203*dfe53cf0SGnoCiYeH             }
204*dfe53cf0SGnoCiYeH         } else {
205*dfe53cf0SGnoCiYeH             ctrl.packet = false;
206*dfe53cf0SGnoCiYeH         }
207*dfe53cf0SGnoCiYeH         Ok(())
208*dfe53cf0SGnoCiYeH     }
209*dfe53cf0SGnoCiYeH 
pty_get_packet_mode(tty: &TtyCoreData, arg: VirtAddr) -> Result<(), SystemError>210*dfe53cf0SGnoCiYeH     pub fn pty_get_packet_mode(tty: &TtyCoreData, arg: VirtAddr) -> Result<(), SystemError> {
211*dfe53cf0SGnoCiYeH         let mut user_writer =
212*dfe53cf0SGnoCiYeH             UserBufferWriter::new(arg.as_ptr::<i32>(), core::mem::size_of::<i32>(), true)?;
213*dfe53cf0SGnoCiYeH         user_writer.copy_one_to_user(&tty.contorl_info_irqsave().packet, 0)?;
214*dfe53cf0SGnoCiYeH         Ok(())
215*dfe53cf0SGnoCiYeH     }
216*dfe53cf0SGnoCiYeH 
unix98pty_init() -> Result<(), SystemError>217*dfe53cf0SGnoCiYeH     pub fn unix98pty_init() -> Result<(), SystemError> {
218*dfe53cf0SGnoCiYeH         let ptm_driver = ptm_driver();
219*dfe53cf0SGnoCiYeH         let pts_driver = pts_driver();
220*dfe53cf0SGnoCiYeH         ptm_driver.set_other_pty_driver(Arc::downgrade(&pts_driver));
221*dfe53cf0SGnoCiYeH         pts_driver.set_other_pty_driver(Arc::downgrade(&ptm_driver));
222*dfe53cf0SGnoCiYeH 
223*dfe53cf0SGnoCiYeH         let idt = IdTable::new(
224*dfe53cf0SGnoCiYeH             String::from("ptmx"),
225*dfe53cf0SGnoCiYeH             Some(DeviceNumber::new(Major::TTYAUX_MAJOR, 2)),
226*dfe53cf0SGnoCiYeH         );
227*dfe53cf0SGnoCiYeH         let ptmx_dev = TtyDevice::new(
228*dfe53cf0SGnoCiYeH             "ptmx".to_string(),
229*dfe53cf0SGnoCiYeH             idt.clone(),
230*dfe53cf0SGnoCiYeH             TtyType::Pty(super::tty_device::PtyType::Ptm),
231*dfe53cf0SGnoCiYeH         );
232*dfe53cf0SGnoCiYeH 
233*dfe53cf0SGnoCiYeH         ptmx_dev.inner_write().metadata_mut().raw_dev = idt.device_number();
234*dfe53cf0SGnoCiYeH         device_register(ptmx_dev.clone())?;
235*dfe53cf0SGnoCiYeH         devfs_register("ptmx", ptmx_dev)?;
236*dfe53cf0SGnoCiYeH 
237*dfe53cf0SGnoCiYeH         TTY_DRIVERS.lock().push(ptm_driver);
238*dfe53cf0SGnoCiYeH         TTY_DRIVERS.lock().push(pts_driver);
239*dfe53cf0SGnoCiYeH 
240*dfe53cf0SGnoCiYeH         Ok(())
241*dfe53cf0SGnoCiYeH     }
242*dfe53cf0SGnoCiYeH }
243*dfe53cf0SGnoCiYeH 
244*dfe53cf0SGnoCiYeH #[unified_init(INITCALL_DEVICE)]
245*dfe53cf0SGnoCiYeH #[inline(never)]
pty_init() -> Result<(), SystemError>246*dfe53cf0SGnoCiYeH pub fn pty_init() -> Result<(), SystemError> {
247*dfe53cf0SGnoCiYeH     let mut ptm_driver = TtyDriver::new(
248*dfe53cf0SGnoCiYeH         NR_UNIX98_PTY_MAX,
249*dfe53cf0SGnoCiYeH         "ptm",
250*dfe53cf0SGnoCiYeH         0,
251*dfe53cf0SGnoCiYeH         Major::UNIX98_PTY_MASTER_MAJOR,
252*dfe53cf0SGnoCiYeH         0,
253*dfe53cf0SGnoCiYeH         TtyDriverType::Pty,
254*dfe53cf0SGnoCiYeH         *TTY_STD_TERMIOS,
255*dfe53cf0SGnoCiYeH         Arc::new(Unix98PtyDriverInner::new()),
256*dfe53cf0SGnoCiYeH     );
257*dfe53cf0SGnoCiYeH     ptm_driver.set_subtype(TtyDriverSubType::PtyMaster);
258*dfe53cf0SGnoCiYeH     let term = ptm_driver.init_termios_mut();
259*dfe53cf0SGnoCiYeH     term.input_mode = InputMode::empty();
260*dfe53cf0SGnoCiYeH     term.output_mode = OutputMode::empty();
261*dfe53cf0SGnoCiYeH     term.control_mode = ControlMode::B38400 | ControlMode::CS8 | ControlMode::CREAD;
262*dfe53cf0SGnoCiYeH     term.local_mode = LocalMode::empty();
263*dfe53cf0SGnoCiYeH     term.input_speed = 38400;
264*dfe53cf0SGnoCiYeH     term.output_speed = 38400;
265*dfe53cf0SGnoCiYeH     PTM_DRIVER.init(TtyDriverManager::tty_register_driver(ptm_driver).unwrap());
266*dfe53cf0SGnoCiYeH 
267*dfe53cf0SGnoCiYeH     let mut pts_driver = TtyDriver::new(
268*dfe53cf0SGnoCiYeH         NR_UNIX98_PTY_MAX,
269*dfe53cf0SGnoCiYeH         "pts",
270*dfe53cf0SGnoCiYeH         0,
271*dfe53cf0SGnoCiYeH         Major::UNIX98_PTY_SLAVE_MAJOR,
272*dfe53cf0SGnoCiYeH         0,
273*dfe53cf0SGnoCiYeH         TtyDriverType::Pty,
274*dfe53cf0SGnoCiYeH         *TTY_STD_TERMIOS,
275*dfe53cf0SGnoCiYeH         Arc::new(Unix98PtyDriverInner::new()),
276*dfe53cf0SGnoCiYeH     );
277*dfe53cf0SGnoCiYeH     pts_driver.set_subtype(TtyDriverSubType::PtySlave);
278*dfe53cf0SGnoCiYeH     let term = pts_driver.init_termios_mut();
279*dfe53cf0SGnoCiYeH     term.input_mode = InputMode::empty();
280*dfe53cf0SGnoCiYeH     term.output_mode = OutputMode::empty();
281*dfe53cf0SGnoCiYeH     term.control_mode = ControlMode::B38400 | ControlMode::CS8 | ControlMode::CREAD;
282*dfe53cf0SGnoCiYeH     term.local_mode = LocalMode::empty();
283*dfe53cf0SGnoCiYeH     term.input_speed = 38400;
284*dfe53cf0SGnoCiYeH     term.output_speed = 38400;
285*dfe53cf0SGnoCiYeH     PTS_DRIVER.init(TtyDriverManager::tty_register_driver(pts_driver).unwrap());
286*dfe53cf0SGnoCiYeH 
287*dfe53cf0SGnoCiYeH     return PtyCommon::unix98pty_init();
288*dfe53cf0SGnoCiYeH }
289