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 #[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_PORTS[current_vcnum as usize].clone(); 93 let tty = port.port_data().tty(); 94 if tty.is_some() { 95 let tty = tty.unwrap(); 96 let _ = tty.write(tty.core(), s.as_bytes(), s.len()); 97 } else { 98 let _ = textui_putstr(s, FontColor::WHITE, FontColor::BLACK); 99 } 100 } else { 101 let _ = textui_putstr(s, FontColor::WHITE, FontColor::BLACK); 102 } 103 } 104 } 105 106 /// 为Printk Writer实现core::fmt::Write, 使得能够借助Rust自带的格式化组件,格式化字符并输出 107 impl fmt::Write for PrintkWriter { 108 fn write_str(&mut self, s: &str) -> fmt::Result { 109 self.__write_string(s); 110 Ok(()) 111 } 112 } 113 114 #[doc(hidden)] 115 pub fn __printk(args: fmt::Arguments) { 116 PrintkWriter.write_fmt(args).unwrap(); 117 } 118 119 pub struct Logger; 120 121 impl Logger { 122 pub fn log(&self, log_level: usize, message: fmt::Arguments) { 123 if unsafe { KMSG.is_some() } { 124 let timestamp: TimeSpec = TimeSpec::now(); 125 let log_level = LogLevel::from(log_level.clone()); 126 127 let log_message = LogMessage::new(timestamp, log_level, message.to_string()); 128 129 unsafe { KMSG.as_ref().unwrap().lock_irqsave().push(log_message) }; 130 } 131 } 132 } 133