Annotation of kernel/kern/miniMon.c, 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: /*
                     26:  * Copyright (c) 1993 NeXT Computer, Inc.  All rights reserved.
                     27:  *
                     28:  * miniMon.c -- Machine-independent mini-monitor.
                     29:  *
                     30:  * HISTORY
                     31:  * 04-Oct-1993         Curtis Galloway at NeXT
                     32:  *     Created.
                     33:  *
                     34:  */
                     35: 
                     36: #import <kern/miniMon.h>
                     37: #import <kern/miniMonPrivate.h>
                     38: #import <sys/param.h>
                     39: #import <sys/systm.h>
                     40: #import <sys/reboot.h>
                     41: #include <stdarg.h>
                     42: #import <mach/machine/simple_lock.h>
                     43: 
                     44: extern int boothowto;
                     45: 
                     46: static boolean_t miniMonContinue(char *);
                     47: static boolean_t miniMonHelp(char *);
                     48: static boolean_t miniMonResetKdp(char *);
                     49: static boolean_t miniMonTryGdb(char *);
                     50: static boolean_t miniMonForceGdb(char *);
                     51: void *miniMonState;
                     52: 
                     53: miniMonCommand_t miniMonCommands[] = {
                     54:     {"continue", miniMonContinue, "Continue execution"},
                     55:     {"reboot", miniMonReboot, "Reboot the computer, no sync"},
                     56:     {"halt", miniMonHalt, "Sync and halt the computer"},
                     57:     {"gdb", miniMonTryGdb, "Break to remote debugger"},
                     58:     {"forcegdb", miniMonForceGdb, "Break to remote debugger"},
                     59:     {"reset", miniMonResetKdp, "Reset debugger state"},
                     60:     {"help", miniMonHelp, 0},
                     61:     {"?", miniMonHelp, 0},
                     62:     {0,0}
                     63: };
                     64: 
                     65:  
                     66: static match_t
                     67: commandcmp(char *command, char *line)
                     68: {
                     69:     while (*command) {
                     70:        if (*line == ' ' || *line == '\t' ||
                     71:            *line == '\n' || *line == '\0')
                     72:                return FOUND;
                     73:        if (*command++ != *line++)
                     74:            return NOT_FOUND;
                     75:     }
                     76:     return FOUND;
                     77: }
                     78: 
                     79: 
                     80: 
                     81: static boolean_t
                     82: miniMonParseLine(char *line)
                     83: {
                     84:     struct miniMonCommand *command, *found_command = NULL;
                     85:     
                     86:     for (command = miniMonCommands; command->name; command++) {
                     87:        if (commandcmp(command->name, line) == FOUND) {
                     88:            if (found_command != NULL) {
                     89:                safe_prf("Ambiguous command - type '?' for help\n");
                     90:                return TRUE;
                     91:            } else {
                     92:                found_command = command;
                     93:            }
                     94:        }
                     95:     }
                     96:     for (command = miniMonMDCommands; command->name; command++) {
                     97:        if (commandcmp(command->name, line) == FOUND) {
                     98:            if (found_command != NULL) {
                     99:                safe_prf("Ambiguous command - type '?' for help\n");
                    100:                return TRUE;
                    101:            } else {
                    102:                found_command = command;
                    103:            }
                    104:        }
                    105:     }
                    106:     if (found_command != NULL) {
                    107:        return (*found_command->function)(line);
                    108:     } else {
                    109:        safe_prf("Invalid command - type '?' for help\n");
                    110:        return TRUE;
                    111:     }
                    112: }
                    113: 
                    114: static void
                    115: miniMonGetLine(char *line, int len)
                    116: {
                    117:     register int c;
                    118:     char *anchor = line;
                    119: 
                    120:     len--;     /* for '\0' */
                    121:     for (;;) {
                    122:        c = miniMonGetchar();
                    123:        switch (c) {
                    124:        case '\r':
                    125:            miniMonPutchar('\n');
                    126:            /* fall into ... */
                    127:        case '\n':
                    128:            *line++ = '\0';
                    129:            return;
                    130:        case '\b':      /* bs */
                    131:            miniMonPutchar(' ');
                    132:            if (line != anchor) {
                    133:                miniMonPutchar('\b');
                    134:                line--;
                    135:                len++;
                    136:            }
                    137:            continue;
                    138:        case '\025':    /* ^u */
                    139:            line = anchor;
                    140:            miniMonPutchar('\n');
                    141:            continue;
                    142:        default:
                    143:            if (len) {
                    144:                *line++ = c;
                    145:                len--;
                    146:            } else {
                    147:                miniMonPutchar('\b');
                    148:                miniMonPutchar(' ');
                    149:                miniMonPutchar('\b');
                    150:            }
                    151:        }
                    152:     }
                    153: }
                    154: 
                    155: simple_lock_t _kernDebuggerLock;
                    156: 
                    157: void
                    158: miniMonInit(void)
                    159: {
                    160:     /*
                    161:      * Initialize kernel debugger lock.
                    162:      */
                    163:     _kernDebuggerLock = simple_lock_alloc();
                    164:     simple_lock_init(_kernDebuggerLock);
                    165: }
                    166: 
                    167: 
                    168: static char miniMonLine[128];
                    169: 
                    170: void
                    171: miniMonLoop(char *prompt, int panic, void *state)
                    172: {
                    173:     int c;
                    174:     
                    175:     miniMonState = state;
                    176:     if (panic) {
                    177:        safe_prf("System Panic:\n");
                    178:        safe_prf("%s\n",panicstr);
                    179: #if defined(ppc)
                    180:     {
                    181:                unsigned int *fp;
                    182:         unsigned int register sp;
                    183:                unsigned int depth=15;
                    184:         __asm__ volatile("mr %0,r1" : "=r" (sp));
                    185: 
                    186:         safe_prf("stack backtrace -  ");
                    187:         fp = *((unsigned int *)sp);
                    188:         while (fp && (--depth)) {
                    189:             safe_prf("0x%08x ", fp[2]);
                    190:             fp = (unsigned int *)*fp;
                    191:         }
                    192:         safe_prf("\n");
                    193:     }
                    194: #endif /* ppc */
                    195: 
                    196:        if ((boothowto & RB_DEBUG) == 0) {
                    197:            /* Reboot automatically */
                    198:            safe_prf("(Type 'm' for monitor,\n");
                    199:            safe_prf("or wait for automatic reboot)");
                    200:            /* Wait for 30 seconds */
                    201:            for (c=30000; c>0; c--) {
                    202:                if (miniMonTryGetchar() == 'm') {
                    203:                    safe_prf("\n");
                    204:                    break;
                    205:                }
                    206:                us_spin(1000);
                    207:            }
                    208:            if (c == 0) {
                    209:                safe_prf("\nRebooting...");
                    210:                miniMonReboot("");
                    211:            }
                    212:        } else {
                    213:            safe_prf("(Type 'r' to reboot or 'm' for monitor)");
                    214:            for (;;) {
                    215:                c = miniMonTryGetchar();
                    216:                if (c == 'r') {
                    217:                    safe_prf("\nRebooting...");
                    218:                    miniMonReboot("");
                    219:                } else if (c == 'm') {
                    220:                    safe_prf("\n");
                    221:                    break;
                    222:                }
                    223:            }
                    224:        }
                    225:     }
                    226:     safe_prf("Mini-monitor\n");
                    227:     for(;;) {
                    228:        safe_prf("%s> ",prompt);
                    229:        miniMonGetLine(miniMonLine, sizeof(miniMonLine));
                    230:        if (miniMonParseLine(miniMonLine) == FALSE)
                    231:            break;
                    232:     }
                    233: }
                    234: 
                    235: static boolean_t
                    236: miniMonContinue(char *line)
                    237: {
                    238:     return FALSE;
                    239: }
                    240: 
                    241: static boolean_t
                    242: miniMonHelp(char *line)
                    243: {
                    244:     struct miniMonCommand *command;
                    245:     safe_prf("Mini-monitor commands:\n");
                    246:     safe_prf("?,help - Print this message\n");
                    247:     for (command = miniMonCommands; command->name; command++) {
                    248:        if (command->help)
                    249:            safe_prf("%s - %s\n",command->name,command->help);
                    250:     }
                    251:     for (command = miniMonMDCommands; command->name; command++) {
                    252:        if (command->help)
                    253:            safe_prf("%s - %s\n",command->name,command->help);
                    254:     }
                    255:     return TRUE;
                    256: }
                    257: 
                    258: /* keep messages from getting written to message log */
                    259: void safe_prf(const char *format, ...)
                    260: {
                    261:     va_list ap;
                    262:     static char buf[512];
                    263:     char *p = buf;
                    264:        
                    265:     va_start(ap, format);
                    266: #define        TOSTR   0x8
                    267:     prf(format, ap, TOSTR, (struct tty *)&p);
                    268:     va_end(ap);
                    269:     *p++ = '\0';
                    270: 
                    271:     p = buf;   
                    272:     while (*p)
                    273:        miniMonPutchar(*p++);
                    274: }
                    275: 
                    276: static boolean_t
                    277: miniMonResetKdp(char *line)
                    278: {
                    279:     extern void kdp_reset(void);
                    280:     
                    281:     kdp_reset();
                    282:     return TRUE;
                    283: }
                    284: 
                    285: static boolean_t
                    286: miniMonTryGdb(char *line)
                    287: {
                    288:     extern simple_lock_t _kernDebuggerLock;
                    289:     boolean_t ret;
                    290: 
                    291:     if (simple_lock_try(_kernDebuggerLock)) {
                    292:        ret = miniMonGdb(line);
                    293:        simple_unlock(_kernDebuggerLock);
                    294:     } else {
                    295:        safe_prf("Couldn't acquire debugger lock:\n");
                    296:        safe_prf("exit from monitor and try again.\n");
                    297:        ret = TRUE;
                    298:     }
                    299:     return ret;
                    300: }
                    301: 
                    302: static boolean_t
                    303: miniMonForceGdb(char *line)
                    304: {
                    305:     extern simple_lock_t _kernDebuggerLock;
                    306:     boolean_t ret;
                    307: 
                    308:     simple_lock_try(_kernDebuggerLock);
                    309:        ret = miniMonGdb(line);
                    310:        simple_unlock(_kernDebuggerLock);
                    311: 
                    312:     return ret;
                    313: }

unix.superglobalmegacorp.com

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