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