451 lines
8.6 KiB
C
451 lines
8.6 KiB
C
|
|
#include "of1275.h"
|
|
#include "endian.h"
|
|
static int (*of1275_server) (void *) = (int (*)(void *)) -1;
|
|
|
|
_start(void *residual_data_structure,
|
|
void *program_entry_point,
|
|
int (*client_interface_handler) (void *), void *args, int argslen)
|
|
{
|
|
int status;
|
|
of1275_server = client_interface_handler;
|
|
status = main();
|
|
of1275_exit(status);
|
|
}
|
|
|
|
/* 6.3.2.1 Client interface */
|
|
|
|
|
|
int of1275_test(const char *name, int *missing)
|
|
{
|
|
int result;
|
|
static of1275_test_service s;
|
|
s.service = "test";
|
|
s.n_args = 1;
|
|
s.n_returns = 1;
|
|
s.name = name;
|
|
result = of1275_server(&s);
|
|
*missing = s.missing;
|
|
return result;
|
|
}
|
|
|
|
|
|
/* 6.3.2.2 Device tree */
|
|
|
|
|
|
int of1275_peer(int phandle, int *sibling_phandle)
|
|
{
|
|
int result;
|
|
static of1275_peer_service s;
|
|
s.service = "peer";
|
|
s.n_args = 1;
|
|
s.n_returns = 1;
|
|
s.phandle = phandle;
|
|
result = of1275_server(&s);
|
|
*sibling_phandle = s.sibling_phandle;
|
|
return result;
|
|
}
|
|
|
|
int of1275_child(int phandle, int *child_phandle)
|
|
{
|
|
int result;
|
|
static of1275_child_service s;
|
|
s.service = "child";
|
|
s.n_args = 1;
|
|
s.n_returns = 1;
|
|
s.phandle = phandle;
|
|
result = of1275_server(&s);
|
|
*child_phandle = s.child_phandle;
|
|
return result;
|
|
}
|
|
|
|
int of1275_parent(int phandle, int *parent_phandle)
|
|
{
|
|
int result;
|
|
static of1275_parent_service s;
|
|
s.service = "parent";
|
|
s.n_args = 1;
|
|
s.n_returns = 1;
|
|
s.phandle = phandle;
|
|
result = of1275_server(&s);
|
|
*parent_phandle = s.parent_phandle;
|
|
return result;
|
|
}
|
|
|
|
int of1275_instance_to_package(int ihandle, int *phandle)
|
|
{
|
|
int result;
|
|
static of1275_instance_to_package_service s;
|
|
s.service = "instance-to-package";
|
|
s.n_args = 1;
|
|
s.n_returns = 1;
|
|
s.ihandle = ihandle;
|
|
result = of1275_server(&s);
|
|
*phandle = s.phandle;
|
|
return result;
|
|
}
|
|
|
|
int of1275_getproplen(int phandle, const char *name, int *proplen)
|
|
{
|
|
int result;
|
|
static of1275_getproplen_service s;
|
|
s.service = "getproplen";
|
|
s.n_args = 2;
|
|
s.n_returns = 1;
|
|
s.phandle = phandle;
|
|
s.name = name;
|
|
result = of1275_server(&s);
|
|
*proplen = s.proplen;
|
|
return result;
|
|
}
|
|
|
|
int
|
|
of1275_getprop(int phandle, const char *name, void *buf, int buflen,
|
|
int *size)
|
|
{
|
|
int result;
|
|
static of1275_getprop_service s;
|
|
s.service = "getprop";
|
|
s.n_args = 4;
|
|
s.n_returns = 1;
|
|
s.phandle = phandle;
|
|
s.name = name;
|
|
s.buf = buf;
|
|
s.buflen = buflen;
|
|
result = of1275_server(&s);
|
|
*size = s.size;
|
|
return result;
|
|
}
|
|
|
|
int
|
|
of1275_nextprop(int phandle, const char *previous, void *buf, int *flag)
|
|
{
|
|
int result;
|
|
static of1275_nextprop_service s;
|
|
s.service = "nextprop";
|
|
s.n_args = 3;
|
|
s.n_returns = 1;
|
|
s.phandle = phandle;
|
|
s.previous = previous;
|
|
s.buf = buf;
|
|
result = of1275_server(&s);
|
|
*flag = s.flag;
|
|
return result;
|
|
}
|
|
|
|
int
|
|
of1275_setprop(int phandle, const char *name, void *buf, int len,
|
|
int *size)
|
|
{
|
|
int result;
|
|
static of1275_setprop_service s;
|
|
s.service = "setprop";
|
|
s.n_args = 4;
|
|
s.n_returns = 1;
|
|
s.phandle = phandle;
|
|
s.name = name;
|
|
s.buf = buf;
|
|
s.len = len;
|
|
result = of1275_server(&s);
|
|
*size = s.size;
|
|
return result;
|
|
}
|
|
|
|
int
|
|
of1275_canon(const char *device_specifier, void *buf, int buflen,
|
|
int *length)
|
|
{
|
|
int result;
|
|
static of1275_canon_service s;
|
|
s.service = "canon";
|
|
s.n_args = 3;
|
|
s.n_returns = 1;
|
|
s.device_specifier = device_specifier;
|
|
s.buf = buf;
|
|
s.buflen = buflen;
|
|
result = of1275_server(&s);
|
|
*length = s.length;
|
|
return result;
|
|
}
|
|
|
|
int of1275_finddevice(const char *device_specifier, int *phandle)
|
|
{
|
|
int result;
|
|
static of1275_finddevice_service s;
|
|
s.service = "finddevice";
|
|
s.n_args = 1;
|
|
s.n_returns = 1;
|
|
s.device_specifier = device_specifier;
|
|
result = of1275_server(&s);
|
|
*phandle = s.phandle;
|
|
return result;
|
|
}
|
|
|
|
int
|
|
of1275_instance_to_path(int ihandle, void *buf, int buflen, int *length)
|
|
{
|
|
int result;
|
|
static of1275_instance_to_path_service s;
|
|
s.service = "instance-to-path";
|
|
s.n_args = 3;
|
|
s.n_returns = 1;
|
|
s.ihandle = ihandle;
|
|
s.buf = buf;
|
|
s.buflen = buflen;
|
|
result = of1275_server(&s);
|
|
*length = s.length;
|
|
return result;
|
|
}
|
|
|
|
int of1275_package_to_path(int phandle, void *buf, int buflen, int *length)
|
|
{
|
|
int result;
|
|
static of1275_package_to_path_service s;
|
|
s.service = "package-to-path";
|
|
s.n_args = 3;
|
|
s.n_returns = 1;
|
|
s.phandle = phandle;
|
|
s.buf = buf;
|
|
s.buflen = buflen;
|
|
result = of1275_server(&s);
|
|
*length = s.length;
|
|
return result;
|
|
}
|
|
|
|
/* int of1275_call_method(const char *method, int ihandle, ...); */
|
|
|
|
|
|
/* 6.3.2.3 Device I/O */
|
|
|
|
|
|
int of1275_open(const char *device_specifier, int *ihandle)
|
|
{
|
|
int result;
|
|
static of1275_open_service s;
|
|
s.service = "open";
|
|
s.n_args = 1;
|
|
s.n_returns = 1;
|
|
s.device_specifier = device_specifier;
|
|
result = of1275_server(&s);
|
|
*ihandle = s.ihandle;
|
|
return result;
|
|
}
|
|
|
|
int of1275_close(int ihandle)
|
|
{
|
|
int result;
|
|
static of1275_close_service s;
|
|
s.service = "close";
|
|
s.n_args = 1;
|
|
s.n_returns = 0;
|
|
s.ihandle = ihandle;
|
|
result = of1275_server(&s);
|
|
return result;
|
|
}
|
|
|
|
int of1275_read(int ihandle, void *addr, int len, int *actual)
|
|
{
|
|
int result;
|
|
static of1275_read_service s;
|
|
s.service = "read";
|
|
s.n_args = 3;
|
|
s.n_returns = 1;
|
|
s.ihandle = ihandle;
|
|
s.addr = addr;
|
|
s.len = len;
|
|
result = of1275_server(&s);
|
|
*actual = s.actual;
|
|
return result;
|
|
}
|
|
|
|
int of1275_write(int ihandle, void *addr, int len, int *actual)
|
|
{
|
|
int result;
|
|
static of1275_write_service s;
|
|
s.service = "write";
|
|
s.n_args = 3;
|
|
s.n_returns = 1;
|
|
s.ihandle = ihandle;
|
|
s.addr = addr;
|
|
s.len = len;
|
|
result = of1275_server(&s);
|
|
*actual = s.actual;
|
|
return result;
|
|
}
|
|
|
|
int of1275_seek(int ihandle, int pos_hi, int pos_lo, int *status)
|
|
{
|
|
int result;
|
|
static of1275_seek_service s;
|
|
s.service = "seek";
|
|
s.n_args = 3;
|
|
s.n_returns = 1;
|
|
s.ihandle = ihandle;
|
|
s.pos_hi = pos_hi;
|
|
s.pos_lo = pos_lo;
|
|
result = of1275_server(&s);
|
|
*status = s.status;
|
|
return result;
|
|
}
|
|
|
|
|
|
/* 6.3.2.4 Memory */
|
|
|
|
|
|
int of1275_claim(void *virt, int size, int align, void **baseaddr)
|
|
{
|
|
int result;
|
|
static of1275_claim_service s;
|
|
s.service = "claim";
|
|
s.n_args = 3;
|
|
s.n_returns = 1;
|
|
s.virt = virt;
|
|
s.size = size;
|
|
s.align = align;
|
|
result = of1275_server(&s);
|
|
*baseaddr = s.baseaddr;
|
|
return result;
|
|
}
|
|
|
|
int of1275_release(void *virt, int size)
|
|
{
|
|
int result;
|
|
static of1275_release_service s;
|
|
s.service = "release";
|
|
s.n_args = 2;
|
|
s.n_returns = 0;
|
|
s.virt = virt;
|
|
s.size = size;
|
|
result = of1275_server(&s);
|
|
return result;
|
|
}
|
|
|
|
|
|
/* 6.3.2.5 Control transfer */
|
|
|
|
|
|
int of1275_boot(const char *bootspec)
|
|
{
|
|
int result;
|
|
static of1275_boot_service s;
|
|
s.service = "boot";
|
|
s.n_args = 1;
|
|
s.n_returns = 0;
|
|
s.bootspec = bootspec;
|
|
result = of1275_server(&s);
|
|
return result;
|
|
}
|
|
|
|
int of1275_enter(void)
|
|
{
|
|
int result;
|
|
static of1275_enter_service s;
|
|
s.service = "enter";
|
|
s.n_args = 0;
|
|
s.n_returns = 0;
|
|
result = of1275_server(&s);
|
|
return result;
|
|
}
|
|
|
|
int of1275_exit(int status)
|
|
{
|
|
int result;
|
|
static of1275_exit_service s;
|
|
s.service = "exit";
|
|
s.n_args = 1;
|
|
s.n_returns = 0;
|
|
s.status = status;
|
|
result = of1275_server(&s);
|
|
return result;
|
|
}
|
|
|
|
/* int of1275_chain(void *virt, int size, void *entry, void *args, int len); */
|
|
|
|
|
|
/* 6.3.2.6 User interface */
|
|
|
|
|
|
/* int of1275_interpret(const char *arg, ...); */
|
|
|
|
int of1275_set_callback(void *newfunc, void **oldfunc)
|
|
{
|
|
int result;
|
|
static of1275_set_callback_service s;
|
|
s.service = "set-callback";
|
|
s.n_args = 1;
|
|
s.n_returns = 1;
|
|
s.newfunc = newfunc;
|
|
result = of1275_server(&s);
|
|
*oldfunc = s.oldfunc;
|
|
return result;
|
|
}
|
|
|
|
int of1275_set_symbol_lookup(void *sym_to_value, void *value_to_sym)
|
|
{
|
|
int result;
|
|
static of1275_set_symbol_lookup_service s;
|
|
s.service = "set-symbol-lookup";
|
|
s.n_args = 2;
|
|
s.n_returns = 0;
|
|
s.sym_to_value = sym_to_value;
|
|
s.value_to_sym = s.value_to_sym;
|
|
result = of1275_server(&s);
|
|
return result;
|
|
}
|
|
|
|
|
|
/* 6.3.2.7 Time */
|
|
|
|
int of1275_milliseconds(int *ms)
|
|
{
|
|
int result;
|
|
static of1275_milliseconds_service s;
|
|
s.service = "milliseconds";
|
|
s.n_args = 0;
|
|
s.n_returns = 1;
|
|
result = of1275_server(&s);
|
|
*ms = s.ms;
|
|
return result;
|
|
}
|
|
|
|
|
|
int of_find_integer_property(const char *device, const char *property)
|
|
{
|
|
int phandle;
|
|
int integer;
|
|
int size;
|
|
/* find the device's phandle */
|
|
if (of1275_finddevice(device, &phandle) < 0) {
|
|
//printk("of1275: no such device '%s'\n", device);
|
|
exit(1);
|
|
}
|
|
/* find the device's property */
|
|
of1275_getprop(phandle, property, &integer,
|
|
sizeof(integer), &size);
|
|
if (size < sizeof(integer)) {
|
|
//printk("of1275: unknown integer property '%s'\n", property);
|
|
exit(1);
|
|
}
|
|
return ntohl(integer);
|
|
}
|
|
|
|
void
|
|
of_find_string_property(const char *device,
|
|
const char *property,
|
|
char *string, int sizeof_string)
|
|
{
|
|
int phandle;
|
|
int size;
|
|
/* find the device's phandle */
|
|
if (of1275_finddevice(device, &phandle) < 0) {
|
|
//printk("of1275: no such device '%s'\n", device);
|
|
exit(1);
|
|
}
|
|
|
|
/* find the device's property */
|
|
of1275_getprop(phandle, property, string, sizeof_string, &size);
|
|
if (size == 0 || size >= sizeof_string) {
|
|
//printk("of1275: unknown string property '%s'\n", property);
|
|
exit(1);
|
|
}
|
|
}
|