xref: /DragonOS/kernel/src/libs/printk.rs (revision 0897bd8e754e88b4262881410c77e372fe258397)
152da9a59SGnoCiYeH use core::{
252da9a59SGnoCiYeH     fmt::{self, Write},
352da9a59SGnoCiYeH     sync::atomic::Ordering,
452da9a59SGnoCiYeH };
56cb769c4Slogin 
68d72b68dSJomo use alloc::string::ToString;
72eab6dd7S曾俊 use log::{info, Level, Log};
88d72b68dSJomo 
9fbe6becdSLoGin use super::lib_ui::textui::{textui_putstr, FontColor};
106cb769c4Slogin 
118d72b68dSJomo use crate::{
12f3b05a97SGnoCiYeH     driver::tty::{
13dfe53cf0SGnoCiYeH         tty_driver::TtyOperation, tty_port::tty_port,
1452da9a59SGnoCiYeH         virtual_terminal::virtual_console::CURRENT_VCNUM,
1552da9a59SGnoCiYeH     },
168d72b68dSJomo     filesystem::procfs::{
178d72b68dSJomo         kmsg::KMSG,
188d72b68dSJomo         log::{LogLevel, LogMessage},
198d72b68dSJomo     },
206fc066acSJomo     time::PosixTimeSpec,
218d72b68dSJomo };
228d72b68dSJomo 
236cb769c4Slogin #[macro_export]
246cb769c4Slogin macro_rules! print {
256cb769c4Slogin     ($($arg:tt)*) => ($crate::libs::printk::__printk(format_args!($($arg)*)));
266cb769c4Slogin }
276cb769c4Slogin 
286cb769c4Slogin #[macro_export]
296cb769c4Slogin macro_rules! println {
306cb769c4Slogin     () => {
316cb769c4Slogin         $crate::print!("\n");
326cb769c4Slogin     };
336cb769c4Slogin     ($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*)));
346cb769c4Slogin }
356cb769c4Slogin 
36fb6c29d0Slogin pub struct PrintkWriter;
37fb6c29d0Slogin 
38fb6c29d0Slogin impl PrintkWriter {
3940fe15e0SLoGin     #[inline]
__write_fmt(&mut self, args: fmt::Arguments)4040fe15e0SLoGin     pub fn __write_fmt(&mut self, args: fmt::Arguments) {
41abe3a6eaShanjiezhou         self.write_fmt(args).ok();
4240fe15e0SLoGin     }
4340fe15e0SLoGin 
44abe3a6eaShanjiezhou     /// 并输出白底黑字
45fb6c29d0Slogin     /// @param str: 要写入的字符
__write_string(&mut self, s: &str)46fb6c29d0Slogin     pub fn __write_string(&mut self, s: &str) {
4752da9a59SGnoCiYeH         let current_vcnum = CURRENT_VCNUM.load(Ordering::SeqCst);
4852da9a59SGnoCiYeH         if current_vcnum != -1 {
4952da9a59SGnoCiYeH             // tty已经初始化了之后才输出到屏幕
50dfe53cf0SGnoCiYeH             let port = tty_port(current_vcnum as usize);
51dfe53cf0SGnoCiYeH             let tty = port.port_data().internal_tty();
52b5b571e0SLoGin             if let Some(tty) = tty {
5352da9a59SGnoCiYeH                 let _ = tty.write(tty.core(), s.as_bytes(), s.len());
5452da9a59SGnoCiYeH             } else {
5552da9a59SGnoCiYeH                 let _ = textui_putstr(s, FontColor::WHITE, FontColor::BLACK);
56fb6c29d0Slogin             }
5752da9a59SGnoCiYeH         } else {
5852da9a59SGnoCiYeH             let _ = textui_putstr(s, FontColor::WHITE, FontColor::BLACK);
5952da9a59SGnoCiYeH         }
6040fe15e0SLoGin     }
61fb6c29d0Slogin }
62fb6c29d0Slogin 
63fb6c29d0Slogin /// 为Printk Writer实现core::fmt::Write, 使得能够借助Rust自带的格式化组件,格式化字符并输出
64fb6c29d0Slogin impl fmt::Write for PrintkWriter {
write_str(&mut self, s: &str) -> fmt::Result65fb6c29d0Slogin     fn write_str(&mut self, s: &str) -> fmt::Result {
66fb6c29d0Slogin         self.__write_string(s);
67fb6c29d0Slogin         Ok(())
68fb6c29d0Slogin     }
69fb6c29d0Slogin }
70fb6c29d0Slogin 
71fb6c29d0Slogin #[doc(hidden)]
__printk(args: fmt::Arguments)72fb6c29d0Slogin pub fn __printk(args: fmt::Arguments) {
73fb6c29d0Slogin     PrintkWriter.write_fmt(args).unwrap();
74fb6c29d0Slogin }
758d72b68dSJomo 
768d72b68dSJomo pub struct Logger;
778d72b68dSJomo 
788d72b68dSJomo impl Logger {
log(&self, log_level: usize, message: fmt::Arguments)798d72b68dSJomo     pub fn log(&self, log_level: usize, message: fmt::Arguments) {
80453452ccSLoGin         if unsafe { KMSG.is_some() } {
816fc066acSJomo             let timestamp: PosixTimeSpec = PosixTimeSpec::now_cpu_time();
82b5b571e0SLoGin             let log_level = LogLevel::from(log_level);
83453452ccSLoGin 
848d72b68dSJomo             let log_message = LogMessage::new(timestamp, log_level, message.to_string());
858d72b68dSJomo 
868d72b68dSJomo             unsafe { KMSG.as_ref().unwrap().lock_irqsave().push(log_message) };
878d72b68dSJomo         }
888d72b68dSJomo     }
898d72b68dSJomo }
90731bc2b3SLoGin 
91731bc2b3SLoGin /// 内核自定义日志器
92731bc2b3SLoGin ///
93*0897bd8eSLoGin /// todo: https://github.com/DragonOS-Community/DragonOS/issues/762
94*0897bd8eSLoGin struct KernelLogger;
95731bc2b3SLoGin 
96*0897bd8eSLoGin impl Log for KernelLogger {
enabled(&self, _metadata: &log::Metadata) -> bool97731bc2b3SLoGin     fn enabled(&self, _metadata: &log::Metadata) -> bool {
98731bc2b3SLoGin         // 这里可以自定义日志过滤规则
99731bc2b3SLoGin         true
100731bc2b3SLoGin     }
101731bc2b3SLoGin 
log(&self, record: &log::Record)102731bc2b3SLoGin     fn log(&self, record: &log::Record) {
103731bc2b3SLoGin         if self.enabled(record.metadata()) {
104731bc2b3SLoGin             // todo: 接入kmsg
1052eab6dd7S曾俊             Self::kernel_log(record);
1062eab6dd7S曾俊             Self::iodisplay(record)
1072eab6dd7S曾俊         }
1082eab6dd7S曾俊     }
109731bc2b3SLoGin 
flush(&self)1102eab6dd7S曾俊     fn flush(&self) {
1112eab6dd7S曾俊         // 如果需要的话,可以在这里实现缓冲区刷新逻辑
1122eab6dd7S曾俊     }
1132eab6dd7S曾俊 }
1142eab6dd7S曾俊 
115*0897bd8eSLoGin impl KernelLogger {
iodisplay(record: &log::Record)1162eab6dd7S曾俊     fn iodisplay(record: &log::Record) {
1172eab6dd7S曾俊         match record.level() {
118*0897bd8eSLoGin             Level::Debug | Level::Info | Level::Trace => {
1192eab6dd7S曾俊                 write!(PrintkWriter, "[ {} ] ", record.level(),)
1202eab6dd7S曾俊             }
1212eab6dd7S曾俊             Level::Error => {
1222eab6dd7S曾俊                 write!(PrintkWriter, "\x1B[41m[ ERROR ] \x1B[0m",)
1232eab6dd7S曾俊             }
1242eab6dd7S曾俊             Level::Warn => {
1252eab6dd7S曾俊                 write!(PrintkWriter, "\x1B[1;33m[ WARN ] \x1B[0m",)
1262eab6dd7S曾俊             }
1272eab6dd7S曾俊         }
1282eab6dd7S曾俊         .unwrap();
129731bc2b3SLoGin         writeln!(
130731bc2b3SLoGin             PrintkWriter,
1312eab6dd7S曾俊             "({}:{})\t {}",
132731bc2b3SLoGin             record.file().unwrap_or(""),
133731bc2b3SLoGin             record.line().unwrap_or(0),
134731bc2b3SLoGin             record.args()
135731bc2b3SLoGin         )
136731bc2b3SLoGin         .unwrap();
137731bc2b3SLoGin     }
138731bc2b3SLoGin 
kernel_log(record: &log::Record)1392eab6dd7S曾俊     fn kernel_log(record: &log::Record) {
1402eab6dd7S曾俊         match record.level() {
1412eab6dd7S曾俊             Level::Debug => Logger.log(
1422eab6dd7S曾俊                 7,
1432eab6dd7S曾俊                 format_args!(
1442eab6dd7S曾俊                     "({}:{})\t {}\n",
1452eab6dd7S曾俊                     record.file().unwrap_or(""),
1462eab6dd7S曾俊                     record.line().unwrap_or(0),
1472eab6dd7S曾俊                     record.args()
1482eab6dd7S曾俊                 ),
1492eab6dd7S曾俊             ),
1502eab6dd7S曾俊             Level::Error => Logger.log(
1512eab6dd7S曾俊                 3,
1522eab6dd7S曾俊                 format_args!(
1532eab6dd7S曾俊                     "({}:{})\t {}\n",
1542eab6dd7S曾俊                     record.file().unwrap_or(""),
1552eab6dd7S曾俊                     record.line().unwrap_or(0),
1562eab6dd7S曾俊                     record.args()
1572eab6dd7S曾俊                 ),
1582eab6dd7S曾俊             ),
1592eab6dd7S曾俊             Level::Info => Logger.log(
1602eab6dd7S曾俊                 6,
1612eab6dd7S曾俊                 format_args!(
1622eab6dd7S曾俊                     "({}:{})\t {}\n",
1632eab6dd7S曾俊                     record.file().unwrap_or(""),
1642eab6dd7S曾俊                     record.line().unwrap_or(0),
1652eab6dd7S曾俊                     record.args()
1662eab6dd7S曾俊                 ),
1672eab6dd7S曾俊             ),
1682eab6dd7S曾俊             Level::Warn => Logger.log(
1692eab6dd7S曾俊                 4,
1702eab6dd7S曾俊                 format_args!(
1712eab6dd7S曾俊                     "({}:{})\t {}\n",
1722eab6dd7S曾俊                     record.file().unwrap_or(""),
1732eab6dd7S曾俊                     record.line().unwrap_or(0),
1742eab6dd7S曾俊                     record.args()
1752eab6dd7S曾俊                 ),
1762eab6dd7S曾俊             ),
1772eab6dd7S曾俊             Level::Trace => {
1782eab6dd7S曾俊                 todo!()
1792eab6dd7S曾俊             }
1802eab6dd7S曾俊         }
181731bc2b3SLoGin     }
182731bc2b3SLoGin }
183731bc2b3SLoGin 
early_init_logging()184731bc2b3SLoGin pub fn early_init_logging() {
185*0897bd8eSLoGin     log::set_logger(&KernelLogger).unwrap();
186731bc2b3SLoGin     log::set_max_level(log::LevelFilter::Debug);
187731bc2b3SLoGin     info!("Logging initialized");
188731bc2b3SLoGin }
189