New framebuffer class!!

This commit is contained in:
apio 2022-09-10 18:42:40 +02:00
parent 07d1943053
commit 6a0cf7cf98
9 changed files with 111 additions and 28 deletions

View File

@ -19,7 +19,7 @@ namespace ACPI
bool ValidateRSDTOrXSDT(SDTHeader* rootSDT); bool ValidateRSDTOrXSDT(SDTHeader* rootSDT);
bool IsXSDT(SDTHeader* rootSDT); bool IsXSDT();
void* FindTable(SDTHeader* rootSDT, const char* signature); void* FindTable(SDTHeader* rootSDT, const char* signature);
} }

View File

@ -1,9 +1,14 @@
#pragma once #pragma once
#include "log/Log.h" #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) \
#define ASSERT(expr) (void)((expr) || __assert_fail("Assertion failed: ", #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) #define TODO(message) __call_assert_fail("TODO at %s, line %d: %s", __FILE__, __LINE__, message)

View File

@ -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;

View File

@ -47,14 +47,20 @@ bool ACPI::ValidateRSDTOrXSDT(ACPI::SDTHeader* rootSDT)
return false; 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) 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); 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", kdbgln("Searching for table %s in the %s at %lx (table contains %d entries)", signature, isXSDT ? "XSDT" : "RSDT",
(uint64_t)rootSDT, entries); (uint64_t)rootSDT, entries);

View File

@ -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;
}

View File

@ -7,7 +7,7 @@
#include "memory/RangeAllocator.h" #include "memory/RangeAllocator.h"
#include "memory/VMM.h" #include "memory/VMM.h"
#include "panic/hang.h" #include "panic/hang.h"
#include "render/Draw.h" #include "render/Framebuffer.h"
#include "render/TextRenderer.h" #include "render/TextRenderer.h"
#include <string.h> #include <string.h>
@ -29,7 +29,8 @@ void Init::early_init()
Interrupts::disable(); Interrupts::disable();
asm volatile("cld"); 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()); // ASSERT(TextRenderer::try_initialize());
kernelPMM.init_from_mmap(); kernelPMM.init_from_mmap();

View File

@ -16,6 +16,7 @@
#include "memory/RangeAllocator.h" #include "memory/RangeAllocator.h"
#include "panic/hang.h" #include "panic/hang.h"
#include "power/reboot.h" #include "power/reboot.h"
#include "render/Framebuffer.h"
#include "scheduling/PIT.h" #include "scheduling/PIT.h"
#include "std/stdio.h" #include "std/stdio.h"
#include "std/stdlib.h" #include "std/stdlib.h"
@ -63,9 +64,11 @@ extern "C" void _start()
kinfoln("Interrupts enabled"); kinfoln("Interrupts enabled");
ACPI::SDTHeader* rootSDT = ACPI::GetRSDTOrXSDT(); ACPI::SDTHeader* rootSDT = ACPI::GetRSDTOrXSDT();
bool isXSDT = ACPI::IsXSDT(rootSDT); bool isXSDT = ACPI::IsXSDT();
if (!ACPI::ValidateRSDTOrXSDT(rootSDT)) kerrorln("Invalid %s", isXSDT ? "XSDT" : "RSDT"); if (!ACPI::ValidateRSDTOrXSDT(rootSDT)) kerrorln("Invalid %s", isXSDT ? "XSDT" : "RSDT");
framebuffer0.clear(Color::Cyan);
sleep(2500); sleep(2500);
reboot(); reboot();

View File

@ -20,14 +20,9 @@ static void try_acpi_reboot()
kwarnln("The pointer to the RSDT/XSDT is null"); kwarnln("The pointer to the RSDT/XSDT is null");
return; return;
} }
if (!ACPI::ValidateSDTHeader(rootSDT)) if (!ACPI::ValidateRSDTOrXSDT(rootSDT))
{ {
kwarnln("The RSDT/XSDT has an invalid header"); kwarnln("The RSDT/XSDT is invalid");
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");
return; return;
} }
kdbgln("Searching for the FADT"); kdbgln("Searching for the FADT");

View File

@ -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]); }
}
}