diff options
Diffstat (limited to 'qemu/roms/openbios/libopenbios/client.c')
-rw-r--r-- | qemu/roms/openbios/libopenbios/client.c | 367 |
1 files changed, 0 insertions, 367 deletions
diff --git a/qemu/roms/openbios/libopenbios/client.c b/qemu/roms/openbios/libopenbios/client.c deleted file mode 100644 index 8b3d582b6..000000000 --- a/qemu/roms/openbios/libopenbios/client.c +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Creation Date: <2003/11/25 14:29:08 samuel> - * Time-stamp: <2004/03/27 01:13:53 samuel> - * - * <client.c> - * - * OpenFirmware client interface - * - * Copyright (C) 2003, 2004 Samuel Rydh (samuel@ibrium.se) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 - * - */ - -#include "config.h" -#include "libopenbios/bindings.h" -#include "libopenbios/of.h" - -/* Uncomment to enable debug printout of client interface calls */ -//#define DEBUG_CIF -//#define DUMP_IO - -/* OF client interface. r3 points to the argument array. On return, - * r3 should contain 0==true or -1==false. r4-r12,cr0,cr1 may - * be modified freely. - * - * -1 should only be returned if the control transfer to OF fails - * (it doesn't) or if the function is unimplemented. - */ - -#define PROM_MAX_ARGS 10 -typedef struct prom_args { - prom_uarg_t service; - prom_arg_t nargs; - prom_arg_t nret; - prom_uarg_t args[PROM_MAX_ARGS]; -} __attribute__((packed)) prom_args_t; - -static inline const char * -arg2pointer(prom_uarg_t value) -{ - return (char*)(uintptr_t)value; -} - -static inline const char * -get_service(prom_args_t *pb) -{ - return arg2pointer(pb->service); -} - -#ifdef DEBUG_CIF -static void memdump(const char *mem, unsigned long size) -{ - int i; - - if (size == (unsigned long) -1) - return; - - for (i = 0; i < size; i += 16) { - int j; - - printk("0x%08lx ", (unsigned long)mem + i); - - for (j = 0; j < 16 && i + j < size; j++) - printk(" %02x", *(unsigned char*)(mem + i + j)); - - for ( ; j < 16; j++) - printk(" __"); - - printk(" "); - - for (j = 0; j < 16 && i + j < size; j++) { - unsigned char c = *(mem + i + j); - if (isprint(c)) - printk("%c", c); - else - printk("."); - } - printk("\n"); - } -} - -static void dump_service(prom_args_t *pb) -{ - int i; - const char *service = get_service(pb); - if (strcmp(service, "test") == 0) { - printk("test(\"%s\") = ", arg2pointer(pb->args[0])); - } else if (strcmp(service, "peer") == 0) { - printk("peer(0x" FMT_prom_uargx ") = ", pb->args[0]); - } else if (strcmp(service, "child") == 0) { - printk("child(0x" FMT_prom_uargx ") = ", pb->args[0]); - } else if (strcmp(service, "parent") == 0) { - printk("parent(0x" FMT_prom_uargx ") = ", pb->args[0]); - } else if (strcmp(service, "instance-to-package") == 0) { - printk("instance-to-package(0x" FMT_prom_uargx ") = ", pb->args[0]); - } else if (strcmp(service, "getproplen") == 0) { - printk("getproplen(0x" FMT_prom_uargx ", \"%s\") = ", - pb->args[0], arg2pointer(pb->args[1])); - } else if (strcmp(service, "getprop") == 0) { - printk("getprop(0x" FMT_prom_uargx ", \"%s\", 0x" FMT_prom_uargx ", " FMT_prom_arg ") = ", - pb->args[0], arg2pointer(pb->args[1]), - pb->args[2], pb->args[3]); - } else if (strcmp(service, "nextprop") == 0) { - printk("nextprop(0x" FMT_prom_uargx ", \"%s\", 0x" FMT_prom_uargx ") = ", - pb->args[0], arg2pointer(pb->args[1]), pb->args[2]); - } else if (strcmp(service, "setprop") == 0) { - printk("setprop(0x" FMT_prom_uargx ", \"%s\", 0x" FMT_prom_uargx ", " FMT_prom_arg ")\n", - pb->args[0], arg2pointer(pb->args[1]), - pb->args[2], pb->args[3]); - memdump(arg2pointer(pb->args[2]), pb->args[3]); - printk(" = "); - } else if (strcmp(service, "canon") == 0) { - printk("canon(\"%s\", 0x" FMT_prom_uargx ", " FMT_prom_arg ")\n", - arg2pointer(pb->args[0]), pb->args[1], pb->args[2]); - } else if (strcmp(service, "finddevice") == 0) { - printk("finddevice(\"%s\") = ", arg2pointer(pb->args[0])); - } else if (strcmp(service, "instance-to-path") == 0) { - printk("instance-to-path(0x" FMT_prom_uargx ", 0x" FMT_prom_uargx ", " FMT_prom_arg ") = ", - pb->args[0], pb->args[1], pb->args[2]); - } else if (strcmp(service, "package-to-path") == 0) { - printk("package-to-path(0x" FMT_prom_uargx ", 0x" FMT_prom_uargx ", " FMT_prom_arg ") = ", - pb->args[0], pb->args[1], pb->args[2]); - } else if (strcmp(service, "open") == 0) { - printk("open(\"%s\") = ", arg2pointer(pb->args[0])); - } else if (strcmp(service, "close") == 0) { - printk("close(0x" FMT_prom_uargx ")\n", pb->args[0]); - } else if (strcmp(service, "read") == 0) { -#ifdef DUMP_IO - printk("read(0x" FMT_prom_uargx ", 0x" FMT_prom_uargx ", " FMT_prom_arg ") = ", - pb->args[0], pb->args[1], pb->args[2]); -#endif - } else if (strcmp(service, "write") == 0) { -#ifdef DUMP_IO - printk("write(0x" FMT_prom_uargx ", 0x" FMT_prom_uargx ", " FMT_prom_arg ")\n", - pb->args[0], pb->args[1], pb->args[2]); - memdump(arg2pointer(pb->args[1]), pb->args[2]); - printk(" = "); -#endif - } else if (strcmp(service, "seek") == 0) { -#ifdef DUMP_IO - printk("seek(0x" FMT_prom_uargx ", 0x" FMT_prom_uargx ", 0x" FMT_prom_uargx ") = ", - pb->args[0], pb->args[1], pb->args[2]); -#endif - } else if (strcmp(service, "claim") == 0) { - printk("claim(0x" FMT_prom_uargx ", " FMT_prom_arg ", " FMT_prom_arg ") = ", - pb->args[0], pb->args[1], pb->args[2]); - } else if (strcmp(service, "release") == 0) { - printk("release(0x" FMT_prom_uargx ", " FMT_prom_arg ")\n", - pb->args[0], pb->args[1]); - } else if (strcmp(service, "boot") == 0) { - printk("boot \"%s\"\n", arg2pointer(pb->args[0])); - } else if (strcmp(service, "enter") == 0) { - printk("enter()\n"); - } else if (strcmp(service, "exit") == 0) { - printk("exit()\n"); - } else if (strcmp(service, "test-method") == 0) { - printk("test-method(0x" FMT_prom_uargx ", \"%s\") = ", - pb->args[0], arg2pointer(pb->args[1])); - } else { - printk("of_client_interface: %s", service); - for( i = 0; i < pb->nargs; i++ ) - printk(" " FMT_prom_uargx, pb->args[i]); - printk("\n"); - } -} - -static void dump_return(prom_args_t *pb) -{ - int i; - const char *service = get_service(pb); - if (strcmp(service, "test") == 0) { - printk(FMT_prom_arg "\n", pb->args[pb->nargs]); - } else if (strcmp(service, "peer") == 0) { - printk("0x" FMT_prom_uargx "\n", pb->args[pb->nargs]); - } else if (strcmp(service, "child") == 0) { - printk("0x" FMT_prom_uargx "\n", pb->args[pb->nargs]); - } else if (strcmp(service, "parent") == 0) { - printk("0x" FMT_prom_uargx "\n", pb->args[pb->nargs]); - } else if (strcmp(service, "instance-to-package") == 0) { - printk("0x" FMT_prom_uargx "\n", pb->args[pb->nargs]); - } else if (strcmp(service, "getproplen") == 0) { - printk("0x" FMT_prom_uargx "\n", pb->args[pb->nargs]); - } else if (strcmp(service, "getprop") == 0) { - printk(FMT_prom_arg "\n", pb->args[pb->nargs]); - if ((prom_arg_t)pb->args[pb->nargs] != -1) - memdump(arg2pointer(pb->args[2]), MIN(pb->args[3], pb->args[pb->nargs])); - } else if (strcmp(service, "nextprop") == 0) { - printk(FMT_prom_arg "\n", pb->args[pb->nargs]); - memdump(arg2pointer(pb->args[2]), 32); - } else if (strcmp(service, "setprop") == 0) { - printk(FMT_prom_arg "\n", pb->args[pb->nargs]); - } else if (strcmp(service, "canon") == 0) { - printk(FMT_prom_arg "\n", pb->args[pb->nargs]); - memdump(arg2pointer(pb->args[1]), pb->args[pb->nargs]); - } else if (strcmp(service, "finddevice") == 0) { - printk("0x" FMT_prom_uargx "\n", pb->args[pb->nargs]); - } else if (strcmp(service, "instance-to-path") == 0) { - printk(FMT_prom_arg "\n", pb->args[pb->nargs]); - memdump(arg2pointer(pb->args[1]), pb->args[pb->nargs]); - } else if (strcmp(service, "package-to-path") == 0) { - printk(FMT_prom_arg "\n", pb->args[pb->nargs]); - memdump(arg2pointer(pb->args[1]), pb->args[pb->nargs]); - } else if (strcmp(service, "open") == 0) { - printk("0x" FMT_prom_uargx "\n", pb->args[pb->nargs]); - } else if (strcmp(service, "close") == 0) { - /* do nothing */ - } else if (strcmp(service, "read") == 0) { -#ifdef DUMP_IO - printk(FMT_prom_arg "\n", pb->args[pb->nargs]); - memdump(arg2pointer(pb->args[1]), pb->args[pb->nargs]); -#endif - } else if (strcmp(service, "write") == 0) { -#ifdef DUMP_IO - printk(FMT_prom_arg "\n", pb->args[pb->nargs]); -#endif - } else if (strcmp(service, "seek") == 0) { -#ifdef DUMP_IO - printk(FMT_prom_arg "\n", pb->args[pb->nargs]); -#endif - } else if (strcmp(service, "claim") == 0) { - printk("0x" FMT_prom_uargx "\n", pb->args[pb->nargs]); - } else if (strcmp(service, "release") == 0) { - /* do nothing */ - } else if (strcmp(service, "boot") == 0) { - /* do nothing */ - } else if (strcmp(service, "enter") == 0) { - /* do nothing */ - } else if (strcmp(service, "exit") == 0) { - /* do nothing */ - } else if (strcmp(service, "test-method") == 0) { - printk("0x" FMT_prom_uargx "\n", pb->args[pb->nargs]); - } else { - printk("of_client_interface return:"); - for (i = 0; i < pb->nret; i++) { - printk(" " FMT_prom_uargx, pb->args[pb->nargs + i]); - } - printk("\n"); - } -} -#endif - -/* call-method, interpret */ -static int -handle_calls(prom_args_t *pb) -{ - int i, j, dstacksave; - ucell val; - -#ifdef DEBUG_CIF - printk("%s %s ([" FMT_prom_arg "] -- [" FMT_prom_arg "])\n", - get_service(pb), arg2pointer(pb->args[0]), pb->nargs, pb->nret); -#endif - - dstacksave = dstackcnt; - for (i = pb->nargs - 1; i >= 0; i--) - PUSH(pb->args[i]); - - push_str(get_service(pb)); - fword("client-call-iface"); - - /* Ignore client-call-iface return */ - POP(); - - /* If the catch result is non-zero, restore stack and exit */ - val = POP(); - if (val) { - printk("%s %s failed with error " FMT_ucellx "\n", get_service(pb), arg2pointer(pb->args[0]), val); - dstackcnt = dstacksave; - return 0; - } - - /* Store catch result */ - pb->args[pb->nargs] = val; - - j = dstackcnt; - for (i = 1; i < pb->nret; i++, j--) { - if (dstackcnt > dstacksave) { - pb->args[pb->nargs + i] = POP(); - } - } - -#ifdef DEBUG_CIF - /* useful for debug but not necessarily an error */ - if (j != dstacksave) { - printk("%s '%s': possible argument error (" FMT_prom_arg "--" FMT_prom_arg ") got %d\n", - get_service(pb), arg2pointer(pb->args[0]), - pb->nargs - 2, pb->nret, j - dstacksave); - } - - printk("handle_calls return:"); - for (i = 0; i < pb->nret; i++) { - printk(" " FMT_prom_uargx, pb->args[pb->nargs + i]); - } - printk("\n"); -#endif - - dstackcnt = dstacksave; - return 0; -} - -int -of_client_interface(int *params) -{ - prom_args_t *pb = (prom_args_t*)params; - ucell val; - int i, j, dstacksave; - - if (pb->nargs < 0 || pb->nret < 0 || - pb->nargs + pb->nret > PROM_MAX_ARGS) - return -1; - -#ifdef DEBUG_CIF - dump_service(pb); -#endif - - /* call-method exceptions are special */ - if (!strcmp("call-method", get_service(pb)) || !strcmp("interpret", get_service(pb))) - return handle_calls(pb); - - dstacksave = dstackcnt; - for (i = pb->nargs - 1; i >= 0; i--) - PUSH(pb->args[i]); - - push_str(get_service(pb)); - fword("client-iface"); - - val = POP(); - if (val) { - if (val == -1) { - printk("Unimplemented service %s ([" FMT_prom_arg "] -- [" FMT_prom_arg "])\n", - get_service(pb), pb->nargs, pb->nret); - } else { -#ifdef DEBUG_CIF - printk("Error calling client interface: " FMT_ucellx "\n", val); -#endif - } - - dstackcnt = dstacksave; - return -1; - } - - j = dstackcnt; - for (i = 0; i < pb->nret; i++, j--) { - if (dstackcnt > dstacksave) { - pb->args[pb->nargs + i] = POP(); - } - } - -#ifdef DEBUG_CIF - if (j != dstacksave) { - printk("service %s: possible argument error (%d %d)\n", - get_service(pb), i, j - dstacksave); - - /* Some clients request less parameters than the CIF method - returns, e.g. getprop with OpenSolaris. Hence we drop any - stack parameters on exit after issuing a warning above */ - } - - dump_return(pb); -#endif - - dstackcnt = dstacksave; - return 0; -} |