Annotation of qemu/roms/openbios/arch/ppc/mol/methods.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *   Creation Date: <2003/10/18 13:24:29 samuel>
        !             3:  *   Time-stamp: <2004/03/27 02:00:30 samuel>
        !             4:  *
        !             5:  *     <methods.c>
        !             6:  *
        !             7:  *     Misc device node methods
        !             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 "mol/mol.h"
        !            21: #include "libopenbios/ofmem.h"
        !            22: #include "mol/prom.h"
        !            23: #include "osi_calls.h"
        !            24: #include "kbd_sh.h"
        !            25: 
        !            26: /************************************************************************/
        !            27: /*     Power Management                                                */
        !            28: /************************************************************************/
        !            29: 
        !            30: DECLARE_NODE( powermgt, INSTALL_OPEN, 0, "/pci/pci-bridge/mac-io/power-mgt" );
        !            31: 
        !            32: /* ( -- ) */
        !            33: static void
        !            34: set_hybernot_flag( void )
        !            35: {
        !            36: }
        !            37: 
        !            38: NODE_METHODS( powermgt ) = {
        !            39:        { "set-hybernot-flag",  set_hybernot_flag       },
        !            40: };
        !            41: 
        !            42: 
        !            43: /************************************************************************/
        !            44: /*     RTAS (run-time abstraction services)                            */
        !            45: /************************************************************************/
        !            46: 
        !            47: DECLARE_NODE( rtas, INSTALL_OPEN, 0, "+/rtas" );
        !            48: 
        !            49: /* ( physbase -- rtas_callback ) */
        !            50: static void
        !            51: rtas_instantiate( void )
        !            52: {
        !            53:        int physbase = POP();
        !            54:        int s=0x1000, size = (int)of_rtas_end - (int)of_rtas_start;
        !            55:        unsigned long virt;
        !            56: 
        !            57:        while( s < size )
        !            58:                s += 0x1000;
        !            59:        virt = ofmem_claim_virt( 0, s, 0x1000 );
        !            60:        ofmem_map( physbase, virt, s, -1 );
        !            61:        memcpy( (char*)virt, of_rtas_start, size );
        !            62: 
        !            63:        printk("RTAS instantiated at %08x\n", physbase );
        !            64:        flush_icache_range( (char*)virt, (char*)virt + size );
        !            65: 
        !            66:        PUSH( physbase );
        !            67: }
        !            68: 
        !            69: NODE_METHODS( rtas ) = {
        !            70:        { "instantiate",        rtas_instantiate },
        !            71:        { "instantiate-rtas",   rtas_instantiate },
        !            72: };
        !            73: 
        !            74: 
        !            75: 
        !            76: /************************************************************************/
        !            77: /*     stdout                                                          */
        !            78: /************************************************************************/
        !            79: 
        !            80: DECLARE_NODE( video_stdout, INSTALL_OPEN, 0, "Tdisplay" );
        !            81: 
        !            82: /* ( addr len -- actual ) */
        !            83: static void
        !            84: stdout_write( void )
        !            85: {
        !            86:        int len = POP();
        !            87:        char *addr = (char*)POP();
        !            88: 
        !            89:        /* printk( "%s", s ); */
        !            90:         console_draw_fstr(addr, len);
        !            91: 
        !            92:        PUSH( len );
        !            93: }
        !            94: 
        !            95: NODE_METHODS( video_stdout ) = {
        !            96:        { "write",      stdout_write    },
        !            97: };
        !            98: 
        !            99: 
        !           100: /************************************************************************/
        !           101: /*     tty                                                             */
        !           102: /************************************************************************/
        !           103: 
        !           104: DECLARE_NODE( tty, INSTALL_OPEN, 0, "+/mol/mol-tty" );
        !           105: 
        !           106: /* ( addr len -- actual ) */
        !           107: static void
        !           108: tty_read( void )
        !           109: {
        !           110:        int ch, len = POP();
        !           111:        char *p = (char*)POP();
        !           112:        int ret=0;
        !           113: 
        !           114:        if( len > 0 ) {
        !           115:                ret = 1;
        !           116:                ch = OSI_TTYGetc();
        !           117:                if( ch >= 0 ) {
        !           118:                        *p = ch;
        !           119:                } else {
        !           120:                        ret = 0;
        !           121:                        OSI_USleep(1);
        !           122:                }
        !           123:        }
        !           124:        PUSH( ret );
        !           125: }
        !           126: 
        !           127: /* ( addr len -- actual ) */
        !           128: static void
        !           129: tty_write( void )
        !           130: {
        !           131:        int i, len = POP();
        !           132:        char *p = (char*)POP();
        !           133:        for( i=0; i<len; i++ )
        !           134:                OSI_TTYPutc( *p++ );
        !           135:        RET( len );
        !           136: }
        !           137: 
        !           138: NODE_METHODS( tty ) = {
        !           139:        { "read",       tty_read        },
        !           140:        { "write",      tty_write       },
        !           141: };
        !           142: 
        !           143: 
        !           144: /************************************************************************/
        !           145: /*     keyboard                                                        */
        !           146: /************************************************************************/
        !           147: 
        !           148: typedef struct {
        !           149:        int     cntrl;
        !           150:        int     shift;
        !           151:        int     meta;
        !           152:        int     alt;
        !           153:        int     save_key;
        !           154:        char    keytable[32];
        !           155: } kbd_state_t;
        !           156: 
        !           157: static const unsigned char adb_ascii_table[128] =
        !           158:        /* 0x00 */      "asdfhgzxcv`bqwer"
        !           159:        /* 0x10 */      "yt123465=97-80]o"
        !           160:        /* 0x20 */      "u[ip\nlj'k;\\,/nm."
        !           161:        /* 0x30 */      "\t <\b \e          "
        !           162:        /* 0x40 */      " . * +     /  - "
        !           163:        /* 0x50 */      " =01234567 89   "
        !           164:        /* 0x60 */      "                "
        !           165:        /* 0x70 */      "                ";
        !           166: 
        !           167: static const unsigned char adb_shift_table[128] =
        !           168:        /* 0x00 */      "ASDFHGZXCV~BQWER"
        !           169:        /* 0x10 */      "YT!@#$^%+(&_*)}O"
        !           170:        /* 0x20 */      "U{IP\nLJ\"K:|<?NM>"
        !           171:        /* 0x30 */      "\t <\b \e          "
        !           172:        /* 0x40 */      " . * +     /  - "
        !           173:        /* 0x50 */      " =01234567 89   "
        !           174:        /* 0x60 */      "                "
        !           175:        /* 0x70 */      "                ";
        !           176: 
        !           177: DECLARE_NODE( kbd, INSTALL_OPEN, sizeof(kbd_state_t),
        !           178:       "/psuedo-hid/keyboard",
        !           179:       "/mol/mol-keyboard",
        !           180:       "/mol/keyboard"
        !           181: );
        !           182: 
        !           183: /* ( -- keymap ) (?) */
        !           184: /* should return a pointer to an array with 32 bytes (256 bits) */
        !           185: static void
        !           186: kbd_get_key_map( kbd_state_t *ks )
        !           187: {
        !           188:        /* printk("met_kbd_get_key_map\n"); */
        !           189: 
        !           190:        /* keytable[5] = 0x40; */
        !           191:        PUSH( (int)ks->keytable );
        !           192: }
        !           193: 
        !           194: /* ( buf len --- actlen ) */
        !           195: static void
        !           196: kbd_read( kbd_state_t *ks )
        !           197: {
        !           198:        int ret=0, len = POP();
        !           199:        char *p = (char*)POP();
        !           200:        int key;
        !           201: 
        !           202:        if( !p || !len ) {
        !           203:                PUSH( -1 );
        !           204:                return;
        !           205:        }
        !           206: 
        !           207:        if( ks->save_key ) {
        !           208:                *p = ks->save_key;
        !           209:                ks->save_key = 0;
        !           210:                RET( 1 );
        !           211:        }
        !           212:        OSI_USleep(1);  /* be nice */
        !           213: 
        !           214:        for( ; (key=OSI_GetAdbKey()) >= 0 ; ) {
        !           215:                int code = (key & 0x7f);
        !           216:                int down = !(key & 0x80);
        !           217: 
        !           218:                if( code == 0x36 /* ctrl */ ) {
        !           219:                        ks->cntrl = down;
        !           220:                        continue;
        !           221:                }
        !           222:                if( code == 0x38 /* shift */ || code == 0x7b) {
        !           223:                        ks->shift = down;
        !           224:                        continue;
        !           225:                }
        !           226:                if( code == 0x37 /* command */ ) {
        !           227:                        ks->meta = down;
        !           228:                        continue;
        !           229:                }
        !           230:                if( code == 0x3a /* alt */ ) {
        !           231:                        ks->alt = down;
        !           232:                        continue;
        !           233:                }
        !           234:                if( !down )
        !           235:                        continue;
        !           236: 
        !           237:                ret = 1;
        !           238:                if( ks->shift )
        !           239:                        key = adb_shift_table[ key & 0x7f ];
        !           240:                else
        !           241:                        key = adb_ascii_table[ key & 0x7f ];
        !           242: 
        !           243:                if( ks->meta ) {
        !           244:                        ks->save_key = key;
        !           245:                        key = 27;
        !           246:                } else if( ks->cntrl ) {
        !           247:                        key = key - 'a' + 1;
        !           248:                }
        !           249:                *p = key;
        !           250:                if( !*p )
        !           251:                        *p = 'x';
        !           252:                break;
        !           253:        }
        !           254:        PUSH( ret );
        !           255: }
        !           256: 
        !           257: NODE_METHODS( kbd ) = {
        !           258:        { "read",               kbd_read                },
        !           259:        { "get-key-map",        kbd_get_key_map         },
        !           260: };
        !           261: 
        !           262: 
        !           263: /************************************************************************/
        !           264: /*     client interface 'quiesce'                                      */
        !           265: /************************************************************************/
        !           266: 
        !           267: DECLARE_NODE( ciface, 0, 0, "/packages/client-iface" );
        !           268: 
        !           269: /* ( -- ) */
        !           270: static void
        !           271: ciface_quiesce( unsigned long args[], unsigned long ret[] )
        !           272: {
        !           273: #if 0
        !           274:        unsigned long msr;
        !           275:        /* This seems to be the correct thing to do - but I'm not sure */
        !           276:        asm volatile("mfmsr %0" : "=r" (msr) : );
        !           277:        msr &= ~(MSR_IR | MSR_DR);
        !           278:        asm volatile("mtmsr %0" :: "r" (msr) );
        !           279: #endif
        !           280:        printk("=============================================================\n\n");
        !           281:        prom_close();
        !           282: 
        !           283:        OSI_KbdCntrl( kKbdCntrlSuspend );
        !           284: }
        !           285: 
        !           286: /* ( -- ms ) */
        !           287: static void
        !           288: ciface_milliseconds( unsigned long args[], unsigned long ret[] )
        !           289: {
        !           290:        static unsigned long mticks=0, usecs=0;
        !           291:        unsigned long t;
        !           292: 
        !           293:        asm volatile("mftb %0" : "=r" (t) : );
        !           294:        if( mticks )
        !           295:                usecs += OSI_MticksToUsecs( t-mticks );
        !           296:        mticks = t;
        !           297: 
        !           298:        PUSH( usecs/1000 );
        !           299: }
        !           300: 
        !           301: 
        !           302: NODE_METHODS( ciface ) = {
        !           303:        { "quiesce",            ciface_quiesce          },
        !           304:        { "milliseconds",       ciface_milliseconds     },
        !           305: };
        !           306: 
        !           307: 
        !           308: /************************************************************************/
        !           309: /*     MMU/memory methods                                              */
        !           310: /************************************************************************/
        !           311: 
        !           312: DECLARE_NODE( memory, INSTALL_OPEN, 0, "/memory" );
        !           313: DECLARE_NODE( mmu, INSTALL_OPEN, 0, "/cpus/@0" );
        !           314: DECLARE_NODE( mmu_ciface, 0, 0, "/packages/client-iface" );
        !           315: 
        !           316: 
        !           317: /* ( phys size align --- base ) */
        !           318: static void
        !           319: mem_claim( void )
        !           320: {
        !           321:        ucell align = POP();
        !           322:        ucell size = POP();
        !           323:        ucell phys = POP();
        !           324:        ucell ret = ofmem_claim_phys( phys, size, align );
        !           325: 
        !           326:        if( ret == -1 ) {
        !           327:                printk("MEM: claim failure\n");
        !           328:                throw( -13 );
        !           329:                return;
        !           330:        }
        !           331:        PUSH( ret );
        !           332: }
        !           333: 
        !           334: /* ( phys size --- ) */
        !           335: static void
        !           336: mem_release( void )
        !           337: {
        !           338:        POP(); POP();
        !           339: }
        !           340: 
        !           341: /* ( phys size align --- base ) */
        !           342: static void
        !           343: mmu_claim( void )
        !           344: {
        !           345:        ucell align = POP();
        !           346:        ucell size = POP();
        !           347:        ucell phys = POP();
        !           348:        ucell ret = ofmem_claim_virt( phys, size, align );
        !           349: 
        !           350:        if( ret == -1 ) {
        !           351:                printk("MMU: CLAIM failure\n");
        !           352:                throw( -13 );
        !           353:                return;
        !           354:        }
        !           355:        PUSH( ret );
        !           356: }
        !           357: 
        !           358: /* ( phys size --- ) */
        !           359: static void
        !           360: mmu_release( void )
        !           361: {
        !           362:        POP(); POP();
        !           363: }
        !           364: 
        !           365: /* ( phys virt size mode -- [ret???] ) */
        !           366: static void
        !           367: mmu_map( void )
        !           368: {
        !           369:        ucell mode = POP();
        !           370:        ucell size = POP();
        !           371:        ucell virt = POP();
        !           372:        ucell phys = POP();
        !           373:        ucell ret;
        !           374: 
        !           375:        /* printk("mmu_map: %x %x %x %x\n", phys, virt, size, mode ); */
        !           376:        ret = ofmem_map( phys, virt, size, mode );
        !           377: 
        !           378:        if( ret ) {
        !           379:                printk("MMU: map failure\n");
        !           380:                throw( -13 );
        !           381:                return;
        !           382:        }
        !           383: }
        !           384: 
        !           385: /* ( virt size -- ) */
        !           386: static void
        !           387: mmu_unmap( void )
        !           388: {
        !           389:        POP(); POP();
        !           390: }
        !           391: 
        !           392: /* ( virt -- false | phys mode true ) */
        !           393: static void
        !           394: mmu_translate( void )
        !           395: {
        !           396:        ucell mode;
        !           397:        ucell virt = POP();
        !           398:        ucell phys = ofmem_translate( virt, &mode );
        !           399: 
        !           400:        if( phys == -1 ) {
        !           401:                PUSH( 0 );
        !           402:        } else {
        !           403:                PUSH( phys );
        !           404:                PUSH( mode );
        !           405:                PUSH( -1 );
        !           406:        }
        !           407: }
        !           408: 
        !           409: /* ( virt size align -- baseaddr|-1 ) */
        !           410: static void
        !           411: ciface_claim( void )
        !           412: {
        !           413:        ucell align = POP();
        !           414:        ucell size = POP();
        !           415:        ucell virt = POP();
        !           416:        ucell ret = ofmem_claim( virt, size, align );
        !           417: 
        !           418:        /* printk("ciface_claim: %08x %08x %x\n", virt, size, align ); */
        !           419:        PUSH( ret );
        !           420: }
        !           421: 
        !           422: /* ( virt size -- ) */
        !           423: static void
        !           424: ciface_release( void )
        !           425: {
        !           426:        POP();
        !           427:        POP();
        !           428: }
        !           429: 
        !           430: 
        !           431: NODE_METHODS( memory ) = {
        !           432:        { "claim",              mem_claim               },
        !           433:        { "release",            mem_release             },
        !           434: };
        !           435: 
        !           436: NODE_METHODS( mmu ) = {
        !           437:        { "claim",              mmu_claim               },
        !           438:        { "release",            mmu_release             },
        !           439:        { "map",                mmu_map                 },
        !           440:        { "unmap",              mmu_unmap               },
        !           441:        { "translate",          mmu_translate           },
        !           442: };
        !           443: 
        !           444: NODE_METHODS( mmu_ciface ) = {
        !           445:        { "cif-claim",          ciface_claim            },
        !           446:        { "cif-release",        ciface_release          },
        !           447: };
        !           448: 
        !           449: 
        !           450: /************************************************************************/
        !           451: /*     init                                                            */
        !           452: /************************************************************************/
        !           453: 
        !           454: void
        !           455: node_methods_init( void )
        !           456: {
        !           457:        REGISTER_NODE( rtas );
        !           458:        REGISTER_NODE( powermgt );
        !           459:        REGISTER_NODE( kbd );
        !           460:        REGISTER_NODE( video_stdout );
        !           461:        REGISTER_NODE( ciface );
        !           462:        REGISTER_NODE( memory );
        !           463:        REGISTER_NODE( mmu );
        !           464:        REGISTER_NODE( mmu_ciface );
        !           465: 
        !           466:        if( OSI_CallAvailable(OSI_TTY_GETC) )
        !           467:                REGISTER_NODE( tty );
        !           468: 
        !           469:        OSI_KbdCntrl( kKbdCntrlActivate );
        !           470: }

unix.superglobalmegacorp.com

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