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