|
|
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/tty.h> ! 38: ! 39: #import <bsd/dev/ppc/cons.h> ! 40: #import <bsd/sys/conf.h> ! 41: #import <sys/systm.h> ! 42: #import <bsd/sys/uio.h> ! 43: #import <bsd/sys/fcntl.h> /* for kmopen */ ! 44: #import <bsd/sys/errno.h> ! 45: #import <bsd/sys/proc.h> /* for kmopen */ ! 46: #import <bsd/sys/msgbuf.h> ! 47: #import <bsd/dev/kmreg_com.h> ! 48: #import <kern/thread_call.h> ! 49: #import <kern/clock.h> ! 50: #import <bsd/sys/time.h> ! 51: #import <kernserv/ns_timer.h> ! 52: #import <bsd/dev/ppc/kmDevice.h> ! 53: #import <bsd/dev/ppc/km.h> ! 54: #import <bsd/dev/ppc/FBConsole.h> ! 55: #import <bsd/dev/ppc/PPCKeyboardPriv.h> ! 56: #import "kernobjc.h" ! 57: ! 58: #import <kern/assert.h> ! 59: ! 60: /* ! 61: * 'Global' variables, shared only by this file and conf.c. ! 62: */ ! 63: extern struct tty cons; ! 64: struct tty *km_tty[1] = { &cons }; ! 65: ! 66: /* ! 67: * 'Global' variables, shared only by this file and kmDevice.m. ! 68: */ ! 69: int initialized = 0; ! 70: kmDevice *kmId; // the kmDevice ! 71: IOConsoleInfo *basicConsole; ! 72: ScreenMode basicConsoleMode; ! 73: extern IOConsoleInfo *kmAlertConsole; ! 74: ! 75: /* ! 76: * Static functions. ! 77: */ ! 78: static int kmoutput(struct tty *tp); ! 79: static void kmstart(struct tty *tp); ! 80: ! 81: #if KERNOBJC ! 82: #else ! 83: extern void KeyboardOpen(void); ! 84: #endif KERNOBJC ! 85: ! 86: /* ! 87: * cdevsw interface to km driver. ! 88: */ ! 89: int ! 90: kmopen( ! 91: dev_t dev, ! 92: int flag, ! 93: int devtype, ! 94: struct proc *pp) ! 95: { ! 96: int rtn; ! 97: int unit; ! 98: struct tty *tp; ! 99: struct winsize *wp; ! 100: struct ConsoleSize size; ! 101: int ret; ! 102: ! 103: unit = minor(dev); ! 104: if(unit >= NUM_KM_DEVS) ! 105: return (ENXIO); ! 106: ! 107: #if KERNOBJC ! 108: if ( (rtn = [kmId kmOpen:flag]) ) ! 109: return rtn; ! 110: #endif ! 111: ! 112: /* ! 113: * This code lifted from 68k km.c. ! 114: */ ! 115: tp = (struct tty *)&cons; ! 116: tp->t_oproc = kmstart; ! 117: tp->t_param = NULL; ! 118: tp->t_dev = dev; ! 119: ! 120: if ( !(tp->t_state & TS_ISOPEN) ) { ! 121: tp->t_iflag = TTYDEF_IFLAG; ! 122: tp->t_oflag = TTYDEF_OFLAG; ! 123: tp->t_cflag = (CREAD | CS8 | CLOCAL); ! 124: tp->t_lflag = TTYDEF_LFLAG; ! 125: tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; ! 126: termioschars(&tp->t_termios); ! 127: ttsetwater(tp); ! 128: } else if ((tp->t_state & TS_XCLUDE) && pp->p_ucred->cr_uid != 0) ! 129: return EBUSY; ! 130: ! 131: tp->t_state |= TS_CARR_ON; /* lie and say carrier exists and is on. */ ! 132: ret = ((*linesw[tp->t_line].l_open)(dev, tp)); ! 133: ! 134: if (ret == 0) { ! 135: #if KERNOBJC ! 136: [kmId getScreenSize:&size]; ! 137: #else ! 138: (*basicConsole->GetSize)(basicConsole, &size); ! 139: #endif ! 140: wp = &tp->t_winsize; ! 141: wp->ws_row = size.rows; ! 142: wp->ws_col = size.cols; ! 143: wp->ws_xpixel = size.pixel_width; ! 144: wp->ws_ypixel = size.pixel_height; ! 145: } ! 146: ! 147: #if KERNOBJC ! 148: #else ! 149: KeyboardOpen(); ! 150: #endif KERNOBJC ! 151: ! 152: return ret; ! 153: } ! 154: ! 155: int ! 156: kmclose( ! 157: dev_t dev, ! 158: int flag, ! 159: int mode, ! 160: struct proc *p) ! 161: { ! 162: /* ! 163: * Note we don't close possible alert window here; we have to rely on ! 164: * user to do a KMIOCRESTORE. ! 165: */ ! 166: ! 167: struct tty *tp; ! 168: ! 169: tp = &cons; ! 170: (*linesw[tp->t_line].l_close)(tp,flag); ! 171: ttyclose(tp); ! 172: return (0); ! 173: } ! 174: ! 175: int ! 176: kmread( ! 177: dev_t dev, ! 178: struct uio *uio, ! 179: int ioflag) ! 180: { ! 181: register struct tty *tp; ! 182: ! 183: tp = &cons; ! 184: return ((*linesw[tp->t_line].l_read)(tp, uio, ioflag)); ! 185: } ! 186: ! 187: int ! 188: kmwrite( ! 189: dev_t dev, ! 190: struct uio *uio, ! 191: int ioflag) ! 192: { ! 193: register struct tty *tp; ! 194: ! 195: tp = &cons; ! 196: return ((*linesw[tp->t_line].l_write)(tp, uio, ioflag)); ! 197: } ! 198: ! 199: int ! 200: kmioctl( ! 201: dev_t dev, ! 202: int cmd, ! 203: caddr_t data, ! 204: int flag, ! 205: struct proc *p) ! 206: { ! 207: int error; ! 208: struct tty *tp = &cons; ! 209: struct ConsoleSize size; ! 210: struct winsize *wp; ! 211: ! 212: switch (cmd) { ! 213: ! 214: #if KERNOBJC ! 215: case KMIOCRESTORE: ! 216: return [kmId restore]; ! 217: ! 218: case KMIOCDRAWRECT: ! 219: return [kmId drawRect:(struct km_drawrect *)data]; ! 220: ! 221: case KMIOCERASERECT: ! 222: return [kmId eraseRect:(struct km_drawrect *)data]; ! 223: ! 224: case KMIOCDISABLCONS: ! 225: return [kmId disableCons]; ! 226: ! 227: case KMIOCANIMCTL: ! 228: return [kmId animationCtl:*(km_anim_ctl_t *)data]; ! 229: case KMIOCDUMPLOG: ! 230: return kmdumplog(); ! 231: #else ! 232: case KMIOCRESTORE: ! 233: case KMIOCDRAWRECT: ! 234: case KMIOCERASERECT: ! 235: case KMIOCDISABLCONS: ! 236: case KMIOCANIMCTL: ! 237: case KMIOCDUMPLOG: ! 238: return 0; ! 239: #endif //KERNOBJC ! 240: ! 241: ! 242: case KMIOCSTATUS: ! 243: ! 244: #if KERNOBJC ! 245: return [kmId getStatus:(unsigned *)data]; ! 246: #else ! 247: *((unsigned *)data) = KMS_SEE_MSGS; ! 248: return 0; ! 249: #endif //KERNOBJC ! 250: ! 251: case KMIOCSIZE: ! 252: #if KERNOBJC ! 253: [kmId getScreenSize:&size]; ! 254: #else ! 255: (*basicConsole->GetSize)(basicConsole, &size); ! 256: #endif //KERNOBJC ! 257: wp = (struct winsize *)data; ! 258: wp->ws_row = size.rows; ! 259: wp->ws_col = size.cols; ! 260: wp->ws_xpixel = size.pixel_width; ! 261: wp->ws_ypixel = size.pixel_height; ! 262: return 0; ! 263: ! 264: case TIOCSWINSZ: ! 265: /* Prevent changing of console size -- ! 266: * this ensures that login doesn't revert to the ! 267: * termcap-defined size ! 268: */ ! 269: return EINVAL; ! 270: ! 271: /* Bodge in the CLOCAL flag as the km device is always local */ ! 272: case TIOCSETA: ! 273: case TIOCSETAW: ! 274: case TIOCSETAF: { ! 275: register struct termios *t = (struct termios *)data; ! 276: t->c_cflag |= CLOCAL; ! 277: /* No Break */ ! 278: } ! 279: default: ! 280: error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); ! 281: if (error >= 0) { ! 282: return error; ! 283: } ! 284: error = ttioctl (tp, cmd, data, flag, p); ! 285: if (error >= 0) { ! 286: return error; ! 287: } ! 288: else { ! 289: return ENOTTY; ! 290: } ! 291: } ! 292: } ! 293: ! 294: /* ! 295: * this works early on, after initialize_screen() but before autoconf (and thus ! 296: * before we have a kmDevice). ! 297: */ ! 298: int ! 299: kmputc( ! 300: dev_t dev, ! 301: int c) ! 302: { ! 303: IOConsoleInfo *console; ! 304: ! 305: if(kmId) { ! 306: /* ! 307: * After autoconfig, let kmDevice handle this. ! 308: */ ! 309: if (c == '\n') { ! 310: [kmId kmPutc:'\r']; ! 311: } ! 312: return [kmId kmPutc:c]; ! 313: } ! 314: ! 315: if( kmAlertConsole) ! 316: console = kmAlertConsole; ! 317: else { ! 318: console = basicConsole; ! 319: if( !initialized || (basicConsoleMode != SCM_TEXT)) ! 320: return( 0); ! 321: } ! 322: ! 323: if(c == '\n') { ! 324: (*console->PutC)(console, '\r'); ! 325: } ! 326: (*console->PutC)(console, c); ! 327: return 0; ! 328: } ! 329: ! 330: int ! 331: kmgetc( ! 332: dev_t dev) ! 333: { ! 334: /* in bsd/dev/ppc/cons.c */ ! 335: extern int cnputc(char c); ! 336: int c; ! 337: ! 338: #if KERNOBJC ! 339: if(kmId == nil) { ! 340: return 0; ! 341: } ! 342: c = [kmId kmGetc]; ! 343: #endif //KERNOBJC ! 344: ! 345: if (c == '\r') { ! 346: c = '\n'; ! 347: } ! 348: cnputc(c); ! 349: return c; ! 350: } ! 351: ! 352: int ! 353: kmgetc_silent( ! 354: dev_t dev) ! 355: { ! 356: int c; ! 357: ! 358: #if KERNOBJC ! 359: if(kmId == nil) { ! 360: return 0; ! 361: } ! 362: c = [kmId kmGetc]; ! 363: #endif //KERNOBJC ! 364: if (c == '\r') { ! 365: c = '\n'; ! 366: } ! 367: return c; ! 368: } ! 369: ! 370: /* ! 371: * Callouts from linesw. ! 372: */ ! 373: ! 374: #define KM_LOWAT_DELAY ((ns_time_t)1000) ! 375: ! 376: static void ! 377: kmstart( ! 378: struct tty *tp) ! 379: { ! 380: if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) ! 381: goto out; ! 382: if (tp->t_outq.c_cc == 0) ! 383: goto out; ! 384: tp->t_state |= TS_BUSY; ! 385: if (tp->t_outq.c_cc > tp->t_lowat) { ! 386: /* ! 387: * Start immediately. ! 388: */ ! 389: thread_call_func( ! 390: (thread_call_func_t) kmoutput, tp, TRUE); ! 391: } ! 392: else { ! 393: /* ! 394: * Wait a bit... ! 395: */ ! 396: ns_timeout((func) kmoutput, tp, KM_LOWAT_DELAY, ! 397: CALLOUT_PRI_THREAD); ! 398: } ! 399: out: ! 400: ttwwakeup(tp); ! 401: } ! 402: ! 403: static int ! 404: kmoutput( ! 405: struct tty *tp) ! 406: { ! 407: /* ! 408: * FIXME - to be grokked...copied from m68k km.c. ! 409: */ ! 410: char buf[80]; ! 411: char *cp; ! 412: int cc = -1; ! 413: ! 414: while (tp->t_outq.c_cc > 0) { ! 415: cc = ndqb(&tp->t_outq, 0); ! 416: if (cc == 0) ! 417: break; ! 418: cc = min(cc, sizeof buf); ! 419: (void) q_to_b(&tp->t_outq, buf, cc); ! 420: for (cp = buf; cp < &buf[cc]; cp++) { ! 421: ! 422: #if KERNOBJC ! 423: [kmId kmPutc:(*cp & 0x7f)]; ! 424: #else ! 425: (*basicConsole->PutC)(basicConsole, *cp & 0x7f); ! 426: #endif ! 427: } ! 428: } ! 429: if (tp->t_outq.c_cc > 0) { ! 430: thread_call_func( ! 431: (thread_call_func_t)kmoutput, tp, TRUE); ! 432: } ! 433: tp->t_state &= ~TS_BUSY; ! 434: ttwwakeup(tp); ! 435: return 0; ! 436: } ! 437: ! 438: /* ! 439: * Alert panel interface (which we'd like to do away with if at all ! 440: * possible). ! 441: */ ! 442: int ! 443: kmpopup ( ! 444: const char *title, ! 445: int flag, ! 446: int width, ! 447: int height, ! 448: boolean_t allocmem) ! 449: { ! 450: ! 451: DoAlert(title, ""); ! 452: return 0; ! 453: } ! 454: ! 455: int ! 456: kmrestore() ! 457: { ! 458: DoRestore(); ! 459: return 0; ! 460: } ! 461: ! 462: ! 463: /* ! 464: * Write message to console; create an alert panel if no text-type window ! 465: * currently exists. Caller must call alert_done() when finished. ! 466: * The height and width arguments are not used; they are provided for ! 467: * compatibility with the 68k version of alert(). ! 468: */ ! 469: int ! 470: alert( ! 471: int width, ! 472: int height, ! 473: const char *title, ! 474: const char *msg, ! 475: int p1, ! 476: int p2, ! 477: int p3, ! 478: int p4, ! 479: int p5, ! 480: int p6, ! 481: int p7, ! 482: int p8) ! 483: { ! 484: char smsg[200]; ! 485: ! 486: sprintf(smsg, msg, p1, p2, p3, p4, p5, p6, p7, p8); ! 487: DoAlert(title, smsg); ! 488: return 0; ! 489: } ! 490: ! 491: int ! 492: alert_done() ! 493: { ! 494: DoRestore(); ! 495: return 0; ! 496: } ! 497: ! 498: /* ! 499: * printf() a message to an an alert panel. Can be used any time after calling ! 500: * alert(). This might go away before release, let's see.. ! 501: */ ! 502: void ! 503: aprint( ! 504: const char *msg, ! 505: int p1, ! 506: int p2, ! 507: int p3, ! 508: int p4, ! 509: int p5, ! 510: int p6, ! 511: int p7, ! 512: int p8) ! 513: { ! 514: char smsg[200]; ! 515: char *cp = smsg; ! 516: ! 517: ASSERT(kmId != nil); ! 518: sprintf(smsg, msg, p1, p2, p3, p4, p5, p6, p7, p8); ! 519: while(cp) { ! 520: kmputc(0, *cp++); ! 521: } ! 522: } ! 523: ! 524: /* ! 525: * Dump message log. ! 526: */ ! 527: int ! 528: kmdumplog() ! 529: { ! 530: ! 531: extern struct msgbuf * msgbufp; /* defined in subr_prf.c */ ! 532: char * mp; ! 533: ! 534: if( msgbufp->msg_magic != MSG_MAGIC) ! 535: return( 0); ! 536: mp = &msgbufp->msg_bufc[msgbufp->msg_bufx]; ! 537: do { ! 538: if( *mp) ! 539: kmputc( 12, *mp); ! 540: if( ++mp >= &msgbufp->msg_bufc[MSG_BSIZE]) ! 541: mp = msgbufp->msg_bufc; ! 542: } while( mp != &msgbufp->msg_bufc[msgbufp->msg_bufx]); ! 543: return 0; ! 544: } ! 545: ! 546: #if KERNOBJC ! 547: ! 548: void ! 549: kmDrawGraphicPanel(GraphicPanelType panelType) ! 550: { ! 551: if (kmId != nil) ! 552: [kmId drawGraphicPanel:panelType]; ! 553: } ! 554: ! 555: void ! 556: kmGraphicPanelString(char *str) ! 557: { ! 558: if (kmId != nil) ! 559: [kmId graphicPanelString:str]; ! 560: } ! 561: ! 562: #endif //KERNOBJC ! 563: ! 564: ! 565: ! 566: /* end of km.m */ ! 567:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.