int OF_package_to_path(int phandle, char *buf, int buflen) { static struct { char *name; int nargs; int nreturns; int phandle; char *buf; int buflen; int length; } args = { "package-to-path", 3, 1, }; ofw_stack(); if (buflen > PAGE_SIZE) return -1; args.phandle = phandle; args.buf = OF_buf; args.buflen = buflen; if (openfirmware(&args) < 0) return -1; if (args.length > 0) ofbcopy(OF_buf, buf, args.length); return args.length; }
int OF_open(char *dname) { static struct { char *name; int nargs; int nreturns; char *dname; int handle; } args = { "open", 1, 1, }; int l; ofw_stack(); if ((l = strlen(dname)) >= PAGE_SIZE) return -1; ofbcopy(dname, OF_buf, l + 1); args.dname = OF_buf; if (openfirmware(&args) == -1) return -1; return args.handle; }
int OF_write(int handle, void *addr, int len) { static struct { char *name; int nargs; int nreturns; int ihandle; void *addr; int len; int actual; } args = { "write", 3, 1, }; int l, act = 0; ofw_stack(); args.ihandle = handle; args.addr = OF_buf; for (; len > 0; len -= l, addr += l) { l = min(PAGE_SIZE, len); ofbcopy(addr, OF_buf, l); args.len = l; if (openfirmware(&args) == -1) return -1; l = args.actual; act += l; } return act; }
int OF_write(int handle, const void *addr, int len) { static struct { const char *name; int nargs; int nreturns; int ihandle; void *addr; int len; int actual; } args = { "write", 3, 1, }; int l, act = 0; const char *p = addr; ofw_stack(); args.ihandle = handle; args.addr = OF_buf; for (; len > 0; len -= l, p += l) { l = min(PAGE_SIZE, len); ofbcopy(p, OF_buf, l); args.len = l; args.actual = l; /* work around a PIBS bug */ if (openfirmware(&args) == -1) return -1; l = args.actual; act += l; } return act; }
int OF_instance_to_path(int ihandle, char *buf, int buflen) { static struct { const char *name; int nargs; int nreturns; int ihandle; char *buf; int buflen; int length; } args = { "instance-to-path", 3, 1, }; if (buflen > PAGE_SIZE) return -1; args.ihandle = ihandle; args.buf = OF_buf; args.buflen = buflen; if (openfirmware(&args) < 0) return -1; if (args.length > buflen) args.length = buflen; if (args.length > 0) ofbcopy(OF_buf, buf, args.length); return args.length; }
int OF_setprop(int handle, const char *prop, const void *buf, int buflen) { struct { const char *name; int nargs; int nreturns; int phandle; const char *prop; const void *buf; int buflen; int size; } args = { "setprop", 4, 1 }; ofw_stack(); if (buflen > NBPG) return -1; ofbcopy(buf, OF_buf, buflen); args.phandle = handle; args.prop = prop; args.buf = OF_buf; args.buflen = buflen; if (openfirmware(&args) == -1) return -1; return args.size; }
int OF_getprop(int handle, const char *prop, void *buf, int buflen) { static struct { const char *name; int nargs; int nreturns; int phandle; const char *prop; void *buf; int buflen; int size; } args = { "getprop", 4, 1, }; ofw_stack(); if (buflen > PAGE_SIZE) return -1; args.phandle = handle; args.prop = prop; args.buf = OF_buf; args.buflen = buflen; if (openfirmware(&args) == -1) return -1; if (args.size > buflen) args.size = buflen; if (args.size > 0) ofbcopy(OF_buf, buf, args.size); return args.size; }
int OF_interpret(const char *cmd, int nargs, int nreturns, ...) { va_list ap; int i, len, status; static struct { const char *name; uint32_t nargs; uint32_t nreturns; uint32_t slots[16]; } args = { "interpret", 1, 2, }; ofw_stack(); if (nreturns > 8) return -1; if ((len = strlen(cmd)) >= PAGE_SIZE) return -1; ofbcopy(cmd, OF_buf, len + 1); i = 0; args.slots[i] = (uint32_t)OF_buf; args.nargs = nargs + 1; args.nreturns = nreturns + 1; va_start(ap, nreturns); i++; while (i < args.nargs) { args.slots[i] = (uint32_t)va_arg(ap, uint32_t *); i++; } if (openfirmware(&args) == -1) return -1; status = args.slots[i]; i++; while (i < args.nargs + args.nreturns) { *va_arg(ap, uint32_t *) = args.slots[i]; i++; } va_end(ap); return status; }
/* * This assumes that character devices don't read in multiples of PAGE_SIZE. */ int OF_read(int handle, void *addr, int len) { static struct { const char *name; int nargs; int nreturns; int ihandle; void *addr; int len; int actual; } args = { "read", 3, 1, }; int l, act = 0; char *p = addr; ofw_stack(); args.ihandle = handle; args.addr = OF_buf; for (; len > 0; len -= l, p += l) { l = min(PAGE_SIZE, len); args.len = l; if (openfirmware(&args) == -1) return -1; if (args.actual > 0) { ofbcopy(OF_buf, p, args.actual); act += args.actual; } if (args.actual < l) { if (act) return act; else return args.actual; } } return act; }
void OF_boot(const char *bootspec) { static struct { const char *name; int nargs; int nreturns; char *bootspec; } args = { "boot", 1, 0, }; int l; if ((l = strlen(bootspec)) >= PAGE_SIZE) panic("OF_boot"); ofw_stack(); ofbcopy(bootspec, OF_buf, l + 1); args.bootspec = OF_buf; openfirmware(&args); while (1); /* just in case */ }