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