xref: /DragonOS/kernel/src/driver/serial/mod.rs (revision c3dc6f2ff9169c309d1cbf47dcb9e4528d509b2f)
1 use core::{fmt::Debug, sync::atomic::AtomicU32};
2 
3 use alloc::sync::Arc;
4 use system_error::SystemError;
5 
6 use crate::{driver::base::device::device_number::DeviceNumber, mm::VirtAddr};
7 
8 use self::serial8250::serial8250_manager;
9 
10 pub mod serial8250;
11 
12 pub trait UartDriver: Debug + Send + Sync {
13     fn device_number(&self) -> DeviceNumber;
14 
15     /// 获取最大的设备数量
16     fn max_devs_num(&self) -> i32;
17 
18     // todo: 获取指向console的指针(在我们系统里面,将来可能是改进后的Textui Window)
19 }
20 
21 /// 串口端口应当实现的trait
22 ///
23 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/serial_core.h#428
24 pub trait UartPort {
25     fn iobase(&self) -> Option<usize> {
26         None
27     }
28     fn membase(&self) -> Option<VirtAddr> {
29         None
30     }
31     fn serial_in(&self, offset: u32) -> u32;
32     fn serial_out(&self, offset: u32, value: u32);
33     fn divisor(&self, baud: BaudRate) -> (u32, DivisorFraction);
34     fn set_divisor(&self, baud: BaudRate) -> Result<(), SystemError>;
35     fn baud_rate(&self) -> Option<BaudRate>;
36     fn startup(&self) -> Result<(), SystemError>;
37     fn shutdown(&self);
38     fn handle_irq(&self) -> Result<(), SystemError>;
39 }
40 
41 int_like!(BaudRate, AtomicBaudRate, u32, AtomicU32);
42 int_like!(DivisorFraction, u32);
43 
44 #[inline(always)]
45 #[allow(dead_code)]
46 pub(super) fn uart_manager() -> &'static UartManager {
47     &UartManager
48 }
49 
50 #[derive(Debug)]
51 pub(super) struct UartManager;
52 
53 impl UartManager {
54     /// todo: 把uart设备注册到tty层
55     ///
56     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/tty/serial/serial_core.c?fi=uart_register_driver#2720
57     #[allow(dead_code)]
58     pub fn register_driver(&self, _driver: &Arc<dyn UartDriver>) -> Result<(), SystemError> {
59         return Ok(());
60     }
61 }
62 
63 pub fn serial_early_init() -> Result<(), SystemError> {
64     serial8250_manager().early_init()?;
65     return Ok(());
66 }
67 
68 pub(super) fn serial_init() -> Result<(), SystemError> {
69     serial8250_manager().init()?;
70     return Ok(());
71 }
72