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_port, 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 #[macro_export] 36 macro_rules! kdebug { 37 ($($arg:tt)*) => { 38 $crate::libs::printk::Logger.log(7,format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*))); 39 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("[ DEBUG ] ({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*))) 40 } 41 } 42 43 #[macro_export] 44 macro_rules! kinfo { 45 ($($arg:tt)*) => { 46 $crate::libs::printk::Logger.log(6,format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*))); 47 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("[ INFO ] ({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*))) 48 } 49 } 50 51 #[macro_export] 52 macro_rules! kwarn { 53 ($($arg:tt)*) => { 54 $crate::libs::printk::Logger.log(4,format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*))); 55 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("\x1B[1;33m[ WARN ] \x1B[0m")); 56 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*))); 57 } 58 } 59 60 #[macro_export] 61 macro_rules! kerror { 62 ($($arg:tt)*) => { 63 $crate::libs::printk::Logger.log(3,format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*))); 64 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("\x1B[41m[ ERROR ] \x1B[0m")); 65 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*))); 66 } 67 } 68 69 #[macro_export] 70 macro_rules! kBUG { 71 ($($arg:tt)*) => { 72 $crate::libs::printk::Logger.log(1,format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*))); 73 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("\x1B[41m[ BUG ] \x1B[0m")); 74 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("({}:{})\t {}\n", file!(), line!(),format_args!($($arg)*))); 75 } 76 } 77 78 pub struct PrintkWriter; 79 80 impl PrintkWriter { 81 #[inline] 82 pub fn __write_fmt(&mut self, args: fmt::Arguments) { 83 self.write_fmt(args).ok(); 84 } 85 86 /// 并输出白底黑字 87 /// @param str: 要写入的字符 88 pub fn __write_string(&mut self, s: &str) { 89 let current_vcnum = CURRENT_VCNUM.load(Ordering::SeqCst); 90 if current_vcnum != -1 { 91 // tty已经初始化了之后才输出到屏幕 92 let port = tty_port(current_vcnum as usize); 93 let tty = port.port_data().internal_tty(); 94 if let Some(tty) = tty { 95 let _ = tty.write(tty.core(), s.as_bytes(), s.len()); 96 } else { 97 let _ = textui_putstr(s, FontColor::WHITE, FontColor::BLACK); 98 } 99 } else { 100 let _ = textui_putstr(s, FontColor::WHITE, FontColor::BLACK); 101 } 102 } 103 } 104 105 /// 为Printk Writer实现core::fmt::Write, 使得能够借助Rust自带的格式化组件,格式化字符并输出 106 impl fmt::Write for PrintkWriter { 107 fn write_str(&mut self, s: &str) -> fmt::Result { 108 self.__write_string(s); 109 Ok(()) 110 } 111 } 112 113 #[doc(hidden)] 114 pub fn __printk(args: fmt::Arguments) { 115 PrintkWriter.write_fmt(args).unwrap(); 116 } 117 118 pub struct Logger; 119 120 impl Logger { 121 pub fn log(&self, log_level: usize, message: fmt::Arguments) { 122 if unsafe { KMSG.is_some() } { 123 let timestamp: TimeSpec = TimeSpec::now(); 124 let log_level = LogLevel::from(log_level); 125 126 let log_message = LogMessage::new(timestamp, log_level, message.to_string()); 127 128 unsafe { KMSG.as_ref().unwrap().lock_irqsave().push(log_message) }; 129 } 130 } 131 } 132