Annotation of kernel/bsd/dev/i386/km.m, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: /*     Copyright (c) 1992 NeXT Computer, Inc.  All rights reserved. 
                     26:  *
                     27:  * km.m - kernel keyboard/monitor module, procedural interface.
                     28:  *
                     29:  * HISTORY
                     30:  * 21 Sep 92   Joe Pasqua
                     31:  *     Created i386 version based on m88k version.
                     32:  */
                     33:  
                     34: #import <driverkit/IODevice.h>
                     35: #import <driverkit/generalFuncs.h>
                     36: #import <bsd/sys/param.h>
                     37: #import <bsd/sys/proc.h>
                     38: #import <bsd/sys/conf.h>
                     39: #import <sys/systm.h>
                     40: #import <bsd/sys/tty.h>
                     41: #import <bsd/sys/uio.h>
                     42: #import <bsd/sys/fcntl.h>              /* for kmopen */
                     43: #import <bsd/sys/errno.h>
                     44: #import <bsd/sys/msgbuf.h>
                     45: #import <bsd/dev/kmreg_com.h>
                     46: #import <kern/thread_call.h>
                     47: #import <kernserv/ns_timer.h>
                     48: #import <bsd/dev/i386/kmDevice.h>
                     49: #import <bsd/dev/i386/km.h>
                     50: #import <bsd/dev/i386/BasicConsole.h>
                     51: #include <machdep/i386/kernBootStruct.h>
                     52: 
                     53: #import <kern/assert.h>
                     54: 
                     55: /*
                     56:  * 'Global' variables, shared only by this file and conf.c.
                     57:  */
                     58: extern struct tty      cons;
                     59: struct tty *km_tty[1] = { &cons };
                     60: 
                     61: /*
                     62:  * 'Global' variables, shared only by this file and kmDevice.m.
                     63:  */
                     64: kmDevice *kmId;                                // the kmDevice
                     65: IOConsoleInfo *basicConsole;
                     66: ScreenMode basicConsoleMode;
                     67: extern IOConsoleInfo *kmAlertConsole;
                     68: static int initialized;                        // = 0
                     69: 
                     70: /*
                     71:  * Static functions.
                     72:  */
                     73: static int kmoutput(struct tty *tp);
                     74: static void kmstart(struct tty *tp);
                     75: 
                     76: void kminit();
                     77: 
                     78: /*
                     79:  * cdevsw interface to km driver.
                     80:  */
                     81: int 
                     82: kmopen(
                     83:        dev_t dev, 
                     84:        int flag,
                     85:        int devtype, 
                     86:        struct proc *pp)
                     87: {
                     88:        int rtn;
                     89:        int unit;
                     90:        struct tty *tp;
                     91:        struct winsize *wp;
                     92:        struct ConsoleSize size;
                     93:        int ret;
                     94:        
                     95: #if notdef
                     96:        if (flag & (O_POPUP|O_ALERT))
                     97:        {
                     98:                /* ensure text console visible, in case someone does a late */
                     99:                /* open of /dev/console for alert purposes */
                    100:                bcTextMode();
                    101:        }
                    102: #endif
                    103: 
                    104:        unit = minor(dev);
                    105:        if(unit >= NUM_KM_DEVS)
                    106:                return (ENXIO);
                    107: 
                    108:        if ( (rtn = [kmId kmOpen:flag]) )
                    109:                return rtn;
                    110: 
                    111:        /*
                    112:         * This code lifted from 68k km.c.
                    113:         */
                    114:        tp = (struct tty *)&cons;
                    115:        tp->t_oproc = kmstart;
                    116:        tp->t_param = NULL;
                    117:        tp->t_dev = dev;
                    118:        
                    119:        if ((tp->t_state & TS_ISOPEN) == 0) {
                    120:                tp->t_iflag = TTYDEF_IFLAG;
                    121:                tp->t_oflag = TTYDEF_OFLAG;
                    122:                tp->t_cflag = (CREAD | CS8 | CLOCAL);
                    123:                tp->t_lflag = TTYDEF_LFLAG;
                    124:                tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
                    125:                termioschars(&tp->t_termios);
                    126:                ttsetwater(tp);
                    127:        } else if ((tp->t_state & TS_XCLUDE) && pp->p_ucred->cr_uid != 0)
                    128:                return EBUSY;
                    129: 
                    130:        tp->t_state |= TS_CARR_ON; /* lie and say carrier exists and is on. */
                    131:        ret = ((*linesw[tp->t_line].l_open)(dev, tp));
                    132: 
                    133:        if (ret == 0) {
                    134:                [kmId getScreenSize:&size];
                    135:                wp = &tp->t_winsize;
                    136:                wp->ws_row = size.rows;
                    137:                wp->ws_col = size.cols;
                    138:                wp->ws_xpixel = size.pixel_width;
                    139:                wp->ws_ypixel = size.pixel_height;
                    140:        }
                    141:        
                    142:        return ret;
                    143: }
                    144: 
                    145: int 
                    146: kmclose(
                    147:        dev_t dev, 
                    148:        int flag,
                    149:        int mode,
                    150:        struct proc *p)
                    151: {
                    152:        /*
                    153:         * Note we don't close possible alert window here; we have to rely on
                    154:         * user to do a KMIOCRESTORE.
                    155:         */
                    156:         
                    157:        struct tty *tp;
                    158: 
                    159:        tp = &cons;
                    160:        (*linesw[tp->t_line].l_close)(tp,flag);
                    161:        ttyclose(tp);
                    162:        return (0);
                    163: }
                    164: 
                    165: int 
                    166: kmread(
                    167:        dev_t dev, 
                    168:        struct uio *uio,
                    169:        int ioflag)
                    170: {
                    171:        register struct tty *tp;
                    172:  
                    173:        tp = &cons;
                    174:        return ((*linesw[tp->t_line].l_read)(tp, uio, ioflag));
                    175: }
                    176: 
                    177: int 
                    178: kmwrite(
                    179:        dev_t dev, 
                    180:        struct uio *uio,
                    181:        int ioflag)
                    182: {
                    183:        register struct tty *tp;
                    184:  
                    185:        tp = &cons;
                    186:        return ((*linesw[tp->t_line].l_write)(tp, uio, ioflag));
                    187: }
                    188: 
                    189: int 
                    190: kmioctl(
                    191:        dev_t dev, 
                    192:        int cmd, 
                    193:        caddr_t data, 
                    194:        int flag,
                    195:        struct proc *p)
                    196: {
                    197:        int error;
                    198:        struct tty *tp = &cons;
                    199:        struct ConsoleSize size;
                    200:        struct winsize *wp;
                    201:        
                    202:        switch (cmd) {
                    203:            case KMIOCRESTORE:
                    204:                return [kmId restore];
                    205:                
                    206:            case KMIOCDRAWRECT:
                    207:                return [kmId drawRect:(struct km_drawrect *)data];
                    208:                
                    209:            case KMIOCERASERECT:
                    210:                return [kmId eraseRect:(struct km_drawrect *)data];
                    211: 
                    212:            case KMIOCDISABLCONS:
                    213:                return [kmId disableCons];
                    214:                
                    215:            case KMIOCDUMPLOG:
                    216:                return [kmId dumpMsgBuf];
                    217:                
                    218:            case KMIOCANIMCTL:
                    219:                return [kmId animationCtl:*(km_anim_ctl_t *)data];
                    220:                
                    221:            case KMIOCSTATUS:
                    222:                return [kmId getStatus:(unsigned *)data];
                    223: 
                    224:            case KMIOCSIZE:
                    225:                [kmId getScreenSize:&size];
                    226:                wp = (struct winsize *)data;
                    227:                wp->ws_row = size.rows;
                    228:                wp->ws_col = size.cols;
                    229:                wp->ws_xpixel = size.pixel_width;
                    230:                wp->ws_ypixel = size.pixel_height;
                    231:                return 0;
                    232:                
                    233:            case TIOCSWINSZ:
                    234:                /* Prevent changing of console size --
                    235:                 * this ensures that login doesn't revert to the
                    236:                 * termcap-defined size
                    237:                 */
                    238:                return EINVAL;
                    239: 
                    240:            /* Bodge in the CLOCAL flag as the km device is always local */
                    241:            case TIOCSETA:
                    242:            case TIOCSETAW:
                    243:            case TIOCSETAF: {
                    244:                register struct termios *t = (struct termios *)data;
                    245:                t->c_cflag |= CLOCAL;
                    246:                /* No Break */
                    247:            }
                    248:            default:            
                    249:                error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
                    250:                if (error >= 0) {
                    251:                        return error;
                    252:                }
                    253:                error = ttioctl (tp, cmd, data, flag, p);
                    254:                if (error >= 0) {
                    255:                        return error;
                    256:                }
                    257:                else {
                    258:                        return ENOTTY;
                    259:                }
                    260:        }
                    261: }
                    262: 
                    263: /*
                    264:  * this works early on, after console_init() but before autoconf (and thus
                    265:  * before we have a kmDevice).
                    266:  */
                    267: int 
                    268: kmputc(
                    269:        dev_t dev,
                    270:        int c)
                    271: {
                    272:        IOConsoleInfo *console;
                    273:        
                    274:        ASSERT(fbg != NULL);
                    275:        if(kmId) {
                    276:                /*
                    277:                 * After autoconfig, let kmDevice handle this.
                    278:                 */
                    279:                if (c == '\n') {
                    280:                        [kmId kmPutc:'\r'];
                    281:                }
                    282:                return [kmId kmPutc:c];
                    283:        }
                    284:        
                    285:        console = kmAlertConsole ? kmAlertConsole : basicConsole;
                    286:        if(c == '\n') {
                    287:                (*console->PutC)(console, '\r');
                    288:        }
                    289:        (*console->PutC)(console, c);
                    290:        return 0;
                    291: }
                    292: 
                    293: int 
                    294: kmgetc(
                    295:        dev_t dev)
                    296: {
                    297:        /* found in bsd/dev/i386/cons.c */
                    298:        extern int cnputc(char c);
                    299:        int c;
                    300:        
                    301:        if(kmId == nil) {
                    302:                return 0;
                    303:        }
                    304:        c = [kmId kmGetc];
                    305:        if (c == '\r') {
                    306:                c = '\n';
                    307:        }
                    308:        cnputc(c);
                    309:        return c;
                    310: }
                    311: 
                    312: int 
                    313: kmgetc_silent(
                    314:        dev_t dev)
                    315: {
                    316:        int c;
                    317:        
                    318:        if(kmId == nil) {
                    319:                return 0;
                    320:        }
                    321:        c = [kmId kmGetc];
                    322:        if (c == '\r') {
                    323:                c = '\n';
                    324:        }
                    325:        return c;
                    326: }
                    327: 
                    328: /*
                    329:  * Callouts from linesw.
                    330:  */
                    331:  
                    332: #define KM_LOWAT_DELAY ((ns_time_t)1000)
                    333: 
                    334: static void 
                    335: kmstart(struct tty *tp)
                    336: {
                    337:        if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
                    338:                goto out;
                    339:        if (tp->t_outq.c_cc == 0)
                    340:                goto out;
                    341:        tp->t_state |= TS_BUSY;
                    342:        if (tp->t_outq.c_cc > tp->t_lowat) {
                    343:                /*
                    344:                 * Start immediately.
                    345:                 */
                    346:                thread_call_func(
                    347:                        (thread_call_func_t) kmoutput, tp, TRUE);
                    348:        }
                    349:        else {
                    350:                /*
                    351:                 * Wait a bit...
                    352:                 */
                    353:                ns_timeout((func) kmoutput, tp, KM_LOWAT_DELAY,
                    354:                                CALLOUT_PRI_THREAD);
                    355:        }
                    356: out:
                    357:        ttwwakeup(tp);
                    358: }
                    359: 
                    360: static int 
                    361: kmoutput(
                    362:        struct tty *tp)
                    363: {
                    364:        /*
                    365:         * FIXME - to be grokked...copied from m68k km.c.
                    366:         */
                    367:        char            buf[80];
                    368:        char            *cp;
                    369:        int             cc = -1;
                    370: 
                    371:        while (tp->t_outq.c_cc > 0) {
                    372:                cc = ndqb(&tp->t_outq, 0);
                    373:                if (cc == 0)
                    374:                        break;
                    375:                cc = min(cc, sizeof buf);
                    376:                (void) q_to_b(&tp->t_outq, buf, cc);
                    377:                for (cp = buf; cp < &buf[cc]; cp++) {
                    378:                        [kmId kmPutc:(*cp & 0x7f)];
                    379:                }
                    380:        }
                    381:         if (tp->t_outq.c_cc > 0) {
                    382:                thread_call_func(
                    383:                        (thread_call_func_t)kmoutput, tp, TRUE);
                    384:        }
                    385:        tp->t_state &= ~TS_BUSY;
                    386:        ttwwakeup(tp);
                    387:        return 0;
                    388: }
                    389: 
                    390: /*
                    391:  * Alert panel interface (which we'd like to do away with if at all 
                    392:  * possible).
                    393:  */
                    394: int 
                    395: kmpopup (
                    396:        const char *title, 
                    397:        int flag, 
                    398:        int width, 
                    399:        int height, 
                    400:        boolean_t allocmem)
                    401: {
                    402:        if (!initialized) {
                    403:            kminit();
                    404:        }
                    405:        DoAlert(title, "");
                    406:        return 0;
                    407: }
                    408: 
                    409: int 
                    410: kmrestore()
                    411: {
                    412:        DoRestore();
                    413:        return 0;
                    414: }
                    415: 
                    416: 
                    417: /*
                    418:  * Write message to console; create an alert panel if no text-type window
                    419:  * currently exists. Caller must call alert_done() when finished.
                    420:  * The height and width arguments are not used; they are provided for 
                    421:  * compatibility with the 68k version of alert().
                    422:  */
                    423: int 
                    424: alert(
                    425:        int width, 
                    426:        int height, 
                    427:        const char *title, 
                    428:        const char *msg, 
                    429:        int p1, 
                    430:        int p2, 
                    431:        int p3, 
                    432:        int p4, 
                    433:        int p5, 
                    434:        int p6, 
                    435:        int p7, 
                    436:        int p8)
                    437: {
                    438:        char smsg[200];
                    439:        
                    440:        sprintf(smsg, msg,  p1, p2, p3, p4, p5, p6, p7, p8);
                    441:        DoAlert(title, smsg);
                    442:        return 0;
                    443: }
                    444: 
                    445: int 
                    446: alert_done()
                    447: {
                    448:        DoRestore();
                    449:        return 0;
                    450: }
                    451: 
                    452: /*
                    453:  * printf() a message to an an alert panel. Can be used any time after calling
                    454:  * alert(). This might go away before release, let's see..
                    455:  */
                    456: void 
                    457: aprint(        
                    458:        const char *msg, 
                    459:        int p1, 
                    460:        int p2, 
                    461:        int p3, 
                    462:        int p4, 
                    463:        int p5, 
                    464:        int p6, 
                    465:        int p7, 
                    466:        int p8)
                    467: {
                    468:        char smsg[200];
                    469:        char *cp = smsg;
                    470:        
                    471:        ASSERT(kmId != nil);
                    472:        sprintf(smsg, msg,  p1, p2, p3, p4, p5, p6, p7, p8);
                    473:        while(cp) {
                    474:                kmputc(0, *cp++);
                    475:        }
                    476: }
                    477:  
                    478: /*
                    479:  * Dump message log.
                    480:  */
                    481: void kmdumplog()
                    482: {
                    483:        if (kmId != nil)
                    484:            [kmId dumpMsgBuf];
                    485: }
                    486: 
                    487: /*
                    488:  * Initialize the console enough for printf's to work via kmputc. No 
                    489:  * text window will be created if booting in icon mode. Keyboard is 
                    490:  * not enabled. 
                    491:  */
                    492:  
                    493: void
                    494: kminit()
                    495: {
                    496:     KERNBOOTSTRUCT *kernbootstruct = KERNSTRUCT_ADDR;
                    497: 
                    498:     initialized = TRUE;
                    499: 
                    500:     basicConsole = BasicAllocateConsole();
                    501:     if (kernbootstruct->graphicsMode) {
                    502:        basicConsoleMode = SCM_GRAPHIC;
                    503:        (*basicConsole->Init)(
                    504:            basicConsole, SCM_GRAPHIC, FALSE, FALSE, mach_title);
                    505:     } else {
                    506:        basicConsoleMode = SCM_TEXT;
                    507:        (*basicConsole->Init)(
                    508:            basicConsole, SCM_TEXT, TRUE, TRUE, mach_title);
                    509:     }
                    510: }
                    511: 
                    512: void
                    513: kmDrawGraphicPanel(GraphicPanelType panelType)
                    514: {
                    515:     if (kmId != nil)
                    516:        [kmId drawGraphicPanel:panelType];
                    517: }
                    518: 
                    519: void
                    520: kmGraphicPanelString(char *str)
                    521: {
                    522:     if (kmId != nil)
                    523:        [kmId graphicPanelString:str];
                    524: }
                    525: 
                    526: /* end of km.m */
                    527: 

unix.superglobalmegacorp.com

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