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