summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2025-05-24 17:04:18 -0700
committer3gg <3gg@shellblade.net>2025-05-24 17:04:18 -0700
commit079cd940e727c1705e9f1b30706b9531d5aedda6 (patch)
tree25cb0748e1365679f5898f3437039af506cdb08e
parenta8a39ba24e36119dce48a01c2139e0e5a25674e1 (diff)
Framebuffer WIPHEADmain
-rw-r--r--src/framebuffer.c30
-rw-r--r--src/framebuffer.h7
-rw-r--r--src/kernel.c13
-rw-r--r--src/mailbox.c4
-rw-r--r--src/mailbox.h31
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
11bool 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
6bool 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
12void main() { 13void 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
33end:
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
24static inline Message msg_make(uint8_t channel, const void* data) { 24static 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
67void mbox_write(uint8_t channel, const void* mail) { 67void 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
14enum
15{
16 MAILBOX_REQUEST = 0,
17 MAILBOX_RESPONSE = 1,
18};
19
20enum
21{
22 MAILBOX_DELIVERY_ERROR = 0,
23 MAILBOX_ERROR = 0x80000001,
24 MAILBOX_SUCCESS = 0x80000000,
25};
26
27enum
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
14typedef struct Tag { 37typedef 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
29typedef struct __attribute__((aligned(MAIL_ALIGN))) Mail { 52typedef 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
35void mbox_init(); 60void mbox_init();
36const Mail* mbox_read(uint8_t channel); 61const Mail* mbox_read(uint8_t channel);
37void mbox_write(uint8_t channel, const void* mail); 62void mbox_write(uint8_t channel, volatile const void* mail);
38 63