Annotation of qemu/roms/openbios/libopenbios/bindings.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *   Creation Date: <2003/11/24 12:30:18 samuel>
                      3:  *   Time-stamp: <2004/01/07 19:37:38 samuel>
                      4:  *
                      5:  *     <bindings.c>
                      6:  *
                      7:  *     Forth bindings
                      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 "libc/string.h"
                     20: #include "libc/stdlib.h"
                     21: #include "libc/byteorder.h"
                     22: 
                     23: 
                     24: /************************************************************************/
                     25: /*     forth interface glue                                            */
                     26: /************************************************************************/
                     27: 
                     28: void
                     29: push_str( const char *str )
                     30: {
                     31:        PUSH( pointer2cell(str) );
                     32:        PUSH( str ? strlen(str) : 0 );
                     33: }
                     34: 
                     35: /* WARNING: sloooow - AVOID */
                     36: cell
                     37: feval( const char *str )
                     38: {
                     39:        push_str( str );
                     40:        return eword("evaluate", 2);
                     41: }
                     42: 
                     43: cell
                     44: _eword( const char *word, xt_t *cache_xt, int nargs )
                     45: {
                     46:        static xt_t catch_xt = 0;
                     47:        cell ret = -1;
                     48: 
                     49:        if( !catch_xt )
                     50:                catch_xt = findword("catch");
                     51:        if( !*cache_xt )
                     52:                *cache_xt = findword( (char*)word );
                     53: 
                     54:        if( *cache_xt ) {
                     55:                PUSH_xt( *cache_xt );
                     56:                enterforth( catch_xt );
                     57:                if( (ret=POP()) )
                     58:                        dstackcnt -= nargs;
                     59:        }
                     60:        return ret;
                     61: }
                     62: 
                     63: /* note: only the built-in dictionary is searched */
                     64: int
                     65: _fword( const char *word, xt_t *cache_xt )
                     66: {
                     67:        if( !*cache_xt )
                     68:                *cache_xt = findword( (char*)word );
                     69: 
                     70:        if( *cache_xt ) {
                     71:                enterforth( *cache_xt );
                     72:                return 0;
                     73:        }
                     74:        return -1;
                     75: }
                     76: 
                     77: int
                     78: _selfword( const char *method, xt_t *cache_xt )
                     79: {
                     80:        if( !*cache_xt )
                     81:                *cache_xt = find_ih_method( method, my_self() );
                     82:        if( *cache_xt ) {
                     83:                enterforth( *cache_xt );
                     84:                return 0;
                     85:        }
                     86:        return -1;
                     87: }
                     88: 
                     89: int
                     90: _parword( const char *method, xt_t *cache_xt )
                     91: {
                     92:        if( !*cache_xt )
                     93:                *cache_xt = find_ih_method( method, my_parent() );
                     94:        if( *cache_xt ) {
                     95:                enterforth( *cache_xt );
                     96:                return 0;
                     97:        }
                     98:        return -1;
                     99: }
                    100: 
                    101: void
                    102: bind_func( const char *name, void (*func)(void) )
                    103: {
                    104:        PUSH( pointer2cell(func) );
                    105:        push_str( name );
                    106:        fword("is-cfunc");
                    107: }
                    108: 
                    109: void
                    110: bind_xtfunc( const char *name, xt_t xt, ucell arg, void (*func)(void) )
                    111: {
                    112:        PUSH_xt( xt );
                    113:        PUSH( arg );
                    114:        PUSH( pointer2cell(func) );
                    115:        push_str( name );
                    116:        fword("is-xt-cfunc");
                    117: }
                    118: 
                    119: xt_t
                    120: bind_noname_func( void (*func)(void) )
                    121: {
                    122:        PUSH( pointer2cell(func) );
                    123:        fword("is-noname-cfunc");
                    124:        return POP_xt();
                    125: }
                    126: 
                    127: void
                    128: throw( int error )
                    129: {
                    130:        PUSH( error );
                    131:        fword("throw");
                    132: }
                    133: 
                    134: 
                    135: /************************************************************************/
                    136: /*     ihandle related                                                 */
                    137: /************************************************************************/
                    138: 
                    139: phandle_t
                    140: ih_to_phandle( ihandle_t ih )
                    141: {
                    142:        PUSH_ih( ih );
                    143:        fword("ihandle>phandle");
                    144:        return POP_ph();
                    145: }
                    146: 
                    147: ihandle_t
                    148: my_parent( void )
                    149: {
                    150:        fword("my-parent");
                    151:        return POP_ih();
                    152: }
                    153: 
                    154: ihandle_t
                    155: my_self( void )
                    156: {
                    157:        fword("my-self");
                    158:        return POP_ih();
                    159: }
                    160: 
                    161: xt_t
                    162: find_package_method( const char *method, phandle_t ph )
                    163: {
                    164:        push_str( method );
                    165:        PUSH_ph( ph );
                    166:        fword("find-method");
                    167:        if( POP() )
                    168:                return POP_xt();
                    169:        return 0;
                    170: }
                    171: 
                    172: xt_t
                    173: find_ih_method( const char *method, ihandle_t ih )
                    174: {
                    175:        return find_package_method( method, ih_to_phandle(ih) );
                    176: }
                    177: 
                    178: 
                    179: xt_t
                    180: find_parent_method( const char *method )
                    181: {
                    182:        return find_ih_method( method, my_parent() );
                    183: }
                    184: 
                    185: void
                    186: call_package( xt_t xt, ihandle_t ihandle )
                    187: {
                    188:        PUSH_xt( xt );
                    189:        PUSH_ih( ihandle );
                    190:        fword("call-package");
                    191: }
                    192: 
                    193: void
                    194: call_parent( xt_t xt )
                    195: {
                    196:        PUSH_xt( xt );
                    197:        fword("call-parent");
                    198: }
                    199: 
                    200: void
                    201: call_parent_method( const char *method )
                    202: {
                    203:        push_str( method );
                    204:        fword("$call-parent");
                    205: }
                    206: 
                    207: 
                    208: /************************************************************************/
                    209: /*     open/close package/dev                                          */
                    210: /************************************************************************/
                    211: 
                    212: ihandle_t
                    213: open_dev( const char *spec )
                    214: {
                    215:        push_str( spec );
                    216:        fword("open-dev");
                    217:        return POP_ih();
                    218: }
                    219: 
                    220: void
                    221: close_dev( ihandle_t ih )
                    222: {
                    223:        PUSH_ih( ih );
                    224:        fword("close-dev");
                    225: }
                    226: 
                    227: ihandle_t
                    228: open_package( const char *argstr, phandle_t ph )
                    229: {
                    230:        push_str( argstr );
                    231:        PUSH_ph( ph );
                    232:        fword("open-package");
                    233:        return POP_ih();
                    234: }
                    235: 
                    236: void
                    237: close_package( ihandle_t ih )
                    238: {
                    239:        PUSH_ih( ih );
                    240:        fword("close-package");
                    241: }
                    242: 
                    243: 
                    244: /************************************************************************/
                    245: /*     ihandle arguments                                               */
                    246: /************************************************************************/
                    247: 
                    248: char *
                    249: pop_fstr_copy( void )
                    250: {
                    251:        int len = POP();
                    252:        char *str, *p = (char*)cell2pointer(POP());
                    253:        if( !len )
                    254:                return NULL;
                    255:        str = malloc( len + 1 );
                    256:         if( !str )
                    257:                 return NULL;
                    258:        memcpy( str, p, len );
                    259:        str[len] = 0;
                    260:        return str;
                    261: }
                    262: 
                    263: char *
                    264: my_args_copy( void )
                    265: {
                    266:        fword("my-args");
                    267:        return pop_fstr_copy();
                    268: }
                    269: 
                    270: 
                    271: /************************************************************************/
                    272: /*     properties                                                      */
                    273: /************************************************************************/
                    274: 
                    275: void
                    276: set_property( phandle_t ph, const char *name, const char *buf, int len )
                    277: {
                    278:        if( !ph ) {
                    279:                printk("set_property: NULL phandle\n");
                    280:                return;
                    281:        }
                    282:        PUSH(pointer2cell(buf));
                    283:        PUSH(len);
                    284:        push_str( name );
                    285:        PUSH_ph(ph);
                    286:        fword("set-property");
                    287: }
                    288: 
                    289: void
                    290: set_int_property( phandle_t ph, const char *name, u32 val )
                    291: {
                    292:        u32 swapped=__cpu_to_be32(val);
                    293:        set_property( ph, name, (char*)&swapped, sizeof(swapped) );
                    294: }
                    295: 
                    296: char *
                    297: get_property( phandle_t ph, const char *name, int *retlen )
                    298: {
                    299:        int len;
                    300: 
                    301:        if( retlen )
                    302:                *retlen = -1;
                    303: 
                    304:        push_str( name );
                    305:        PUSH_ph( ph );
                    306:        fword("get-package-property");
                    307:        if( POP() )
                    308:                return NULL;
                    309:        len = POP();
                    310:        if( retlen )
                    311:                *retlen = len;
                    312:        return (char*)cell2pointer(POP());
                    313: }
                    314: 
                    315: u32
                    316: get_int_property( phandle_t ph, const char *name, int *retlen )
                    317: {
                    318:        u32 *p;
                    319: 
                    320:        if( !(p=(u32 *)get_property(ph, name, retlen)) )
                    321:                return 0;
                    322:        return __be32_to_cpu(*p);
                    323: }
                    324: 
                    325: 
                    326: /************************************************************************/
                    327: /*     device selection / iteration                                    */
                    328: /************************************************************************/
                    329: 
                    330: void
                    331: activate_dev( phandle_t ph )
                    332: {
                    333:        PUSH_ph( ph );
                    334:        fword("active-package!");
                    335: }
                    336: 
                    337: phandle_t
                    338: activate_device( const char *str )
                    339: {
                    340:        phandle_t ph = find_dev( str );
                    341:        activate_dev( ph );
                    342:        return ph;
                    343: }
                    344: 
                    345: void
                    346: device_end( void )
                    347: {
                    348:        fword("device-end");
                    349: }
                    350: 
                    351: phandle_t
                    352: get_cur_dev( void )
                    353: {
                    354:        fword("active-package");
                    355:        return POP_ph();
                    356: }
                    357: 
                    358: phandle_t
                    359: find_dev( const char *path )
                    360: {
                    361:        phandle_t ret = 0;
                    362:        push_str( path );
                    363:        fword("(find-dev)");
                    364:        if( POP() )
                    365:                return POP_ph();
                    366:        return ret;
                    367: }
                    368: 
                    369: phandle_t
                    370: dt_iter_begin( void )
                    371: {
                    372:        fword("iterate-tree-begin");
                    373:        return POP_ph();
                    374: }
                    375: 
                    376: phandle_t
                    377: dt_iterate( phandle_t last_tree )
                    378: {
                    379:         if( !last_tree )
                    380:                return dt_iter_begin();
                    381: 
                    382:         PUSH_ph( last_tree );
                    383:        fword("iterate-tree");
                    384:        return POP_ph();
                    385: }
                    386: 
                    387: phandle_t
                    388: dt_iterate_type( phandle_t last_tree, const char *type )
                    389: {
                    390:         if( !last_tree )
                    391:                 last_tree = dt_iter_begin();
                    392: 
                    393:        /* root node is never matched but we don't care about that */
                    394:         while( (last_tree = dt_iterate(last_tree)) ) {
                    395:                 char *s = get_property( last_tree, "device_type", NULL );
                    396:                if( s && !strcmp(type, s) )
                    397:                        break;
                    398:        }
                    399:         return last_tree;
                    400: }
                    401: 
                    402: 
                    403: /************************************************************************/
                    404: /*     node methods                                                    */
                    405: /************************************************************************/
                    406: 
                    407: void
                    408: make_openable( int only_parents )
                    409: {
                    410:        phandle_t ph, save_ph = get_cur_dev();
                    411:        PUSH_ph( save_ph );
                    412: 
                    413:        for( ;; ) {
                    414:                if( only_parents++ )
                    415:                        fword("parent");
                    416:                if( !(ph=POP_ph()) )
                    417:                        break;
                    418:                activate_dev( ph );
                    419:                PUSH_ph( ph );
                    420:                fword("is-open");
                    421:        }
                    422:        activate_dev( save_ph );
                    423: }
                    424: 
                    425: static void
                    426: call1_func( void )
                    427: {
                    428:        void (*func)(cell v);
                    429:        func = (void*)cell2pointer(POP());
                    430: 
                    431:        (*func)( POP() );
                    432: }
                    433: 
                    434: 
                    435: static void
                    436: add_methods( int flags, int size, const method_t *methods, int nmet )
                    437: {
                    438:        xt_t xt=0;
                    439:        int i;
                    440: 
                    441:        /* nodes might be matched multiple times */
                    442:        if( find_package_method(methods[0].name, get_cur_dev()) )
                    443:                return;
                    444: 
                    445:        if( size ) {
                    446:                PUSH( size );
                    447:                fword("is-ibuf");
                    448:                xt = POP_xt();
                    449:        }
                    450: 
                    451:        for( i=0; i<nmet; i++ ) {
                    452:                /* null-name methods specify static initializers */
                    453:                if( !methods[i].name ) {
                    454:                        typedef void (*initfunc)( void *p );
                    455:                        char *buf = NULL;
                    456:                        if( xt ) {
                    457:                                enterforth( xt );
                    458:                                buf = (char*)cell2pointer(POP());
                    459:                        }
                    460:                        (*(initfunc)methods[i].func)( buf );
                    461:                        continue;
                    462:                }
                    463:                if( !size )
                    464:                        bind_func( methods[i].name, methods[i].func );
                    465:                else
                    466:                        bind_xtfunc( methods[i].name, xt, pointer2cell(methods[i].func),
                    467:                                     &call1_func );
                    468:        }
                    469: 
                    470:        if( flags & INSTALL_OPEN )
                    471:                make_openable(0);
                    472: }
                    473: 
                    474: void
                    475: bind_node( int flags, int size, const char * const *paths, int npaths,
                    476:           const method_t *methods, int nmet )
                    477: {
                    478:        phandle_t save_ph = get_cur_dev();
                    479:        int i;
                    480: 
                    481:        for( i=0; i<npaths; i++ ) {
                    482:                const char *name = paths[i];
                    483: 
                    484:                /* type matching? */
                    485:                if( *name == 'T' ) {
                    486:                        phandle_t ph = 0;
                    487:                        name++;
                    488:                        while( (ph=dt_iterate_type(ph, name)) ) {
                    489:                                activate_dev( ph );
                    490:                                add_methods( flags, size, methods, nmet );
                    491:                        }
                    492:                        continue;
                    493:                }
                    494: 
                    495:                /* path patching */
                    496:                if( activate_device(name) )
                    497:                        add_methods( flags, size, methods, nmet );
                    498:                else if( *name == '+' ) {
                    499:                        /* create node (and missing parents) */
                    500:                        if( !activate_device(++name) ) {
                    501:                                push_str( name );
                    502:                                fword("create-node");
                    503:                        }
                    504:                        add_methods( flags, size, methods, nmet );
                    505:                }
                    506:        }
                    507:        activate_dev( save_ph );
                    508: }
                    509: 
                    510: phandle_t
                    511: bind_new_node( int flags, int size, const char *name,
                    512:           const method_t *methods, int nmet )
                    513: {
                    514:        phandle_t save_ph = get_cur_dev();
                    515:        phandle_t new_ph;
                    516:        /* create node */
                    517:        push_str( name );
                    518:        fword("create-node");
                    519:        add_methods( flags, size, methods, nmet );
                    520:     new_ph = get_cur_dev();
                    521: 
                    522:        activate_dev( save_ph );
                    523:        return new_ph;
                    524: }

unix.superglobalmegacorp.com

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