Skip to main content

kernel/kprint/
log_entry.rs

1// SPDX-License-Identifier: GPL-3.0-only
2//! Metadata for log entries (Log Entry Header and Log Level definitions)
3//!
4//! Authors: MarioS271
5
6use crate::lib::macros::bitflags::bitflags;
7use crate::lib::types::packed_u8::PackedU8;
8
9/// Header of one ring buffer log entry, after it comes `text_len` bytes of text
10#[derive(Copy, Clone)]
11#[repr(C, packed)]
12pub struct LogEntryHeader {
13    pub seq: u64,
14    pub ts_nsec: u64,
15    pub text_len: u16,
16    /// Upper 5 bit are flags, lower 3 are log level
17    pub flags_and_level: PackedU8,
18}
19impl LogEntryHeader {
20    pub const FLAGS_START_BIT: u8 = 0;
21    pub const FLAGS_NUM_BITS: u8 = 5;
22    pub const LEVEL_START_BIT: u8 = 5;
23    pub const LEVEL_NUM_BITS: u8 = 3;
24}
25
26/// Struct which represents the kernel log levels
27#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
28#[repr(u8)]
29pub enum LogLevel {
30    Emergency = 0,
31    Alert = 1,
32    Critical = 2,
33    Error = 3,
34    Warn = 4,
35    Notice = 5,
36    Info = 6,
37    Debug = 7
38}
39impl LogLevel {
40    /// Checks if a [`u8`] is a valid log level
41    pub const fn is_valid_loglevel(value: u8) -> bool {
42        use LogLevel::*;
43        if value >= Emergency as u8 && value <= Debug as u8 {
44            return true;
45        }
46        false
47    }
48
49    /// Constructs a new [`LogLevel`] from a [`u8`]
50    pub const fn from_u8(value: u8) -> Option<Self> {
51        use LogLevel::*;
52        if !Self::is_valid_loglevel(value) {
53            return None;
54        }
55        Some(match value {
56            0 => Emergency,
57            1 => Alert,
58            2 => Critical,
59            3 => Error,
60            4 => Warn,
61            5 => Notice,
62            6 => Info,
63            7 => Debug,
64            _ => unreachable!()
65        })
66    }
67
68    /// Returns the starting letter for that log level as a byte
69    pub const fn get_letter(&self) -> u8 {
70        use LogLevel::*;
71        match self {
72            Emergency => b'!',
73            Alert => b'A',
74            Critical => b'C',
75            Error => b'E',
76            Warn => b'W',
77            Notice => b'N',
78            Info => b'I',
79            Debug => b'D'
80        }
81    }
82
83    /// Returns a color for that log level in the format of `00 RR GG BB`
84    pub const fn get_color(&self) -> u32 {
85        use LogLevel::*;
86        match self {
87            Emergency => 0x00ff00aa,
88            Alert => 0x00ffaa00,
89            Critical => 0x008a00ff,
90            Error => 0x00ff0000,
91            Warn => 0x00ffff00,
92            Notice => 0x0000ffaa,
93            Info => 0x0000ff00,
94            Debug => 0x000000ff
95        }
96    }
97}
98
99bitflags!(
100    /// Bitflags to further define log entries (does it have a line feed? is it just a part of a full log?)
101    LogFlags, u8
102);
103impl LogFlags {
104    pub const NEWLINE: Self = Self(1 << 0);
105    pub const CONT: Self = Self(1 << 1);
106}