#include #include #include #include #define WIDTH 640 #define HEIGHT 480 #define DEPTH 32 #define ALIGNMENT 16 // Framebuffer byte alignment. typedef struct Framebuffer { volatile void* pixels; size_t size; } Framebuffer; static Framebuffer framebuffer = {}; bool framebuffer_init(uint32_t* error) { MAIL_T uint32_t ConfigureScreen[20] = { 80, // Size in bytes, aligned to MAIL_ALIGN. 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 // Padding. }; mbox_write(PROPERTY_CHANNEL, ConfigureScreen); const Mail* response = mbox_read(PROPERTY_CHANNEL); if (response->code != MAILBOX_SUCCESS) { goto end; } MAIL_T uint32_t InitFramebuffer[8] = { 32, // Size in bytes, aligned to MAIL_ALIGN. MAILBOX_REQUEST, TAG_FRAMEBUFFER_ALLOCATE, 8, MAILBOX_REQUEST, ALIGNMENT, 0, TAG_END }; mbox_write(PROPERTY_CHANNEL, InitFramebuffer); response = mbox_read(PROPERTY_CHANNEL); if (response->code != MAILBOX_SUCCESS) { goto end; } // The input mail is overwritten with the response. // u32 fb base address // u32 fb size framebuffer.pixels = (void*)(uintptr_t)InitFramebuffer[5]; framebuffer.size = InitFramebuffer[6]; end: *error = response->code; return response->code == MAILBOX_SUCCESS; }