kernel/drivers/uart/
virt.rs1use core::{fmt, any::Any, ptr::{read_volatile, write_volatile}};
4use core::fmt::Write;
5use alloc::boxed::Box;
6
7use crate::{early_initcall, traits::serial::Serial, device::{Device, DeviceType, char::CharDevice}};
8
9
10#[derive(Clone)]
11pub struct Uart {
12 base: usize,
13}
14
15pub const RHR_OFFSET: usize = 0x00;
16pub const THR_OFFSET: usize = 0x00;
17pub const LSR_OFFSET: usize = 0x05;
18
19pub const LSR_THRE: u8 = 0x20;
20pub const LSR_DR: u8 = 0x01;
21
22impl Uart {
23 pub fn new(base: usize) -> Self {
24 Uart { base }
25 }
26
27 fn reg_write(&self, offset: usize, value: u8) {
28 let addr = self.base + offset;
29 unsafe { write_volatile(addr as *mut u8, value) }
30 }
31
32 fn reg_read(&self, offset: usize) -> u8 {
33 let addr = self.base + offset;
34 unsafe { read_volatile(addr as *const u8) }
35 }
36
37 fn write_byte_internal(&self, c: u8) {
38 while self.reg_read(LSR_OFFSET) & LSR_THRE == 0 {}
39 self.reg_write(THR_OFFSET, c);
40 }
41
42 fn read_byte_internal(&self) -> u8 {
43 if self.reg_read(LSR_OFFSET) & LSR_DR == 0 {
44 return 0;
45 }
46 self.reg_read(RHR_OFFSET)
47 }
48}
49
50impl Serial for Uart {
51 fn init(&mut self) {
52 }
55
56 fn put(&mut self, c: char) -> fmt::Result {
67 self.write_byte_internal(c as u8); Ok(())
69 }
70
71 fn get(&mut self) -> Option<char> {
76 if self.can_read() {
77 Some(self.read_byte_internal() as char)
78 } else {
79 None
80 }
81 }
82}
83
84impl Device for Uart {
85 fn device_type(&self) -> DeviceType {
86 DeviceType::Char
87 }
88
89 fn name(&self) -> &'static str {
90 "virt-uart"
91 }
92
93 fn id(&self) -> usize {
94 0
95 }
96
97 fn as_any(&self) -> &dyn Any {
98 self
99 }
100
101 fn as_any_mut(&mut self) -> &mut dyn Any {
102 self
103 }
104
105 fn as_char_device(&mut self) -> Option<&mut dyn CharDevice> {
106 Some(self)
107 }
108}
109
110impl CharDevice for Uart {
111 fn read_byte(&mut self) -> Option<u8> {
112 if self.can_read() {
113 Some(self.read_byte_internal())
114 } else {
115 None
116 }
117 }
118
119 fn write_byte(&mut self, byte: u8) -> Result<(), &'static str> {
120 self.write_byte_internal(byte); Ok(())
122 }
123
124 fn can_read(&self) -> bool {
125 self.reg_read(LSR_OFFSET) & LSR_DR != 0
126 }
127
128 fn can_write(&self) -> bool {
129 self.reg_read(LSR_OFFSET) & LSR_THRE != 0
130 }
131
132}
133
134impl Write for Uart {
135 fn write_str(&mut self, s: &str) -> fmt::Result {
136 for c in s.chars() {
137 if c == '\n' {
138 self.put('\r')?; }
140 self.put(c)?;
141 }
142 Ok(())
143 }
144}
145
146fn register_uart() {
147 let uart = Uart::new(0x1000_0000);
148 crate::device::manager::register_serial(Box::new(uart));
149}
150
151early_initcall!(register_uart);