forked from rust-osdev/bootloader
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlogger.rs
More file actions
71 lines (62 loc) · 2.14 KB
/
Copy pathlogger.rs
File metadata and controls
71 lines (62 loc) · 2.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
use crate::{framebuffer::FrameBufferWriter, serial::SerialPort};
use bootloader_api::info::FrameBufferInfo;
use conquer_once::spin::OnceCell;
use core::fmt::Write;
use spinning_top::Spinlock;
/// The global logger instance used for the `log` crate.
pub static LOGGER: OnceCell<LockedLogger> = OnceCell::uninit();
/// A logger instance protected by a spinlock.
pub struct LockedLogger {
framebuffer: Option<Spinlock<FrameBufferWriter>>,
serial: Option<Spinlock<SerialPort>>,
}
impl LockedLogger {
/// Create a new instance that logs to the given framebuffer.
pub fn new(
framebuffer: &'static mut [u8],
info: FrameBufferInfo,
frame_buffer_logger_status: bool,
serial_logger_status: bool,
) -> Self {
let framebuffer = match frame_buffer_logger_status {
true => Some(Spinlock::new(FrameBufferWriter::new(framebuffer, info))),
false => None,
};
let serial = match serial_logger_status {
true => Some(Spinlock::new(unsafe { SerialPort::init() })),
false => None,
};
LockedLogger {
framebuffer,
serial,
}
}
/// Force-unlocks the logger to prevent a deadlock.
///
/// ## Safety
/// This method is not memory safe and should be only used when absolutely necessary.
pub unsafe fn force_unlock(&self) {
if let Some(framebuffer) = &self.framebuffer {
unsafe { framebuffer.force_unlock() };
}
if let Some(serial) = &self.serial {
unsafe { serial.force_unlock() };
}
}
}
impl log::Log for LockedLogger {
fn enabled(&self, _metadata: &log::Metadata) -> bool {
true
}
fn log(&self, record: &log::Record) {
if let Some(framebuffer) = &self.framebuffer {
let mut framebuffer = framebuffer.lock();
writeln!(framebuffer, "{:5}: {}", record.level(), record.args()).unwrap();
}
if let Some(serial) = &self.serial {
let mut serial = serial.lock();
writeln!(serial, "{:5}: {}", record.level(), record.args()).unwrap();
}
}
fn flush(&self) {}
}