diff --git a/definitions/memory_layout.yaml b/definitions/memory_layout.yaml index dd42627..bf3072b 100644 --- a/definitions/memory_layout.yaml +++ b/definitions/memory_layout.yaml @@ -24,3 +24,6 @@ - name: buffers size: 64G + +- name: logs + size: 2G diff --git a/src/kernel/kernel_main.cpp b/src/kernel/kernel_main.cpp index 767f9ef..f35a0fb 100644 --- a/src/kernel/kernel_main.cpp +++ b/src/kernel/kernel_main.cpp @@ -36,9 +36,8 @@ kernel_main(bootproto::args *args) panic::install(args->panic_handler, args->symbol_table); } - logger_init(); - cpu_data *cpu = bsp_early_init(); + mem::initialize(*args); kassert(args->magic == bootproto::args_magic, "Bad kernel args magic number"); @@ -51,7 +50,6 @@ kernel_main(bootproto::args *args) disable_legacy_pic(); - mem::initialize(*args); bsp_late_init(); diff --git a/src/kernel/logger.cpp b/src/kernel/logger.cpp index 3e7b8a8..fd6cc21 100644 --- a/src/kernel/logger.cpp +++ b/src/kernel/logger.cpp @@ -6,15 +6,9 @@ #include "assert.h" #include "logger.h" -#include "memory.h" #include "objects/system.h" #include "objects/thread.h" -static constexpr bool j6_debugcon_enable = false; -static constexpr uint16_t j6_debugcon_port = 0x6600; - -static uint8_t log_buffer[log::logger::log_pages * arch::frame_size]; - // The logger is initialized _before_ global constructors are called, // so that we can start log output immediately. Keep its constructor // from being called here so as to not overwrite the previous initialization. @@ -25,36 +19,16 @@ log::logger &g_logger = __g_logger_storage.value; namespace log { logger *logger::s_log = nullptr; -const char *logger::s_level_names[] = {"", "fatal", "error", "warn", "info", "verbose", "spam"}; -const char *logger::s_area_names[] = { -#define LOG(name, lvl) #name , -#include -#undef LOG - nullptr -}; - -inline void -debug_out(const char *msg, size_t size) -{ - asm ( "rep outsb;" :: "c"(size), "d"(j6_debugcon_port), "S"(msg) ); -} - -inline void -debug_newline() -{ - static const char *newline = "\r\n"; - asm ( "rep outsb;" :: "c"(2), "d"(j6_debugcon_port), "S"(newline) ); -} logger::logger() : - m_buffer(nullptr, 0) + m_buffer {nullptr, 0} { memset(&m_levels, 0, sizeof(m_levels)); s_log = this; } -logger::logger(uint8_t *buffer, size_t size) : - m_buffer(buffer, size) +logger::logger(util::buffer data) : + m_buffer {data.pointer, data.count} { memset(&m_levels, 0, sizeof(m_levels)); s_log = this; @@ -70,13 +44,6 @@ logger::output(level severity, logs area, const char *fmt, va_list args) { char buffer[256]; - if constexpr (j6_debugcon_enable) { - size_t dlen = util::format({buffer, sizeof(buffer)}, "%7s %7s| ", - s_area_names[static_cast(area)], - s_level_names[static_cast(severity)]); - debug_out(buffer, dlen); - } - entry *header = reinterpret_cast(buffer); header->bytes = sizeof(entry); header->area = area; @@ -86,11 +53,6 @@ logger::output(level severity, logs area, const char *fmt, va_list args) header->message[mlen] = 0; header->bytes += mlen + 1; - if constexpr (j6_debugcon_enable) { - debug_out(header->message, mlen); - debug_newline(); - } - util::scoped_lock lock {m_lock}; uint8_t *out; @@ -103,7 +65,7 @@ logger::output(level severity, logs area, const char *fmt, va_list args) memcpy(out, buffer, n); m_buffer.commit(n); - m_event.signal(1); + m_waiting.clear(); } size_t @@ -115,7 +77,7 @@ logger::get_entry(void *buffer, size_t size) size_t out_size = m_buffer.get_block(&out); if (out_size == 0 || out == 0) { lock.release(); - m_event.wait(); + m_waiting.wait(); lock.reacquire(); out_size = m_buffer.get_block(&out); @@ -168,9 +130,3 @@ void fatal(logs area, const char *fmt, ...) } } // namespace log - - -void logger_init() -{ - new (&g_logger) log::logger(log_buffer, sizeof(log_buffer)); -} diff --git a/src/kernel/logger.h b/src/kernel/logger.h index bab2b2e..b788111 100644 --- a/src/kernel/logger.h +++ b/src/kernel/logger.h @@ -6,6 +6,7 @@ #include #include +#include #include #include "objects/event.h" @@ -19,6 +20,9 @@ enum class logs : uint8_t { namespace log { +/// Size of the log ring buffer +inline constexpr unsigned log_pages = 16; + enum class level : uint8_t { silent, fatal, error, warn, info, verbose, spam, max }; @@ -29,26 +33,16 @@ constexpr unsigned areas_count = class logger { public: - /// Size of the log ring buffer - static constexpr unsigned log_pages = 16; - /// Default constructor. Creates a logger without a backing store. logger(); /// Constructor. Logs are written to the given buffer. /// \arg buffer Buffer to which logs are written - /// \arg size Size of `buffer`, in bytes - logger(uint8_t *buffer, size_t size); + logger(util::buffer buffer); /// Get the default logger. inline logger & get() { return *s_log; } - /// Get the registered name for a given area - inline const char * area_name(logs area) const { return s_area_names[static_cast(area)]; } - - /// Get the name of a level - inline const char * level_name(level l) const { return s_level_names[static_cast(l)]; } - /// Write to the log /// \arg severity The severity of the message /// \arg area The log area to write to @@ -100,7 +94,7 @@ private: return m_levels[static_cast(area)]; } - obj::event m_event; + wait_queue m_waiting; level m_levels[areas_count]; @@ -108,8 +102,6 @@ private: util::spinlock m_lock; static logger *s_log; - static const char *s_area_names[areas_count+1]; - static const char *s_level_names[static_cast(level::max)]; }; void spam (logs area, const char *fmt, ...); @@ -119,8 +111,6 @@ void warn (logs area, const char *fmt, ...); void error (logs area, const char *fmt, ...); void fatal (logs area, const char *fmt, ...); -extern log::logger &g_logger; - } // namespace log -void logger_init(); +extern log::logger &g_logger; diff --git a/src/kernel/memory_bootstrap.cpp b/src/kernel/memory_bootstrap.cpp index 6843bc0..3bb5139 100644 --- a/src/kernel/memory_bootstrap.cpp +++ b/src/kernel/memory_bootstrap.cpp @@ -40,6 +40,9 @@ frame_allocator &g_frame_allocator = __g_frame_allocator_storage.value; static util::no_construct __g_kernel_heap_area_storage; obj::vm_area_untracked &g_kernel_heap_area = __g_kernel_heap_area_storage.value; +static util::no_construct __g_kernel_log_area_storage; +obj::vm_area_ring &g_kernel_log_area = __g_kernel_log_area_storage.value; + static util::no_construct __g_kernel_heapmap_area_storage; obj::vm_area_untracked &g_kernel_heapmap_area = __g_kernel_heapmap_area_storage.value; @@ -78,7 +81,7 @@ memory_initialize_pre_ctors(bootproto::args &kargs) page_table *kpml4 = static_cast(kargs.pml4); - + // Initialize the frame allocator frame_block *blocks = reinterpret_cast(mem::bitmap_offset); new (&g_frame_allocator) frame_allocator {blocks, kargs.frame_blocks.count}; @@ -91,10 +94,11 @@ memory_initialize_pre_ctors(bootproto::args &kargs) reg = reg->next; } - + // Initialize the kernel "process" and vm_space obj::process *kp = obj::process::create_kernel_process(kpml4); vm_space &vm = kp->space(); + // Create the heap space and heap allocator obj::vm_area *heap = new (&g_kernel_heap_area) obj::vm_area_untracked(mem::heap_size, vm_flags::write); @@ -106,6 +110,16 @@ memory_initialize_pre_ctors(bootproto::args &kargs) new (&g_kernel_heap) heap_allocator {mem::heap_offset, mem::heap_size, mem::heapmap_offset}; + // Set up the log area and logger + size_t log_buffer_size = log::log_pages * arch::frame_size; + obj::vm_area *logs = new (&g_kernel_log_area) + obj::vm_area_ring(log_buffer_size, vm_flags::write); + vm.add(mem::logs_offset, logs); + + new (&g_logger) log::logger( + util::buffer::from(mem::logs_offset, log_buffer_size)); + + // Set up the capability tables obj::vm_area *caps = new (&g_cap_table_area) obj::vm_area_untracked(mem::caps_size, vm_flags::write); diff --git a/src/kernel/objects/vm_area.cpp b/src/kernel/objects/vm_area.cpp index 51f757a..1203ebf 100644 --- a/src/kernel/objects/vm_area.cpp +++ b/src/kernel/objects/vm_area.cpp @@ -141,6 +141,11 @@ vm_area_open::get_page(uintptr_t offset, uintptr_t &phys) return page_tree::find_or_add(m_mapped, offset, phys); } +void +vm_area_open::add_existing(uintptr_t offset, uintptr_t phys) +{ +} + vm_area_guarded::vm_area_guarded(uintptr_t start, size_t buf_pages, size_t size, vm_flags flags) : m_pages {buf_pages + 1}, // Sections are N+1 pages for the leading guard page @@ -179,4 +184,20 @@ vm_area_guarded::get_page(uintptr_t offset, uintptr_t &phys) return vm_area_open::get_page(offset, phys); } +vm_area_ring::vm_area_ring(size_t size, vm_flags flags) : + vm_area_open {size * 2, flags}, + m_bufsize {size} +{ +} + +vm_area_ring::~vm_area_ring() {} + +bool +vm_area_ring::get_page(uintptr_t offset, uintptr_t &phys) +{ + if (offset > m_bufsize) + offset -= m_bufsize; + return vm_area_open::get_page(offset, phys); +} + } // namespace obj diff --git a/src/kernel/objects/vm_area.h b/src/kernel/objects/vm_area.h index 8bc57c3..8d28b32 100644 --- a/src/kernel/objects/vm_area.h +++ b/src/kernel/objects/vm_area.h @@ -126,6 +126,10 @@ public: virtual bool get_page(uintptr_t offset, uintptr_t &phys) override; + /// Tell this VMA about an existing mapping that did not originate + /// from get_page. + void add_existing(uintptr_t offset, uintptr_t phys); + private: page_tree *m_mapped; }; @@ -178,4 +182,25 @@ private: block_allocator m_stacks; }; + +/// Area that maps its pages twice for use in ring buffers. +/// Cannot be resized. +class vm_area_ring : + public vm_area_open +{ +public: + /// Constructor. + /// \arg size Virtual size of the ring buffer. Note that + /// the VMA size will be double this value. + /// \arg flags Flags for this memory area + vm_area_ring(size_t size, vm_flags flags); + virtual ~vm_area_ring(); + + virtual bool get_page(uintptr_t offset, uintptr_t &phys) override; + +private: + size_t m_bufsize; + page_tree *m_mapped; +}; + } // namespace obj diff --git a/src/kernel/wait_queue.cpp b/src/kernel/wait_queue.cpp index 1092c7f..d14a108 100644 --- a/src/kernel/wait_queue.cpp +++ b/src/kernel/wait_queue.cpp @@ -11,6 +11,14 @@ wait_queue::add_thread(obj::thread *t) m_threads.push_back(t); } +void +wait_queue::wait() +{ + obj::thread ¤t = obj::thread::current(); + add_thread(¤t); + current.block(); +} + void wait_queue::pop_exited() { diff --git a/src/kernel/wait_queue.h b/src/kernel/wait_queue.h index 2de60ec..2b12498 100644 --- a/src/kernel/wait_queue.h +++ b/src/kernel/wait_queue.h @@ -19,6 +19,9 @@ public: /// queue lock. void add_thread(obj::thread *t); + /// Block the current thread on the queue. + void wait(); + /// Pops the next waiting thread off the queue. /// Locks the queue lock. inline obj::thread * pop_next() { diff --git a/src/libraries/util/util/counted.h b/src/libraries/util/util/counted.h index 7ac2b4b..948e81d 100644 --- a/src/libraries/util/util/counted.h +++ b/src/libraries/util/util/counted.h @@ -70,7 +70,7 @@ struct counted size_t count = 0; template - static inline counted from(T *p, size_t c) { + static inline counted from(T p, size_t c) { return {reinterpret_cast(p), c}; } @@ -108,7 +108,7 @@ struct counted size_t count = 0; template - static inline counted from(T *p, size_t c) { + static inline counted from(T p, size_t c) { return {reinterpret_cast(p), c}; }