static int vcreq(int tag, void *buf, int vallen, int rsplen) { uintptr r; int n; Prophdr *prop; uintptr aprop; static int busaddr = 1; if(rsplen < vallen) rsplen = vallen; rsplen = (rsplen+3) & ~3; prop = (Prophdr*)(VCBUFFER); n = sizeof(Prophdr) + rsplen + 8; memset(prop, 0, n); prop->len = n; prop->req = Req; prop->tag = tag; prop->tagbuflen = rsplen; prop->taglen = vallen; if(vallen > 0) memmove(prop->data, buf, vallen); cachedwbinvse(prop, prop->len); for(;;){ aprop = busaddr? dmaaddr(prop) : PTR2UINT(prop); vcwrite(ChanProps, aprop); r = vcread(ChanProps); if(r == aprop) break; if(!busaddr) return -1; busaddr = 0; } if(prop->req == RspOk && prop->tag == tag && (prop->taglen&TagResp)) { if((n = prop->taglen & ~TagResp) < rsplen) rsplen = n; memmove(buf, prop->data, rsplen); }else rsplen = -1; return rsplen; }
static int vcreq(int tag, void *buf, int vallen, int rsplen) { uintptr r; int n; Prophdr *prop; static uintptr base = BUSDRAM; if(rsplen < vallen) rsplen = vallen; rsplen = (rsplen+3) & ~3; prop = (Prophdr*)(VCBUFFER); n = sizeof(Prophdr) + rsplen + 8; memset(prop, 0, n); prop->len = n; prop->req = Req; prop->tag = tag; prop->tagbuflen = rsplen; prop->taglen = vallen; if(vallen > 0) memmove(prop->data, buf, vallen); cachedwbinvse(prop, prop->len); for(;;){ vcwrite(ChanProps, PADDR(prop) + base); r = vcread(ChanProps); if(r == PADDR(prop) + base) break; if(base == 0) return -1; base = 0; } if(prop->req == RspOk && prop->tag == tag && (prop->taglen&TagResp)) { if((n = prop->taglen & ~TagResp) < rsplen) rsplen = n; memmove(buf, prop->data, rsplen); }else rsplen = -1; return rsplen; }
void* fbinit(int set, int *width, int *height, int *depth) { Fbinfo *fi; uintptr va; if(!set) fbdefault(width, height, depth); /* Screen width must be a multiple of 16 */ *width &= ~0xF; fi = (Fbinfo*)(VCBUFFER); memset(fi, 0, sizeof(*fi)); fi->xres = fi->xresvirtual = *width; fi->yres = fi->yresvirtual = *height; fi->bpp = *depth; cachedwbinvse(fi, sizeof(*fi)); vcwrite(ChanFb, DMAADDR(fi)); if(vcread(ChanFb) != 0) return 0; va = mmukmap(FRAMEBUFFER, PADDR(fi->base), fi->screensize); if(va) memset((char*)va, 0x7F, fi->screensize); return (void*)va; }