11 static int detect(void);
15 uint32_t rpi_mem_base, rpi_mem_size, rpi_vmem_base, rpi_vmem_size;
18 /* needs to by 16-byte aligned, because the address we send over the mailbox
19 * interface, will have its 4 least significant bits masked off and taken over
22 static char propbuf[256] __attribute__((aligned(16)));
23 static struct rpi_prop *wrprop, *rdprop;
28 struct rpi_prop *prop;
30 if((rpi_model = detect()) == -1) {
36 /* The model detected by detect is not accurate, get the correct board model
37 * through the mailbox property interface if possible.
38 * Also, detect the amount of CPU and GPU memory available.
41 rpi_prop(RPI_TAG_GETREV);
42 rpi_prop(RPI_TAG_GETRAM);
43 rpi_prop(RPI_TAG_GETVRAM);
44 if(rpi_prop_send() != -1) {
45 //hexdump(propbuf, sizeof propbuf);
47 while((prop = rpi_prop_next())) {
50 printf("board revision: %x\n", prop->data[0]);
51 /* TODO: guess rpi model based on board revision */
55 rpi_mem_base = prop->data[0];
56 rpi_mem_size = prop->data[1];
60 rpi_vmem_base = prop->data[0];
61 rpi_vmem_size = prop->data[1];
71 static int detect(void)
75 static uint32_t base[] = {0x20000000, 0x3f000000, 0xfe000000};
80 for(j=0; j<256; j++) {
93 PM_WDOG_REG = PM_PASSWD | 1;
94 PM_RSTC_REG = PM_PASSWD | (PM_RSTC_REG & PMRSTC_WRCFG_CLEAR) | PMRSTC_WRCFG_FULL_RESET;
98 void rpi_mbox_send(int chan, uint32_t msg)
101 while(MBOX_STATUS_REG & MBOX_STAT_FULL);
102 MBOX_WRITE_REG = (msg & 0xfffffff0) | chan;
106 uint32_t rpi_mbox_recv(int chan)
111 while(MBOX_STATUS_REG & MBOX_STAT_EMPTY);
113 } while((msg & 0xf) != chan);
115 return msg & 0xfffffff0;
118 int rpi_mbox_pending(int chan)
121 return (MBOX_STATUS_REG & MBOX_STAT_EMPTY) == 0;
126 int id, req_len, resp_len;
128 {RPI_TAG_GETMODEL, 0, 4},
129 {RPI_TAG_GETREV, 0, 4},
130 {RPI_TAG_GETRAM, 0, 8},
131 {RPI_TAG_GETVRAM, 0, 8},
132 {RPI_TAG_SETCLOCK, 4, 8},
133 {RPI_TAG_ALLOCFB, 4, 8},
134 {RPI_TAG_RELEASEFB, 0, 0},
135 {RPI_TAG_BLANKSCR, 4, 4},
136 {RPI_TAG_SETFBPHYS, 8, 8},
137 {RPI_TAG_SETFBVIRT, 8, 8},
138 {RPI_TAG_SETFBDEPTH, 4, 4},
139 {RPI_TAG_GETFBPITCH, 0, 4},
140 {RPI_TAG_SETFBOFFS, 8, 8},
141 {RPI_TAG_GETFBOFFS, 0, 8},
145 void rpi_prop(int id, ...)
147 int i, req_len = 0, resp_len = 0;
151 wrprop = (struct rpi_prop*)(propbuf + sizeof(struct rpi_prop_header));
154 for(i=0; taginfo[i].id; i++) {
155 if(taginfo[i].id == id) {
156 req_len = taginfo[i].req_len;
157 resp_len = taginfo[i].resp_len;
163 wrprop->size = resp_len;
167 for(i=0; i<resp_len >> 2; i++) {
168 if(i < req_len >> 2) {
169 wrprop->data[i] = va_arg(ap, uint32_t);
176 wrprop = RPI_PROP_NEXT(wrprop);
179 int rpi_prop_send(void)
181 struct rpi_prop_header *hdr = (struct rpi_prop_header*)propbuf;
182 uint32_t addr = (uint32_t)propbuf;
185 /* terminate with null tag */
188 size = (char*)wrprop - propbuf + 4;
190 hdr->size = (size + 15) & 0xfffffff0;
195 /* clean and invalidate cache, otherwise VC will see stale data */
196 sysctl_dcache_clean_inval(addr, hdr->size);
198 rpi_mbox_send(RPI_MBOX_PROP, addr);
199 while(rpi_mbox_recv(RPI_MBOX_PROP) != addr);
201 sysctl_dcache_clean_inval(addr, hdr->size);
203 if(hdr->res != 0x80000000) {
204 printf("Property request failed: %x\n", hdr->res);
210 struct rpi_prop *rpi_prop_next(void)
212 struct rpi_prop *res;
214 rdprop = (struct rpi_prop*)(propbuf + sizeof(struct rpi_prop_header));
217 if(rdprop->id == 0) {
221 rdprop->size = rdprop->res & 0x7fffffff;
222 rdprop = RPI_PROP_NEXT(rdprop);
227 struct rpi_prop *rpi_prop_find(int id)
229 struct rpi_prop *prop = (struct rpi_prop*)(propbuf + sizeof(struct rpi_prop_header));
232 prop->size = prop->res & 0x7fffffff;
236 prop = RPI_PROP_NEXT(prop);