From 7fe1b7d1f53d2ef8d7a98c05d61df7a1d226ac28 Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Tue, 19 Mar 2019 00:51:33 -0700 Subject: [PATCH] Add temporary log output Currently the kernel idle process is an infinite loop printing logs, with no locking. --- src/kernel/log.cpp | 28 ++++++++++++++ src/kernel/log.h | 1 + src/kernel/main.cpp | 1 + src/libraries/kutil/include/kutil/logger.h | 15 ++++++++ src/libraries/kutil/logger.cpp | 43 ++++++++++++++-------- 5 files changed, 73 insertions(+), 15 deletions(-) diff --git a/src/kernel/log.cpp b/src/kernel/log.cpp index 69eaafb..94d6204 100644 --- a/src/kernel/log.cpp +++ b/src/kernel/log.cpp @@ -1,5 +1,6 @@ #include "kutil/constexpr_hash.h" #include "kutil/memory.h" +#include "console.h" #include "log.h" namespace logs { @@ -13,6 +14,33 @@ static log::logger g_logger(log_buffer, sizeof(log_buffer)); #include "log_areas.inc" #undef LOG +static const uint8_t level_colors[] = {0x07, 0x07, 0x0f, 0x0b, 0x09}; + +static void +output_log(log::level severity, log::area_t area, const char *message) +{ +} + +void +output_logs() +{ + uint8_t buffer[257]; + auto *ent = reinterpret_cast(buffer); + auto *cons = console::get(); + + while (true) { + if(g_logger.get_entry(buffer, sizeof(buffer))) { + buffer[ent->bytes] = 0; + cons->set_color(level_colors[static_cast(ent->severity)]); + cons->printf("%9s %8s: %s\n", + g_logger.area_name(ent->area), + g_logger.level_name(ent->severity), + ent->message); + cons->set_color(); + } + } +} + void init() { new (&g_logger) log::logger(log_buffer, sizeof(log_buffer)); diff --git a/src/kernel/log.h b/src/kernel/log.h index be48901..4a4f7a4 100644 --- a/src/kernel/log.h +++ b/src/kernel/log.h @@ -11,6 +11,7 @@ namespace logs { #undef LOG void init(); +void output_logs(); } // namespace logs diff --git a/src/kernel/main.cpp b/src/kernel/main.cpp index f768b50..a9cf843 100644 --- a/src/kernel/main.cpp +++ b/src/kernel/main.cpp @@ -138,4 +138,5 @@ kernel_main(kernel_args *header) } sched->start(); + logs::output_logs(); } diff --git a/src/libraries/kutil/include/kutil/logger.h b/src/libraries/kutil/include/kutil/logger.h index 6efe0df..6d8506e 100644 --- a/src/libraries/kutil/include/kutil/logger.h +++ b/src/libraries/kutil/include/kutil/logger.h @@ -55,6 +55,21 @@ public: va_end(args); } + struct entry + { + uint8_t bytes; + area_t area; + level severity; + uint8_t sequence; + char message[0]; + }; + + /// Get the next log entry from the buffer + /// \arg buffer The buffer to copy the log message into + /// \arg size Size of the passed-in buffer, in bytes + /// \returns Number of bytes copied into the buffer + size_t get_entry(void *buffer, size_t size); + private: friend void debug(area_t area, const char *fmt, ...); friend void info (area_t area, const char *fmt, ...); diff --git a/src/libraries/kutil/logger.cpp b/src/libraries/kutil/logger.cpp index b15a173..24efc71 100644 --- a/src/libraries/kutil/logger.cpp +++ b/src/libraries/kutil/logger.cpp @@ -9,17 +9,8 @@ namespace log { using kutil::memset; using kutil::memcpy; -struct entry_header -{ - uint8_t bytes; - uint8_t area; - uint8_t level; - uint8_t sequence; - char message[0]; -}; - logger *logger::s_log = nullptr; -const char *logger::s_level_names[] = {"debug", " info", " warn", "error", "fatal"}; +const char *logger::s_level_names[] = {"", "debug", " info", " warn", "error", "fatal"}; logger::logger() : m_buffer(nullptr, 0), @@ -73,18 +64,18 @@ void logger::output(level severity, area_t area, const char *fmt, va_list args) { uint8_t buffer[256]; - entry_header *header = reinterpret_cast(buffer); - header->bytes = sizeof(entry_header); + entry *header = reinterpret_cast(buffer); + header->bytes = sizeof(entry); header->area = area; - header->level = static_cast(severity); + header->severity = severity; header->sequence = m_sequence++; header->bytes += - vsnprintf(header->message, sizeof(buffer) - sizeof(entry_header), fmt, args); + vsnprintf(header->message, sizeof(buffer) - sizeof(entry), fmt, args); uint8_t *out; size_t n = m_buffer.reserve(header->bytes, reinterpret_cast(&out)); - if (n < sizeof(entry_header)) { + if (n < sizeof(entry)) { m_buffer.commit(0); // Cannot even write the header, abort return; } @@ -96,6 +87,28 @@ logger::output(level severity, area_t area, const char *fmt, va_list args) m_buffer.commit(n); } +size_t +logger::get_entry(void *buffer, size_t size) +{ + void *out; + size_t out_size = m_buffer.get_block(&out); + entry *ent = reinterpret_cast(out); + if (out_size == 0) + return 0; + + kassert(out_size >= sizeof(entry), "Couldn't read a full entry"); + if (out_size < sizeof(entry)) + return 0; + + kassert(size >= ent->bytes, "Didn't pass a big enough buffer"); + if (size < ent->bytes) + return 0; + + memcpy(buffer, out, ent->bytes); + m_buffer.consume(ent->bytes); + return ent->bytes; +} + #define LOG_LEVEL_FUNCTION(name) \ void name (area_t area, const char *fmt, ...) { \ logger *l = logger::s_log; \