16cb769c4Slogin #![allow(unused)] 2*40fe15e0SLoGin use crate::{ 3*40fe15e0SLoGin driver::uart::uart::c_uart_send_str, 4*40fe15e0SLoGin include::bindings::bindings::{printk_color, BLACK, WHITE}, 5*40fe15e0SLoGin }; 6fb6c29d0Slogin use ::core::ffi::c_char; 7fb6c29d0Slogin use alloc::vec::Vec; 8*40fe15e0SLoGin use core::{ 9*40fe15e0SLoGin fmt::{self, Write}, 10*40fe15e0SLoGin intrinsics::{likely, unlikely}, 11*40fe15e0SLoGin sync::atomic::{AtomicBool, Ordering}, 12*40fe15e0SLoGin }; 136cb769c4Slogin 146cb769c4Slogin // ====== 定义颜色 ====== 156cb769c4Slogin /// 白色 166cb769c4Slogin pub const COLOR_WHITE: u32 = 0x00ffffff; 176cb769c4Slogin /// 黑色 186cb769c4Slogin pub const COLOR_BLACK: u32 = 0x00000000; 196cb769c4Slogin /// 红色 206cb769c4Slogin pub const COLOR_RED: u32 = 0x00ff0000; 216cb769c4Slogin /// 橙色 226cb769c4Slogin pub const COLOR_ORANGE: u32 = 0x00ff8000; 236cb769c4Slogin /// 黄色 246cb769c4Slogin pub const COLOR_YELLOW: u32 = 0x00ffff00; 256cb769c4Slogin /// 绿色 266cb769c4Slogin pub const COLOR_GREEN: u32 = 0x0000ff00; 276cb769c4Slogin /// 蓝色 286cb769c4Slogin pub const COLOR_BLUE: u32 = 0x000000ff; 296cb769c4Slogin /// 靛色 306cb769c4Slogin pub const COLOR_INDIGO: u32 = 0x0000ffff; 316cb769c4Slogin /// 紫色 326cb769c4Slogin pub const COLOR_PURPLE: u32 = 0x008000ff; 336cb769c4Slogin 346cb769c4Slogin #[macro_export] 356cb769c4Slogin macro_rules! print { 366cb769c4Slogin ($($arg:tt)*) => ($crate::libs::printk::__printk(format_args!($($arg)*))); 376cb769c4Slogin } 386cb769c4Slogin 396cb769c4Slogin #[macro_export] 406cb769c4Slogin macro_rules! println { 416cb769c4Slogin () => { 426cb769c4Slogin $crate::print!("\n"); 436cb769c4Slogin }; 446cb769c4Slogin ($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*))); 456cb769c4Slogin } 466cb769c4Slogin 476cb769c4Slogin /// 指定颜色,彩色输出 486cb769c4Slogin /// @param FRcolor 前景色 496cb769c4Slogin /// @param BKcolor 背景色 506cb769c4Slogin #[macro_export] 516cb769c4Slogin macro_rules! printk_color { 526cb769c4Slogin 536cb769c4Slogin ($FRcolor:expr, $BKcolor:expr, $($arg:tt)*) => { 546cb769c4Slogin use alloc; 556cb769c4Slogin $crate::libs::printk::PrintkWriter.__write_string_color($FRcolor, $BKcolor, alloc::fmt::format(format_args!($($arg)*)).as_str()) 566cb769c4Slogin }; 576cb769c4Slogin } 586cb769c4Slogin 596cb769c4Slogin #[macro_export] 606cb769c4Slogin macro_rules! kdebug { 616cb769c4Slogin ($($arg:tt)*) => { 62*40fe15e0SLoGin $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("[ DEBUG ] ({}:{})\t{}\n", file!(), line!(),format_args!($($arg)*))) 63*40fe15e0SLoGin 646cb769c4Slogin } 656cb769c4Slogin } 666cb769c4Slogin 676cb769c4Slogin #[macro_export] 686cb769c4Slogin macro_rules! kinfo { 696cb769c4Slogin ($($arg:tt)*) => { 70*40fe15e0SLoGin $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("[ INFO ] ({}:{})\t{}\n", file!(), line!(),format_args!($($arg)*))) 716cb769c4Slogin } 726cb769c4Slogin } 736cb769c4Slogin 746cb769c4Slogin #[macro_export] 756cb769c4Slogin macro_rules! kwarn { 766cb769c4Slogin ($($arg:tt)*) => { 776cb769c4Slogin $crate::libs::printk::PrintkWriter.__write_string_color($crate::libs::printk::COLOR_YELLOW, $crate::libs::printk::COLOR_BLACK, "[ WARN ] "); 78*40fe15e0SLoGin $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("({}:{})\t{}\n", file!(), line!(),format_args!($($arg)*))); 796cb769c4Slogin } 806cb769c4Slogin } 816cb769c4Slogin 826cb769c4Slogin #[macro_export] 836cb769c4Slogin macro_rules! kerror { 846cb769c4Slogin ($($arg:tt)*) => { 856cb769c4Slogin $crate::libs::printk::PrintkWriter.__write_string_color($crate::libs::printk::COLOR_RED, $crate::libs::printk::COLOR_BLACK, "[ ERROR ] "); 86*40fe15e0SLoGin $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("({}:{})\t{}\n", file!(), line!(),format_args!($($arg)*))); 876cb769c4Slogin } 886cb769c4Slogin } 896cb769c4Slogin 906cb769c4Slogin #[macro_export] 916cb769c4Slogin macro_rules! kBUG { 926cb769c4Slogin ($($arg:tt)*) => { 936cb769c4Slogin $crate::libs::printk::PrintkWriter.__write_string_color($crate::libs::printk::COLOR_RED, $crate::libs::printk::COLOR_BLACK, "[ BUG ] "); 94*40fe15e0SLoGin $crate::libs::printk::PrintkWriter.__write_fmt(format_args!("({}:{})\t{}\n", file!(), line!(),format_args!($($arg)*))); 956cb769c4Slogin } 966cb769c4Slogin } 976cb769c4Slogin 98fb6c29d0Slogin pub struct PrintkWriter; 99fb6c29d0Slogin 100*40fe15e0SLoGin /// 由于内存管理初始化完成之前,无法使用动态内存分配,所以需要在内存管理初始化完成之后才能使用动态内存分配 101*40fe15e0SLoGin static ALLOW_ALLOC_ATOMIC: AtomicBool = AtomicBool::new(false); 102*40fe15e0SLoGin static mut ALLOW_ALLOC_BOOL: bool = false; 103*40fe15e0SLoGin 104fb6c29d0Slogin impl PrintkWriter { 105*40fe15e0SLoGin #[inline] 106*40fe15e0SLoGin pub fn __write_fmt(&mut self, args: fmt::Arguments) { 107*40fe15e0SLoGin self.write_fmt(args); 108*40fe15e0SLoGin } 109*40fe15e0SLoGin 110fb6c29d0Slogin /// 调用C语言编写的printk_color,并输出白底黑字(暂时只支持ascii字符) 111fb6c29d0Slogin /// @param str: 要写入的字符 112fb6c29d0Slogin pub fn __write_string(&mut self, s: &str) { 113*40fe15e0SLoGin if unlikely(!self.allow_alloc()) { 114*40fe15e0SLoGin self.__write_string_on_stack(s); 115*40fe15e0SLoGin return; 116*40fe15e0SLoGin } 117fb6c29d0Slogin let str_to_print = self.__utf8_to_ascii(s); 118fb6c29d0Slogin unsafe { 119fb6c29d0Slogin printk_color(WHITE, BLACK, str_to_print.as_ptr() as *const c_char); 120fb6c29d0Slogin } 121fb6c29d0Slogin } 122fb6c29d0Slogin 123fb6c29d0Slogin pub fn __write_string_color(&self, fr_color: u32, bk_color: u32, s: &str) { 124*40fe15e0SLoGin if unlikely(!self.allow_alloc()) { 125*40fe15e0SLoGin self.__write_string_on_stack(s); 126*40fe15e0SLoGin return; 127*40fe15e0SLoGin } 128*40fe15e0SLoGin 129fb6c29d0Slogin let str_to_print = self.__utf8_to_ascii(s); 130fb6c29d0Slogin unsafe { 131fb6c29d0Slogin printk_color(fr_color, bk_color, str_to_print.as_ptr() as *const c_char); 132fb6c29d0Slogin } 133fb6c29d0Slogin } 134fb6c29d0Slogin 135*40fe15e0SLoGin #[inline] 136*40fe15e0SLoGin fn allow_alloc(&self) -> bool { 137*40fe15e0SLoGin // 由于allow_alloc只可能由false变为true 138*40fe15e0SLoGin // 因此采用两种方式读取它,一种是原子操作,一种是普通的bool,以优化性能。 139*40fe15e0SLoGin if likely(unsafe { ALLOW_ALLOC_BOOL }) { 140*40fe15e0SLoGin return true; 141*40fe15e0SLoGin } else { 142*40fe15e0SLoGin return ALLOW_ALLOC_ATOMIC.load(Ordering::SeqCst); 143*40fe15e0SLoGin } 144*40fe15e0SLoGin } 145*40fe15e0SLoGin 146*40fe15e0SLoGin /// 允许动态内存分配 147*40fe15e0SLoGin pub fn enable_alloc(&self) { 148*40fe15e0SLoGin ALLOW_ALLOC_ATOMIC.store(true, Ordering::SeqCst); 149*40fe15e0SLoGin unsafe { 150*40fe15e0SLoGin ALLOW_ALLOC_BOOL = true; 151*40fe15e0SLoGin } 152*40fe15e0SLoGin } 153*40fe15e0SLoGin 154fb6c29d0Slogin /// 将s这个utf8字符串,转换为ascii字符串 155fb6c29d0Slogin /// @param s 待转换的utf8字符串 156fb6c29d0Slogin /// @return Vec<u8> 转换结束后的Ascii字符串 157fb6c29d0Slogin pub fn __utf8_to_ascii(&self, s: &str) -> Vec<u8> { 158fb6c29d0Slogin let mut ascii_str: Vec<u8> = Vec::with_capacity(s.len() + 1); 159fb6c29d0Slogin for byte in s.bytes() { 160fb6c29d0Slogin match byte { 161fb6c29d0Slogin 0..=127 => { 162fb6c29d0Slogin ascii_str.push(byte); 163fb6c29d0Slogin } 164fb6c29d0Slogin _ => {} 165fb6c29d0Slogin } 166fb6c29d0Slogin } 167fb6c29d0Slogin ascii_str.push(b'\0'); 168fb6c29d0Slogin return ascii_str; 169fb6c29d0Slogin } 170*40fe15e0SLoGin 171*40fe15e0SLoGin fn __write_string_on_stack(&self, s: &str) { 172*40fe15e0SLoGin let s_len = s.len(); 173*40fe15e0SLoGin assert!(s_len < 1024, "s_len is too long"); 174*40fe15e0SLoGin let mut str_to_print: [u8; 1024] = [0; 1024]; 175*40fe15e0SLoGin let mut i = 0; 176*40fe15e0SLoGin for byte in s.bytes() { 177*40fe15e0SLoGin match byte { 178*40fe15e0SLoGin 0..=127 => { 179*40fe15e0SLoGin str_to_print[i] = byte; 180*40fe15e0SLoGin i += 1; 181*40fe15e0SLoGin } 182*40fe15e0SLoGin _ => {} 183*40fe15e0SLoGin } 184*40fe15e0SLoGin } 185*40fe15e0SLoGin str_to_print[i] = b'\0'; 186*40fe15e0SLoGin unsafe { 187*40fe15e0SLoGin printk_color(WHITE, BLACK, str_to_print.as_ptr() as *const c_char); 188*40fe15e0SLoGin } 189*40fe15e0SLoGin } 190*40fe15e0SLoGin 191*40fe15e0SLoGin fn __write_string_color_on_stack(&self, fr_color: u32, bk_color: u32, s: &str) { 192*40fe15e0SLoGin let s_len = s.len(); 193*40fe15e0SLoGin assert!(s_len < 1024, "s_len is too long"); 194*40fe15e0SLoGin let mut str_to_print: [u8; 1024] = [0; 1024]; 195*40fe15e0SLoGin let mut i = 0; 196*40fe15e0SLoGin for byte in s.bytes() { 197*40fe15e0SLoGin match byte { 198*40fe15e0SLoGin 0..=127 => { 199*40fe15e0SLoGin str_to_print[i] = byte; 200*40fe15e0SLoGin i += 1; 201*40fe15e0SLoGin } 202*40fe15e0SLoGin _ => {} 203*40fe15e0SLoGin } 204*40fe15e0SLoGin } 205*40fe15e0SLoGin str_to_print[i] = b'\0'; 206*40fe15e0SLoGin unsafe { 207*40fe15e0SLoGin printk_color(fr_color, bk_color, str_to_print.as_ptr() as *const c_char); 208*40fe15e0SLoGin } 209*40fe15e0SLoGin } 210fb6c29d0Slogin } 211fb6c29d0Slogin 212fb6c29d0Slogin /// 为Printk Writer实现core::fmt::Write, 使得能够借助Rust自带的格式化组件,格式化字符并输出 213fb6c29d0Slogin impl fmt::Write for PrintkWriter { 214fb6c29d0Slogin fn write_str(&mut self, s: &str) -> fmt::Result { 215fb6c29d0Slogin self.__write_string(s); 216fb6c29d0Slogin Ok(()) 217fb6c29d0Slogin } 218fb6c29d0Slogin } 219fb6c29d0Slogin 220fb6c29d0Slogin #[doc(hidden)] 221fb6c29d0Slogin pub fn __printk(args: fmt::Arguments) { 222fb6c29d0Slogin use fmt::Write; 223fb6c29d0Slogin PrintkWriter.write_fmt(args).unwrap(); 224fb6c29d0Slogin } 225