1use alloc::{boxed::Box, collections::VecDeque, sync::Arc};
4use core::fmt::Write;
5use core::{any::Any, fmt};
6use spin::{Mutex, RwLock};
7
8use crate::{
9 device::{
10 Device, DeviceInfo, DeviceType,
11 char::CharDevice,
12 events::{
13 DeviceEventEmitter, DeviceEventListener, EventCapableDevice, InputEvent,
14 InterruptCapableDevice,
15 },
16 manager::{DeviceManager, DriverPriority},
17 platform::{
18 PlatformDeviceDriver, PlatformDeviceInfo, resource::PlatformDeviceResourceType,
19 },
20 },
21 driver_initcall,
22 interrupt::{InterruptId, InterruptManager},
23 object::capability::{ControlOps, MemoryMappingOps, Selectable},
24 traits::serial::Serial,
25};
26
27pub struct Uart {
28 base: usize,
30 interrupt_id: RwLock<Option<InterruptId>>,
31 rx_buffer: Mutex<VecDeque<u8>>,
32 event_emitter: Mutex<DeviceEventEmitter>,
33}
34
35pub const RHR_OFFSET: usize = 0x00;
36pub const THR_OFFSET: usize = 0x00;
37pub const IER_OFFSET: usize = 0x01; pub const IIR_OFFSET: usize = 0x02; pub const FCR_OFFSET: usize = 0x02; pub const LCR_OFFSET: usize = 0x03; pub const LSR_OFFSET: usize = 0x05;
42
43pub const LSR_THRE: u8 = 0x20;
44pub const LSR_DR: u8 = 0x01;
45
46pub const IER_RDA: u8 = 0x01; pub const IER_THRE: u8 = 0x02; pub const IER_RLS: u8 = 0x04; pub const IIR_PENDING: u8 = 0x01; pub const IIR_RDA: u8 = 0x04; pub const IIR_THRE: u8 = 0x02; pub const FCR_ENABLE: u8 = 0x01; pub const FCR_CLEAR_RX: u8 = 0x02; pub const FCR_CLEAR_TX: u8 = 0x04; pub const LCR_BAUD_LATCH: u8 = 0x80; impl Uart {
64 pub fn new(base: usize) -> Self {
65 Uart {
66 base,
67 interrupt_id: RwLock::new(None),
68 rx_buffer: Mutex::new(VecDeque::new()),
69 event_emitter: Mutex::new(DeviceEventEmitter::new()),
70 }
71 }
72
73 pub fn init(&self) {
74 self.reg_write(IER_OFFSET, 0x00);
76
77 self.reg_write(LCR_OFFSET, LCR_BAUD_LATCH);
79
80 self.reg_write(0x00, 0x03);
82
83 self.reg_write(0x01, 0x00);
85
86 self.reg_write(LCR_OFFSET, 0x03); self.reg_write(FCR_OFFSET, FCR_ENABLE | FCR_CLEAR_RX | FCR_CLEAR_TX);
91 }
92
93 pub fn enable_interrupts(&self, interrupt_id: InterruptId) -> Result<(), &'static str> {
95 self.interrupt_id.write().replace(interrupt_id);
96 self.reg_write(IER_OFFSET, IER_RDA);
98
99 InterruptManager::with_manager(|mgr| {
101 mgr.enable_external_interrupt(interrupt_id, 0) })
103 .map_err(|_| "Failed to enable interrupt")?;
104
105 Ok(())
106 }
107
108 fn reg_write(&self, offset: usize, value: u8) {
109 let addr = self.base + offset;
110 unsafe { crate::arch::mmio::write8(addr, value) }
111 }
112
113 fn reg_read(&self, offset: usize) -> u8 {
114 let addr = self.base + offset;
115 unsafe { crate::arch::mmio::read8(addr) }
116 }
117
118 fn write_byte_internal(&self, c: u8) {
119 while self.reg_read(LSR_OFFSET) & LSR_THRE == 0 {}
120 self.reg_write(THR_OFFSET, c);
121 }
122
123 fn read_byte_internal(&self) -> u8 {
124 if self.reg_read(LSR_OFFSET) & LSR_DR == 0 {
125 return 0;
126 }
127 self.reg_read(RHR_OFFSET)
128 }
129
130 fn can_read(&self) -> bool {
131 self.reg_read(LSR_OFFSET) & LSR_DR != 0
132 }
133
134 fn can_write(&self) -> bool {
135 self.reg_read(LSR_OFFSET) & LSR_THRE != 0
136 }
137}
138
139impl Serial for Uart {
140 fn put(&self, c: char) -> fmt::Result {
151 self.write_byte_internal(c as u8); Ok(())
153 }
154
155 fn get(&self) -> Option<char> {
162 let mut buffer = self.rx_buffer.lock();
163 if let Some(byte) = buffer.pop_front() {
165 return Some(byte as char);
166 }
167
168 None
169 }
170
171 fn as_any_mut(&mut self) -> &mut dyn Any {
173 self
174 }
175}
176
177impl MemoryMappingOps for Uart {
178 fn get_mapping_info(
179 &self,
180 _offset: usize,
181 _length: usize,
182 ) -> Result<(usize, usize, bool), &'static str> {
183 Err("Memory mapping not supported for UART")
184 }
185
186 fn on_mapped(&self, _vaddr: usize, _paddr: usize, _length: usize, _offset: usize) {
187 }
189
190 fn on_unmapped(&self, _vaddr: usize, _length: usize) {
191 }
193
194 fn supports_mmap(&self) -> bool {
195 false
196 }
197}
198
199static UART_CAPS: [crate::device::DeviceCapability; 1] = [crate::device::DeviceCapability::Serial];
200
201impl Device for Uart {
202 fn device_type(&self) -> DeviceType {
203 DeviceType::Char
204 }
205
206 fn name(&self) -> &'static str {
207 "virt-uart"
208 }
209
210 fn as_any(&self) -> &dyn Any {
211 self
212 }
213
214 fn as_any_mut(&mut self) -> &mut dyn Any {
215 self
216 }
217
218 fn as_char_device(&self) -> Option<&dyn CharDevice> {
219 Some(self)
220 }
221
222 fn capabilities(&self) -> &'static [crate::device::DeviceCapability] {
223 &UART_CAPS
224 }
225
226 fn as_event_capable(&self) -> Option<&dyn EventCapableDevice> {
227 Some(self)
228 }
229}
230
231impl CharDevice for Uart {
232 fn read_byte(&self) -> Option<u8> {
233 let mut buffer = self.rx_buffer.lock();
234 buffer.pop_front()
236 }
237
238 fn write_byte(&self, byte: u8) -> Result<(), &'static str> {
239 self.write_byte_internal(byte); Ok(())
241 }
242
243 fn can_read(&self) -> bool {
244 self.can_read()
245 }
246
247 fn can_write(&self) -> bool {
248 self.can_write()
249 }
250}
251
252impl ControlOps for Uart {
253 fn control(&self, _command: u32, _arg: usize) -> Result<i32, &'static str> {
255 Err("Control operations not supported")
256 }
257}
258
259impl Write for Uart {
260 fn write_str(&mut self, s: &str) -> fmt::Result {
261 for c in s.chars() {
262 if c == '\n' {
263 self.put('\r')?; }
265 self.put(c)?;
266 }
267 Ok(())
268 }
269}
270
271impl EventCapableDevice for Uart {
272 fn register_event_listener(&self, listener: alloc::sync::Weak<dyn DeviceEventListener>) {
273 self.event_emitter.lock().register_listener(listener);
274 }
275
276 fn unregister_event_listener(&self, _listener_id: &str) {
277 }
279
280 fn emit_event(&self, event: &dyn crate::device::events::DeviceEvent) {
281 self.event_emitter.lock().emit(event);
282 }
283}
284
285impl InterruptCapableDevice for Uart {
286 fn handle_interrupt(&self) -> crate::interrupt::InterruptResult<()> {
287 let iir = self.reg_read(IIR_OFFSET);
290
291 if iir & IIR_PENDING == 0 {
292 let c = self.read_byte_internal();
293 if c != 0 {
294 self.emit_event(&InputEvent { data: c as u8 });
296 } else {
297 return Ok(());
299 }
300 }
301
302 Ok(())
303 }
304
305 fn interrupt_id(&self) -> Option<InterruptId> {
306 self.interrupt_id.read().clone()
307 }
308}
309
310impl Selectable for Uart {
311 fn wait_until_ready(
312 &self,
313 _interest: crate::object::capability::selectable::ReadyInterest,
314 _trapframe: &mut crate::arch::Trapframe,
315 _timeout_ticks: Option<u64>,
316 ) -> crate::object::capability::selectable::SelectWaitOutcome {
317 crate::object::capability::selectable::SelectWaitOutcome::Ready
318 }
319}
320
321fn register_uart() {
322 use alloc::vec;
323
324 let driver = Box::new(PlatformDeviceDriver::new(
326 "virt-uart-driver",
327 uart_probe,
328 uart_remove,
329 vec!["ns16550a", "ns16550", "uart16550", "serial"],
330 ));
331
332 DeviceManager::get_manager().register_driver(driver, DriverPriority::Core);
334}
335
336fn uart_probe(device_info: &PlatformDeviceInfo) -> Result<(), &'static str> {
338 crate::early_println!("Probing UART device: {}", device_info.name());
339
340 let memory_resource = device_info
342 .get_resources()
343 .iter()
344 .find(|r| r.res_type == PlatformDeviceResourceType::MEM)
345 .ok_or("No memory resource found for UART")?;
346
347 let base_addr = memory_resource.start;
348 crate::early_println!("UART base address: 0x{:x}", base_addr);
349
350 let uart = Arc::new(Uart::new(base_addr));
352
353 uart.init();
355
356 if let Some(irq_resource) = device_info
358 .get_resources()
359 .iter()
360 .find(|r| r.res_type == PlatformDeviceResourceType::IRQ)
361 {
362 let uart_interrupt_id = irq_resource.start as u32;
363 crate::early_println!("UART interrupt ID: {}", uart_interrupt_id);
364
365 if let Err(e) = uart.enable_interrupts(uart_interrupt_id) {
367 crate::early_println!("Failed to enable UART interrupts: {}", e);
368 } else {
370 crate::early_println!("UART interrupts enabled (ID: {})", uart_interrupt_id);
371
372 if let Err(e) = InterruptManager::with_manager(|mgr| {
374 mgr.register_interrupt_device(uart_interrupt_id, uart.clone())
375 }) {
376 crate::early_println!("Failed to register UART interrupt device: {}", e);
377 } else {
378 crate::early_println!("UART interrupt device registered");
379 }
380 }
381 } else {
382 crate::early_println!("No interrupt resource found for UART, using polling mode");
383 }
384
385 let device_id = DeviceManager::get_manager().register_device(uart);
387 crate::early_println!("UART device registered with ID: {}", device_id);
388
389 Ok(())
390}
391
392fn uart_remove(_device_info: &PlatformDeviceInfo) -> Result<(), &'static str> {
394 Ok(())
396}
397
398driver_initcall!(register_uart);