1use super::ringbuffer::Ringbuffer;
7use crate::kprint::log_entry::LogLevel;
8use crate::lib::macros::bitflags::bitflags;
9use crate::lib::sync::irq_mutex::{IrqMutex, IrqMutexGuard};
10use core::sync::atomic::{AtomicU8, Ordering};
11
12#[repr(align(64))]
15pub struct KPrint {
16 lockable: IrqMutex<KPrintState>,
17 config: KPrintConfig
18}
19impl KPrint {
20 pub const fn new() -> Self {
23 Self {
24 lockable: IrqMutex::new(KPrintState::new()),
25 config: KPrintConfig::new()
26 }
27 }
28
29 pub fn init(&self) {
31 self.config.init();
32 }
33
34 pub fn lock(&self) -> IrqMutexGuard<'_, KPrintState> {
36 self.lockable.lock()
37 }
38
39 pub fn config(&self) -> &KPrintConfig {
41 &self.config
42 }
43}
44
45pub struct KPrintState {
48 pub ring_buffer: Ringbuffer,
49 pub basic_fb_state: BasicFbState
50}
51impl KPrintState {
52 pub const fn new() -> Self {
55 Self {
56 ring_buffer: Ringbuffer::new(),
57 basic_fb_state: BasicFbState::new()
58 }
59 }
60}
61
62#[repr(align(64))]
64pub struct KPrintConfig {
65 max_log_level: AtomicU8,
66 log_targets: AtomicU8
67}
68impl KPrintConfig {
69 pub const fn new() -> Self {
74 Self {
75 max_log_level: AtomicU8::new(0),
76 log_targets: AtomicU8::new(0)
77 }
78 }
79
80 pub fn init(&self) {
82 self.max_log_level.store(crate::config::MAX_LOG_LEVEL as u8, Ordering::Release);
83 self.log_targets.store(crate::config::DEFAULT_LOG_TARGETS.as_u8(), Ordering::Release);
84 }
85
86 pub fn set_max_log_level(&self, log_level: LogLevel) {
88 self.max_log_level.store(log_level as u8, Ordering::Release);
89 }
90
91 pub fn set_log_targets(&self, log_targets: LogTargets) {
93 self.log_targets.store(log_targets.as_u8(), Ordering::Release);
94 }
95
96 pub fn max_log_level(&self) -> LogLevel {
98 LogLevel::from_u8(self.max_log_level.load(Ordering::Relaxed)).unwrap_or(crate::config::MAX_LOG_LEVEL)
99 }
100
101 pub fn log_targets(&self) -> LogTargets {
103 LogTargets::from_u8(self.log_targets.load(Ordering::Acquire))
104 }
105}
106
107bitflags!(
108 LogTargets, u8
110);
111impl LogTargets {
112 pub const ALL: Self = Self(u8::MAX);
113 pub const UART: Self = Self(1 << 0);
114 pub const BASIC_FB: Self = Self(1 << 1);
115
116 pub fn is_valid_log_target(value: u8) -> bool {
118 if value == Self::UART.as_u8()
119 || value == Self::BASIC_FB.as_u8()
120 { return true; }
121 false
122 }
123}
124
125pub struct BasicFbState {
127 pub cursor_x: usize,
128 pub cursor_y: usize
129}
130impl BasicFbState {
131 pub const fn new() -> Self {
133 Self {
134 cursor_x: 0,
135 cursor_y: 0
136 }
137 }
138}