/* * Perform I/O within region in access units of accsz bytes. * All units in bytes. */ static int32_t regio(Reg *r, void *p, uint32_t len, uintptr_t off, int iswr) { Regio rio; uintptr_t rp; DBG("reg%s %s %#p %#ullx %#lx sz=%d\n", iswr ? "out" : "in", r->name, p, off, len, r->accsz); rp = 0; if(off + len > r->len){ print("regio: access outside limits"); len = r->len - off; } if(len <= 0){ print("regio: zero len\n"); return 0; } switch(r->spc){ case Rsysmem: // XXX should map only what we are going to use // A region might be too large. if(r->p == nil) r->p = vmap(r->base, len); if(r->p == nil) error("regio: vmap failed"); rp = (uintptr_t)r->p + off; rio = memio; break; case Rsysio: rp = r->base + off; rio = ioio; break; case Rpcicfg: rp = r->base + off; rio = cfgio; rio.arg = r; break; case Rpcibar: case Rembed: case Rsmbus: case Rcmos: case Ripmi: case Rfixedhw: print("regio: reg %s not supported\n", acpiregstr(r->spc)); error("region not supported"); } if(iswr) regcpy(&rio, rp, &memio, (uintptr_t)p, len, r->accsz); else regcpy(&memio, (uintptr_t)p, &rio, rp, len, r->accsz); return len; }
// Copy the contents of the given region to dest. Return status. int regvcpy(Value *destp,Region *regp) { // Preallocate a string and copy. if(vsalloc(destp,regp->r_size + 1) != 0) return vrcset(); regcpy(destp->v_strp,regp); return rc.status; }
static void parse_url(URL *url, const char *str) { int i; regcpy(url->url, str); if(0 == memcmp(url->url, "udp://", 6)) { i = 7; url->ip = url->url + i; while(':' != *(url->url + i)) {i++;} *(url->url + i++) = '\0'; url->port = atoi(url->url + i); url->protocol = PRTCL_UDP; } else { url->filename = url->url; url->protocol = PRTCL_FILE; } }