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