kernel/drivers/uart/
virt.rs

1// UART driver for QEMU virt machine
2
3use 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    // inner: Arc<Mutex<UartInner>>,
29    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; // Interrupt Enable Register
38pub const IIR_OFFSET: usize = 0x02; // Interrupt Identification Register
39pub const FCR_OFFSET: usize = 0x02; // FIFO Control Register (write only)
40pub const LCR_OFFSET: usize = 0x03; // Line Control Register
41pub const LSR_OFFSET: usize = 0x05;
42
43pub const LSR_THRE: u8 = 0x20;
44pub const LSR_DR: u8 = 0x01;
45
46// IER bits
47pub const IER_RDA: u8 = 0x01; // Received Data Available
48pub const IER_THRE: u8 = 0x02; // Transmit Holding Register Empty
49pub const IER_RLS: u8 = 0x04; // Receiver Line Status
50
51// IIR bits
52pub const IIR_PENDING: u8 = 0x01; // 0=interrupt pending, 1=no interrupt
53pub const IIR_RDA: u8 = 0x04; // Received Data Available
54pub const IIR_THRE: u8 = 0x02; // Transmit Holding Register Empty
55
56// FCR bits
57pub const FCR_ENABLE: u8 = 0x01; // FIFO enable
58pub const FCR_CLEAR_RX: u8 = 0x02; // Clear receive FIFO
59pub const FCR_CLEAR_TX: u8 = 0x04; // Clear transmit FIFO
60
61pub const LCR_BAUD_LATCH: u8 = 0x80; // Set baud rate divisor latch access bit
62
63impl 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        // Disable all interrupts
75        self.reg_write(IER_OFFSET, 0x00);
76
77        // Set special mode to set baud rate
78        self.reg_write(LCR_OFFSET, LCR_BAUD_LATCH);
79
80        // LSB of baud rate divisor
81        self.reg_write(0x00, 0x03);
82
83        // MSB of baud rate divisor
84        self.reg_write(0x01, 0x00);
85
86        // Set line control register for 8 data bits, no parity, 1 stop bit
87        self.reg_write(LCR_OFFSET, 0x03); // 8 bits, no
88
89        // Enable FIFO
90        self.reg_write(FCR_OFFSET, FCR_ENABLE | FCR_CLEAR_RX | FCR_CLEAR_TX);
91    }
92
93    /// Enable UART interrupts
94    pub fn enable_interrupts(&self, interrupt_id: InterruptId) -> Result<(), &'static str> {
95        self.interrupt_id.write().replace(interrupt_id);
96        // Enable receive data available interrupt
97        self.reg_write(IER_OFFSET, IER_RDA);
98
99        // Register interrupt with interrupt manager
100        InterruptManager::with_manager(|mgr| {
101            mgr.enable_external_interrupt(interrupt_id, 0) // Enable for CPU 0
102        })
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    /// Writes a character to the UART. (blocking)
141    ///
142    /// This function will block until the UART is ready to accept the character.
143    ///
144    /// # Arguments
145    /// * `c` - The character to write to the UART
146    ///
147    /// # Returns
148    /// A `fmt::Result` indicating success or failure.
149    ///
150    fn put(&self, c: char) -> fmt::Result {
151        self.write_byte_internal(c as u8); // Block until ready
152        Ok(())
153    }
154
155    /// Reads a character from the UART. (non-blocking)
156    ///
157    /// Returns `Some(char)` if a character is available, or `None` if not.
158    /// If interrupts are enabled, reads from the interrupt buffer.
159    /// Otherwise, falls back to polling mode.
160    ///
161    fn get(&self) -> Option<char> {
162        let mut buffer = self.rx_buffer.lock();
163        // Try to read from interrupt buffer
164        if let Some(byte) = buffer.pop_front() {
165            return Some(byte as char);
166        }
167
168        None
169    }
170
171    /// Get a mutable reference to Any for downcasting
172    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        // UART devices don't support memory mapping
188    }
189
190    fn on_unmapped(&self, _vaddr: usize, _length: usize) {
191        // UART devices don't support memory mapping
192    }
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        // Try to read from interrupt buffer
235        buffer.pop_front()
236    }
237
238    fn write_byte(&self, byte: u8) -> Result<(), &'static str> {
239        self.write_byte_internal(byte); // Block until ready
240        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    // UART devices don't support control operations by default
254    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')?; // Convert newline to carriage return + newline
264            }
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        // Implementation later - normally WeakRef is automatically removed
278    }
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 inner = self.inner.lock();
288        // Check interrupt identification register
289        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                // Emit received character event
295                self.emit_event(&InputEvent { data: c as u8 });
296            } else {
297                // No data available, return Ok
298                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    // Create UART platform device driver
325    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    // Register with Core priority since UART is essential for early console output
333    DeviceManager::get_manager().register_driver(driver, DriverPriority::Core);
334}
335
336/// Probe function for UART devices
337fn uart_probe(device_info: &PlatformDeviceInfo) -> Result<(), &'static str> {
338    crate::early_println!("Probing UART device: {}", device_info.name());
339
340    // Get memory resource (base address)
341    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    // Create UART instance
351    let uart = Arc::new(Uart::new(base_addr));
352
353    // Initialize UART
354    uart.init();
355
356    // Get interrupt resource if available
357    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        // Enable UART interrupts
366        if let Err(e) = uart.enable_interrupts(uart_interrupt_id) {
367            crate::early_println!("Failed to enable UART interrupts: {}", e);
368            // Continue without interrupts - polling mode will work
369        } else {
370            crate::early_println!("UART interrupts enabled (ID: {})", uart_interrupt_id);
371
372            // Register interrupt handler
373            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    // Register the UART device with the device manager
386    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
392/// Remove function for UART devices  
393fn uart_remove(_device_info: &PlatformDeviceInfo) -> Result<(), &'static str> {
394    // TODO: Implement device removal logic
395    Ok(())
396}
397
398driver_initcall!(register_uart);