diff options
-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 | ||