kernel/device/char/
tty.rs1extern crate alloc;
7use core::any::Any;
8use alloc::collections::VecDeque;
9use alloc::sync::Arc;
10use spin::Mutex;
11use crate::arch::get_cpu;
12use crate::device::{Device, DeviceType};
13use crate::device::char::CharDevice;
14use crate::device::events::{DeviceEvent, DeviceEventListener, InputEvent, EventCapableDevice};
15use crate::device::manager::DeviceManager;
16use crate::drivers::uart;
17use crate::sync::waker::Waker;
18use crate::late_initcall;
19use crate::task::mytask;
20
21fn init_tty_subsystem() {
23 let result = try_init_tty_subsystem();
24 if let Err(e) = result {
25 crate::early_println!("Failed to initialize TTY subsystem: {}", e);
26 }
27}
28
29fn try_init_tty_subsystem() -> Result<(), &'static str> {
30 let device_manager = DeviceManager::get_manager();
31
32 if let Some(uart_device_id) = device_manager.get_first_device_by_type(crate::device::DeviceType::Char) {
34 let tty_device = Arc::new(TtyDevice::new("tty0", uart_device_id));
36 let uart_device = device_manager.get_device(uart_device_id).ok_or("UART device not found")?;
37
38 if let Some(uart) = uart_device.as_any().downcast_ref::<crate::drivers::uart::virt::Uart>() {
40 let weak_tty = Arc::downgrade(&tty_device);
41 uart.register_event_listener(weak_tty);
43 crate::early_println!("TTY registered as UART event listener");
44 } else {
45 crate::early_println!("Failed to cast UART device to specific type");
46 }
47
48 let _tty_id = device_manager.register_device_with_name("tty0".into(), tty_device);
50
51 crate::early_println!("TTY subsystem initialized successfully");
52 Ok(())
53 } else {
54 Err("No UART device found for TTY initialization")
55 }
56}
57
58late_initcall!(init_tty_subsystem);
59
60pub struct TtyDevice {
65 name: &'static str,
66 uart_device_id: usize,
67
68 input_buffer: Arc<Mutex<VecDeque<u8>>>,
70
71 input_waker: Waker,
73
74 canonical_mode: bool,
76 echo_enabled: bool,
77
78 }
82
83impl TtyDevice {
84 pub fn new(name: &'static str, uart_device_id: usize) -> Self {
85 Self {
86 name,
87 uart_device_id,
88 input_buffer: Arc::new(Mutex::new(VecDeque::new())),
89 input_waker: Waker::new_interruptible("tty_input"),
90 canonical_mode: true,
91 echo_enabled: true,
92 }
93 }
94
95 fn handle_input_byte(&self, byte: u8) {
99 if self.canonical_mode {
103 match byte {
104 0x08 | 0x7F => {
106 let mut input_buffer = self.input_buffer.lock();
108 if input_buffer.pop_back().is_some() && self.echo_enabled {
109 self.echo_backspace();
110 }
111 }
112 b'\r' | b'\n' => {
114 if self.echo_enabled {
116 self.echo_char(b'\r');
117 self.echo_char(b'\n');
118 }
119 let mut input_buffer = self.input_buffer.lock();
120 input_buffer.push_back(b'\n');
121 drop(input_buffer);
124 self.input_waker.wake_all();
125 }
126 0x03 => {
128 crate::early_println!("TTY: Ctrl+C detected");
129 }
132 0x1A => {
133 crate::early_println!("TTY: Ctrl+Z detected");
134 }
137 byte => {
139 if self.echo_enabled {
141 self.echo_char(byte);
142 }
143 let mut input_buffer = self.input_buffer.lock();
144 input_buffer.push_back(byte);
145 drop(input_buffer);
148 if !self.canonical_mode {
149 self.input_waker.wake_all();
150 }
151 }
152 }
153 } else {
154 let mut input_buffer = self.input_buffer.lock();
156 input_buffer.push_back(byte);
157 drop(input_buffer);
158 self.input_waker.wake_all();
160 }
161 }
162
163 fn echo_char(&self, byte: u8) {
165 let device_manager = DeviceManager::get_manager();
167 if let Some(uart_device) = device_manager.get_device(self.uart_device_id) {
168 if let Some(char_device) = uart_device.as_char_device() {
170 let _ = char_device.write_byte(byte);
171 }
172 }
173 }
174
175 fn echo_backspace(&self) {
177 self.echo_char(0x08);
179 self.echo_char(b' ');
180 self.echo_char(0x08);
181 }
182}
183
184impl DeviceEventListener for TtyDevice {
185 fn on_device_event(&self, event: &dyn DeviceEvent) {
186 if let Some(input_event) = event.as_any().downcast_ref::<InputEvent>() {
187 self.handle_input_byte(input_event.data);
195 }
196 }
197
198 fn interested_in(&self, event_type: &str) -> bool {
199 event_type == "input"
200 }
201}
202
203impl Device for TtyDevice {
204 fn device_type(&self) -> DeviceType {
205 DeviceType::Char
206 }
207
208 fn name(&self) -> &'static str {
209 self.name
210 }
211
212 fn as_any(&self) -> &dyn Any {
213 self
214 }
215
216 fn as_any_mut(&mut self) -> &mut dyn Any {
217 self
218 }
219
220 fn as_char_device(&self) -> Option<&dyn CharDevice> {
221 Some(self)
222 }
223}
224
225impl CharDevice for TtyDevice {
226 fn read_byte(&self) -> Option<u8> {
227 let mut input_buffer = self.input_buffer.lock();
228 if let Some(byte) = input_buffer.pop_front() {
229 return Some(byte);
230 }
231 drop(input_buffer);
232
233 if let Some(mut task) = mytask() {
235 let mut cpu = get_cpu();
236
237 self.input_waker.wait(&mut task, &mut cpu);
239 }
240
241 None
242 }
243
244 fn write_byte(&self, byte: u8) -> Result<(), &'static str> {
245 let device_manager = DeviceManager::get_manager();
247 if let Some(uart_device) = device_manager.get_device(self.uart_device_id) {
248 if let Some(char_device) = uart_device.as_char_device() {
250 if byte == b'\n' {
252 char_device.write_byte(b'\r')?;
253 char_device.write_byte(b'\n')?;
254 } else {
255 char_device.write_byte(byte)?;
256 }
257 return Ok(());
258 }
259 }
260 Err("UART device not available")
261 }
262
263 fn can_read(&self) -> bool {
264 let input_buffer = self.input_buffer.lock();
265 !input_buffer.is_empty()
266 }
267
268 fn can_write(&self) -> bool {
269 let device_manager = DeviceManager::get_manager();
271 if let Some(uart_device) = device_manager.get_device(self.uart_device_id) {
272 if let Some(uart) = uart_device.as_any().downcast_ref::<crate::drivers::uart::virt::Uart>() {
273 return uart.can_write();
274 }
275 }
276 false
277 }
278}