--- /dev/null
+#include <stdio.h>
+#include <ctype.h>
+#include "debug.h"
+
+
+void hexdump(void *start, int nbytes)
+{
+ int i, j, nlines;
+ unsigned char *ptr = start;
+ unsigned char *end = ptr + nbytes;
+
+ nlines = (nbytes + 0xf) >> 4;
+
+ for(i=0; i<nlines; i++) {
+ printf("%08x ", (uint32_t)ptr);
+
+ for(j=0; j<16; j++) {
+ if(ptr + j < end) {
+ printf("%02x ", ptr[j]);
+ } else {
+ printf(" ");
+ }
+ if((j & 7) == 7) putchar(' ');
+ }
+
+ putchar('|');
+ for(j=0; j<16; j++) {
+ if(ptr + j < end) {
+ putchar(isprint(ptr[j]) ? ptr[j] : '.');
+ } else {
+ putchar(' ');
+ }
+ }
+ printf("|\n");
+
+ ptr += 16;
+ }
+}
--- /dev/null
+#ifndef DEBUG_H_
+#define DEBUG_H_
+
+void hexdump(void *start, int nbytes);
+
+#endif /* DEBUG_H_ */
void dbgled(int x);
+void reboot(void);
+
static void cmdrun(char *cmd);
int main(void)
return 0;
}
+void reboot(void)
+{
+ printf("Rebooting ...\n");
+ rpi_reboot();
+}
+
static void cmdrun(char *cmd)
{
char *ptr, *args;
*ptr = 0;
args = ptr + 1;
- if(strcmp(cmd, "help") == 0) {
+ if(strcmp(cmd, "reboot") == 0) {
+ reboot();
+ } else if(strcmp(cmd, "help") == 0) {
printf("help not implemented yet\n");
} else if(strcmp(cmd, "ver") == 0) {
printf("rpikern version 0.0\n");
#ifndef MEM_H_
#define MEM_H_
-#define MEM_BUS_COHERENT(addr) (((uint32_t)addr) | 0x40000000)
-#define MEM_BUS_UNCACHED(addr) (((uint32_t)addr) | 0xc0000000)
-
#endif /* MEM_H_ */
#define TMCTL_PRESCALER(x) (((uint32_t)(x) & 0xff) << 16)
+/* watchdog */
+#define PM_RSTC_REG IOREG(0x10001c)
+#define PM_WDOG_REG IOREG(0x100024)
+
+#define PM_PASSWD 0x5a000000
+#define PMRSTC_WRCFG_FULL_RESET 0x00000020
+#define PMRSTC_WRCFG_CLEAR 0xffffffcf
/* MAILBOX */
#define MBOX_READ_REG IOREG(0xb880)
return -1;
}
+void rpi_reboot(void)
+{
+ PM_WDOG_REG = PM_PASSWD | 1;
+ PM_RSTC_REG = PM_PASSWD | (PM_RSTC_REG & PMRSTC_WRCFG_CLEAR) | PMRSTC_WRCFG_FULL_RESET;
+ for(;;) halt_cpu();
+}
void rpi_mbox_send(int chan, uint32_t msg)
{
#include <stdint.h>
+
+#define RPI_MEM_BUS_COHERENT(addr) (((uint32_t)addr) | 0x40000000)
+#define RPI_MEM_BUS_UNCACHED(addr) (((uint32_t)addr) | 0xc0000000)
+
+
#define RPI_MBOX_FRAMEBUF 1
#define RPI_MBOX_PROP 8
#define RPI_TAG_ALLOCFB 0x040001
#define RPI_TAG_RELEASEFB 0x048001
+#define RPI_TAG_BLANKSCR 0x040002
#define RPI_TAG_SETFBPHYS 0x048003
#define RPI_TAG_SETFBVIRT 0x048004
#define RPI_TAG_SETFBDEPTH 0x048005
-struct rpi_tag_getmodel {
- uint32_t id, size, res;
- uint32_t model;
-};
-
-struct rpi_tag_getram {
- uint32_t id, size, res;
- uint32_t membase, memsize;
+struct rpi_prop_header {
+ uint32_t size;
+ uint32_t res;
};
-struct rpi_tag_setclock {
+struct rpi_prop {
uint32_t id, size, res;
- uint32_t clock_id, rate, skip_turbo;
+ uint32_t data[1];
};
-struct rpi_prop_header {
- uint32_t size;
- uint32_t res;
-};
+#define RPI_PROP_NEXT(p) \
+ ((struct rpi_prop*)((char*)((p) + 1) + ((p)->size - sizeof (p)->data)))
extern int rpi_model;
extern uint32_t rpi_iobase;
extern uint32_t rpi_memsize, rpi_vc_memsize;
void rpi_init(void);
+void rpi_reboot(void) __attribute__((noreturn));
void rpi_mbox_send(int chan, uint32_t msg);
uint32_t rpi_mbox_recv(int chan);
#include "rpi.h"
#include "video.h"
#include "mem.h"
+#include "debug.h"
/* needs to by 16-byte aligned, because the address we send over the mailbox
* interface, will have its 4 least significant bits masked off and taken over
* by the mailbox id
*/
-static uint8_t propbuf[64] __attribute__((aligned(16)));
+static char propbuf[256] __attribute__((aligned(16)));
+
+static void *fb_pixels;
+static int fb_width, fb_height, fb_depth, fb_size;
int video_init(void)
{
+ int i;
+ struct rpi_prop_header *hdr = (struct rpi_prop_header*)propbuf;
+ struct rpi_prop *prop = (struct rpi_prop*)(hdr + 1);
+
+ hdr->size = sizeof propbuf;
+ hdr->res = 0;
+
+ fb_width = 1024;
+ fb_height = 600;
+ fb_depth = 32;
+
+ prop->id = RPI_TAG_SETFBPHYS;
+ prop->size = 8;
+ prop->res = 0;
+ prop->data[0] = fb_width;
+ prop->data[1] = fb_height;
+ prop = RPI_PROP_NEXT(prop);
+
+ prop->id = RPI_TAG_SETFBVIRT;
+ prop->size = 8;
+ prop->res = 0;
+ prop->data[0] = fb_width;
+ prop->data[1] = fb_height;
+ prop = RPI_PROP_NEXT(prop);
+
+ prop->id = RPI_TAG_SETFBDEPTH;
+ prop->size = 4;
+ prop->res = 0;
+ prop->data[0] = fb_depth;
+ prop = RPI_PROP_NEXT(prop);
+
+ prop->id = RPI_TAG_ALLOCFB;
+ prop->size = 4;
+ prop->res = 0;
+ prop->data[0] = 4; /* alignment */
+ prop = RPI_PROP_NEXT(prop);
+
+ prop->id = 0;
+ prop->size = 0;
+ prop->res = 0;
+ prop = RPI_PROP_NEXT(prop);
+
+ printf("Requesting video mode: %dx%d (%d bpp)\n", fb_width, fb_height, fb_depth);
+
+ rpi_mbox_send(RPI_MBOX_PROP, RPI_MEM_BUS_COHERENT(propbuf));
+ while(rpi_mbox_recv(RPI_MBOX_PROP) != RPI_MEM_BUS_COHERENT(propbuf));
+
+ hexdump(propbuf, sizeof propbuf);
+
+ if(hdr->res != 0x80000000) {
+ printf("Request failed, error: %x\n", hdr->res);
+ return -1;
+ }
+
+ prop = (struct rpi_prop*)(hdr + 1);
+ while(prop->id) {
+ prop->size = prop->res & 0x7fffffff;
+
+ switch(prop->id) {
+ case RPI_TAG_SETFBPHYS:
+ printf("setfbphys");
+ break;
+
+ case RPI_TAG_SETFBVIRT:
+ printf("setfbvirt");
+ fb_width = prop->data[0];
+ fb_height = prop->data[1];
+ break;
+
+ case RPI_TAG_SETFBDEPTH:
+ printf("setfbdepth");
+ fb_depth = prop->data[0];
+ break;
+
+ case RPI_TAG_ALLOCFB:
+ printf("allocfb");
+ fb_pixels = (void*)prop->data[0];
+ fb_size = prop->data[1];
+ break;
+
+ default:
+ printf("tag %x", prop->id);
+ break;
+ }
+
+ printf(" %08x (%u bytes):", prop->res, prop->size);
+ for(i=0; i<prop->size / 4; i++) {
+ printf(" %u", prop->data[i]);
+ }
+ putchar('\n');
+ prop = RPI_PROP_NEXT(prop);
+ }
+
+ printf("Got video mode: %dx%d (%d bpp) at %p (%d bytes)\n", fb_width, fb_height,
+ fb_depth, fb_pixels, fb_size);
+
+ memset(fb_pixels, 0, fb_size);
return 0;
}