kernel/drivers/uart/
virt.rs

1// UART driver for QEMU virt machine
2
3use core::{fmt, any::Any, ptr::{read_volatile, write_volatile}};
4use core::fmt::Write;
5use alloc::{boxed::Box, collections::VecDeque, sync::Arc};
6use spin::{Mutex, RwLock};
7
8use crate::{
9    device::{
10        char::CharDevice, events::{DeviceEventEmitter, DeviceEventListener, EventCapableDevice, InputEvent, InterruptCapableDevice}, manager::{DeviceManager, DriverPriority}, platform::{
11            resource::PlatformDeviceResourceType, PlatformDeviceDriver, PlatformDeviceInfo
12        }, Device, DeviceInfo, DeviceType
13    }, driver_initcall, drivers::uart, interrupt::{InterruptId, InterruptManager}, traits::serial::Serial
14};
15
16pub struct Uart {
17    // inner: Arc<Mutex<UartInner>>,
18    base: usize,
19    interrupt_id: RwLock<Option<InterruptId>>,
20    rx_buffer: Mutex<VecDeque<u8>>,
21    event_emitter: Mutex<DeviceEventEmitter>,
22}
23
24pub const RHR_OFFSET: usize = 0x00;
25pub const THR_OFFSET: usize = 0x00;
26pub const IER_OFFSET: usize = 0x01;  // Interrupt Enable Register
27pub const IIR_OFFSET: usize = 0x02;  // Interrupt Identification Register
28pub const FCR_OFFSET: usize = 0x02;  // FIFO Control Register (write only)
29pub const LCR_OFFSET: usize = 0x03;  // Line Control Register
30pub const LSR_OFFSET: usize = 0x05;
31
32pub const LSR_THRE: u8 = 0x20;
33pub const LSR_DR: u8 = 0x01;
34
35// IER bits
36pub const IER_RDA: u8 = 0x01;    // Received Data Available
37pub const IER_THRE: u8 = 0x02;   // Transmit Holding Register Empty
38pub const IER_RLS: u8 = 0x04;    // Receiver Line Status
39
40// IIR bits
41pub const IIR_PENDING: u8 = 0x01; // 0=interrupt pending, 1=no interrupt
42pub const IIR_RDA: u8 = 0x04;     // Received Data Available
43pub const IIR_THRE: u8 = 0x02;    // Transmit Holding Register Empty
44
45// FCR bits
46pub const FCR_ENABLE: u8 = 0x01;   // FIFO enable
47pub const FCR_CLEAR_RX: u8 = 0x02; // Clear receive FIFO
48pub const FCR_CLEAR_TX: u8 = 0x04; // Clear transmit FIFO
49
50pub const LCR_BAUD_LATCH: u8 = 0x80; // Set baud rate divisor latch access bit
51
52impl Uart {
53    pub fn new(base: usize) -> Self {
54        Uart { 
55            base,
56            interrupt_id: RwLock::new(None),
57            rx_buffer: Mutex::new(VecDeque::new()),
58            event_emitter: Mutex::new(DeviceEventEmitter::new()),
59        }
60    }
61
62    pub fn init(&self) {
63        // Disable all interrupts
64        self.reg_write(IER_OFFSET, 0x00);
65
66        // Set special mode to set baud rate
67        self.reg_write(LCR_OFFSET, LCR_BAUD_LATCH);
68
69        // LSB of baud rate divisor
70        self.reg_write(0x00, 0x03);
71
72        // MSB of baud rate divisor
73        self.reg_write(0x01, 0x00);
74
75        // Set line control register for 8 data bits, no parity, 1 stop bit
76        self.reg_write(LCR_OFFSET, 0x03); // 8 bits, no
77
78        // Enable FIFO
79        self.reg_write(FCR_OFFSET, FCR_ENABLE | FCR_CLEAR_RX | FCR_CLEAR_TX);
80    }
81
82    /// Enable UART interrupts
83    pub fn enable_interrupts(&self, interrupt_id: InterruptId) -> Result<(), &'static str> {
84        self.interrupt_id.write().replace(interrupt_id);
85        // Enable receive data available interrupt
86        self.reg_write(IER_OFFSET, IER_RDA);
87
88        // Register interrupt with interrupt manager
89        InterruptManager::with_manager(|mgr| {
90            mgr.enable_external_interrupt(interrupt_id, 0) // Enable for CPU 0
91        }).map_err(|_| "Failed to enable interrupt")?;
92        
93        Ok(())
94    }
95
96    fn reg_write(&self, offset: usize, value: u8) {
97        let addr = self.base + offset;
98        unsafe { write_volatile(addr as *mut u8, value) }
99    }
100
101    fn reg_read(&self, offset: usize) -> u8 {
102        let addr = self.base + offset;
103        unsafe { read_volatile(addr as *const u8) }
104    }
105
106    fn write_byte_internal(&self, c: u8) {
107        while self.reg_read(LSR_OFFSET) & LSR_THRE == 0 {}
108        self.reg_write(THR_OFFSET, c);
109    }
110
111    fn read_byte_internal(&self) -> u8 {
112        if self.reg_read(LSR_OFFSET) & LSR_DR == 0 {
113            return 0;
114        }
115        self.reg_read(RHR_OFFSET)
116    }
117
118    fn can_read(&self) -> bool {
119        self.reg_read(LSR_OFFSET) & LSR_DR != 0
120    }
121
122    fn can_write(&self) -> bool {
123        self.reg_read(LSR_OFFSET) & LSR_THRE != 0
124    }
125}
126
127impl Serial for Uart {
128    /// Writes a character to the UART. (blocking)
129    /// 
130    /// This function will block until the UART is ready to accept the character.
131    /// 
132    /// # Arguments
133    /// * `c` - The character to write to the UART
134    /// 
135    /// # Returns
136    /// A `fmt::Result` indicating success or failure.
137    /// 
138    fn put(&self, c: char) -> fmt::Result {
139        self.write_byte_internal(c as u8); // Block until ready
140        Ok(())
141    }
142
143    /// Reads a character from the UART. (non-blocking)
144    /// 
145    /// Returns `Some(char)` if a character is available, or `None` if not.
146    /// If interrupts are enabled, reads from the interrupt buffer.
147    /// Otherwise, falls back to polling mode.
148    /// 
149    fn get(&self) -> Option<char> {
150        let mut buffer = self.rx_buffer.lock();
151            // Try to read from interrupt buffer
152        if let Some(byte) = buffer.pop_front() {
153            return Some(byte as char);
154        }
155
156        None
157    }
158
159    /// Get a mutable reference to Any for downcasting
160    fn as_any_mut(&mut self) -> &mut dyn Any {
161        self
162    }
163}
164
165impl Device for Uart {
166    fn device_type(&self) -> DeviceType {
167        DeviceType::Char
168    }
169
170    fn name(&self) -> &'static str {
171        "virt-uart"
172    }
173
174    fn as_any(&self) -> &dyn Any {
175        self
176    }
177    
178    fn as_any_mut(&mut self) -> &mut dyn Any {
179        self
180    }
181    
182    fn as_char_device(&self) -> Option<&dyn CharDevice> {
183        Some(self)
184    }
185}
186
187impl CharDevice for Uart {
188    fn read_byte(&self) -> Option<u8> {
189        let mut buffer = self.rx_buffer.lock();
190        // Try to read from interrupt buffer
191        buffer.pop_front()
192    }
193
194    fn write_byte(&self, byte: u8) -> Result<(), &'static str> {
195        self.write_byte_internal(byte); // Block until ready
196        Ok(())
197    }
198
199    fn can_read(&self) -> bool {
200        self.can_read()
201    }
202
203    fn can_write(&self) -> bool {
204        self.can_write()
205    }
206    
207}
208
209impl Write for Uart {
210    fn write_str(&mut self, s: &str) -> fmt::Result {
211        for c in s.chars() {
212            if c == '\n' {
213                self.put('\r')?; // Convert newline to carriage return + newline
214            }
215            self.put(c)?;
216        }
217        Ok(())
218    }
219}
220
221impl EventCapableDevice for Uart {
222    fn register_event_listener(&self, listener: alloc::sync::Weak<dyn DeviceEventListener>) {
223        self.event_emitter.lock().register_listener(listener);
224    }
225    
226    fn unregister_event_listener(&self, _listener_id: &str) {
227        // Implementation later - normally WeakRef is automatically removed
228    }
229    
230    fn emit_event(&self, event: &dyn crate::device::events::DeviceEvent) {
231        self.event_emitter.lock().emit(event);
232    }
233}
234
235impl InterruptCapableDevice for Uart {
236    fn handle_interrupt(&self) -> crate::interrupt::InterruptResult<()> {
237        // let inner = self.inner.lock();
238        // Check interrupt identification register
239        let iir = self.reg_read(IIR_OFFSET);
240        
241        if iir & IIR_PENDING == 0 {
242            let c = self.read_byte_internal();
243            if c != 0 {
244                // Emit received character event
245                self.emit_event(
246                    &InputEvent {
247                        data: c as u8,
248                    }
249                );
250            } else {
251                // No data available, return Ok
252                return Ok(());
253            }
254        }
255        
256        Ok(())
257    }
258    
259    fn interrupt_id(&self) -> Option<InterruptId> {
260        self.interrupt_id.read().clone()
261    }
262}
263
264fn register_uart() {
265    use alloc::vec;
266    
267    // Create UART platform device driver
268    let driver = Box::new(PlatformDeviceDriver::new(
269        "virt-uart-driver",
270        uart_probe,
271        uart_remove,
272        vec!["ns16550a", "ns16550", "uart16550", "serial"]
273    ));
274    
275    // Register with Core priority since UART is essential for early console output
276    DeviceManager::get_mut_manager().register_driver(driver, DriverPriority::Core);
277}
278
279/// Probe function for UART devices
280fn uart_probe(device_info: &PlatformDeviceInfo) -> Result<(), &'static str> {
281    crate::early_println!("Probing UART device: {}", device_info.name());
282    
283    // Get memory resource (base address)
284    let memory_resource = device_info.get_resources()
285        .iter()
286        .find(|r| r.res_type == PlatformDeviceResourceType::MEM)
287        .ok_or("No memory resource found for UART")?;
288    
289    let base_addr = memory_resource.start;
290    crate::early_println!("UART base address: 0x{:x}", base_addr);
291    
292    // Create UART instance
293    let uart = Arc::new(Uart::new(base_addr));
294
295    // Initialize UART
296    uart.init();
297
298    // Get interrupt resource if available
299    if let Some(irq_resource) = device_info.get_resources()
300        .iter()
301        .find(|r| r.res_type == PlatformDeviceResourceType::IRQ) {
302        
303        let uart_interrupt_id = irq_resource.start as u32;
304        crate::early_println!("UART interrupt ID: {}", uart_interrupt_id);
305        
306        // Enable UART interrupts
307        if let Err(e) = uart.enable_interrupts(uart_interrupt_id) {
308            crate::early_println!("Failed to enable UART interrupts: {}", e);
309            // Continue without interrupts - polling mode will work
310        } else {
311            crate::early_println!("UART interrupts enabled (ID: {})", uart_interrupt_id);
312            
313            // Register interrupt handler
314            if let Err(e) = InterruptManager::with_manager(|mgr| {
315                mgr.register_interrupt_device(uart_interrupt_id, uart.clone())
316            }) {
317                crate::early_println!("Failed to register UART interrupt device: {}", e);
318            } else {
319                crate::early_println!("UART interrupt device registered using trait-based system");
320            }
321        }
322    } else {
323        crate::early_println!("No interrupt resource found for UART, using polling mode");
324    }
325    
326    // Register the UART device with the device manager
327    let device_id = DeviceManager::get_mut_manager().register_device(uart);
328    crate::early_println!("UART device registered with ID: {}", device_id);
329
330    Ok(())
331}
332
333/// Remove function for UART devices  
334fn uart_remove(_device_info: &PlatformDeviceInfo) -> Result<(), &'static str> {
335    // TODO: Implement device removal logic
336    Ok(())
337}
338
339driver_initcall!(register_uart);