diff options
Diffstat (limited to 'qemu/roms/openbios/utils/ofclient')
-rw-r--r-- | qemu/roms/openbios/utils/ofclient/Makefile | 14 | ||||
-rw-r--r-- | qemu/roms/openbios/utils/ofclient/README | 4 | ||||
-rw-r--r-- | qemu/roms/openbios/utils/ofclient/endian.h | 18 | ||||
-rw-r--r-- | qemu/roms/openbios/utils/ofclient/of1275.c | 451 | ||||
-rw-r--r-- | qemu/roms/openbios/utils/ofclient/of1275.h | 437 | ||||
-rw-r--r-- | qemu/roms/openbios/utils/ofclient/of1275_io.c | 51 | ||||
-rw-r--r-- | qemu/roms/openbios/utils/ofclient/ofclient.c | 9 |
7 files changed, 984 insertions, 0 deletions
diff --git a/qemu/roms/openbios/utils/ofclient/Makefile b/qemu/roms/openbios/utils/ofclient/Makefile new file mode 100644 index 000000000..f3c515964 --- /dev/null +++ b/qemu/roms/openbios/utils/ofclient/Makefile @@ -0,0 +1,14 @@ +PROGRAM := ofclient +OBJECTS := of1275.o of1275_io.o ofclient.o +CC := gcc +CFLAGS := -m32 -fpic -fno-builtin-strlen -Os +LDFLAGS := -melf_i386 -s -N -Ttext 0x200000 -e _start + +$(PROGRAM): $(OBJECTS) + $(LD) $(LDFLAGS) -Map $(PROGRAM).map -o $(PROGRAM) $(OBJECTS) + +clean: + rm -f $(OBJECTS) + +distclean: clean + rm -f $(PROGRAM) $(PROGRAM).map diff --git a/qemu/roms/openbios/utils/ofclient/README b/qemu/roms/openbios/utils/ofclient/README new file mode 100644 index 000000000..785f6ec2d --- /dev/null +++ b/qemu/roms/openbios/utils/ofclient/README @@ -0,0 +1,4 @@ +This is an example program using the openfirmware client +interface on x86. The same program can be compiled on ppc. + + diff --git a/qemu/roms/openbios/utils/ofclient/endian.h b/qemu/roms/openbios/utils/ofclient/endian.h new file mode 100644 index 000000000..4d20e7171 --- /dev/null +++ b/qemu/roms/openbios/utils/ofclient/endian.h @@ -0,0 +1,18 @@ + +#define __bswap32(x) \ + ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) + +static int little_endian(void) +{ + static short one=1; + return *(char *)&one==1; +} + +static unsigned int ntohl(unsigned int netlong) +{ + if(little_endian()) + return __bswap32(netlong); + + return netlong; +} diff --git a/qemu/roms/openbios/utils/ofclient/of1275.c b/qemu/roms/openbios/utils/ofclient/of1275.c new file mode 100644 index 000000000..ff0778279 --- /dev/null +++ b/qemu/roms/openbios/utils/ofclient/of1275.c @@ -0,0 +1,451 @@ + +#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); + } +} diff --git a/qemu/roms/openbios/utils/ofclient/of1275.h b/qemu/roms/openbios/utils/ofclient/of1275.h new file mode 100644 index 000000000..a73bb19a8 --- /dev/null +++ b/qemu/roms/openbios/utils/ofclient/of1275.h @@ -0,0 +1,437 @@ +/* OpenFirmware interface */ + + +/* 6.3.2.1 Client interface */ + + +typedef struct _of1275_test_service { + const char *service; + int n_args; + int n_returns; + /*in */ + const char *name; + /*out */ + int missing; +} of1275_test_service; + +int of1275_test(const char *name, int *missing); + + +/* 6.3.2.2 Device tree */ + + +typedef struct _of1275_peer_service { + const char *service; + int n_args; + int n_returns; + /*in */ + int phandle; + /*out */ + int sibling_phandle; +} of1275_peer_service; + +int of1275_peer(int phandle, int *sibling_phandle); + + +typedef struct _of1275_child_service { + const char *service; + int n_args; + int n_returns; + /*in */ + int phandle; + /*out */ + int child_phandle; +} of1275_child_service; + +int of1275_child(int phandle, int *child_phandle); + + +typedef struct _of1275_parent_service { + const char *service; + int n_args; + int n_returns; + /*in */ + int phandle; + /*out */ + int parent_phandle; +} of1275_parent_service; + +int of1275_child(int phandle, int *parent_phandle); + + +typedef struct _of1275_instance_to_package_service { + const char *service; + int n_args; + int n_returns; + /*in */ + int ihandle; + /*out */ + int phandle; +} of1275_instance_to_package_service; + +int of1275_instance_to_package(int ihandle, int *phandle); + + +typedef struct _of1275_getproplen_service { + const char *service; + int n_args; + int n_returns; + /*in */ + int phandle; + const char *name; + /*out */ + int proplen; +} of1275_getproplen_service; + +int of1275_getproplen(int phandle, const char *name, int *proplen); + + +typedef struct _of1275_getprop_service { + const char *service; + int n_args; + int n_returns; + /*in */ + int phandle; + const char *name; + void *buf; + int buflen; + /*out */ + int size; +} of1275_getprop_service; + +int of1275_getprop(int phandle, const char *name, void *buf, int buflen, + int *size); + + +typedef struct _of1275_nextprop_service { + const char *service; + int n_args; + int n_returns; + /*in */ + int phandle; + const char *previous; + void *buf; + /*out */ + int flag; +} of1275_nextprop_service; + +int of1275_nextprop(int phandle, const char *previous, void *buf, + int *flag); + + +typedef struct _of1275_setprop_service { + const char *service; + int n_args; + int n_returns; + /*in */ + int phandle; + const char *name; + void *buf; + int len; + /*out */ + int size; +} of1275_setprop_service; + +int of1275_setprop(int phandle, const char *name, void *buf, int len, + int *size); + + +typedef struct _of1275_canon_service { + const char *service; + int n_args; + int n_returns; + /*in */ + const char *device_specifier; + void *buf; + int buflen; + /*out */ + int length; +} of1275_canon_service; + +int of1275_canon(const char *device_specifier, void *buf, int buflen, + int *length); + + +typedef struct _of1275_finddevice_service { + const char *service; + int n_args; + int n_returns; + /*in */ + const char *device_specifier; + /*out */ + int phandle; +} of1275_finddevice_service; + +int of1275_finddevice(const char *device_specifier, int *phandle); + + +typedef struct _of1275_instance_to_path_service { + const char *service; + int n_args; + int n_returns; + /*in */ + int ihandle; + void *buf; + int buflen; + /*out */ + int length; +} of1275_instance_to_path_service; + +int of1275_instance_to_path(int ihandle, void *buf, int buflen, + int *length); + + +typedef struct _of1275_package_to_path_service { + const char *service; + int n_args; + int n_returns; + /*in */ + int phandle; + void *buf; + int buflen; + /*out */ + int length; +} of1275_package_to_path_service; + +int of1275_package_to_path(int phandle, void *buf, int buflen, + int *length); + + +typedef struct _of1275_call_method_service { + const char *service; + int n_args; + int n_returns; + /*in */ + const char *method; + int ihandle; + /*... */ + int args[0]; +} of1275_call_method_service; + +int of1275_call_method(const char *method, int ihandle, ...); + + +/* 6.3.2.3 Device I/O */ + + +typedef struct _of1275_open_service { + const char *service; + int n_args; + int n_returns; + /*in */ + const char *device_specifier; + /*out */ + int ihandle; +} of1275_open_service; + +int of1275_open(const char *device_specifier, int *ihandle); + + +typedef struct _of1275_close_service { + const char *service; + int n_args; + int n_returns; + /*in */ + int ihandle; + /*out */ +} of1275_close_service; + +int of1275_close(int ihandle); + + +typedef struct _of1275_read_service { + const char *service; + int n_args; + int n_returns; + /*in */ + int ihandle; + void *addr; + int len; + /*out */ + int actual; +} of1275_read_service; + +int of1275_read(int ihandle, void *addr, int len, int *actual); + + +typedef struct _of1275_write_service { + const char *service; + int n_args; + int n_returns; + /*in */ + int ihandle; + void *addr; + int len; + /*out */ + int actual; +} of1275_write_service; + +int of1275_write(int ihandle, void *addr, int len, int *actual); + + +typedef struct _of1275_seek_service { + const char *service; + int n_args; + int n_returns; + /*in */ + int ihandle; + int pos_hi; + int pos_lo; + /*out */ + int status; +} of1275_seek_service; + +int of1275_seek(int ihandle, int pos_hi, int pos_lo, int *status); + + +/* 6.3.2.4 Memory */ + + +typedef struct _of1275_claim_service { + const char *service; + int n_args; + int n_returns; + /*in */ + void *virt; + int size; + int align; + /*out */ + void *baseaddr; +} of1275_claim_service; + +int of1275_claim(void *virt, int size, int align, void **baseaddr); + + +typedef struct _of1275_release_service { + const char *service; + int n_args; + int n_returns; + /*in */ + void *virt; + int size; + int align; + /*out */ +} of1275_release_service; + +int of1275_release(void *virt, int size); + + +/* 6.3.2.5 Control transfer */ + + +typedef struct _of1275_boot_service { + const char *service; + int n_args; + int n_returns; + /*in */ + const char *bootspec; + /*out */ +} of1275_boot_service; + +int of1275_boot(const char *bootspec); + + +typedef struct _of1275_enter_service { + const char *service; + int n_args; + int n_returns; + /*in */ + /*out */ +} of1275_enter_service; + +int of1275_enter(void); + +typedef struct _of1275_exit_service { + const char *service; + int n_args; + int n_returns; + /*in */ + int status; + /*out */ +} of1275_exit_service; + +int of1275_exit(int status); + + +typedef struct _of1275_chain_service { + const char *service; + int n_args; + int n_returns; + /*in */ + void *virt; + int size; + void *entry; + void *args; + int len; + /*out */ +} of1275_chain_service; + +int of1275_chain(void *virt, int size, void *entry, void *args, int len); + + +/* 6.3.2.6 User interface */ + + +typedef struct _of1275_interpret_service { + const char *service; + int n_args; + int n_returns; + /*in */ + const char *cmd; + int args[0]; + /*... */ + /*out */ + /*... */ +} of1275_interpret_service; + +int of1275_interpret(const char *arg, ...); + + +typedef struct _of1275_set_callback_service { + const char *service; + int n_args; + int n_returns; + /*in */ + void *newfunc; + /*out */ + void *oldfunc; +} of1275_set_callback_service; + +int of1275_set_callback(void *newfunc, void **oldfunc); + + +typedef struct _of1275_set_symbol_lookup_service { + const char *service; + int n_args; + int n_returns; + /*in */ + void *sym_to_value; + void *value_to_sym; + /*out */ +} of1275_set_symbol_lookup_service; + +int of1275_set_symbol_lookup(void *sym_to_value, void *value_to_sym); + + +/* 6.3.2.7 Time */ + + +typedef struct _of1275_milliseconds_service { + const char *service; + int n_args; + int n_returns; + /*in */ + /*out */ + int ms; +} of1275_milliseconds_service; + +int of1275_milliseconds(int *ms); + + +/* Common and useful utilities */ + + +int of_find_integer_property(const char *path, const char *property); + +void of_find_string_property(const char *path, const char *property, + char *string, int sizeof_string); diff --git a/qemu/roms/openbios/utils/ofclient/of1275_io.c b/qemu/roms/openbios/utils/ofclient/of1275_io.c new file mode 100644 index 000000000..25d1132c3 --- /dev/null +++ b/qemu/roms/openbios/utils/ofclient/of1275_io.c @@ -0,0 +1,51 @@ +#include "of1275.h" + +static int of_write_initialized = 0; +static int stdout_ihandle = 0; +static int of_read_initialized = 0; +static int stdin_ihandle = 0; + +int write(int fd, char *buf, int len) +{ + int actual; + + if (fd != 1 && fd != 2) { + // printk("write: bad id %x\n", fd); + exit(1); + } + + if (!of_write_initialized) { + stdout_ihandle = + of_find_integer_property("/chosen", "stdout"); + // printk("stdout_ihandle: %x\n",stdout_ihandle); + of_write_initialized = 1; + } + + of1275_write(stdout_ihandle, buf, len, &actual); + return actual; +} + +int read(int fd, char *buf, int len) +{ + int actual; + + if (fd != 0) { + // printk("write: bad id %x\n", fd); + exit(1); + } + + if (!of_read_initialized) { + stdin_ihandle = + of_find_integer_property("/chosen", "stdin"); + of_read_initialized = 1; + } + + of1275_read(stdin_ihandle, buf, len, &actual); + return actual; +} + +exit(int status) +{ + of1275_exit(status); + while (1); +} diff --git a/qemu/roms/openbios/utils/ofclient/ofclient.c b/qemu/roms/openbios/utils/ofclient/ofclient.c new file mode 100644 index 000000000..94214c6ca --- /dev/null +++ b/qemu/roms/openbios/utils/ofclient/ofclient.c @@ -0,0 +1,9 @@ +#include "of1275.h" + +int write(int fd, char *buf, int len); + +int main(void) +{ + write(1, "Hello world!\n", 13 ); + return 0; +} |