kernel/kprint/
kernel_writer.rs1use crate::kprint::log_entry::{LogFlags, LogLevel};
8use crate::kprint::receivers::KPrintReceiver;
9use crate::kprint::state::{KPrintState, LogTargets};
10use crate::lib::sync::irq_mutex::IrqMutexGuard;
11use crate::state::kstate::KSTATE;
12use core::fmt::Write;
13
14pub const WRITE_BUFFER_SIZE: usize = 1 << 11;
16
17pub struct KernelWriter {
22 state: IrqMutexGuard<'static, KPrintState>,
23 buffer: [u8; WRITE_BUFFER_SIZE],
24 text_len: usize,
25 log_level: LogLevel,
26 log_flags: LogFlags
27}
28impl KernelWriter {
29 pub fn lock(log_level: LogLevel, log_flags: LogFlags) -> Self {
31 Self {
32 state: KSTATE.kprint.lock(),
33 buffer: [0u8; WRITE_BUFFER_SIZE],
34 text_len: 0,
35 log_level,
36 log_flags
37 }
38 }
39}
40impl Write for KernelWriter {
41 fn write_str(&mut self, string: &str) -> core::fmt::Result {
43 let bytes = string.as_bytes();
44 let remaining = WRITE_BUFFER_SIZE - self.text_len;
45 let to_copy = bytes.len().min(remaining);
46
47 self.buffer[self.text_len..self.text_len + to_copy]
48 .copy_from_slice(&bytes[..to_copy]);
49
50 self.text_len += to_copy;
51 Ok(())
52 }
53}
54impl Drop for KernelWriter {
55 fn drop(&mut self) {
57 if self.log_flags.contains(LogFlags::NEWLINE) {
58 if self.text_len < WRITE_BUFFER_SIZE {
59 self.buffer[self.text_len] = b'\n';
60 self.text_len += 1;
61 } else {
62 self.buffer[WRITE_BUFFER_SIZE - 1] = b'\n';
63 }
64 }
65
66 let header = self.state.ring_buffer.write_entry(
67 self.log_level,
68 self.log_flags,
69 &self.buffer[..self.text_len]
70 );
71
72 let text= unsafe {
75 core::str::from_utf8_unchecked(&self.buffer[..self.text_len])
76 };
77
78 let log_targets = KSTATE.kprint.config().log_targets();
79
80 if log_targets.contains(LogTargets::UART) {
81 super::receivers::uart::UartReceiver::receive(
82 &mut *self.state,
83 &header,
84 text
85 );
86 }
87 if log_targets.contains(LogTargets::BASIC_FB) {
88 super::receivers::basic_fb::BasicFbReceiver::receive(
89 &mut *self.state,
90 &header,
91 text
92 );
93 }
94 }
95}