1 use super::super::base::device::Device;
2 use crate::{
3 driver::base::{
4 char::CharDevice,
5 device::{driver::Driver, DeviceState, DeviceType, IdTable, KObject},
6 platform::{
7 self, platform_device::PlatformDevice, platform_driver::PlatformDriver, CompatibleTable,
8 },
9 },
10 filesystem::{
11 sysfs::bus::{bus_device_register, bus_driver_register},
12 vfs::IndexNode,
13 },
14 include::bindings::bindings::{io_in8, io_out8},
15 libs::spinlock::SpinLock,
16 syscall::SystemError,
17 };
18 use alloc::sync::Arc;
19 use core::{char, intrinsics::offset, str};
20
21 const UART_SUCCESS: i32 = 0;
22 const E_UART_BITS_RATE_ERROR: i32 = 1;
23 const E_UART_SERIAL_FAULT: i32 = 2;
24 const UART_MAX_BITS_RATE: u32 = 115200;
25
26 lazy_static! {
27 // 串口设备
28 pub static ref UART_DEV: Arc<LockedUart> = Arc::new(LockedUart::default());
29 // 串口驱动
30 pub static ref UART_DRV: Arc<LockedUartDriver> = Arc::new(LockedUartDriver::default());
31 }
32
33 // @brief 串口端口
34 #[allow(dead_code)]
35 #[repr(u16)]
36 #[derive(Clone, Debug)]
37 pub enum UartPort {
38 COM1 = 0x3f8,
39 COM2 = 0x2f8,
40 COM3 = 0x3e8,
41 COM4 = 0x2e8,
42 COM5 = 0x5f8,
43 COM6 = 0x4f8,
44 COM7 = 0x5e8,
45 COM8 = 0x4e8,
46 }
47
48 impl UartPort {
49 ///@brief 将u16转换为UartPort枚举类型
50 ///@param val 要转换的u16类型
51 ///@return 输入的端口地址正确,返回UartPort类型,错误,返回错误信息
52 #[allow(dead_code)]
from_u16(val: u16) -> Result<Self, &'static str>53 pub fn from_u16(val: u16) -> Result<Self, &'static str> {
54 match val {
55 0x3f8 => Ok(Self::COM1),
56 0x2f8 => Ok(Self::COM2),
57 0x3e8 => Ok(Self::COM3),
58 0x2e8 => Ok(Self::COM4),
59 0x5f8 => Ok(Self::COM5),
60 0x4f8 => Ok(Self::COM6),
61 0x5e8 => Ok(Self::COM7),
62 0x4e8 => Ok(Self::COM8),
63 _ => Err("port error!"),
64 }
65 }
66
67 ///@brief 将UartPort枚举类型转换为u16类型
68 ///@param self 要转换的UartPort
69 ///@return 转换的u16值
70 #[allow(dead_code)]
to_u16(self: &Self) -> u1671 pub fn to_u16(self: &Self) -> u16 {
72 match self {
73 Self::COM1 => 0x3f8,
74 Self::COM2 => 0x2f8,
75 Self::COM3 => 0x3e8,
76 Self::COM4 => 0x2e8,
77 Self::COM5 => 0x5f8,
78 Self::COM6 => 0x4f8,
79 Self::COM7 => 0x5e8,
80 Self::COM8 => 0x4e8,
81 }
82 }
83 }
84
85 // @brief 串口寄存器
86 #[allow(dead_code)]
87 #[repr(C)]
88 #[derive(Debug, Copy, Clone)]
89 struct UartRegister {
90 reg_data: u8,
91 reg_interrupt_enable: u8,
92 reg_ii_fifo: u8, // Interrupt Identification and FIFO control registers
93 reg_line_config: u8,
94 reg_modem_config: u8,
95 reg_line_status: u8,
96 reg_modem_statue: u8,
97 reg_scartch: u8,
98 }
99
100 // @brief 串口设备结构体
101 #[derive(Debug)]
102 pub struct Uart {
103 state: DeviceState, // 设备状态
104 sys_info: Option<Arc<dyn IndexNode>>,
105 driver: Option<Arc<dyn PlatformDriver>>,
106 }
107
108 impl Default for Uart {
default() -> Self109 fn default() -> Self {
110 Self {
111 state: DeviceState::NotInitialized,
112 sys_info: None,
113 driver: None,
114 }
115 }
116 }
117
118 // @brief 串口设备结构体(加锁)
119 #[derive(Debug)]
120 pub struct LockedUart(SpinLock<Uart>);
121
122 impl Default for LockedUart {
default() -> Self123 fn default() -> Self {
124 Self(SpinLock::new(Uart::default()))
125 }
126 }
127
128 impl KObject for LockedUart {}
129
130 impl PlatformDevice for LockedUart {
compatible_table(&self) -> platform::CompatibleTable131 fn compatible_table(&self) -> platform::CompatibleTable {
132 platform::CompatibleTable::new(vec!["uart"])
133 }
134
is_initialized(&self) -> bool135 fn is_initialized(&self) -> bool {
136 let state = self.0.lock().state;
137 match state {
138 DeviceState::Initialized => true,
139 _ => false,
140 }
141 }
142
set_state(&self, set_state: DeviceState)143 fn set_state(&self, set_state: DeviceState) {
144 let state = &mut self.0.lock().state;
145 *state = set_state;
146 }
147
set_driver(&self, driver: Option<Arc<dyn PlatformDriver>>)148 fn set_driver(&self, driver: Option<Arc<dyn PlatformDriver>>) {
149 self.0.lock().driver = driver;
150 }
151 }
152
153 impl Device for LockedUart {
id_table(&self) -> IdTable154 fn id_table(&self) -> IdTable {
155 IdTable::new("uart", 0)
156 }
157
set_sys_info(&self, sys_info: Option<Arc<dyn IndexNode>>)158 fn set_sys_info(&self, sys_info: Option<Arc<dyn IndexNode>>) {
159 self.0.lock().sys_info = sys_info;
160 }
161
sys_info(&self) -> Option<Arc<dyn IndexNode>>162 fn sys_info(&self) -> Option<Arc<dyn IndexNode>> {
163 self.0.lock().sys_info.clone()
164 }
165
dev_type(&self) -> DeviceType166 fn dev_type(&self) -> DeviceType {
167 DeviceType::Serial
168 }
169
as_any_ref(&'static self) -> &'static dyn core::any::Any170 fn as_any_ref(&'static self) -> &'static dyn core::any::Any {
171 self
172 }
173 }
174
175 // @brief 串口驱动结构体
176 #[repr(C)]
177 #[derive(Debug)]
178 pub struct UartDriver {
179 port: UartPort,
180 baud_rate: u32,
181 sys_info: Option<Arc<dyn IndexNode>>,
182 }
183
184 impl Default for UartDriver {
default() -> Self185 fn default() -> Self {
186 Self {
187 port: UartPort::COM1,
188 baud_rate: 115200,
189 sys_info: None,
190 }
191 }
192 }
193
194 // @brief 串口驱动结构体(加锁)
195 #[derive(Debug)]
196 pub struct LockedUartDriver(SpinLock<UartDriver>);
197
198 impl Default for LockedUartDriver {
default() -> Self199 fn default() -> Self {
200 Self(SpinLock::new(UartDriver::default()))
201 }
202 }
203
204 impl KObject for LockedUartDriver {}
205
206 impl Driver for LockedUartDriver {
as_any_ref(&'static self) -> &'static dyn core::any::Any207 fn as_any_ref(&'static self) -> &'static dyn core::any::Any {
208 self
209 }
210
id_table(&self) -> IdTable211 fn id_table(&self) -> IdTable {
212 return IdTable::new("uart_driver", 0);
213 }
214
set_sys_info(&self, sys_info: Option<Arc<dyn IndexNode>>)215 fn set_sys_info(&self, sys_info: Option<Arc<dyn IndexNode>>) {
216 self.0.lock().sys_info = sys_info;
217 }
218
sys_info(&self) -> Option<Arc<dyn IndexNode>>219 fn sys_info(&self) -> Option<Arc<dyn IndexNode>> {
220 return self.0.lock().sys_info.clone();
221 }
222 }
223
224 impl CharDevice for LockedUartDriver {
open(&self, _file: Arc<dyn IndexNode>) -> Result<(), crate::syscall::SystemError>225 fn open(&self, _file: Arc<dyn IndexNode>) -> Result<(), crate::syscall::SystemError> {
226 return Ok(());
227 }
228
close(&self, _file: Arc<dyn IndexNode>) -> Result<(), crate::syscall::SystemError>229 fn close(&self, _file: Arc<dyn IndexNode>) -> Result<(), crate::syscall::SystemError> {
230 return Ok(());
231 }
232 }
233
234 impl LockedUartDriver {
235 /// @brief 创建串口驱动
236 /// @param port 端口号
237 /// baud_rate 波特率
238 /// sys_info: sys文件系统inode
239 /// @return
240 #[allow(dead_code)]
new(port: UartPort, baud_rate: u32, sys_info: Option<Arc<dyn IndexNode>>) -> Self241 pub fn new(port: UartPort, baud_rate: u32, sys_info: Option<Arc<dyn IndexNode>>) -> Self {
242 Self(SpinLock::new(UartDriver::new(port, baud_rate, sys_info)))
243 }
244 }
245
246 impl PlatformDriver for LockedUartDriver {
probe( &self, _device: Arc<dyn PlatformDevice>, ) -> Result<(), crate::driver::base::device::driver::DriverError>247 fn probe(
248 &self,
249 _device: Arc<dyn PlatformDevice>,
250 ) -> Result<(), crate::driver::base::device::driver::DriverError> {
251 return Ok(());
252 }
253
compatible_table(&self) -> platform::CompatibleTable254 fn compatible_table(&self) -> platform::CompatibleTable {
255 return CompatibleTable::new(vec!["uart"]);
256 }
257 }
258
259 impl UartDriver {
260 /// @brief 创建串口驱动
261 /// @param port 端口号
262 /// baud_rate 波特率
263 /// sys_info: sys文件系统inode
264 /// @return 返回串口驱动
265 #[allow(dead_code)]
new(port: UartPort, baud_rate: u32, sys_info: Option<Arc<dyn IndexNode>>) -> Self266 pub fn new(port: UartPort, baud_rate: u32, sys_info: Option<Arc<dyn IndexNode>>) -> Self {
267 Self {
268 port,
269 baud_rate,
270 sys_info,
271 }
272 }
273
274 /// @brief 串口初始化
275 /// @param uart_port 端口号
276 /// @param baud_rate 波特率
277 /// @return 初始化成功,返回0,失败,返回错误信息
278 #[allow(dead_code)]
uart_init(uart_port: &UartPort, baud_rate: u32) -> Result<i32, &'static str>279 pub fn uart_init(uart_port: &UartPort, baud_rate: u32) -> Result<i32, &'static str> {
280 let message: &'static str = "uart init.";
281 let port = uart_port.to_u16();
282 // 错误的比特率
283 if baud_rate > UART_MAX_BITS_RATE || UART_MAX_BITS_RATE % baud_rate != 0 {
284 return Err("uart init error.");
285 }
286
287 unsafe {
288 io_out8(port + 1, 0x00); // Disable all interrupts
289 io_out8(port + 3, 0x80); // Enable DLAB (set baud rate divisor)
290
291 let divisor = UART_MAX_BITS_RATE / baud_rate;
292
293 io_out8(port + 0, (divisor & 0xff) as u8); // Set divisor (lo byte)
294 io_out8(port + 1, ((divisor >> 8) & 0xff) as u8); // (hi byte)
295 io_out8(port + 3, 0x03); // 8 bits, no parity, one stop bit
296 io_out8(port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
297 io_out8(port + 4, 0x08); // IRQs enabled, RTS/DSR clear (现代计算机上一般都不需要hardware flow control,因此不需要置位RTS/DSR)
298 io_out8(port + 4, 0x1E); // Set in loopback mode, test the serial chip
299 io_out8(port + 0, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte)
300
301 // Check if serial is faulty (i.e: not same byte as sent)
302 if io_in8(port + 0) != 0xAE {
303 return Err("uart faulty");
304 }
305
306 // If serial is not faulty set it in normal operation mode
307 // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
308 io_out8(port + 4, 0x08);
309 }
310 UartDriver::uart_send(uart_port, message);
311 Ok(0)
312 /*
313 Notice that the initialization code above writes to [PORT + 1]
314 twice with different values. This is once to write to the Divisor
315 register along with [PORT + 0] and once to write to the Interrupt
316 register as detailed in the previous section.
317 The second write to the Line Control register [PORT + 3]
318 clears the DLAB again as well as setting various other bits.
319 */
320 }
321
serial_received(offset: u16) -> bool322 fn serial_received(offset: u16) -> bool {
323 if unsafe { io_in8(offset + 5) } & 1 != 0 {
324 true
325 } else {
326 false
327 }
328 }
329
is_transmit_empty(offset: u16) -> bool330 fn is_transmit_empty(offset: u16) -> bool {
331 if unsafe { io_in8(offset + 5) } & 0x20 != 0 {
332 true
333 } else {
334 false
335 }
336 }
337
338 /// @brief 串口发送
339 /// @param uart_port 端口号
340 /// @param str 发送字符切片
341 /// @return None
342 #[allow(dead_code)]
uart_send(uart_port: &UartPort, s: &str)343 fn uart_send(uart_port: &UartPort, s: &str) {
344 let port = uart_port.to_u16();
345 while UartDriver::is_transmit_empty(port) == false {
346 for c in s.bytes() {
347 unsafe {
348 io_out8(port, c);
349 }
350 }
351 } //TODO:pause
352 }
353
354 /// @brief 串口接收一个字节
355 /// @param uart_port 端口号
356 /// @return 接收的字节
357 #[allow(dead_code)]
uart_read_byte(uart_port: &UartPort) -> char358 fn uart_read_byte(uart_port: &UartPort) -> char {
359 let port = uart_port.to_u16();
360 while UartDriver::serial_received(port) == false {} //TODO:pause
361 unsafe { io_in8(port) as char }
362 }
363
364 #[allow(dead_code)]
port() -> u16365 fn port() -> u16 {
366 UartPort::COM1.to_u16()
367 }
368 }
369
370 ///@brief 发送数据
371 ///@param port 端口号
372 ///@param c 要发送的数据
373 #[no_mangle]
c_uart_send(port: u16, c: u8)374 pub extern "C" fn c_uart_send(port: u16, c: u8) {
375 while UartDriver::is_transmit_empty(port) == false {} //TODO:pause
376 unsafe {
377 io_out8(port, c);
378 }
379 }
380
381 ///@brief 从uart接收数据
382 ///@param port 端口号
383 ///@return u8 接收到的数据
384 #[no_mangle]
c_uart_read(port: u16) -> u8385 pub extern "C" fn c_uart_read(port: u16) -> u8 {
386 while UartDriver::serial_received(port) == false {} //TODO:pause
387 unsafe { io_in8(port) }
388 }
389
390 ///@brief 通过串口发送整个字符串
391 ///@param port 串口端口
392 ///@param str 字符串S
393 #[no_mangle]
c_uart_send_str(port: u16, s: *const u8)394 pub extern "C" fn c_uart_send_str(port: u16, s: *const u8) {
395 unsafe {
396 let mut i = 0isize;
397 while *offset(s, i) != '\0' as u8 {
398 c_uart_send(port, *offset(s, i));
399 i = i + 1;
400 }
401 }
402 }
403
404 /// @brief 串口初始化
405 /// @param u16 端口号
406 /// @param baud_rate 波特率
407 /// @return 初始化成功,返回0,失败,返回错误码
408 #[no_mangle]
c_uart_init(port: u16, baud_rate: u32) -> i32409 pub extern "C" fn c_uart_init(port: u16, baud_rate: u32) -> i32 {
410 let message: &'static str = "uart init\n";
411 // 错误的比特率
412 if baud_rate > UART_MAX_BITS_RATE || UART_MAX_BITS_RATE % baud_rate != 0 {
413 return -E_UART_BITS_RATE_ERROR;
414 }
415
416 unsafe {
417 io_out8(port + 1, 0x00); // Disable all interrupts
418 io_out8(port + 3, 0x80); // Enable DLAB (set baud rate divisor)
419
420 let divisor = UART_MAX_BITS_RATE / baud_rate;
421
422 io_out8(port + 0, (divisor & 0xff) as u8); // Set divisor (lo byte)
423 io_out8(port + 1, ((divisor >> 8) & 0xff) as u8); // CompatibleTable(hi byte)
424 io_out8(port + 3, 0x03); // 8 bits, no parity, one stop bit
425 io_out8(port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
426 io_out8(port + 4, 0x08); // IRQs enabled, RTS/DSR clear (现代计算机上一般都不需要hardware flow control,因此不需要置位RTS/DSR)
427 io_out8(port + 4, 0x1E); // Set in loopback mode, test the serial chip
428 io_out8(port + 0, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte)
429
430 // Check if serial is faulty (i.e: not same byte as sent)
431 if io_in8(port + 0) != 0xAE {
432 return -E_UART_SERIAL_FAULT;
433 }
434
435 // If serial is not faulty set it in normal operation mode
436 // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
437 io_out8(port + 4, 0x08);
438 let bytes = message.as_bytes();
439 for c in bytes {
440 c_uart_send(port, *c);
441 }
442 }
443 return UART_SUCCESS;
444 /*
445 Notice that the initialization code above writes to [PORT + 1]
446 twice with different values. This is once to write to the Divisor
447 register along with [PORT + 0] and once to write to the Interrupt
448 register as detailed in the previous section.
449 The second write to the Line Control register [PORT + 3]
450 clears the DLAB again as well as setting various other bits.
451 */
452 }
453
454 /// @brief 串口初始化,注册串口
455 /// @param none
456 /// @return 初始化成功,返回(),失败,返回错误码
uart_init() -> Result<(), SystemError>457 pub fn uart_init() -> Result<(), SystemError> {
458 let device_inode = bus_device_register("platform:0", &UART_DEV.id_table().to_name())
459 .expect("uart device register error");
460 UART_DEV.set_sys_info(Some(device_inode));
461 let driver_inode = bus_driver_register("platform:0", &UART_DRV.id_table().to_name())
462 .expect("uart driver register error");
463 UART_DRV.set_sys_info(Some(driver_inode));
464 UART_DEV.set_driver(Some(UART_DRV.clone()));
465 UART_DEV.set_state(DeviceState::Initialized);
466 return Ok(());
467 }
468