bootloader_x86_64_common/
logger.rs1use crate::{framebuffer::FrameBufferWriter, serial::SerialPort};
2use bootloader_api::info::FrameBufferInfo;
3use conquer_once::spin::OnceCell;
4use core::fmt::Write;
5use spinning_top::Spinlock;
6
7pub static LOGGER: OnceCell<LockedLogger> = OnceCell::uninit();
9
10pub struct LockedLogger {
12 framebuffer: Option<Spinlock<FrameBufferWriter>>,
13 serial: Option<Spinlock<SerialPort>>,
14}
15
16impl LockedLogger {
17 pub fn new(
19 framebuffer: &'static mut [u8],
20 info: FrameBufferInfo,
21 frame_buffer_logger_status: bool,
22 serial_logger_status: bool,
23 ) -> Self {
24 let framebuffer = match frame_buffer_logger_status {
25 true => Some(Spinlock::new(FrameBufferWriter::new(framebuffer, info))),
26 false => None,
27 };
28
29 let serial = match serial_logger_status {
30 true => Some(Spinlock::new(unsafe { SerialPort::init() })),
31 false => None,
32 };
33
34 LockedLogger {
35 framebuffer,
36 serial,
37 }
38 }
39
40 pub unsafe fn force_unlock(&self) {
45 if let Some(framebuffer) = &self.framebuffer {
46 unsafe { framebuffer.force_unlock() };
47 }
48 if let Some(serial) = &self.serial {
49 unsafe { serial.force_unlock() };
50 }
51 }
52}
53
54impl log::Log for LockedLogger {
55 fn enabled(&self, _metadata: &log::Metadata) -> bool {
56 true
57 }
58
59 fn log(&self, record: &log::Record) {
60 if let Some(framebuffer) = &self.framebuffer {
61 let mut framebuffer = framebuffer.lock();
62 writeln!(framebuffer, "{:5}: {}", record.level(), record.args()).unwrap();
63 }
64 if let Some(serial) = &self.serial {
65 let mut serial = serial.lock();
66 writeln!(serial, "{:5}: {}", record.level(), record.args()).unwrap();
67 }
68 }
69
70 fn flush(&self) {}
71}