Annotation of qemu/roms/openbios/libopenbios/client.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *   Creation Date: <2003/11/25 14:29:08 samuel>
        !             3:  *   Time-stamp: <2004/03/27 01:13:53 samuel>
        !             4:  *
        !             5:  *     <client.c>
        !             6:  *
        !             7:  *     OpenFirmware client interface
        !             8:  *
        !             9:  *   Copyright (C) 2003, 2004 Samuel Rydh ([email protected])
        !            10:  *
        !            11:  *   This program is free software; you can redistribute it and/or
        !            12:  *   modify it under the terms of the GNU General Public License
        !            13:  *   version 2
        !            14:  *
        !            15:  */
        !            16: 
        !            17: #include "config.h"
        !            18: #include "libopenbios/bindings.h"
        !            19: #include "libopenbios/of.h"
        !            20: 
        !            21: /* Uncomment to enable debug printout of client interface calls */
        !            22: //#define DEBUG_CIF
        !            23: //#define DUMP_IO
        !            24: 
        !            25: /* OF client interface. r3 points to the argument array. On return,
        !            26:  * r3 should contain 0==true or -1==false. r4-r12,cr0,cr1 may
        !            27:  * be modified freely.
        !            28:  *
        !            29:  * -1 should only be returned if the control transfer to OF fails
        !            30:  * (it doesn't) or if the function is unimplemented.
        !            31:  */
        !            32: 
        !            33: #define PROM_MAX_ARGS  10
        !            34: typedef struct prom_args {
        !            35:     prom_uarg_t service;
        !            36:     prom_arg_t  nargs;
        !            37:     prom_arg_t  nret;
        !            38:     prom_uarg_t args[PROM_MAX_ARGS];
        !            39: } __attribute__((packed)) prom_args_t;
        !            40: 
        !            41: static inline const char *
        !            42: arg2pointer(prom_uarg_t value)
        !            43: {
        !            44:     return (char*)(uintptr_t)value;
        !            45: }
        !            46: 
        !            47: static inline const char *
        !            48: get_service(prom_args_t *pb)
        !            49: {
        !            50:     return arg2pointer(pb->service);
        !            51: }
        !            52: 
        !            53: #ifdef DEBUG_CIF
        !            54: static void memdump(const char *mem, unsigned long size)
        !            55: {
        !            56:        int i;
        !            57:        
        !            58:        if (size == (unsigned long) -1)
        !            59:                return;
        !            60: 
        !            61:        for (i = 0; i < size; i += 16) {
        !            62:                int j;
        !            63: 
        !            64:                printk("0x%08lx ", (unsigned long)mem + i);
        !            65: 
        !            66:                for (j = 0; j < 16 && i + j < size; j++)
        !            67:                        printk(" %02x", *(unsigned char*)(mem + i + j));
        !            68: 
        !            69:                for ( ; j < 16; j++)
        !            70:                        printk(" __");
        !            71: 
        !            72:                printk("  ");
        !            73: 
        !            74:                for (j = 0; j < 16 && i + j < size; j++) {
        !            75:                        unsigned char c = *(mem + i + j);
        !            76:                        if (isprint(c))
        !            77:                                printk("%c", c);
        !            78:                        else
        !            79:                                printk(".");
        !            80:                }
        !            81:                printk("\n");
        !            82:        }
        !            83: }
        !            84: 
        !            85: static void dump_service(prom_args_t *pb)
        !            86: {
        !            87:        int i;
        !            88:        const char *service = get_service(pb);
        !            89:        if (strcmp(service, "test") == 0) {
        !            90:                printk("test(\"%s\") = ", arg2pointer(pb->args[0]));
        !            91:        } else if (strcmp(service, "peer") == 0) {
        !            92:                printk("peer(0x" FMT_prom_uargx ") = ", pb->args[0]);
        !            93:        } else if (strcmp(service, "child") == 0) {
        !            94:                printk("child(0x" FMT_prom_uargx ") = ", pb->args[0]);
        !            95:        } else if (strcmp(service, "parent") == 0) {
        !            96:                printk("parent(0x" FMT_prom_uargx ") = ", pb->args[0]);
        !            97:        } else if (strcmp(service, "instance-to-package") == 0) {
        !            98:                printk("instance-to-package(0x" FMT_prom_uargx ") = ", pb->args[0]);
        !            99:        } else if (strcmp(service, "getproplen") == 0) {
        !           100:                printk("getproplen(0x" FMT_prom_uargx ", \"%s\") = ",
        !           101:                        pb->args[0], arg2pointer(pb->args[1]));
        !           102:        } else if (strcmp(service, "getprop") == 0) {
        !           103:                printk("getprop(0x" FMT_prom_uargx ", \"%s\", 0x" FMT_prom_uargx ", " FMT_prom_arg ") = ",
        !           104:                        pb->args[0], arg2pointer(pb->args[1]),
        !           105:                        pb->args[2], pb->args[3]);
        !           106:        } else if (strcmp(service, "nextprop") == 0) {
        !           107:                printk("nextprop(0x" FMT_prom_uargx ", \"%s\", 0x" FMT_prom_uargx ") = ",
        !           108:                        pb->args[0], arg2pointer(pb->args[1]), pb->args[2]);
        !           109:        } else if (strcmp(service, "setprop") == 0) {
        !           110:                printk("setprop(0x" FMT_prom_uargx ", \"%s\", 0x" FMT_prom_uargx ", " FMT_prom_arg ")\n",
        !           111:                        pb->args[0], arg2pointer(pb->args[1]),
        !           112:                        pb->args[2], pb->args[3]);
        !           113:                memdump(arg2pointer(pb->args[2]), pb->args[3]);
        !           114:                printk(" = ");
        !           115:        } else if (strcmp(service, "canon") == 0) {
        !           116:                printk("canon(\"%s\", 0x" FMT_prom_uargx ", " FMT_prom_arg ")\n",
        !           117:                        arg2pointer(pb->args[0]), pb->args[1], pb->args[2]);
        !           118:        } else if (strcmp(service, "finddevice") == 0) {
        !           119:                printk("finddevice(\"%s\") = ", arg2pointer(pb->args[0]));
        !           120:        } else if (strcmp(service, "instance-to-path") == 0) {
        !           121:                printk("instance-to-path(0x" FMT_prom_uargx ", 0x" FMT_prom_uargx ", " FMT_prom_arg ") = ",
        !           122:                        pb->args[0], pb->args[1], pb->args[2]);
        !           123:        } else if (strcmp(service, "package-to-path") == 0) {
        !           124:                printk("package-to-path(0x" FMT_prom_uargx ", 0x" FMT_prom_uargx ", " FMT_prom_arg ") = ",
        !           125:                        pb->args[0], pb->args[1], pb->args[2]);
        !           126:        } else if (strcmp(service, "open") == 0) {
        !           127:                printk("open(\"%s\") = ", arg2pointer(pb->args[0]));
        !           128:        } else if (strcmp(service, "close") == 0) {
        !           129:                printk("close(0x" FMT_prom_uargx ")\n", pb->args[0]);
        !           130:        } else if (strcmp(service, "read") == 0) {
        !           131: #ifdef DUMP_IO
        !           132:                printk("read(0x" FMT_prom_uargx ", 0x" FMT_prom_uargx ", " FMT_prom_arg ") = ",
        !           133:                        pb->args[0], pb->args[1], pb->args[2]);
        !           134: #endif
        !           135:        } else if (strcmp(service, "write") == 0) {
        !           136: #ifdef DUMP_IO
        !           137:                printk("write(0x" FMT_prom_uargx ", 0x" FMT_prom_uargx ", " FMT_prom_arg ")\n",
        !           138:                        pb->args[0], pb->args[1], pb->args[2]);
        !           139:                memdump(arg2pointer(pb->args[1]), pb->args[2]);
        !           140:                printk(" = ");
        !           141: #endif
        !           142:        } else if (strcmp(service, "seek") == 0) {
        !           143: #ifdef DUMP_IO
        !           144:                printk("seek(0x" FMT_prom_uargx ", 0x" FMT_prom_uargx ", 0x" FMT_prom_uargx ") = ",
        !           145:                        pb->args[0], pb->args[1], pb->args[2]);
        !           146: #endif
        !           147:        } else if (strcmp(service, "claim") == 0) {
        !           148:                printk("claim(0x" FMT_prom_uargx ", " FMT_prom_arg ", " FMT_prom_arg ") = ",
        !           149:                        pb->args[0], pb->args[1], pb->args[2]);
        !           150:        } else if (strcmp(service, "release") == 0) {
        !           151:                printk("release(0x" FMT_prom_uargx ", " FMT_prom_arg ")\n",
        !           152:                        pb->args[0], pb->args[1]);
        !           153:        } else if (strcmp(service, "boot") == 0) {
        !           154:                printk("boot \"%s\"\n", arg2pointer(pb->args[0]));
        !           155:        } else if (strcmp(service, "enter") == 0) {
        !           156:                printk("enter()\n");
        !           157:        } else if (strcmp(service, "exit") == 0) {
        !           158:                printk("exit()\n");
        !           159:        } else if (strcmp(service, "test-method") == 0) {
        !           160:                printk("test-method(0x" FMT_prom_uargx ", \"%s\") = ",
        !           161:                        pb->args[0], arg2pointer(pb->args[1]));
        !           162:        } else {
        !           163:                printk("of_client_interface: %s", service);
        !           164:                for( i = 0; i < pb->nargs; i++ )
        !           165:                        printk(" " FMT_prom_uargx, pb->args[i]);
        !           166:                printk("\n");
        !           167:        }
        !           168: }
        !           169: 
        !           170: static void dump_return(prom_args_t *pb)
        !           171: {
        !           172:        int i;
        !           173:        const char *service = get_service(pb);
        !           174:        if (strcmp(service, "test") == 0) {
        !           175:                printk(FMT_prom_arg "\n", pb->args[pb->nargs]);
        !           176:        } else if (strcmp(service, "peer") == 0) {
        !           177:                printk("0x" FMT_prom_uargx "\n", pb->args[pb->nargs]);
        !           178:        } else if (strcmp(service, "child") == 0) {
        !           179:                printk("0x" FMT_prom_uargx "\n", pb->args[pb->nargs]);
        !           180:        } else if (strcmp(service, "parent") == 0) {
        !           181:                printk("0x" FMT_prom_uargx "\n", pb->args[pb->nargs]);
        !           182:        } else if (strcmp(service, "instance-to-package") == 0) {
        !           183:                printk("0x" FMT_prom_uargx "\n", pb->args[pb->nargs]);
        !           184:        } else if (strcmp(service, "getproplen") == 0) {
        !           185:                printk("0x" FMT_prom_uargx "\n", pb->args[pb->nargs]);
        !           186:        } else if (strcmp(service, "getprop") == 0) {
        !           187:                printk(FMT_prom_arg "\n", pb->args[pb->nargs]);
        !           188:                if ((prom_arg_t)pb->args[pb->nargs] != -1)
        !           189:                        memdump(arg2pointer(pb->args[2]), MIN(pb->args[3], pb->args[pb->nargs]));
        !           190:        } else if (strcmp(service, "nextprop") == 0) {
        !           191:                printk(FMT_prom_arg "\n", pb->args[pb->nargs]);
        !           192:                memdump(arg2pointer(pb->args[2]), pb->args[pb->nargs]);
        !           193:        } else if (strcmp(service, "setprop") == 0) {
        !           194:                printk(FMT_prom_arg "\n", pb->args[pb->nargs]);
        !           195:        } else if (strcmp(service, "canon") == 0) {
        !           196:                printk(FMT_prom_arg "\n", pb->args[pb->nargs]);
        !           197:                memdump(arg2pointer(pb->args[1]), pb->args[pb->nargs]);
        !           198:        } else if (strcmp(service, "finddevice") == 0) {
        !           199:                printk("0x" FMT_prom_uargx "\n", pb->args[pb->nargs]);
        !           200:        } else if (strcmp(service, "instance-to-path") == 0) {
        !           201:                printk(FMT_prom_arg "\n", pb->args[pb->nargs]);
        !           202:                memdump(arg2pointer(pb->args[1]), pb->args[pb->nargs]);
        !           203:        } else if (strcmp(service, "package-to-path") == 0) {
        !           204:                printk(FMT_prom_arg "\n", pb->args[pb->nargs]);
        !           205:                memdump(arg2pointer(pb->args[1]), pb->args[pb->nargs]);
        !           206:        } else if (strcmp(service, "open") == 0) {
        !           207:                printk("0x" FMT_prom_uargx "\n", pb->args[pb->nargs]);
        !           208:        } else if (strcmp(service, "close") == 0) {
        !           209:                /* do nothing */
        !           210:        } else if (strcmp(service, "read") == 0) {
        !           211: #ifdef DUMP_IO
        !           212:                printk(FMT_prom_arg "\n", pb->args[pb->nargs]);
        !           213:                memdump(arg2pointer(pb->args[1]), pb->args[pb->nargs]);
        !           214: #endif
        !           215:        } else if (strcmp(service, "write") == 0) {
        !           216: #ifdef DUMP_IO
        !           217:                printk(FMT_prom_arg "\n", pb->args[pb->nargs]);
        !           218: #endif
        !           219:        } else if (strcmp(service, "seek") == 0) {
        !           220: #ifdef DUMP_IO
        !           221:                printk(FMT_prom_arg "\n", pb->args[pb->nargs]);
        !           222: #endif
        !           223:        } else if (strcmp(service, "claim") == 0) {
        !           224:                printk("0x" FMT_prom_uargx "\n", pb->args[pb->nargs]);
        !           225:        } else if (strcmp(service, "release") == 0) {
        !           226:                /* do nothing */
        !           227:        } else if (strcmp(service, "boot") == 0) {
        !           228:                /* do nothing */
        !           229:        } else if (strcmp(service, "enter") == 0) {
        !           230:                /* do nothing */
        !           231:        } else if (strcmp(service, "exit") == 0) {
        !           232:                /* do nothing */
        !           233:        } else if (strcmp(service, "test-method") == 0) {
        !           234:                printk("0x" FMT_prom_uargx "\n", pb->args[pb->nargs]);
        !           235:        } else {
        !           236:                printk("of_client_interface return:");
        !           237:                for (i = 0; i < pb->nret; i++) {
        !           238:                        printk(" " FMT_prom_uargx, pb->args[pb->nargs + i]);
        !           239:                }
        !           240:                printk("\n");
        !           241:        }
        !           242: }
        !           243: #endif
        !           244: 
        !           245: /* call-method, interpret */
        !           246: static int
        !           247: handle_calls( prom_args_t *pb )
        !           248: {
        !           249:        int i, dstacksave = dstackcnt;
        !           250:     prom_uarg_t val;
        !           251: 
        !           252: #ifdef DEBUG_CIF
        !           253:     printk("%s %s ([" FMT_prom_arg "] -- [" FMT_prom_arg "])\n",
        !           254:            get_service(pb), arg2pointer(pb->args[0]), pb->nargs, pb->nret);
        !           255: #endif
        !           256: 
        !           257:        for( i=pb->nargs-1; i>=0; i-- )
        !           258:                PUSH( pb->args[i] );
        !           259: 
        !           260:        push_str(get_service(pb));
        !           261:        fword("client-call-iface");
        !           262: 
        !           263:        /* Drop the return code from client-call-iface (status is handled by the 
        !           264:           catch result which is the first parameter below) */
        !           265:        POP();
        !           266: 
        !           267:        for( i=0; i<pb->nret; i++ ) {
        !           268:                 val = POP();
        !           269:                pb->args[pb->nargs + i] = val;
        !           270: 
        !           271:                /* don't pop args if an exception occured */
        !           272:                if( !i && val )
        !           273:                        break;
        !           274:        }
        !           275: 
        !           276: #ifdef DEBUG_CIF
        !           277:     /* useful for debug but not necessarily an error */
        !           278:     if (i != pb->nret || dstackcnt != dstacksave) {
        !           279:         printk("%s '%s': possible argument error (" FMT_prom_arg "--" FMT_prom_arg ") got %d\n",
        !           280:                get_service(pb), arg2pointer(pb->args[0]),
        !           281:                pb->nargs - 2, pb->nret, i);
        !           282:     }
        !           283: 
        !           284:     printk("handle_calls return:");
        !           285:     for (i = 0; i < pb->nret; i++) {
        !           286:         printk(" " FMT_prom_uargx, pb->args[pb->nargs + i]);
        !           287:     }
        !           288:     printk("\n");
        !           289: #endif
        !           290: 
        !           291:        dstackcnt = dstacksave;
        !           292:        return 0;
        !           293: }
        !           294: 
        !           295: int
        !           296: of_client_interface( int *params )
        !           297: {
        !           298:        prom_args_t *pb = (prom_args_t*)params;
        !           299:        int val, i, dstacksave;
        !           300: 
        !           301:        if( pb->nargs < 0 || pb->nret < 0 ||
        !           302:             pb->nargs + pb->nret > PROM_MAX_ARGS)
        !           303:                return -1;
        !           304: 
        !           305: #ifdef DEBUG_CIF
        !           306:        dump_service(pb);
        !           307: #endif
        !           308: 
        !           309:        /* call-method exceptions are special */
        !           310:        if (!strcmp("call-method", get_service(pb)) || !strcmp("interpret", get_service(pb)))
        !           311:                return handle_calls( pb );
        !           312: 
        !           313:        dstacksave = dstackcnt;
        !           314:        for( i=pb->nargs-1; i>=0; i-- )
        !           315:                PUSH( pb->args[i] );
        !           316: 
        !           317:        push_str(get_service(pb));
        !           318:        fword("client-iface");
        !           319: 
        !           320:        if( (val=POP()) ) {
        !           321:                dstackcnt = dstacksave;
        !           322:                if( val == -1 )
        !           323:                        printk("Unimplemented service %s ([" FMT_prom_arg "] -- [" FMT_prom_arg "])\n",
        !           324:                               get_service(pb), pb->nargs, pb->nret );
        !           325: #ifdef DEBUG_CIF
        !           326:                else
        !           327:                        printk("ERROR!\n");
        !           328: #endif
        !           329:                return -1;
        !           330:        }
        !           331: 
        !           332:        for( i=0; i<pb->nret ; i++ )
        !           333:                pb->args[pb->nargs + i] = POP();
        !           334: 
        !           335:        if( dstackcnt != dstacksave ) {
        !           336: #ifdef DEBUG_CIF
        !           337:                printk("service %s: possible argument error (%d %d)\n",
        !           338:                       get_service(pb), i, dstackcnt - dstacksave );
        !           339: #endif
        !           340:                /* Some clients request less parameters than the CIF method
        !           341:                returns, e.g. getprop with OpenSolaris. Hence we drop any
        !           342:                stack parameters after issuing a warning above */
        !           343:                dstackcnt = dstacksave;
        !           344:        }
        !           345: 
        !           346: #ifdef DEBUG_CIF
        !           347:        dump_return(pb);
        !           348: #endif
        !           349:        return 0;
        !           350: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.