xref: /DragonOS/kernel/src/driver/serial/mod.rs (revision d031d46fd9e9a62e8e975dba76e3bdef027f63b6)
1 use core::{fmt::Debug, sync::atomic::AtomicU32};
2 
3 use alloc::sync::Arc;
4 use system_error::SystemError;
5 
6 use crate::mm::VirtAddr;
7 
8 use self::serial8250::serial8250_manager;
9 
10 use super::tty::{
11     termios::{ControlMode, InputMode, LocalMode, OutputMode, Termios, INIT_CONTORL_CHARACTERS},
12     tty_ldisc::LineDisciplineType,
13 };
14 
15 pub mod serial8250;
16 
17 #[allow(dead_code)]
18 pub trait UartDriver: Debug + Send + Sync {
19     /// 获取最大的设备数量
max_devs_num(&self) -> i3220     fn max_devs_num(&self) -> i32;
21 
22     // todo: 获取指向console的指针(在我们系统里面,将来可能是改进后的Textui Window)
23 }
24 
25 pub const SERIAL_BAUDRATE: BaudRate = BaudRate::new(115200);
26 
27 /// 串口端口应当实现的trait
28 ///
29 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/serial_core.h#428
30 #[allow(dead_code)]
31 pub trait UartPort {
iobase(&self) -> Option<usize>32     fn iobase(&self) -> Option<usize> {
33         None
34     }
membase(&self) -> Option<VirtAddr>35     fn membase(&self) -> Option<VirtAddr> {
36         None
37     }
serial_in(&self, offset: u32) -> u3238     fn serial_in(&self, offset: u32) -> u32;
serial_out(&self, offset: u32, value: u32)39     fn serial_out(&self, offset: u32, value: u32);
divisor(&self, baud: BaudRate) -> (u32, DivisorFraction)40     fn divisor(&self, baud: BaudRate) -> (u32, DivisorFraction);
set_divisor(&self, baud: BaudRate) -> Result<(), SystemError>41     fn set_divisor(&self, baud: BaudRate) -> Result<(), SystemError>;
baud_rate(&self) -> Option<BaudRate>42     fn baud_rate(&self) -> Option<BaudRate>;
startup(&self) -> Result<(), SystemError>43     fn startup(&self) -> Result<(), SystemError>;
shutdown(&self)44     fn shutdown(&self);
handle_irq(&self) -> Result<(), SystemError>45     fn handle_irq(&self) -> Result<(), SystemError>;
46 }
47 
48 int_like!(BaudRate, AtomicBaudRate, u32, AtomicU32);
49 int_like!(DivisorFraction, u32);
50 
51 lazy_static! {
52     pub static ref TTY_SERIAL_DEFAULT_TERMIOS: Termios = {
53         Termios {
54             input_mode: InputMode::ICRNL | InputMode::IXON | InputMode::IUTF8,
55             output_mode: OutputMode::OPOST | OutputMode::ONLCR,
56             control_mode: ControlMode::B115200
57                 | ControlMode::CREAD
58                 | ControlMode::HUPCL
59                 | ControlMode::CS8,
60             local_mode: LocalMode::ISIG
61                 | LocalMode::ICANON
62                 | LocalMode::ECHO
63                 | LocalMode::ECHOE
64                 | LocalMode::ECHOK
65                 | LocalMode::ECHOCTL
66                 | LocalMode::ECHOKE
67                 | LocalMode::IEXTEN,
68             control_characters: INIT_CONTORL_CHARACTERS,
69             line: LineDisciplineType::NTty,
70             input_speed: SERIAL_BAUDRATE.data(),
71             output_speed: SERIAL_BAUDRATE.data(),
72         }
73     };
74 }
75 
76 #[inline(always)]
77 #[allow(dead_code)]
uart_manager() -> &'static UartManager78 pub(super) fn uart_manager() -> &'static UartManager {
79     &UartManager
80 }
81 #[derive(Debug)]
82 pub(super) struct UartManager;
83 
84 impl UartManager {
85     pub const NR_TTY_SERIAL_MAX: u32 = 128;
86     /// todo: 把uart设备注册到tty层
87     ///
88     /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/tty/serial/serial_core.c?fi=uart_register_driver#2720
89     #[allow(dead_code)]
register_driver(&self, _driver: &Arc<dyn UartDriver>) -> Result<(), SystemError>90     pub fn register_driver(&self, _driver: &Arc<dyn UartDriver>) -> Result<(), SystemError> {
91         return Ok(());
92     }
93 }
94 
serial_early_init() -> Result<(), SystemError>95 pub fn serial_early_init() -> Result<(), SystemError> {
96     serial8250_manager().early_init()?;
97     return Ok(());
98 }
99 
serial_init() -> Result<(), SystemError>100 pub(super) fn serial_init() -> Result<(), SystemError> {
101     serial8250_manager().init()?;
102     return Ok(());
103 }
104