From 6a0cf7cf988559b617df05a132a7b9017e336cbc Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 10 Sep 2022 18:42:40 +0200 Subject: [PATCH] New framebuffer class!! --- kernel/include/acpi/RSDT.h | 2 +- kernel/include/assert.h | 13 ++++--- kernel/include/render/Framebuffer.h | 30 ++++++++++++++++ kernel/src/acpi/RSDT.cpp | 12 +++++-- kernel/src/assert.cpp | 10 ------ kernel/src/init/Init.cpp | 5 +-- kernel/src/main.cpp | 5 ++- kernel/src/power/reboot.cpp | 9 ++--- kernel/src/render/Framebuffer.cpp | 53 +++++++++++++++++++++++++++++ 9 files changed, 111 insertions(+), 28 deletions(-) create mode 100644 kernel/include/render/Framebuffer.h delete mode 100644 kernel/src/assert.cpp create mode 100644 kernel/src/render/Framebuffer.cpp diff --git a/kernel/include/acpi/RSDT.h b/kernel/include/acpi/RSDT.h index 2ccd5af2..00a3128b 100644 --- a/kernel/include/acpi/RSDT.h +++ b/kernel/include/acpi/RSDT.h @@ -19,7 +19,7 @@ namespace ACPI bool ValidateRSDTOrXSDT(SDTHeader* rootSDT); - bool IsXSDT(SDTHeader* rootSDT); + bool IsXSDT(); void* FindTable(SDTHeader* rootSDT, const char* signature); } \ No newline at end of file diff --git a/kernel/include/assert.h b/kernel/include/assert.h index 46f745cd..04701929 100644 --- a/kernel/include/assert.h +++ b/kernel/include/assert.h @@ -1,9 +1,14 @@ #pragma once #include "log/Log.h" +#include "panic/hang.h" -extern bool __call_assert_fail(const char* function, const char* message); +#define __call_assert_fail(...) \ + kerrorln(__VA_ARGS__); \ + hang(); -#define __assert_fail(prefix, message) __call_assert_fail(__FUNCTION__, prefix message) -#define ASSERT(expr) (void)((expr) || __assert_fail("Assertion failed: ", #expr)) +#define ASSERT(expr) \ + do { \ + if (!(expr)) { __call_assert_fail("Assertion failed at %s, line %d: %s", __FILE__, __LINE__, #expr) } \ + } while (0) -#define TODO(message) __assert_fail("TODO: ", message) \ No newline at end of file +#define TODO(message) __call_assert_fail("TODO at %s, line %d: %s", __FILE__, __LINE__, message) \ No newline at end of file diff --git a/kernel/include/render/Framebuffer.h b/kernel/include/render/Framebuffer.h new file mode 100644 index 00000000..c8b53fe2 --- /dev/null +++ b/kernel/include/render/Framebuffer.h @@ -0,0 +1,30 @@ +#pragma once +#include "render/Color.h" + +class Framebuffer +{ + public: + void init(void* fb_address, int fb_type, int fb_scanline, int fb_width, int fb_height); + void set_pixel(uint32_t x, uint32_t y, Color color); + Color get_pixel(uint32_t x, uint32_t y); + void paint_rect(uint32_t x, uint32_t y, uint32_t w, uint32_t h, Color color); + void paint_rect(uint32_t x, uint32_t y, uint32_t w, uint32_t h, Color* colors); + void clear(Color color); + int width() + { + return m_fb_width; + } + int height() + { + return m_fb_height; + } + + private: + void* m_fb_address; + int m_fb_type; + int m_fb_scanline; + int m_fb_width; + int m_fb_height; +}; + +extern Framebuffer framebuffer0; \ No newline at end of file diff --git a/kernel/src/acpi/RSDT.cpp b/kernel/src/acpi/RSDT.cpp index c0e2ded9..3c2c336d 100644 --- a/kernel/src/acpi/RSDT.cpp +++ b/kernel/src/acpi/RSDT.cpp @@ -47,14 +47,20 @@ bool ACPI::ValidateRSDTOrXSDT(ACPI::SDTHeader* rootSDT) return false; } -bool ACPI::IsXSDT(ACPI::SDTHeader* rootSDT) +bool ACPI::IsXSDT() { - return strncmp(rootSDT->Signature, "XSDT", 4) == 0; + static bool cached = false; + static bool cache = false; + if (cached) return cache; + SDTHeader* rootSDT = GetRSDTOrXSDT(); + cache = (strncmp(rootSDT->Signature, "XSDT", 4) == 0); + cached = true; + return cache; } void* ACPI::FindTable(ACPI::SDTHeader* rootSDT, const char* signature) { - bool isXSDT = (strncmp(rootSDT->Signature, "XSDT", 4) == 0); + bool isXSDT = IsXSDT(); int entries = (rootSDT->Length - sizeof(SDTHeader)) / (isXSDT ? 8 : 4); kdbgln("Searching for table %s in the %s at %lx (table contains %d entries)", signature, isXSDT ? "XSDT" : "RSDT", (uint64_t)rootSDT, entries); diff --git a/kernel/src/assert.cpp b/kernel/src/assert.cpp deleted file mode 100644 index 066f268b..00000000 --- a/kernel/src/assert.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "assert.h" -#include "log/Log.h" -#include "panic/hang.h" - -bool __call_assert_fail(const char* function, const char* message) -{ - KernelLog::logln(function, LogLevel::ERROR, "%s", message); - hang(); - return true; -} \ No newline at end of file diff --git a/kernel/src/init/Init.cpp b/kernel/src/init/Init.cpp index 41b6bb3d..e870f571 100644 --- a/kernel/src/init/Init.cpp +++ b/kernel/src/init/Init.cpp @@ -7,7 +7,7 @@ #include "memory/RangeAllocator.h" #include "memory/VMM.h" #include "panic/hang.h" -#include "render/Draw.h" +#include "render/Framebuffer.h" #include "render/TextRenderer.h" #include @@ -29,7 +29,8 @@ void Init::early_init() Interrupts::disable(); asm volatile("cld"); - ASSERT(Draw::try_initialize()); + framebuffer0.init((void*)bootboot.fb_ptr, bootboot.fb_type, bootboot.fb_scanline, bootboot.fb_width, + bootboot.fb_height); // ASSERT(TextRenderer::try_initialize()); kernelPMM.init_from_mmap(); diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 4039a4c2..987284a9 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -16,6 +16,7 @@ #include "memory/RangeAllocator.h" #include "panic/hang.h" #include "power/reboot.h" +#include "render/Framebuffer.h" #include "scheduling/PIT.h" #include "std/stdio.h" #include "std/stdlib.h" @@ -63,9 +64,11 @@ extern "C" void _start() kinfoln("Interrupts enabled"); ACPI::SDTHeader* rootSDT = ACPI::GetRSDTOrXSDT(); - bool isXSDT = ACPI::IsXSDT(rootSDT); + bool isXSDT = ACPI::IsXSDT(); if (!ACPI::ValidateRSDTOrXSDT(rootSDT)) kerrorln("Invalid %s", isXSDT ? "XSDT" : "RSDT"); + framebuffer0.clear(Color::Cyan); + sleep(2500); reboot(); diff --git a/kernel/src/power/reboot.cpp b/kernel/src/power/reboot.cpp index e659f3af..9f0f1008 100644 --- a/kernel/src/power/reboot.cpp +++ b/kernel/src/power/reboot.cpp @@ -20,14 +20,9 @@ static void try_acpi_reboot() kwarnln("The pointer to the RSDT/XSDT is null"); return; } - if (!ACPI::ValidateSDTHeader(rootSDT)) + if (!ACPI::ValidateRSDTOrXSDT(rootSDT)) { - kwarnln("The RSDT/XSDT has an invalid header"); - return; - } - if (strncmp(rootSDT->Signature, "RSDT", 4) != 0 && strncmp(rootSDT->Signature, "XSDT", 4) != 0) - { - kwarnln("The RSDT/XSDT's signature is not RSDT or XSDT"); + kwarnln("The RSDT/XSDT is invalid"); return; } kdbgln("Searching for the FADT"); diff --git a/kernel/src/render/Framebuffer.cpp b/kernel/src/render/Framebuffer.cpp new file mode 100644 index 00000000..fb2e136c --- /dev/null +++ b/kernel/src/render/Framebuffer.cpp @@ -0,0 +1,53 @@ +#define MODULE "fb" + +#include "render/Framebuffer.h" +#include "assert.h" +#include "bootboot.h" + +Framebuffer framebuffer0; + +void Framebuffer::init(void* fb_address, int fb_type, int fb_scanline, int fb_width, int fb_height) +{ + m_fb_address = fb_address; + m_fb_height = fb_height; + m_fb_width = fb_width; + m_fb_scanline = fb_scanline; + m_fb_type = fb_type; + ASSERT(m_fb_type == FB_ARGB); // FIXME: support more framebuffer types +} + +void Framebuffer::set_pixel(uint32_t x, uint32_t y, Color color) +{ + *(uint32_t*)((char*)m_fb_address + m_fb_scanline * y + x * 4) = *(uint32_t*)&color; +} + +Color Framebuffer::get_pixel(uint32_t x, uint32_t y) +{ + return *(Color*)((char*)m_fb_address + m_fb_scanline * y + x * 4); +} + +void Framebuffer::clear(Color color) +{ + paint_rect(0, 0, m_fb_width, m_fb_height, color); +} + +void Framebuffer::paint_rect(uint32_t x, uint32_t y, uint32_t w, uint32_t h, Color color) +{ + for (uint32_t i = y; i < (y + h); i++) + { + uint64_t addr = (uint64_t)((char*)m_fb_address + (m_fb_scanline * i) + (x * 4)); + for (uint64_t addr_current = addr; addr_current < (addr + w * 4); addr_current += 4) + { + *(uint32_t*)addr_current = *(uint32_t*)&color; + } + } +} + +void Framebuffer::paint_rect(uint32_t x, uint32_t y, uint32_t w, uint32_t h, Color* colors) +{ + uint32_t j; + for (uint32_t l = j = 0; l < h; l++) + { + for (uint32_t i = 0; i < w; i++, j++) { set_pixel(x + i, y + l, colors[j]); } + } +}