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