|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.