From 079cd940e727c1705e9f1b30706b9531d5aedda6 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Sat, 24 May 2025 17:04:18 -0700 Subject: Framebuffer WIP --- src/framebuffer.c | 30 ++++++++++++++++++++++++++++++ src/framebuffer.h | 7 +++++++ src/kernel.c | 13 +++++++++++++ src/mailbox.c | 4 ++-- src/mailbox.h | 31 ++++++++++++++++++++++++++++--- 5 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 src/framebuffer.c create mode 100644 src/framebuffer.h diff --git a/src/framebuffer.c b/src/framebuffer.c new file mode 100644 index 0000000..a90bcaa --- /dev/null +++ b/src/framebuffer.c @@ -0,0 +1,30 @@ +#include + +#include + +#include + +#define WIDTH 640 +#define HEIGHT 480 +#define DEPTH 32 + +bool framebuffer_init(uint32_t* error) { + volatile const Mail* mail; + + volatile __attribute__((aligned(MAIL_ALIGN))) uint32_t InitFramebuffer[] = { + 80, // Size in bytes aligned to MAIL_ALIGN(16). + MAILBOX_REQUEST, + TAG_FRAMEBUFFER_SET_PHYSICAL_SCREEN_SIZE, 8, MAILBOX_REQUEST, WIDTH, HEIGHT, + TAG_FRAMEBUFFER_SET_VIRTUAL_SCREEN_SIZE, 8, MAILBOX_REQUEST, WIDTH, HEIGHT, + TAG_FRAMEBUFFER_SET_DEPTH, 4, MAILBOX_REQUEST, DEPTH, + TAG_END, + 0, 0, 0 // Pad. + }; + + mbox_write(PROPERTY_CHANNEL, InitFramebuffer); + while ((mail = mbox_read(PROPERTY_CHANNEL)) != (volatile Mail*)(InitFramebuffer)); + + *error = mail->code; + return mail->code == MAILBOX_SUCCESS; +} + diff --git a/src/framebuffer.h b/src/framebuffer.h new file mode 100644 index 0000000..d2d57cd --- /dev/null +++ b/src/framebuffer.h @@ -0,0 +1,7 @@ +#pragma once + +#include +#include + +bool framebuffer_init(uint32_t* error); + diff --git a/src/kernel.c b/src/kernel.c index 4296aa7..ac803cc 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -10,14 +11,26 @@ static void halt() { } void main() { + bool success = true; + uint32_t error = -1; + const int raspi = raspi_init(); mmio_init(raspi); // Must be initialized before other peripherals. mbox_init(); uart_init(raspi); + success = framebuffer_init(&error); + if (!success) { + uart_print("Failed to initialize framebuffer\n"); + if (error == MAILBOX_DELIVERY_ERROR) { + uart_print("MAILBOX_DELIVERY_ERROR\n"); + } + goto end; + } uart_print("Hello world!\n"); +end: halt(); } diff --git a/src/mailbox.c b/src/mailbox.c index eaf0955..aacb747 100644 --- a/src/mailbox.c +++ b/src/mailbox.c @@ -21,7 +21,7 @@ static inline const void* msg_data(Message msg) { return (const void*)((uintptr_t)(msg >> 4)); } -static inline Message msg_make(uint8_t channel, const void* data) { +static inline Message msg_make(uint8_t channel, volatile const void* data) { return ((uintptr_t)(data) << 4) | (channel & 0xf); } @@ -64,7 +64,7 @@ const Mail* mbox_read(uint8_t channel) { return (const Mail*)(msg_data(msg)); } -void mbox_write(uint8_t channel, const void* mail) { +void mbox_write(uint8_t channel, volatile const void* mail) { // Wait until the outbox is clear. while (outbox_full(pMailbox)); // Send the mail. diff --git a/src/mailbox.h b/src/mailbox.h index e96a4ed..3cca366 100644 --- a/src/mailbox.h +++ b/src/mailbox.h @@ -11,6 +11,29 @@ enum PROPERTY_CHANNEL = 8, }; +enum +{ + MAILBOX_REQUEST = 0, + MAILBOX_RESPONSE = 1, +}; + +enum +{ + MAILBOX_DELIVERY_ERROR = 0, + MAILBOX_ERROR = 0x80000001, + MAILBOX_SUCCESS = 0x80000000, +}; + +enum +{ + TAG_END = 0, + TAG_FRAMEBUFFER_ALLOCATE = 0x00040001, + TAG_FRAMEBUFFER_RELEASE = 0x00048001, + TAG_FRAMEBUFFER_SET_PHYSICAL_SCREEN_SIZE = 0x00048003, + TAG_FRAMEBUFFER_SET_VIRTUAL_SCREEN_SIZE = 0x00048004, + TAG_FRAMEBUFFER_SET_DEPTH = 0x00048005, +}; + typedef struct Tag { union { uint32_t all; @@ -23,16 +46,18 @@ typedef struct Tag { }; uint32_t size; // Buffer size. uint32_t code; // Request/response code. - uint32_t data[1]; // Buffer data. + uint32_t data[]; // Buffer data. } Tag; typedef struct __attribute__((aligned(MAIL_ALIGN))) Mail { uint32_t size; // Buffer size. uint32_t code; // Request/response code. - Tag tags[1]; // Variable quantity. + Tag tags[]; // Variable quantity. } Mail; +#define MAIL_SIZE(TYPE) (sizeof(TYPE) + (2 * sizeof(uint32_t))) + void mbox_init(); const Mail* mbox_read(uint8_t channel); -void mbox_write(uint8_t channel, const void* mail); +void mbox_write(uint8_t channel, volatile const void* mail); -- cgit v1.2.3