Annotation of qemu/roms/openbios/libopenbios/client.c, revision 1.1.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.