X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=rpikern;a=blobdiff_plain;f=src%2Fmain.c;h=03a69ea81b06776cfed1e2f9fc04901bdf550438;hp=8f502699b4d3d1c609b8b3b5b28ad3efcdecd45d;hb=322d8fe4bf7ecd74ffb5288539efd3db828aa72a;hpb=23900e0baeb014e7e0b7e8e55942771da1523050 diff --git a/src/main.c b/src/main.c index 8f50269..03a69ea 100644 --- a/src/main.c +++ b/src/main.c @@ -1,19 +1,11 @@ -/* mailbox registers (MB 0: input 1: output) - * function | MB 0 | MB 1 - * rd/wr | 00 | 20 ( upper 28: data, lower 4: channel ) - * peek | 10 | 30 - * sender | 14 | 34 - * status | 18 | 38 - * config | 1c | 3c - * - * channel 1: framebuffer - * channel 8: request - * - * read: read status reg loop while empty flag is set - * write: read status loop while full flag is set - */ #include #include +#include "asm.h" +#include "serial.h" + +#define WIDTH 640 +#define HEIGHT 480 +#define BPP 16 #ifdef RPI1 #define IOBASEADDR 0x20000000 @@ -60,34 +52,105 @@ #define PROP_TAG_CUR_STATE 0x00011 +void panic(void); +static int send_prop(uint32_t *buf); int prop_blankscr(int onoff); +int prop_setres(int xsz, int ysz); +int prop_getres(int *xsz, int *ysz); int prop_setvres(int xsz, int ysz); -void *prop_allocbuf(void); +int prop_getvres(int *xsz, int *ysz); +int prop_setdepth(int bpp); +int prop_getdepth(void); +int prop_getpitch(void); +void *prop_allocbuf(int *size); uint32_t mb_read(int chan); void mb_write(int chan, uint32_t val); +void dbgled(int x); +void exit(int x); + +uint32_t propbuf[64] __attribute__((aligned(16))); +uint32_t premade[] __attribute__((aligned(16))) = { + 80, /* size */ + 0, /* request */ + 0x00048003, 8, 0, WIDTH, HEIGHT, /* set phys */ + 0x00048004, 8, 0, WIDTH, HEIGHT, /* set virt */ + 0x00048005, 4, 0, BPP, /* set depth */ + 0, /* end */ + 0, 0, 0 /* padding */ +}; + + int main(void) { - int i; - uint16_t *fb; + int i, j, bpp, fbsize, pitch, xsz, ysz; +#if BPP == 16 + uint16_t *fb, *fbptr; +#elif BPP == 24 + unsigned char *fb, *fbptr; +#elif BPP == 32 + uint32_t *fb, *fbptr; +#endif + + disable_intr(); + + init_serial(115200); + ser_printstr("starting rpkern\n"); - prop_setvres(640, 480); - fb = prop_allocbuf(); + /*if(send_prop(premade) == -1) panic();*/ - for(i=0; i<640 * 480; i++) { - *fb++ = (i & 0xff) | ((i & 0xff) << 8); + /*if(prop_setres(WIDTH, HEIGHT) == -1) panic();*/ + if(prop_setvres(WIDTH, HEIGHT) == -1) panic(); + if(prop_setdepth(BPP) == -1) panic(); + if(!(fb = prop_allocbuf(&fbsize))) panic(); + + prop_getvres(&xsz, &ysz); + bpp = prop_getdepth(); + pitch = prop_getpitch(); + + if(xsz != WIDTH || ysz != HEIGHT) panic(); + if(bpp != BPP) panic(); + + fbptr = fb; + for(i=0; i> 1) & 0xff; + int g = xor & 0xff; + int b = (xor << 1) & 0xff; + +#if BPP == 16 + *fbptr++ = ((r << 8) & 0xf800) | ((g << 3) & 0x7e0) | ((b >> 3) & 0x1f); +#elif BPP == 24 + *fbptr++ = r; + *fbptr++ = g; + *fbptr++ = b; +#elif BPP == 32 + *fbptr++ = ((r << 16) & 0xff0000) | ((g << 8) & 0xff00) | (b & 0xff); +#endif + } + + //fbptr += pitch / 2 - 640; } + fb[0] = 0xf800; + return 0; } -static uint32_t propbuf[64] __attribute__((aligned(16))); +void panic(void) +{ + dbgled(1); + exit(0); +} static int send_prop(uint32_t *buf) { + mem_barrier(); mb_write(MB_CHAN_PROP, (uint32_t)buf >> 4); mb_read(MB_CHAN_PROP); + mem_barrier(); return propbuf[1] == PROP_RESP_OK ? 0 : -1; } @@ -95,7 +158,7 @@ int prop_blankscr(int onoff) { uint32_t *pb = propbuf; - *pb++ = 0; + *pb++ = 32; *pb++ = 0; *pb++ = PROP_TAG_BLANKSCR; *pb++ = 4; /* data size */ @@ -103,34 +166,152 @@ int prop_blankscr(int onoff) *pb++ = onoff ? 1 : 0; *pb++ = PROP_TAG_END; *pb++ = 0; /* padding */ - propbuf[0] = (char*)pb - (char*)propbuf; return send_prop(propbuf); } -int prop_setvres(int xsz, int ysz) +int prop_setres(int xsz, int ysz) { uint32_t *pb = propbuf; + *pb++ = 32; + *pb++ = 0; + *pb++ = PROP_TAG_PHYSRES | PROP_TAG_SET; + *pb++ = 8; /* data size */ + *pb++ = PROP_CODE_REQ; + *pb++ = xsz; + *pb++ = ysz; + *pb++ = PROP_TAG_END; + + return send_prop(propbuf); +} + +int prop_getres(int *xsz, int *ysz) +{ + uint32_t *pb = propbuf; + uint32_t *data; + + *pb++ = 32; + *pb++ = 0; + *pb++ = PROP_TAG_PHYSRES; + *pb++ = 8; + *pb++ = PROP_CODE_REQ; + data = pb; *pb++ = 0; *pb++ = 0; + *pb++ = PROP_TAG_END; + + if(send_prop(propbuf) == -1) { + return -1; + } + *xsz = data[0]; + *ysz = data[1]; + return 0; +} + +int prop_setvres(int xsz, int ysz) +{ + uint32_t *pb = propbuf; + + *pb++ = 32; + *pb++ = 0; *pb++ = PROP_TAG_VIRTRES | PROP_TAG_SET; *pb++ = 8; /* data size */ *pb++ = PROP_CODE_REQ; *pb++ = xsz; *pb++ = ysz; *pb++ = PROP_TAG_END; - propbuf[0] = (char*)pb - (char*)propbuf; return send_prop(propbuf); } -void *prop_allocbuf(void) +int prop_getvres(int *xsz, int *ysz) { uint32_t *pb = propbuf; uint32_t *data; + *pb++ = 32; *pb++ = 0; + *pb++ = PROP_TAG_VIRTRES; + *pb++ = 8; + *pb++ = PROP_CODE_REQ; + data = pb; + *pb++ = 0; + *pb++ = 0; + *pb++ = PROP_TAG_END; + + if(send_prop(propbuf) == -1) { + return -1; + } + *xsz = data[0]; + *ysz = data[1]; + return 0; +} + +int prop_setdepth(int bpp) +{ + uint32_t *pb = propbuf; + + *pb++ = 32; + *pb++ = 0; + *pb++ = PROP_TAG_DEPTH | PROP_TAG_SET; + *pb++ = 4; + *pb++ = PROP_CODE_REQ; + *pb++ = bpp; + *pb++ = PROP_TAG_END; + *pb++ = 0; /* padding */ + + return send_prop(propbuf); +} + +int prop_getdepth(void) +{ + uint32_t *pb = propbuf; + uint32_t *data; + + *pb++ = 32; + *pb++ = 0; + *pb++ = PROP_TAG_DEPTH; + *pb++ = 4; /* data size */ + *pb++ = PROP_CODE_REQ; + data = pb; + *pb++ = 0; + *pb++ = PROP_TAG_END; + *pb++ = 0; /* padding */ + + if(send_prop(propbuf) == -1) { + return 0; + } + return *data; +} + +int prop_getpitch(void) +{ + uint32_t *pb = propbuf; + uint32_t *data; + + *pb++ = 32; + *pb++ = 0; + *pb++ = PROP_TAG_PITCH; + *pb++ = 4; /* data size */ + *pb++ = PROP_CODE_REQ; + data = pb; + *pb++ = 0; + *pb++ = PROP_TAG_END; + *pb++ = 0; /* padding */ + + if(send_prop(propbuf) == -1) { + return 0; + } + return *data; +} + +void *prop_allocbuf(int *size) +{ + uint32_t *pb = propbuf; + uint32_t *data; + + *pb++ = 32; *pb++ = 0; *pb++ = PROP_TAG_ALLOCBUF; *pb++ = 8; /* data size */ @@ -139,20 +320,21 @@ void *prop_allocbuf(void) *pb++ = 16; /* alignment */ *pb++ = 0; *pb++ = PROP_TAG_END; - propbuf[0] = (char*)pb - (char*)propbuf; if(send_prop(propbuf) == -1) { return 0; } - - return (void*)bus2phys(*data); + *size = data[1]; + return (void*)bus2phys(data[0]); } uint32_t mb_read(int chan) { uint32_t val; do { + mem_barrier(); while(REG_MB_STAT & MB_STAT_EMPTY); + mem_barrier(); val = REG_MB_READ; } while((val & 0xf) != chan); return val >> 4; @@ -160,6 +342,10 @@ uint32_t mb_read(int chan) void mb_write(int chan, uint32_t val) { - while(REG_MB_STAT & MB_STAT_FULL); + mem_barrier(); + while(REG_MB_STAT & MB_STAT_FULL) { + mem_barrier(); + } REG_MB_WRITE = (val << 4) | chan; + mem_barrier(); }