diff options
| author | 3gg <3gg@shellblade.net> | 2025-05-24 17:04:18 -0700 |
|---|---|---|
| committer | 3gg <3gg@shellblade.net> | 2025-05-24 17:04:18 -0700 |
| commit | 079cd940e727c1705e9f1b30706b9531d5aedda6 (patch) | |
| tree | 25cb0748e1365679f5898f3437039af506cdb08e | |
| parent | a8a39ba24e36119dce48a01c2139e0e5a25674e1 (diff) | |
Framebuffer WIP
| -rw-r--r-- | src/framebuffer.c | 30 | ||||
| -rw-r--r-- | src/framebuffer.h | 7 | ||||
| -rw-r--r-- | src/kernel.c | 13 | ||||
| -rw-r--r-- | src/mailbox.c | 4 | ||||
| -rw-r--r-- | src/mailbox.h | 31 |
5 files changed, 80 insertions, 5 deletions
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 @@ | |||
| 1 | #include <framebuffer.h> | ||
| 2 | |||
| 3 | #include <mailbox.h> | ||
| 4 | |||
| 5 | #include <stdint.h> | ||
| 6 | |||
| 7 | #define WIDTH 640 | ||
| 8 | #define HEIGHT 480 | ||
| 9 | #define DEPTH 32 | ||
| 10 | |||
| 11 | bool framebuffer_init(uint32_t* error) { | ||
| 12 | volatile const Mail* mail; | ||
| 13 | |||
| 14 | volatile __attribute__((aligned(MAIL_ALIGN))) uint32_t InitFramebuffer[] = { | ||
| 15 | 80, // Size in bytes aligned to MAIL_ALIGN(16). | ||
| 16 | MAILBOX_REQUEST, | ||
| 17 | TAG_FRAMEBUFFER_SET_PHYSICAL_SCREEN_SIZE, 8, MAILBOX_REQUEST, WIDTH, HEIGHT, | ||
| 18 | TAG_FRAMEBUFFER_SET_VIRTUAL_SCREEN_SIZE, 8, MAILBOX_REQUEST, WIDTH, HEIGHT, | ||
| 19 | TAG_FRAMEBUFFER_SET_DEPTH, 4, MAILBOX_REQUEST, DEPTH, | ||
| 20 | TAG_END, | ||
| 21 | 0, 0, 0 // Pad. | ||
| 22 | }; | ||
| 23 | |||
| 24 | mbox_write(PROPERTY_CHANNEL, InitFramebuffer); | ||
| 25 | while ((mail = mbox_read(PROPERTY_CHANNEL)) != (volatile Mail*)(InitFramebuffer)); | ||
| 26 | |||
| 27 | *error = mail->code; | ||
| 28 | return mail->code == MAILBOX_SUCCESS; | ||
| 29 | } | ||
| 30 | |||
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 @@ | |||
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <stdbool.h> | ||
| 4 | #include <stdint.h> | ||
| 5 | |||
| 6 | bool framebuffer_init(uint32_t* error); | ||
| 7 | |||
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 @@ | |||
| 1 | #include <framebuffer.h> | ||
| 1 | #include <mailbox.h> | 2 | #include <mailbox.h> |
| 2 | #include <mmio.h> | 3 | #include <mmio.h> |
| 3 | #include <raspi.h> | 4 | #include <raspi.h> |
| @@ -10,14 +11,26 @@ static void halt() { | |||
| 10 | } | 11 | } |
| 11 | 12 | ||
| 12 | void main() { | 13 | void main() { |
| 14 | bool success = true; | ||
| 15 | uint32_t error = -1; | ||
| 16 | |||
| 13 | const int raspi = raspi_init(); | 17 | const int raspi = raspi_init(); |
| 14 | mmio_init(raspi); // Must be initialized before other peripherals. | 18 | mmio_init(raspi); // Must be initialized before other peripherals. |
| 15 | 19 | ||
| 16 | mbox_init(); | 20 | mbox_init(); |
| 17 | uart_init(raspi); | 21 | uart_init(raspi); |
| 22 | success = framebuffer_init(&error); | ||
| 23 | if (!success) { | ||
| 24 | uart_print("Failed to initialize framebuffer\n"); | ||
| 25 | if (error == MAILBOX_DELIVERY_ERROR) { | ||
| 26 | uart_print("MAILBOX_DELIVERY_ERROR\n"); | ||
| 27 | } | ||
| 28 | goto end; | ||
| 29 | } | ||
| 18 | 30 | ||
| 19 | uart_print("Hello world!\n"); | 31 | uart_print("Hello world!\n"); |
| 20 | 32 | ||
| 33 | end: | ||
| 21 | halt(); | 34 | halt(); |
| 22 | } | 35 | } |
| 23 | 36 | ||
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) { | |||
| 21 | return (const void*)((uintptr_t)(msg >> 4)); | 21 | return (const void*)((uintptr_t)(msg >> 4)); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | static inline Message msg_make(uint8_t channel, const void* data) { | 24 | static inline Message msg_make(uint8_t channel, volatile const void* data) { |
| 25 | return ((uintptr_t)(data) << 4) | (channel & 0xf); | 25 | return ((uintptr_t)(data) << 4) | (channel & 0xf); |
| 26 | } | 26 | } |
| 27 | 27 | ||
| @@ -64,7 +64,7 @@ const Mail* mbox_read(uint8_t channel) { | |||
| 64 | return (const Mail*)(msg_data(msg)); | 64 | return (const Mail*)(msg_data(msg)); |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | void mbox_write(uint8_t channel, const void* mail) { | 67 | void mbox_write(uint8_t channel, volatile const void* mail) { |
| 68 | // Wait until the outbox is clear. | 68 | // Wait until the outbox is clear. |
| 69 | while (outbox_full(pMailbox)); | 69 | while (outbox_full(pMailbox)); |
| 70 | // Send the mail. | 70 | // 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 | |||
| 11 | PROPERTY_CHANNEL = 8, | 11 | PROPERTY_CHANNEL = 8, |
| 12 | }; | 12 | }; |
| 13 | 13 | ||
| 14 | enum | ||
| 15 | { | ||
| 16 | MAILBOX_REQUEST = 0, | ||
| 17 | MAILBOX_RESPONSE = 1, | ||
| 18 | }; | ||
| 19 | |||
| 20 | enum | ||
| 21 | { | ||
| 22 | MAILBOX_DELIVERY_ERROR = 0, | ||
| 23 | MAILBOX_ERROR = 0x80000001, | ||
| 24 | MAILBOX_SUCCESS = 0x80000000, | ||
| 25 | }; | ||
| 26 | |||
| 27 | enum | ||
| 28 | { | ||
| 29 | TAG_END = 0, | ||
| 30 | TAG_FRAMEBUFFER_ALLOCATE = 0x00040001, | ||
| 31 | TAG_FRAMEBUFFER_RELEASE = 0x00048001, | ||
| 32 | TAG_FRAMEBUFFER_SET_PHYSICAL_SCREEN_SIZE = 0x00048003, | ||
| 33 | TAG_FRAMEBUFFER_SET_VIRTUAL_SCREEN_SIZE = 0x00048004, | ||
| 34 | TAG_FRAMEBUFFER_SET_DEPTH = 0x00048005, | ||
| 35 | }; | ||
| 36 | |||
| 14 | typedef struct Tag { | 37 | typedef struct Tag { |
| 15 | union { | 38 | union { |
| 16 | uint32_t all; | 39 | uint32_t all; |
| @@ -23,16 +46,18 @@ typedef struct Tag { | |||
| 23 | }; | 46 | }; |
| 24 | uint32_t size; // Buffer size. | 47 | uint32_t size; // Buffer size. |
| 25 | uint32_t code; // Request/response code. | 48 | uint32_t code; // Request/response code. |
| 26 | uint32_t data[1]; // Buffer data. | 49 | uint32_t data[]; // Buffer data. |
| 27 | } Tag; | 50 | } Tag; |
| 28 | 51 | ||
| 29 | typedef struct __attribute__((aligned(MAIL_ALIGN))) Mail { | 52 | typedef struct __attribute__((aligned(MAIL_ALIGN))) Mail { |
| 30 | uint32_t size; // Buffer size. | 53 | uint32_t size; // Buffer size. |
| 31 | uint32_t code; // Request/response code. | 54 | uint32_t code; // Request/response code. |
| 32 | Tag tags[1]; // Variable quantity. | 55 | Tag tags[]; // Variable quantity. |
| 33 | } Mail; | 56 | } Mail; |
| 34 | 57 | ||
| 58 | #define MAIL_SIZE(TYPE) (sizeof(TYPE) + (2 * sizeof(uint32_t))) | ||
| 59 | |||
| 35 | void mbox_init(); | 60 | void mbox_init(); |
| 36 | const Mail* mbox_read(uint8_t channel); | 61 | const Mail* mbox_read(uint8_t channel); |
| 37 | void mbox_write(uint8_t channel, const void* mail); | 62 | void mbox_write(uint8_t channel, volatile const void* mail); |
| 38 | 63 | ||
