more debugging, and serial port
[rpikern] / src / main.c
1 #include <string.h>
2 #include <stdint.h>
3 #include "asm.h"
4 #include "serial.h"
5
6 #define WIDTH   640
7 #define HEIGHT  480
8 #define BPP             16
9
10 #ifdef RPI1
11 #define IOBASEADDR      0x20000000
12 #else
13 #define IOBASEADDR      0x3f000000
14 #endif
15
16 #define phys2bus(addr)  ((addr) | 0x40000000)
17 #define bus2phys(addr)  ((addr) & 0x3fffffff)
18
19 #define IOREG_ADDR(x)   (IOBASEADDR | (x))
20 #define REG_MB_READ             *((volatile uint32_t*)IOREG_ADDR(0xb880))
21 #define REG_MB_STAT             *((volatile uint32_t*)IOREG_ADDR(0xb898))
22 #define REG_MB_WRITE    *((volatile uint32_t*)IOREG_ADDR(0xb8a0))
23
24 #define MB_STAT_FULL    0x80000000
25 #define MB_STAT_EMPTY   0x40000000
26
27 #define MB_CHAN_FRAMEBUF        1
28 #define MB_CHAN_PROP            8
29
30 #define PROP_CODE_REQ   0
31 #define PROP_RESP_OK    0x80000000
32
33
34 #define PROP_TAG_END                    0
35
36 #define PROP_TAG_SET                    0x08000
37 #define PROP_TAG_TEST                   0x04000
38 #define PROP_TAG_GET                    0
39
40 #define PROP_TAG_ALLOCBUF               0x40001
41 #define PROP_TAG_BLANKSCR               0x40002
42 #define PROP_TAG_PHYSRES                0x40003
43 #define PROP_TAG_VIRTRES                0x40004
44 #define PROP_TAG_DEPTH                  0x40005
45 #define PROP_TAG_PIXEL_ORDER    0x40006
46 #define PROP_TAG_ALPHA_MODE             0x40007
47 #define PROP_TAG_PITCH                  0x40008
48 #define PROP_TAG_VOFFS                  0x40009
49 #define PROP_TAG_OVERSCAN               0x4000a
50 #define PROP_TAG_PALETTE                0x4000b
51 #define PROP_TAG_CUR_INFO               0x00010
52 #define PROP_TAG_CUR_STATE              0x00011
53
54
55 void panic(void);
56 static int send_prop(uint32_t *buf);
57 int prop_blankscr(int onoff);
58 int prop_setres(int xsz, int ysz);
59 int prop_getres(int *xsz, int *ysz);
60 int prop_setvres(int xsz, int ysz);
61 int prop_getvres(int *xsz, int *ysz);
62 int prop_setdepth(int bpp);
63 int prop_getdepth(void);
64 int prop_getpitch(void);
65 void *prop_allocbuf(int *size);
66
67 uint32_t mb_read(int chan);
68 void mb_write(int chan, uint32_t val);
69
70 void dbgled(int x);
71 void exit(int x);
72
73 uint32_t propbuf[64] __attribute__((aligned(16)));
74 uint32_t premade[] __attribute__((aligned(16))) = {
75         80,                             /* size */
76         0,                              /* request */
77         0x00048003, 8, 0, WIDTH, HEIGHT,        /* set phys */
78         0x00048004, 8, 0, WIDTH, HEIGHT,        /* set virt */
79         0x00048005, 4, 0, BPP,                          /* set depth */
80         0,                              /* end */
81         0, 0, 0                 /* padding */
82 };
83
84
85 int main(void)
86 {
87         int i, j, bpp, fbsize, pitch, xsz, ysz;
88 #if BPP == 16
89         uint16_t *fb, *fbptr;
90 #elif BPP == 24
91         unsigned char *fb, *fbptr;
92 #elif BPP == 32
93         uint32_t *fb, *fbptr;
94 #endif
95
96         disable_intr();
97
98         init_serial(115200);
99         ser_printstr("starting rpkern\n");
100
101         /*if(send_prop(premade) == -1) panic();*/
102
103         /*if(prop_setres(WIDTH, HEIGHT) == -1) panic();*/
104         if(prop_setvres(WIDTH, HEIGHT) == -1) panic();
105         if(prop_setdepth(BPP) == -1) panic();
106         if(!(fb = prop_allocbuf(&fbsize))) panic();
107
108         prop_getvres(&xsz, &ysz);
109         bpp = prop_getdepth();
110         pitch = prop_getpitch();
111
112         if(xsz != WIDTH || ysz != HEIGHT) panic();
113         if(bpp != BPP) panic();
114
115         fbptr = fb;
116         for(i=0; i<HEIGHT; i++) {
117                 for(j=0; j<WIDTH; j++) {
118                         int xor = i ^ j;
119                         int r = (xor >> 1) & 0xff;
120                         int g = xor & 0xff;
121                         int b = (xor << 1) & 0xff;
122
123 #if BPP == 16
124                         *fbptr++ = ((r << 8) & 0xf800) | ((g << 3) & 0x7e0) | ((b >> 3) & 0x1f);
125 #elif BPP == 24
126                         *fbptr++ = r;
127                         *fbptr++ = g;
128                         *fbptr++ = b;
129 #elif BPP == 32
130                         *fbptr++ = ((r << 16) & 0xff0000) | ((g << 8) & 0xff00) | (b & 0xff);
131 #endif
132                 }
133
134                 //fbptr += pitch / 2 - 640;
135         }
136
137         fb[0] = 0xf800;
138
139         return 0;
140 }
141
142 void panic(void)
143 {
144         dbgled(1);
145         exit(0);
146 }
147
148 static int send_prop(uint32_t *buf)
149 {
150         mem_barrier();
151         mb_write(MB_CHAN_PROP, (uint32_t)buf >> 4);
152         mb_read(MB_CHAN_PROP);
153         mem_barrier();
154         return propbuf[1] == PROP_RESP_OK ? 0 : -1;
155 }
156
157 int prop_blankscr(int onoff)
158 {
159         uint32_t *pb = propbuf;
160
161         *pb++ = 32;
162         *pb++ = 0;
163         *pb++ = PROP_TAG_BLANKSCR;
164         *pb++ = 4;      /* data size */
165         *pb++ = PROP_CODE_REQ;
166         *pb++ = onoff ? 1 : 0;
167         *pb++ = PROP_TAG_END;
168         *pb++ = 0;      /* padding */
169
170         return send_prop(propbuf);
171 }
172
173 int prop_setres(int xsz, int ysz)
174 {
175         uint32_t *pb = propbuf;
176
177         *pb++ = 32;
178         *pb++ = 0;
179         *pb++ = PROP_TAG_PHYSRES | PROP_TAG_SET;
180         *pb++ = 8;      /* data size */
181         *pb++ = PROP_CODE_REQ;
182         *pb++ = xsz;
183         *pb++ = ysz;
184         *pb++ = PROP_TAG_END;
185
186         return send_prop(propbuf);
187 }
188
189 int prop_getres(int *xsz, int *ysz)
190 {
191         uint32_t *pb = propbuf;
192         uint32_t *data;
193
194         *pb++ = 32;
195         *pb++ = 0;
196         *pb++ = PROP_TAG_PHYSRES;
197         *pb++ = 8;
198         *pb++ = PROP_CODE_REQ;
199         data = pb;
200         *pb++ = 0;
201         *pb++ = 0;
202         *pb++ = PROP_TAG_END;
203
204         if(send_prop(propbuf) == -1) {
205                 return -1;
206         }
207         *xsz = data[0];
208         *ysz = data[1];
209         return 0;
210 }
211
212 int prop_setvres(int xsz, int ysz)
213 {
214         uint32_t *pb = propbuf;
215
216         *pb++ = 32;
217         *pb++ = 0;
218         *pb++ = PROP_TAG_VIRTRES | PROP_TAG_SET;
219         *pb++ = 8;      /* data size */
220         *pb++ = PROP_CODE_REQ;
221         *pb++ = xsz;
222         *pb++ = ysz;
223         *pb++ = PROP_TAG_END;
224
225         return send_prop(propbuf);
226 }
227
228 int prop_getvres(int *xsz, int *ysz)
229 {
230         uint32_t *pb = propbuf;
231         uint32_t *data;
232
233         *pb++ = 32;
234         *pb++ = 0;
235         *pb++ = PROP_TAG_VIRTRES;
236         *pb++ = 8;
237         *pb++ = PROP_CODE_REQ;
238         data = pb;
239         *pb++ = 0;
240         *pb++ = 0;
241         *pb++ = PROP_TAG_END;
242
243         if(send_prop(propbuf) == -1) {
244                 return -1;
245         }
246         *xsz = data[0];
247         *ysz = data[1];
248         return 0;
249 }
250
251 int prop_setdepth(int bpp)
252 {
253         uint32_t *pb = propbuf;
254
255         *pb++ = 32;
256         *pb++ = 0;
257         *pb++ = PROP_TAG_DEPTH | PROP_TAG_SET;
258         *pb++ = 4;
259         *pb++ = PROP_CODE_REQ;
260         *pb++ = bpp;
261         *pb++ = PROP_TAG_END;
262         *pb++ = 0;      /* padding */
263
264         return send_prop(propbuf);
265 }
266
267 int prop_getdepth(void)
268 {
269         uint32_t *pb = propbuf;
270         uint32_t *data;
271
272         *pb++ = 32;
273         *pb++ = 0;
274         *pb++ = PROP_TAG_DEPTH;
275         *pb++ = 4;      /* data size */
276         *pb++ = PROP_CODE_REQ;
277         data = pb;
278         *pb++ = 0;
279         *pb++ = PROP_TAG_END;
280         *pb++ = 0;      /* padding */
281
282         if(send_prop(propbuf) == -1) {
283                 return 0;
284         }
285         return *data;
286 }
287
288 int prop_getpitch(void)
289 {
290         uint32_t *pb = propbuf;
291         uint32_t *data;
292
293         *pb++ = 32;
294         *pb++ = 0;
295         *pb++ = PROP_TAG_PITCH;
296         *pb++ = 4;      /* data size */
297         *pb++ = PROP_CODE_REQ;
298         data = pb;
299         *pb++ = 0;
300         *pb++ = PROP_TAG_END;
301         *pb++ = 0;      /* padding */
302
303         if(send_prop(propbuf) == -1) {
304                 return 0;
305         }
306         return *data;
307 }
308
309 void *prop_allocbuf(int *size)
310 {
311         uint32_t *pb = propbuf;
312         uint32_t *data;
313
314         *pb++ = 32;
315         *pb++ = 0;
316         *pb++ = PROP_TAG_ALLOCBUF;
317         *pb++ = 8;      /* data size */
318         *pb++ = PROP_CODE_REQ;
319         data = pb;
320         *pb++ = 16;     /* alignment */
321         *pb++ = 0;
322         *pb++ = PROP_TAG_END;
323
324         if(send_prop(propbuf) == -1) {
325                 return 0;
326         }
327         *size = data[1];
328         return (void*)bus2phys(data[0]);
329 }
330
331 uint32_t mb_read(int chan)
332 {
333         uint32_t val;
334         do {
335                 mem_barrier();
336                 while(REG_MB_STAT & MB_STAT_EMPTY);
337                 mem_barrier();
338                 val = REG_MB_READ;
339         } while((val & 0xf) != chan);
340         return val >> 4;
341 }
342
343 void mb_write(int chan, uint32_t val)
344 {
345         mem_barrier();
346         while(REG_MB_STAT & MB_STAT_FULL) {
347                 mem_barrier();
348         }
349         REG_MB_WRITE = (val << 4) | chan;
350         mem_barrier();
351 }