xref: /DragonOS/kernel/src/libs/printk.rs (revision 338f6903262c5031abad3c8e361813355a27fcdb)
1 use core::{
2     fmt::{self, Write},
3     sync::atomic::Ordering,
4 };
5 
6 use alloc::string::ToString;
7 
8 use super::lib_ui::textui::{textui_putstr, FontColor};
9 
10 use crate::{
11     driver::tty::{
12         tty_driver::TtyOperation, tty_port::TTY_PORTS,
13         virtual_terminal::virtual_console::CURRENT_VCNUM,
14     },
15     filesystem::procfs::{
16         kmsg::KMSG,
17         log::{LogLevel, LogMessage},
18     },
19     time::TimeSpec,
20 };
21 
22 #[macro_export]
23 macro_rules! print {
24     ($($arg:tt)*) => ($crate::libs::printk::__printk(format_args!($($arg)*)));
25 }
26 
27 #[macro_export]
28 macro_rules! println {
29     () => {
30         $crate::print!("\n");
31     };
32     ($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*)));
33 }
34 
35 /// 指定颜色,彩色输出
36 /// @param FRcolor 前景色
37 /// @param BKcolor 背景色
38 #[macro_export]
39 macro_rules! printk_color {
40 
41     ($FRcolor:expr, $BKcolor:expr, $($arg:tt)*) => {
42         use alloc;
43         $crate::libs::printk::PrintkWriter.__write_string_color($FRcolor, $BKcolor, alloc::fmt::format(format_args!($($arg)*)).as_str())
44     };
45 }
46 
47 #[macro_export]
48 macro_rules! kdebug {
49     ($($arg:tt)*) => {
50         $crate::libs::printk::Logger.log(7,format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)));
51         $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("[ DEBUG ] ({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)))
52     }
53 }
54 
55 #[macro_export]
56 macro_rules! kinfo {
57     ($($arg:tt)*) => {
58         $crate::libs::printk::Logger.log(6,format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)));
59         $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("[ INFO ] ({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)))
60     }
61 }
62 
63 #[macro_export]
64 macro_rules! kwarn {
65     ($($arg:tt)*) => {
66         $crate::libs::printk::Logger.log(4,format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)));
67         $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("\x1B[1;33m[ WARN ] \x1B[0m"));
68         $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)));
69     }
70 }
71 
72 #[macro_export]
73 macro_rules! kerror {
74     ($($arg:tt)*) => {
75         $crate::libs::printk::Logger.log(3,format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)));
76         $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("\x1B[41m[ ERROR ] \x1B[0m"));
77         $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)));
78     }
79 }
80 
81 #[macro_export]
82 macro_rules! kBUG {
83     ($($arg:tt)*) => {
84         $crate::libs::printk::Logger.log(1,format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)));
85         $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("\x1B[41m[ BUG ] \x1B[0m"));
86         $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*)));
87     }
88 }
89 
90 pub struct PrintkWriter;
91 
92 impl PrintkWriter {
93     #[inline]
94     pub fn __write_fmt(&mut self, args: fmt::Arguments) {
95         self.write_fmt(args).ok();
96     }
97 
98     /// 并输出白底黑字
99     /// @param str: 要写入的字符
100     pub fn __write_string(&mut self, s: &str) {
101         let current_vcnum = CURRENT_VCNUM.load(Ordering::SeqCst);
102         if current_vcnum != -1 {
103             // tty已经初始化了之后才输出到屏幕
104             let port = TTY_PORTS[current_vcnum as usize].clone();
105             let tty = port.port_data().tty();
106             if tty.is_some() {
107                 let tty = tty.unwrap();
108                 let _ = tty.write(tty.core(), s.as_bytes(), s.len());
109             } else {
110                 let _ = textui_putstr(s, FontColor::WHITE, FontColor::BLACK);
111             }
112         } else {
113             let _ = textui_putstr(s, FontColor::WHITE, FontColor::BLACK);
114         }
115     }
116 }
117 
118 /// 为Printk Writer实现core::fmt::Write, 使得能够借助Rust自带的格式化组件,格式化字符并输出
119 impl fmt::Write for PrintkWriter {
120     fn write_str(&mut self, s: &str) -> fmt::Result {
121         self.__write_string(s);
122         Ok(())
123     }
124 }
125 
126 #[doc(hidden)]
127 pub fn __printk(args: fmt::Arguments) {
128     PrintkWriter.write_fmt(args).unwrap();
129 }
130 
131 pub struct Logger;
132 
133 impl Logger {
134     pub fn log(&self, log_level: usize, message: fmt::Arguments) {
135         if unsafe { KMSG.is_some() } {
136             let timestamp: TimeSpec = TimeSpec::now();
137             let log_level = LogLevel::from(log_level.clone());
138 
139             let log_message = LogMessage::new(timestamp, log_level, message.to_string());
140 
141             unsafe { KMSG.as_ref().unwrap().lock_irqsave().push(log_message) };
142         }
143     }
144 }
145