xref: /DragonOS/kernel/src/libs/printk.rs (revision 40fe15e0953f989ccfeb74826d61621d43dea6bb)
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