kernel/drivers/uart/
virt.rs1use 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 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; pub const IIR_OFFSET: usize = 0x02; pub const FCR_OFFSET: usize = 0x02; pub const LCR_OFFSET: usize = 0x03; pub const LSR_OFFSET: usize = 0x05;
31
32pub const LSR_THRE: u8 = 0x20;
33pub const LSR_DR: u8 = 0x01;
34
35pub 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 {
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 self.reg_write(IER_OFFSET, 0x00);
65
66 self.reg_write(LCR_OFFSET, LCR_BAUD_LATCH);
68
69 self.reg_write(0x00, 0x03);
71
72 self.reg_write(0x01, 0x00);
74
75 self.reg_write(LCR_OFFSET, 0x03); self.reg_write(FCR_OFFSET, FCR_ENABLE | FCR_CLEAR_RX | FCR_CLEAR_TX);
80 }
81
82 pub fn enable_interrupts(&self, interrupt_id: InterruptId) -> Result<(), &'static str> {
84 self.interrupt_id.write().replace(interrupt_id);
85 self.reg_write(IER_OFFSET, IER_RDA);
87
88 InterruptManager::with_manager(|mgr| {
90 mgr.enable_external_interrupt(interrupt_id, 0) }).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 fn put(&self, c: char) -> fmt::Result {
139 self.write_byte_internal(c as u8); Ok(())
141 }
142
143 fn get(&self) -> Option<char> {
150 let mut buffer = self.rx_buffer.lock();
151 if let Some(byte) = buffer.pop_front() {
153 return Some(byte as char);
154 }
155
156 None
157 }
158
159 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 buffer.pop_front()
192 }
193
194 fn write_byte(&self, byte: u8) -> Result<(), &'static str> {
195 self.write_byte_internal(byte); 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')?; }
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 }
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 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 self.emit_event(
246 &InputEvent {
247 data: c as u8,
248 }
249 );
250 } else {
251 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 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 DeviceManager::get_mut_manager().register_driver(driver, DriverPriority::Core);
277}
278
279fn uart_probe(device_info: &PlatformDeviceInfo) -> Result<(), &'static str> {
281 crate::early_println!("Probing UART device: {}", device_info.name());
282
283 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 let uart = Arc::new(Uart::new(base_addr));
294
295 uart.init();
297
298 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 if let Err(e) = uart.enable_interrupts(uart_interrupt_id) {
308 crate::early_println!("Failed to enable UART interrupts: {}", e);
309 } else {
311 crate::early_println!("UART interrupts enabled (ID: {})", uart_interrupt_id);
312
313 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 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
333fn uart_remove(_device_info: &PlatformDeviceInfo) -> Result<(), &'static str> {
335 Ok(())
337}
338
339driver_initcall!(register_uart);