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