1 #![allow(unused)] 2 use crate::{ 3 driver::uart::uart::c_uart_send_str, 4 include::bindings::bindings::{printk_color, BLACK, WHITE}, 5 }; 6 use ::core::ffi::c_char; 7 use alloc::vec::Vec; 8 use core::{ 9 fmt::{self, Write}, 10 intrinsics::{likely, unlikely}, 11 sync::atomic::{AtomicBool, Ordering}, 12 }; 13 14 // ====== 定义颜色 ====== 15 /// 白色 16 pub const COLOR_WHITE: u32 = 0x00ffffff; 17 /// 黑色 18 pub const COLOR_BLACK: u32 = 0x00000000; 19 /// 红色 20 pub const COLOR_RED: u32 = 0x00ff0000; 21 /// 橙色 22 pub const COLOR_ORANGE: u32 = 0x00ff8000; 23 /// 黄色 24 pub const COLOR_YELLOW: u32 = 0x00ffff00; 25 /// 绿色 26 pub const COLOR_GREEN: u32 = 0x0000ff00; 27 /// 蓝色 28 pub const COLOR_BLUE: u32 = 0x000000ff; 29 /// 靛色 30 pub const COLOR_INDIGO: u32 = 0x0000ffff; 31 /// 紫色 32 pub const COLOR_PURPLE: u32 = 0x008000ff; 33 34 #[macro_export] 35 macro_rules! print { 36 ($($arg:tt)*) => ($crate::libs::printk::__printk(format_args!($($arg)*))); 37 } 38 39 #[macro_export] 40 macro_rules! println { 41 () => { 42 $crate::print!("\n"); 43 }; 44 ($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*))); 45 } 46 47 /// 指定颜色,彩色输出 48 /// @param FRcolor 前景色 49 /// @param BKcolor 背景色 50 #[macro_export] 51 macro_rules! printk_color { 52 53 ($FRcolor:expr, $BKcolor:expr, $($arg:tt)*) => { 54 use alloc; 55 $crate::libs::printk::PrintkWriter.__write_string_color($FRcolor, $BKcolor, alloc::fmt::format(format_args!($($arg)*)).as_str()) 56 }; 57 } 58 59 #[macro_export] 60 macro_rules! kdebug { 61 ($($arg:tt)*) => { 62 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("[ DEBUG ] ({}:{})\t{}\n", file!(), line!(),format_args!($($arg)*))) 63 64 } 65 } 66 67 #[macro_export] 68 macro_rules! kinfo { 69 ($($arg:tt)*) => { 70 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("[ INFO ] ({}:{})\t{}\n", file!(), line!(),format_args!($($arg)*))) 71 } 72 } 73 74 #[macro_export] 75 macro_rules! kwarn { 76 ($($arg:tt)*) => { 77 $crate::libs::printk::PrintkWriter.__write_string_color($crate::libs::printk::COLOR_YELLOW, $crate::libs::printk::COLOR_BLACK, "[ WARN ] "); 78 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("({}:{})\t{}\n", file!(), line!(),format_args!($($arg)*))); 79 } 80 } 81 82 #[macro_export] 83 macro_rules! kerror { 84 ($($arg:tt)*) => { 85 $crate::libs::printk::PrintkWriter.__write_string_color($crate::libs::printk::COLOR_RED, $crate::libs::printk::COLOR_BLACK, "[ ERROR ] "); 86 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("({}:{})\t{}\n", file!(), line!(),format_args!($($arg)*))); 87 } 88 } 89 90 #[macro_export] 91 macro_rules! kBUG { 92 ($($arg:tt)*) => { 93 $crate::libs::printk::PrintkWriter.__write_string_color($crate::libs::printk::COLOR_RED, $crate::libs::printk::COLOR_BLACK, "[ BUG ] "); 94 $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("({}:{})\t{}\n", file!(), line!(),format_args!($($arg)*))); 95 } 96 } 97 98 pub struct PrintkWriter; 99 100 /// 由于内存管理初始化完成之前,无法使用动态内存分配,所以需要在内存管理初始化完成之后才能使用动态内存分配 101 static ALLOW_ALLOC_ATOMIC: AtomicBool = AtomicBool::new(false); 102 static mut ALLOW_ALLOC_BOOL: bool = false; 103 104 impl PrintkWriter { 105 #[inline] 106 pub fn __write_fmt(&mut self, args: fmt::Arguments) { 107 self.write_fmt(args); 108 } 109 110 /// 调用C语言编写的printk_color,并输出白底黑字(暂时只支持ascii字符) 111 /// @param str: 要写入的字符 112 pub fn __write_string(&mut self, s: &str) { 113 if unlikely(!self.allow_alloc()) { 114 self.__write_string_on_stack(s); 115 return; 116 } 117 let str_to_print = self.__utf8_to_ascii(s); 118 unsafe { 119 printk_color(WHITE, BLACK, str_to_print.as_ptr() as *const c_char); 120 } 121 } 122 123 pub fn __write_string_color(&self, fr_color: u32, bk_color: u32, s: &str) { 124 if unlikely(!self.allow_alloc()) { 125 self.__write_string_on_stack(s); 126 return; 127 } 128 129 let str_to_print = self.__utf8_to_ascii(s); 130 unsafe { 131 printk_color(fr_color, bk_color, str_to_print.as_ptr() as *const c_char); 132 } 133 } 134 135 #[inline] 136 fn allow_alloc(&self) -> bool { 137 // 由于allow_alloc只可能由false变为true 138 // 因此采用两种方式读取它,一种是原子操作,一种是普通的bool,以优化性能。 139 if likely(unsafe { ALLOW_ALLOC_BOOL }) { 140 return true; 141 } else { 142 return ALLOW_ALLOC_ATOMIC.load(Ordering::SeqCst); 143 } 144 } 145 146 /// 允许动态内存分配 147 pub fn enable_alloc(&self) { 148 ALLOW_ALLOC_ATOMIC.store(true, Ordering::SeqCst); 149 unsafe { 150 ALLOW_ALLOC_BOOL = true; 151 } 152 } 153 154 /// 将s这个utf8字符串,转换为ascii字符串 155 /// @param s 待转换的utf8字符串 156 /// @return Vec<u8> 转换结束后的Ascii字符串 157 pub fn __utf8_to_ascii(&self, s: &str) -> Vec<u8> { 158 let mut ascii_str: Vec<u8> = Vec::with_capacity(s.len() + 1); 159 for byte in s.bytes() { 160 match byte { 161 0..=127 => { 162 ascii_str.push(byte); 163 } 164 _ => {} 165 } 166 } 167 ascii_str.push(b'\0'); 168 return ascii_str; 169 } 170 171 fn __write_string_on_stack(&self, s: &str) { 172 let s_len = s.len(); 173 assert!(s_len < 1024, "s_len is too long"); 174 let mut str_to_print: [u8; 1024] = [0; 1024]; 175 let mut i = 0; 176 for byte in s.bytes() { 177 match byte { 178 0..=127 => { 179 str_to_print[i] = byte; 180 i += 1; 181 } 182 _ => {} 183 } 184 } 185 str_to_print[i] = b'\0'; 186 unsafe { 187 printk_color(WHITE, BLACK, str_to_print.as_ptr() as *const c_char); 188 } 189 } 190 191 fn __write_string_color_on_stack(&self, fr_color: u32, bk_color: u32, s: &str) { 192 let s_len = s.len(); 193 assert!(s_len < 1024, "s_len is too long"); 194 let mut str_to_print: [u8; 1024] = [0; 1024]; 195 let mut i = 0; 196 for byte in s.bytes() { 197 match byte { 198 0..=127 => { 199 str_to_print[i] = byte; 200 i += 1; 201 } 202 _ => {} 203 } 204 } 205 str_to_print[i] = b'\0'; 206 unsafe { 207 printk_color(fr_color, bk_color, str_to_print.as_ptr() as *const c_char); 208 } 209 } 210 } 211 212 /// 为Printk Writer实现core::fmt::Write, 使得能够借助Rust自带的格式化组件,格式化字符并输出 213 impl fmt::Write for PrintkWriter { 214 fn write_str(&mut self, s: &str) -> fmt::Result { 215 self.__write_string(s); 216 Ok(()) 217 } 218 } 219 220 #[doc(hidden)] 221 pub fn __printk(args: fmt::Arguments) { 222 use fmt::Write; 223 PrintkWriter.write_fmt(args).unwrap(); 224 } 225