blob: c1a212ec6c2847a8e0d95577d8f450c0893e46b6 [file] [log] [blame]
/*
* callofw.c - Open Firmware client interface for 32-bit systems.
* This code is intended to be portable to any 32-bit Open Firmware
* implementation with a standard client interface that can be
* called when Linux is running.
*/
#include <stdarg.h>
typedef unsigned long u32;
extern u32 call_firmware(u32 *);
#define MAXARGS 20
int callofw(char *name, int numargs, int numres, ...)
{
va_list ap;
u32 argarray[MAXARGS+3];
int argnum = 3;
int retval;
int *intp;
unsigned long flags;
argarray[0] = (u32)name;
argarray[1] = numargs;
argarray[2] = numres;
if ((numargs + numres) > MAXARGS)
return -1;
va_start(ap, numres);
while (numargs--)
argarray[argnum++] = va_arg(ap, int);
retval = call_firmware(argarray);
if (retval == 0) {
while (numres--) {
intp = va_arg(ap, int *);
*intp = argarray[argnum++];
}
}
va_end(ap);
return retval;
}
/*
The return value from callofw in all cases is 0 if the attempt to call the
function succeeded, nonzero otherwise. That return value is from the
gateway function only. Any results from the called function are returned
via output argument pointers.
Here are call templates for all the standard OFW client services.
callofw("test", 1, 1, namestr, &missing);
callofw("peer", 1, 1, phandle, &sibling_phandle);
callofw("child", 1, 1, phandle, &child_phandle);
callofw("parent", 1, 1, phandle, &parent_phandle);
callofw("instance-to-package", 1, 1, ihandle, &phandle);
callofw("getproplen", 2, 1, phandle, namestr, &proplen);
callofw("getprop", 4, 1, phandle, namestr, bufaddr, buflen, &size);
callofw("nextprop", 3, 1, phandle, previousstr, bufaddr, &flag);
callofw("setprop", 4, 1, phandle, namestr, bufaddr, len, &size);
callofw("canon", 3, 1, devspecstr, bufaddr, buflen, &length);
callofw("finddevice", 1, 1, devspecstr, &phandle);
callofw("instance-to-path", 3, 1, ihandle, bufaddr, buflen, &length);
callofw("instance-to-interposed-path", 3, 1, ihandle, bufaddr, buflen, &length);
callofw("package-to-path", 3, 1, phandle, bufaddr, buflen, &length);
callofw("call-method", numin, numout, in0, in1, ..., &out0, &out1, ...);
callofw("open", 1, 1, devspecstr, &ihandle);
callofw("close", 1, 0, ihandle);
callofw("read", 3, 1, ihandle, addr, len, &actual);
callofw("write", 3, 1, ihandle, addr, len, &actual);
callofw("seek", 3, 1, ihandle, pos_hi, pos_lo, &status);
callofw("claim", 3, 1, virtaddr, size, align, &baseaddr);
callofw("release", 2, 0, virtaddr, size);
callofw("boot", 1, 0, bootspecstr);
callofw("enter", 0, 0);
callofw("exit", 0, 0);
callofw("chain", 5, 0, virtaddr, size, entryaddr, argsaddr, len);
callofw("interpret", numin+1, numout+1, cmdstr, in0, ..., &catchres, &out0, ...);
callofw("set-callback", 1, 1, newfuncaddr, &oldfuncaddr);
callofw("set-symbol-lookup", 2, 0, symtovaladdr, valtosymaddr);
callofw("milliseconds", 0, 1, &ms);
*/