aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-09-13 18:37:26 +0200
committerBad Diode <bd@badd10de.dev>2021-09-13 18:37:26 +0200
commit162a1ee7f91aac21329d7acf290f9d350fb083bd (patch)
tree3db6e1393b6d6d9c9e439799dd1c9196319b5586
parentf7826ed2b13f5c7290ce6c73f554bae588d1ace1 (diff)
downloaduxnrpi-162a1ee7f91aac21329d7acf290f9d350fb083bd.tar.gz
uxnrpi-162a1ee7f91aac21329d7acf290f9d350fb083bd.zip
Update FB initialization to use mbox instead of structs
The framebuffer initialization was breaking randomly, I suspect because the memory access of the static fb_request was not 16 bit aligned. For simplicity, I went back to the volatile mbox array implementation. Additionally, now on fb_init the rgb order is requested to properly adjust the palette on docolors.
-rw-r--r--src/common.h53
-rw-r--r--src/main.c14
-rw-r--r--src/ppu.c98
3 files changed, 72 insertions, 93 deletions
diff --git a/src/common.h b/src/common.h
index ad3aad8..0057950 100644
--- a/src/common.h
+++ b/src/common.h
@@ -171,40 +171,6 @@ uart_hex(unsigned int d) {
171// VideoCore Mailboxes. 171// VideoCore Mailboxes.
172// 172//
173 173
174typedef struct MboxTagHeader {
175 u32 id;
176 u32 buf_size;
177 u32 code;
178} MboxTagHeader;
179
180typedef struct MboxScreenTag {
181 MboxTagHeader header;
182 u32 width;
183 u32 height;
184} MboxScreenTag;
185
186typedef struct MboxDepthTag {
187 MboxTagHeader header;
188 u32 depth;
189} MboxDepthTag;
190
191typedef struct MboxFramebufferTag {
192 MboxTagHeader header;
193 u32 fb_addr;
194 u32 fb_size;
195} MboxFramebufferTag;
196
197typedef struct MboxFramebufferRequest {
198 u32 buf_size;
199 u32 code;
200 MboxScreenTag screen_tag;
201 MboxScreenTag virtual_screen_tag;
202 MboxDepthTag depth_tag;
203 MboxFramebufferTag framebuffer_tag;
204 u32 end_tag;
205 u8 padding[8];
206} MboxFramebufferRequest;
207
208typedef struct MailboxRegs { 174typedef struct MailboxRegs {
209 vu32 read; 175 vu32 read;
210 vu32 reserved[5]; 176 vu32 reserved[5];
@@ -236,10 +202,21 @@ typedef enum MboxChannels {
236#define MBOX_FULL 0x80000000 202#define MBOX_FULL 0x80000000
237#define MBOX_EMPTY 0x40000000 203#define MBOX_EMPTY 0x40000000
238 204
205// Mailbox tags.
206#define MBOX_TAG_SET_SCREEN 0x48003
207#define MBOX_TAG_SET_VSCREEN 0x48004
208#define MBOX_TAG_SET_DEPTH 0x48005
209#define MBOX_TAG_SET_RGB 0x48006
210#define MBOX_TAG_GET_FB 0x40001
211#define MBOX_TAG_END 0
212
213// Mailbox request buffer. Needs to be 16 bit aligned to avoid issues.
214volatile u32 __attribute__((aligned(16))) mbox[64];
215
239static inline void 216static inline void
240mb_write(u8 channel, void *data) { 217mb_write(u8 channel) {
241 while (MBOX->status & MBOX_FULL); 218 while (MBOX->status & MBOX_FULL);
242 MBOX->write = ((uintptr_t)data & ~0xF) | (channel & 0xF); 219 MBOX->write = ((uintptr_t)mbox & ~0xF) | (channel & 0xF);
243} 220}
244 221
245static inline u32 222static inline u32
@@ -254,8 +231,8 @@ mb_read(u8 channel) {
254} 231}
255 232
256static inline int 233static inline int
257mb_call(unsigned char ch, void *msg) { 234mb_call(unsigned char ch) {
258 mb_write(ch, msg); 235 mb_write(ch);
259 return mb_read(ch); 236 return mb_read(ch);
260} 237}
261 238
diff --git a/src/main.c b/src/main.c
index c379ace..1853192 100644
--- a/src/main.c
+++ b/src/main.c
@@ -40,15 +40,11 @@ docolors(Device *d) {
40 u8 g = ((d->dat[0xa + i / 2] >> (!(i % 2) << 2)) & 0x0f) * 0x11; 40 u8 g = ((d->dat[0xa + i / 2] >> (!(i % 2) << 2)) & 0x0f) * 0x11;
41 u8 b = ((d->dat[0xc + i / 2] >> (!(i % 2) << 2)) & 0x0f) * 0x11; 41 u8 b = ((d->dat[0xc + i / 2] >> (!(i % 2) << 2)) & 0x0f) * 0x11;
42 42
43 // NOTE: This is a bit of a hack. We probably want to check the RGB byte 43 if (rgb_order) {
44 // order on the mailbox request. 44 palette[i] = (b << 16) | (g << 8) | r;
45#if RPI_VERSION == 3 45 } else {
46 palette[i] = (b << 16) | (g << 8) | r; 46 palette[i] = (r << 16) | (g << 8) | b;
47#endif 47 }
48
49#if RPI_VERSION == 4
50 palette[i] = (r << 16) | (g << 8) | b;
51#endif
52 } 48 }
53 for(size_t i = 4; i < 16; ++i) { 49 for(size_t i = 4; i < 16; ++i) {
54 palette[i] = palette[i / 4]; 50 palette[i] = palette[i / 4];
diff --git a/src/ppu.c b/src/ppu.c
index e153c4d..ac0feeb 100644
--- a/src/ppu.c
+++ b/src/ppu.c
@@ -24,6 +24,7 @@ static u32 palette[16];
24static u8 pixels_buf[SCREEN_WIDTH * SCREEN_HEIGHT]; 24static u8 pixels_buf[SCREEN_WIDTH * SCREEN_HEIGHT];
25static u8 dirty_lines[SCREEN_HEIGHT]; 25static u8 dirty_lines[SCREEN_HEIGHT];
26static u8 reqdraw = 0; 26static u8 reqdraw = 0;
27static u32 rgb_order;
27 28
28static Uint8 blending[5][16] = { 29static Uint8 blending[5][16] = {
29 {0, 0, 0, 0, 1, 0, 1, 1, 2, 2, 0, 2, 3, 3, 3, 0}, 30 {0, 0, 0, 0, 1, 0, 1, 1, 2, 2, 0, 2, 3, 3, 3, 0},
@@ -84,57 +85,62 @@ redraw_screen(void) {
84 } 85 }
85} 86}
86 87
88void
89fb_init(void) {
90 mbox[0] = 25 * 4;
91 mbox[1] = MBOX_REQUEST;
92
93 // Screen request.
94 mbox[2] = MBOX_TAG_SET_SCREEN;
95 mbox[3] = 8;
96 mbox[4] = 0;
97 mbox[5] = SCREEN_WIDTH;
98 mbox[6] = SCREEN_HEIGHT;
99
100 // Virtual screen.
101 mbox[7] = MBOX_TAG_SET_VSCREEN;
102 mbox[8] = 8;
103 mbox[9] = 0;
104 mbox[10] = SCREEN_WIDTH;
105 mbox[11] = SCREEN_HEIGHT;
106
107 // Bit depth.
108 mbox[12] = MBOX_TAG_SET_DEPTH;
109 mbox[13] = 4;
110 mbox[14] = 0;
111 mbox[15] = 32;
112
113 // RGB order.
114 mbox[16] = MBOX_TAG_SET_RGB;
115 mbox[17] = 4;
116 mbox[18] = 0;
117 mbox[19] = 1;
118
119 // Framebuffer request.
120 mbox[20] = MBOX_TAG_GET_FB;
121 mbox[21] = 8;
122 mbox[22] = 0;
123 mbox[23] = 0;
124 mbox[24] = 0;
125
126 // End tag.
127 mbox[25] = MBOX_TAG_END;
128
129 if (mb_call(MBOX_CH_PROP) && mbox[15] == 32 && mbox[23] != 0) {
130 framebuffer = (u32*)((uintptr_t)(mbox[23]) & 0x3FFFFFFF);
131 rgb_order = mbox[19];
132 uart_puts("Framebuffer initialized\n");
133 } else {
134 uart_puts("Unable to initialize framebuffer\n");
135 }
136}
137
87int 138int
88ppu_init(Ppu *p, Uint8 hor, Uint8 ver) { 139ppu_init(Ppu *p, Uint8 hor, Uint8 ver) {
89 p->width = 8 * hor; 140 p->width = 8 * hor;
90 p->height = 8 * ver; 141 p->height = 8 * ver;
91 142
92 // Initialize the framebuffer. 143 fb_init();
93 static MboxFramebufferRequest fb_request = {
94 .buf_size = 96,
95 .code = MBOX_REQUEST,
96 .screen_tag = {
97 .header = {
98 .id = 0x48003,
99 .buf_size = 8,
100 },
101 .width = SCREEN_WIDTH,
102 .height = SCREEN_HEIGHT,
103 },
104 .virtual_screen_tag = {
105 .header = {
106 .id = 0x48004,
107 .buf_size = 8,
108 },
109 .width = SCREEN_WIDTH,
110 .height = SCREEN_HEIGHT,
111 },
112 .depth_tag = {
113 .header = {
114 .id = 0x48005,
115 .buf_size = 4,
116 },
117 .depth = 32,
118 },
119 .framebuffer_tag = {
120 .header = {
121 .id = 0x40001,
122 .buf_size = 8,
123 },
124 .fb_addr = 0,
125 .fb_size = 0,
126 }
127 };
128
129 if (mb_call(MBOX_CH_PROP, &fb_request)
130 && fb_request.depth_tag.depth == 32
131 && fb_request.framebuffer_tag.fb_addr != 0) {
132 fb_request.framebuffer_tag.fb_addr &= 0x3FFFFFFF;
133 framebuffer = (u32*)((uintptr_t)fb_request.framebuffer_tag.fb_addr);
134 } else {
135 uart_puts("Unable initialize framebuffer\n");
136 return 0;
137 }
138 144
139 p->pixels = pixels_buf; 145 p->pixels = pixels_buf;
140 146