From 9f5fb547f7c26a4bc357e876987174b7b2c8384c Mon Sep 17 00:00:00 2001 From: apio Date: Wed, 30 Nov 2022 13:29:28 +0100 Subject: [PATCH] Add logging system :) --- kernel/CMakeLists.txt | 1 + kernel/src/Log.cpp | 115 +++++++++++++++++++++++++++++++ kernel/src/Log.h | 29 ++++++++ kernel/src/boot/Init.cpp | 6 +- kernel/src/main.cpp | 17 +++-- kernel/src/video/TextConsole.cpp | 10 +++ kernel/src/video/TextConsole.h | 2 + 7 files changed, 173 insertions(+), 7 deletions(-) create mode 100644 kernel/src/Log.cpp create mode 100644 kernel/src/Log.h diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index f65760a5..e23e42fd 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -1,5 +1,6 @@ set(SOURCES src/main.cpp + src/Log.cpp src/video/Framebuffer.cpp src/video/TextConsole.cpp src/memory/MemoryManager.cpp diff --git a/kernel/src/Log.cpp b/kernel/src/Log.cpp new file mode 100644 index 00000000..1a7c34c9 --- /dev/null +++ b/kernel/src/Log.cpp @@ -0,0 +1,115 @@ +#include "Log.h" +#include "arch/Serial.h" +#include "arch/Timer.h" +#include "video/TextConsole.h" +#include + +static bool g_debug_enabled = true; +static bool g_serial_enabled = true; +static bool g_text_console_enabled = false; + +static constexpr u32 BLACK = 0xff000000; +static constexpr u32 WHITE = 0xffffffff; +static constexpr u32 YELLOW = 0xffffff00; +static constexpr u32 RED = 0xffff0000; + +static Result log_serial(LogLevel, const char* format, va_list origin) +{ + va_list ap; + va_copy(ap, origin); + + TRY(Serial::printf("[%6zu.%.6zu] ", Timer::ticks(), Timer::ticks_us() - (Timer::ticks() * 1000000))); + + TRY(cstyle_format( + format, + [](char c, void*) -> Result { + Serial::putchar(c); + return {}; + }, + nullptr, ap)); + + Serial::putchar('\n'); + + va_end(ap); + + return {}; +} + +static Result log_text_console(LogLevel level, const char* format, va_list origin) +{ + va_list ap; + va_copy(ap, origin); + + u32 original_foreground = TextConsole::foreground(); + u32 original_background = TextConsole::background(); + + TextConsole::set_background(BLACK); + + if (level == LogLevel::Warn) TextConsole::set_foreground(YELLOW); + else if (level == LogLevel::Error) + TextConsole::set_foreground(RED); + else + TextConsole::set_foreground(WHITE); + + TRY(cstyle_format( + format, + [](char c, void*) -> Result { + TextConsole::putchar(c); + return {}; + }, + nullptr, ap)); + + TextConsole::putchar('\n'); + + TextConsole::set_background(original_background); + + TextConsole::set_foreground(original_foreground); + + va_end(ap); + + return {}; +} + +Result vlog(LogLevel level, const char* format, va_list ap) +{ + if (!g_debug_enabled && level == LogLevel::Debug) return {}; + + if (g_serial_enabled) TRY(log_serial(level, format, ap)); + if (g_text_console_enabled) TRY(log_text_console(level, format, ap)); + + return {}; +} + +Result log(LogLevel level, const char* format, ...) +{ + va_list ap; + va_start(ap, format); + + TRY(vlog(level, format, ap)); + + va_end(ap); + + return {}; +} + +void setup_log(bool enable_debug, bool enable_serial, bool enable_text_console) +{ + g_debug_enabled = enable_debug; + g_serial_enabled = enable_serial; + g_text_console_enabled = enable_text_console; +} + +bool log_debug_enabled() +{ + return g_debug_enabled; +} + +bool log_serial_enabled() +{ + return g_serial_enabled; +} + +bool log_text_console_enabled() +{ + return g_text_console_enabled; +} \ No newline at end of file diff --git a/kernel/src/Log.h b/kernel/src/Log.h new file mode 100644 index 00000000..6250a758 --- /dev/null +++ b/kernel/src/Log.h @@ -0,0 +1,29 @@ +#pragma once +#include +#include + +enum class LogLevel +{ + Debug, + Info, + Warn, + Error, +}; + +Result vlog(LogLevel level, const char* format, va_list ap); +Result log(LogLevel level, const char* format, ...); + +void setup_log(bool enable_debug, bool enable_serial, bool enable_text_console); +bool log_debug_enabled(); +bool log_serial_enabled(); +bool log_text_console_enabled(); + +#define kdbgln(...) log(LogLevel::Debug, __VA_ARGS__) +#define kinfoln(...) log(LogLevel::Info, __VA_ARGS__) +#define kwarnln(...) log(LogLevel::Warn, __VA_ARGS__) +#define kerrorln(...) log(LogLevel::Error, __VA_ARGS__) + +#define try_kdbgln(...) TRY(log(LogLevel::Debug, __VA_ARGS__)) +#define try_kinfoln(...) TRY(log(LogLevel::Info, __VA_ARGS__)) +#define try_kwarnln(...) TRY(log(LogLevel::Warn, __VA_ARGS__)) +#define try_kerrorln(...) TRY(log(LogLevel::Error, __VA_ARGS__)) \ No newline at end of file diff --git a/kernel/src/boot/Init.cpp b/kernel/src/boot/Init.cpp index ab7a0ee1..291cdc93 100644 --- a/kernel/src/boot/Init.cpp +++ b/kernel/src/boot/Init.cpp @@ -1,4 +1,5 @@ #include "boot/Init.h" +#include "Log.h" #include "arch/CPU.h" #include "arch/Serial.h" #include "boot/bootboot.h" @@ -23,9 +24,12 @@ void Init::early_init() CPU::disable_interrupts(); Framebuffer::init(); + + setup_log(log_debug_enabled(), log_serial_enabled(), true); + MemoryManager::init(); CPU::platform_init(); - check(MemoryManager::protect_kernel_sections().has_value()); + MemoryManager::protect_kernel_sections().release_value(); } \ No newline at end of file diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 24b3bcd0..25d8c2fc 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -1,3 +1,4 @@ +#include "Log.h" #include "arch/CPU.h" #include "arch/MMU.h" #include "arch/Serial.h" @@ -36,10 +37,14 @@ Result init() TextConsole::set_foreground(0xff000055); TextConsole::set_background(0xff88ff00); - TextConsole::printf("Hello from Moon for the %s architecture!", CPU::platform_string()); + TextConsole::printf("Hello from Moon for the %s architecture!\n", CPU::platform_string()); Timer::init(); + kinfoln("Hello, world!"); + kwarnln("THIS IS A WARNING"); + kerrorln("ERROR: Please do something."); + CPU::platform_finish_init(); CPU::enable_interrupts(); @@ -54,17 +59,17 @@ Result init() char buffer[64]; to_dynamic_unit(MemoryManager::free(), buffer, sizeof(buffer)); - Serial::printf("Free memory: %s\n", buffer); + kinfoln("Free memory: %s", buffer); to_dynamic_unit(MemoryManager::used(), buffer, sizeof(buffer)); - Serial::printf("Used memory: %s\n", buffer); + kinfoln("Used memory: %s", buffer); to_dynamic_unit(MemoryManager::reserved(), buffer, sizeof(buffer)); - Serial::printf("Reserved memory: %s\n", buffer); + kinfoln("Reserved memory: %s", buffer); while (1) { - while ((Timer::ticks_ms() - start) < 20) { CPU::wait_for_interrupt(); } + while ((Timer::ticks_ms() - start) < 100) { CPU::wait_for_interrupt(); } start = Timer::ticks_ms(); - Serial::printf("%8zu milliseconds have passed!\n", start); + kdbgln("%8zu milliseconds have passed!", start); } return {}; diff --git a/kernel/src/video/TextConsole.cpp b/kernel/src/video/TextConsole.cpp index 6d30e557..5e6b46f3 100644 --- a/kernel/src/video/TextConsole.cpp +++ b/kernel/src/video/TextConsole.cpp @@ -122,6 +122,16 @@ namespace TextConsole g_background_color = color; } + u32 foreground() + { + return g_foreground_color; + } + + u32 background() + { + return g_background_color; + } + void move_to(u32 x, u32 y) { g_x_position = x; diff --git a/kernel/src/video/TextConsole.h b/kernel/src/video/TextConsole.h index 21e6de6b..62dfb51f 100644 --- a/kernel/src/video/TextConsole.h +++ b/kernel/src/video/TextConsole.h @@ -9,6 +9,8 @@ namespace TextConsole void putchar(char c); void set_foreground(u32 color); void set_background(u32 color); + u32 foreground(); + u32 background(); void move_to(u32 x, u32 y); void print(const char* str); void println(const char* str);