Annotation of qemu/monitor.c, revision 1.1.1.5

1.1       root        1: /*
                      2:  * QEMU monitor
                      3:  * 
                      4:  * Copyright (c) 2003-2004 Fabrice Bellard
                      5:  * 
                      6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                      7:  * of this software and associated documentation files (the "Software"), to deal
                      8:  * in the Software without restriction, including without limitation the rights
                      9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     10:  * copies of the Software, and to permit persons to whom the Software is
                     11:  * furnished to do so, subject to the following conditions:
                     12:  *
                     13:  * The above copyright notice and this permission notice shall be included in
                     14:  * all copies or substantial portions of the Software.
                     15:  *
                     16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
                     19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     22:  * THE SOFTWARE.
                     23:  */
                     24: #include "vl.h"
                     25: #include "disas.h"
                     26: #include <dirent.h>
                     27: 
                     28: //#define DEBUG
                     29: //#define DEBUG_COMPLETION
                     30: 
                     31: #ifndef offsetof
                     32: #define offsetof(type, field) ((size_t) &((type *)0)->field)
                     33: #endif
                     34: 
                     35: /*
                     36:  * Supported types:
                     37:  * 
                     38:  * 'F'          filename
                     39:  * 'B'          block device name
                     40:  * 's'          string (accept optional quote)
                     41:  * 'i'          32 bit integer
                     42:  * 'l'          target long (32 or 64 bit)
                     43:  * '/'          optional gdb-like print format (like "/10x")
                     44:  *
                     45:  * '?'          optional type (for 'F', 's' and 'i')
                     46:  *
                     47:  */
                     48: 
                     49: typedef struct term_cmd_t {
                     50:     const char *name;
                     51:     const char *args_type;
                     52:     void (*handler)();
                     53:     const char *params;
                     54:     const char *help;
                     55: } term_cmd_t;
                     56: 
                     57: static CharDriverState *monitor_hd;
1.1.1.5 ! root       58: static int hide_banner;
1.1       root       59: 
                     60: static term_cmd_t term_cmds[];
                     61: static term_cmd_t info_cmds[];
                     62: 
                     63: static char term_outbuf[1024];
                     64: static int term_outbuf_index;
                     65: 
                     66: static void monitor_start_input(void);
                     67: 
1.1.1.2   root       68: CPUState *mon_cpu = NULL;
                     69: 
1.1       root       70: void term_flush(void)
                     71: {
                     72:     if (term_outbuf_index > 0) {
                     73:         qemu_chr_write(monitor_hd, term_outbuf, term_outbuf_index);
                     74:         term_outbuf_index = 0;
                     75:     }
                     76: }
                     77: 
                     78: /* flush at every end of line or if the buffer is full */
                     79: void term_puts(const char *str)
                     80: {
                     81:     int c;
                     82:     for(;;) {
                     83:         c = *str++;
                     84:         if (c == '\0')
                     85:             break;
1.1.1.4   root       86:         if (c == '\n')
                     87:             term_outbuf[term_outbuf_index++] = '\r';
1.1       root       88:         term_outbuf[term_outbuf_index++] = c;
1.1.1.4   root       89:         if (term_outbuf_index >= (sizeof(term_outbuf) - 1) ||
1.1       root       90:             c == '\n')
                     91:             term_flush();
                     92:     }
                     93: }
                     94: 
                     95: void term_vprintf(const char *fmt, va_list ap)
                     96: {
                     97:     char buf[4096];
                     98:     vsnprintf(buf, sizeof(buf), fmt, ap);
                     99:     term_puts(buf);
                    100: }
                    101: 
                    102: void term_printf(const char *fmt, ...)
                    103: {
                    104:     va_list ap;
                    105:     va_start(ap, fmt);
                    106:     term_vprintf(fmt, ap);
                    107:     va_end(ap);
                    108: }
                    109: 
1.1.1.5 ! root      110: void term_print_filename(const char *filename)
        !           111: {
        !           112:     int i;
        !           113: 
        !           114:     for (i = 0; filename[i]; i++) {
        !           115:        switch (filename[i]) {
        !           116:        case ' ':
        !           117:        case '"':
        !           118:        case '\\':
        !           119:            term_printf("\\%c", filename[i]);
        !           120:            break;
        !           121:        case '\t':
        !           122:            term_printf("\\t");
        !           123:            break;
        !           124:        case '\r':
        !           125:            term_printf("\\r");
        !           126:            break;
        !           127:        case '\n':
        !           128:            term_printf("\\n");
        !           129:            break;
        !           130:        default:
        !           131:            term_printf("%c", filename[i]);
        !           132:            break;
        !           133:        }
        !           134:     }
        !           135: }
        !           136: 
1.1       root      137: static int monitor_fprintf(FILE *stream, const char *fmt, ...)
                    138: {
                    139:     va_list ap;
                    140:     va_start(ap, fmt);
                    141:     term_vprintf(fmt, ap);
                    142:     va_end(ap);
                    143:     return 0;
                    144: }
                    145: 
                    146: static int compare_cmd(const char *name, const char *list)
                    147: {
                    148:     const char *p, *pstart;
                    149:     int len;
                    150:     len = strlen(name);
                    151:     p = list;
                    152:     for(;;) {
                    153:         pstart = p;
                    154:         p = strchr(p, '|');
                    155:         if (!p)
                    156:             p = pstart + strlen(pstart);
                    157:         if ((p - pstart) == len && !memcmp(pstart, name, len))
                    158:             return 1;
                    159:         if (*p == '\0')
                    160:             break;
                    161:         p++;
                    162:     }
                    163:     return 0;
                    164: }
                    165: 
                    166: static void help_cmd1(term_cmd_t *cmds, const char *prefix, const char *name)
                    167: {
                    168:     term_cmd_t *cmd;
                    169: 
                    170:     for(cmd = cmds; cmd->name != NULL; cmd++) {
                    171:         if (!name || !strcmp(name, cmd->name))
                    172:             term_printf("%s%s %s -- %s\n", prefix, cmd->name, cmd->params, cmd->help);
                    173:     }
                    174: }
                    175: 
                    176: static void help_cmd(const char *name)
                    177: {
                    178:     if (name && !strcmp(name, "info")) {
                    179:         help_cmd1(info_cmds, "info ", NULL);
                    180:     } else {
                    181:         help_cmd1(term_cmds, "", name);
                    182:         if (name && !strcmp(name, "log")) {
                    183:             CPULogItem *item;
                    184:             term_printf("Log items (comma separated):\n");
                    185:             term_printf("%-10s %s\n", "none", "remove all logs");
                    186:             for(item = cpu_log_items; item->mask != 0; item++) {
                    187:                 term_printf("%-10s %s\n", item->name, item->help);
                    188:             }
                    189:         }
                    190:     }
                    191: }
                    192: 
                    193: static void do_help(const char *name)
                    194: {
                    195:     help_cmd(name);
                    196: }
                    197: 
1.1.1.5 ! root      198: static void do_commit(const char *device)
1.1       root      199: {
1.1.1.5 ! root      200:     int i, all_devices;
        !           201:     
        !           202:     all_devices = !strcmp(device, "all");
1.1       root      203:     for (i = 0; i < MAX_DISKS; i++) {
                    204:         if (bs_table[i]) {
1.1.1.5 ! root      205:             if (all_devices || 
        !           206:                 !strcmp(bdrv_get_device_name(bs_table[i]), device))
        !           207:                 bdrv_commit(bs_table[i]);
1.1       root      208:         }
                    209:     }
                    210: }
                    211: 
                    212: static void do_info(const char *item)
                    213: {
                    214:     term_cmd_t *cmd;
                    215: 
                    216:     if (!item)
                    217:         goto help;
                    218:     for(cmd = info_cmds; cmd->name != NULL; cmd++) {
                    219:         if (compare_cmd(item, cmd->name)) 
                    220:             goto found;
                    221:     }
                    222:  help:
                    223:     help_cmd("info");
                    224:     return;
                    225:  found:
                    226:     cmd->handler();
                    227: }
                    228: 
                    229: static void do_info_version(void)
                    230: {
                    231:   term_printf("%s\n", QEMU_VERSION);
                    232: }
                    233: 
1.1.1.2   root      234: static void do_info_block(void)
1.1       root      235: {
1.1.1.2   root      236:     bdrv_info();
                    237: }
                    238: 
                    239: /* get the current CPU defined by the user */
                    240: int mon_set_cpu(int cpu_index)
                    241: {
                    242:     CPUState *env;
                    243: 
                    244:     for(env = first_cpu; env != NULL; env = env->next_cpu) {
                    245:         if (env->cpu_index == cpu_index) {
                    246:             mon_cpu = env;
                    247:             return 0;
1.1       root      248:         }
                    249:     }
1.1.1.2   root      250:     return -1;
1.1       root      251: }
1.1.1.2   root      252: 
                    253: CPUState *mon_get_cpu(void)
1.1       root      254: {
1.1.1.2   root      255:     if (!mon_cpu) {
                    256:         mon_set_cpu(0);
                    257:     }
                    258:     return mon_cpu;
1.1       root      259: }
                    260: 
                    261: static void do_info_registers(void)
                    262: {
1.1.1.2   root      263:     CPUState *env;
                    264:     env = mon_get_cpu();
                    265:     if (!env)
                    266:         return;
1.1       root      267: #ifdef TARGET_I386
1.1.1.2   root      268:     cpu_dump_state(env, NULL, monitor_fprintf,
1.1       root      269:                    X86_DUMP_FPU);
                    270: #else
1.1.1.2   root      271:     cpu_dump_state(env, NULL, monitor_fprintf, 
1.1       root      272:                    0);
                    273: #endif
                    274: }
                    275: 
1.1.1.2   root      276: static void do_info_cpus(void)
                    277: {
                    278:     CPUState *env;
                    279: 
                    280:     /* just to set the default cpu if not already done */
                    281:     mon_get_cpu();
                    282: 
                    283:     for(env = first_cpu; env != NULL; env = env->next_cpu) {
                    284:         term_printf("%c CPU #%d:", 
                    285:                     (env == mon_cpu) ? '*' : ' ',
                    286:                     env->cpu_index);
                    287: #if defined(TARGET_I386)
                    288:         term_printf(" pc=0x" TARGET_FMT_lx, env->eip + env->segs[R_CS].base);
                    289:         if (env->hflags & HF_HALTED_MASK)
                    290:             term_printf(" (halted)");
                    291: #elif defined(TARGET_PPC)
                    292:         term_printf(" nip=0x" TARGET_FMT_lx, env->nip);
                    293:         if (env->halted)
                    294:             term_printf(" (halted)");
                    295: #elif defined(TARGET_SPARC)
                    296:         term_printf(" pc=0x" TARGET_FMT_lx " npc=0x" TARGET_FMT_lx, env->pc, env->npc);
                    297:         if (env->halted)
                    298:             term_printf(" (halted)");
                    299: #endif
                    300:         term_printf("\n");
                    301:     }
                    302: }
                    303: 
                    304: static void do_cpu_set(int index)
                    305: {
                    306:     if (mon_set_cpu(index) < 0)
                    307:         term_printf("Invalid CPU index\n");
                    308: }
                    309: 
1.1       root      310: static void do_info_jit(void)
                    311: {
                    312:     dump_exec_info(NULL, monitor_fprintf);
                    313: }
                    314: 
                    315: static void do_info_history (void)
                    316: {
                    317:     int i;
                    318:     const char *str;
                    319:     
                    320:     i = 0;
                    321:     for(;;) {
                    322:         str = readline_get_history(i);
                    323:         if (!str)
                    324:             break;
                    325:        term_printf("%d: '%s'\n", i, str);
                    326:         i++;
                    327:     }
                    328: }
                    329: 
                    330: static void do_quit(void)
                    331: {
                    332:     exit(0);
                    333: }
                    334: 
                    335: static int eject_device(BlockDriverState *bs, int force)
                    336: {
                    337:     if (bdrv_is_inserted(bs)) {
                    338:         if (!force) {
                    339:             if (!bdrv_is_removable(bs)) {
                    340:                 term_printf("device is not removable\n");
                    341:                 return -1;
                    342:             }
                    343:             if (bdrv_is_locked(bs)) {
                    344:                 term_printf("device is locked\n");
                    345:                 return -1;
                    346:             }
                    347:         }
                    348:         bdrv_close(bs);
                    349:     }
                    350:     return 0;
                    351: }
                    352: 
                    353: static void do_eject(int force, const char *filename)
                    354: {
                    355:     BlockDriverState *bs;
                    356: 
                    357:     bs = bdrv_find(filename);
                    358:     if (!bs) {
                    359:         term_printf("device not found\n");
                    360:         return;
                    361:     }
                    362:     eject_device(bs, force);
                    363: }
                    364: 
                    365: static void do_change(const char *device, const char *filename)
                    366: {
                    367:     BlockDriverState *bs;
                    368:     int i;
                    369:     char password[256];
                    370: 
                    371:     bs = bdrv_find(device);
                    372:     if (!bs) {
                    373:         term_printf("device not found\n");
                    374:         return;
                    375:     }
                    376:     if (eject_device(bs, 0) < 0)
                    377:         return;
                    378:     bdrv_open(bs, filename, 0);
                    379:     if (bdrv_is_encrypted(bs)) {
                    380:         term_printf("%s is encrypted.\n", device);
                    381:         for(i = 0; i < 3; i++) {
                    382:             monitor_readline("Password: ", 1, password, sizeof(password));
                    383:             if (bdrv_set_key(bs, password) == 0)
                    384:                 break;
                    385:             term_printf("invalid password\n");
                    386:         }
                    387:     }
                    388: }
                    389: 
                    390: static void do_screen_dump(const char *filename)
                    391: {
1.1.1.3   root      392:     vga_hw_screen_dump(filename);
1.1       root      393: }
                    394: 
                    395: static void do_log(const char *items)
                    396: {
                    397:     int mask;
                    398:     
                    399:     if (!strcmp(items, "none")) {
                    400:         mask = 0;
                    401:     } else {
                    402:         mask = cpu_str_to_log_mask(items);
                    403:         if (!mask) {
                    404:             help_cmd("log");
                    405:             return;
                    406:         }
                    407:     }
                    408:     cpu_set_log(mask);
                    409: }
                    410: 
                    411: static void do_stop(void)
                    412: {
                    413:     vm_stop(EXCP_INTERRUPT);
                    414: }
                    415: 
                    416: static void do_cont(void)
                    417: {
                    418:     vm_start();
                    419: }
                    420: 
                    421: #ifdef CONFIG_GDBSTUB
                    422: static void do_gdbserver(int has_port, int port)
                    423: {
                    424:     if (!has_port)
                    425:         port = DEFAULT_GDBSTUB_PORT;
1.1.1.5 ! root      426:     if (gdbserver_start_port(port) < 0) {
1.1       root      427:         qemu_printf("Could not open gdbserver socket on port %d\n", port);
                    428:     } else {
                    429:         qemu_printf("Waiting gdb connection on port %d\n", port);
                    430:     }
                    431: }
                    432: #endif
                    433: 
                    434: static void term_printc(int c)
                    435: {
                    436:     term_printf("'");
                    437:     switch(c) {
                    438:     case '\'':
                    439:         term_printf("\\'");
                    440:         break;
                    441:     case '\\':
                    442:         term_printf("\\\\");
                    443:         break;
                    444:     case '\n':
                    445:         term_printf("\\n");
                    446:         break;
                    447:     case '\r':
                    448:         term_printf("\\r");
                    449:         break;
                    450:     default:
                    451:         if (c >= 32 && c <= 126) {
                    452:             term_printf("%c", c);
                    453:         } else {
                    454:             term_printf("\\x%02x", c);
                    455:         }
                    456:         break;
                    457:     }
                    458:     term_printf("'");
                    459: }
                    460: 
                    461: static void memory_dump(int count, int format, int wsize, 
                    462:                         target_ulong addr, int is_physical)
                    463: {
1.1.1.2   root      464:     CPUState *env;
1.1       root      465:     int nb_per_line, l, line_size, i, max_digits, len;
                    466:     uint8_t buf[16];
                    467:     uint64_t v;
                    468: 
                    469:     if (format == 'i') {
                    470:         int flags;
                    471:         flags = 0;
1.1.1.2   root      472:         env = mon_get_cpu();
                    473:         if (!env && !is_physical)
                    474:             return;
1.1       root      475: #ifdef TARGET_I386
                    476:         if (wsize == 2) {
                    477:             flags = 1;
                    478:         } else if (wsize == 4) {
                    479:             flags = 0;
                    480:         } else {
1.1.1.3   root      481:             /* as default we use the current CS size */
1.1       root      482:             flags = 0;
1.1.1.3   root      483:             if (env) {
                    484: #ifdef TARGET_X86_64
                    485:                 if ((env->efer & MSR_EFER_LMA) && 
                    486:                     (env->segs[R_CS].flags & DESC_L_MASK))
                    487:                     flags = 2;
                    488:                 else
                    489: #endif
                    490:                 if (!(env->segs[R_CS].flags & DESC_B_MASK))
                    491:                     flags = 1;
                    492:             }
1.1       root      493:         }
                    494: #endif
1.1.1.2   root      495:         monitor_disas(env, addr, count, is_physical, flags);
1.1       root      496:         return;
                    497:     }
                    498: 
                    499:     len = wsize * count;
                    500:     if (wsize == 1)
                    501:         line_size = 8;
                    502:     else
                    503:         line_size = 16;
                    504:     nb_per_line = line_size / wsize;
                    505:     max_digits = 0;
                    506: 
                    507:     switch(format) {
                    508:     case 'o':
                    509:         max_digits = (wsize * 8 + 2) / 3;
                    510:         break;
                    511:     default:
                    512:     case 'x':
                    513:         max_digits = (wsize * 8) / 4;
                    514:         break;
                    515:     case 'u':
                    516:     case 'd':
                    517:         max_digits = (wsize * 8 * 10 + 32) / 33;
                    518:         break;
                    519:     case 'c':
                    520:         wsize = 1;
                    521:         break;
                    522:     }
                    523: 
                    524:     while (len > 0) {
                    525:         term_printf(TARGET_FMT_lx ":", addr);
                    526:         l = len;
                    527:         if (l > line_size)
                    528:             l = line_size;
                    529:         if (is_physical) {
                    530:             cpu_physical_memory_rw(addr, buf, l, 0);
                    531:         } else {
1.1.1.2   root      532:             env = mon_get_cpu();
                    533:             if (!env)
                    534:                 break;
                    535:             cpu_memory_rw_debug(env, addr, buf, l, 0);
1.1       root      536:         }
                    537:         i = 0; 
                    538:         while (i < l) {
                    539:             switch(wsize) {
                    540:             default:
                    541:             case 1:
                    542:                 v = ldub_raw(buf + i);
                    543:                 break;
                    544:             case 2:
                    545:                 v = lduw_raw(buf + i);
                    546:                 break;
                    547:             case 4:
                    548:                 v = (uint32_t)ldl_raw(buf + i);
                    549:                 break;
                    550:             case 8:
                    551:                 v = ldq_raw(buf + i);
                    552:                 break;
                    553:             }
                    554:             term_printf(" ");
                    555:             switch(format) {
                    556:             case 'o':
1.1.1.4   root      557:                 term_printf("%#*" PRIo64, max_digits, v);
1.1       root      558:                 break;
                    559:             case 'x':
1.1.1.4   root      560:                 term_printf("0x%0*" PRIx64, max_digits, v);
1.1       root      561:                 break;
                    562:             case 'u':
1.1.1.4   root      563:                 term_printf("%*" PRIu64, max_digits, v);
1.1       root      564:                 break;
                    565:             case 'd':
1.1.1.4   root      566:                 term_printf("%*" PRId64, max_digits, v);
1.1       root      567:                 break;
                    568:             case 'c':
                    569:                 term_printc(v);
                    570:                 break;
                    571:             }
                    572:             i += wsize;
                    573:         }
                    574:         term_printf("\n");
                    575:         addr += l;
                    576:         len -= l;
                    577:     }
                    578: }
                    579: 
                    580: #if TARGET_LONG_BITS == 64
                    581: #define GET_TLONG(h, l) (((uint64_t)(h) << 32) | (l))
                    582: #else
                    583: #define GET_TLONG(h, l) (l)
                    584: #endif
                    585: 
                    586: static void do_memory_dump(int count, int format, int size, 
                    587:                            uint32_t addrh, uint32_t addrl)
                    588: {
                    589:     target_long addr = GET_TLONG(addrh, addrl);
                    590:     memory_dump(count, format, size, addr, 0);
                    591: }
                    592: 
                    593: static void do_physical_memory_dump(int count, int format, int size,
                    594:                                     uint32_t addrh, uint32_t addrl)
                    595: 
                    596: {
                    597:     target_long addr = GET_TLONG(addrh, addrl);
                    598:     memory_dump(count, format, size, addr, 1);
                    599: }
                    600: 
                    601: static void do_print(int count, int format, int size, unsigned int valh, unsigned int vall)
                    602: {
                    603:     target_long val = GET_TLONG(valh, vall);
                    604: #if TARGET_LONG_BITS == 32
                    605:     switch(format) {
                    606:     case 'o':
                    607:         term_printf("%#o", val);
                    608:         break;
                    609:     case 'x':
                    610:         term_printf("%#x", val);
                    611:         break;
                    612:     case 'u':
                    613:         term_printf("%u", val);
                    614:         break;
                    615:     default:
                    616:     case 'd':
                    617:         term_printf("%d", val);
                    618:         break;
                    619:     case 'c':
                    620:         term_printc(val);
                    621:         break;
                    622:     }
                    623: #else
                    624:     switch(format) {
                    625:     case 'o':
1.1.1.4   root      626:         term_printf("%#" PRIo64, val);
1.1       root      627:         break;
                    628:     case 'x':
1.1.1.4   root      629:         term_printf("%#" PRIx64, val);
1.1       root      630:         break;
                    631:     case 'u':
1.1.1.4   root      632:         term_printf("%" PRIu64, val);
1.1       root      633:         break;
                    634:     default:
                    635:     case 'd':
1.1.1.4   root      636:         term_printf("%" PRId64, val);
1.1       root      637:         break;
                    638:     case 'c':
                    639:         term_printc(val);
                    640:         break;
                    641:     }
                    642: #endif
                    643:     term_printf("\n");
                    644: }
                    645: 
1.1.1.5 ! root      646: static void do_memory_save(unsigned int valh, unsigned int vall, 
        !           647:                            uint32_t size, const char *filename)
        !           648: {
        !           649:     FILE *f;
        !           650:     target_long addr = GET_TLONG(valh, vall);
        !           651:     uint32_t l;
        !           652:     CPUState *env;
        !           653:     uint8_t buf[1024];
        !           654: 
        !           655:     env = mon_get_cpu();
        !           656:     if (!env)
        !           657:         return;
        !           658: 
        !           659:     f = fopen(filename, "wb");
        !           660:     if (!f) {
        !           661:         term_printf("could not open '%s'\n", filename);
        !           662:         return;
        !           663:     }
        !           664:     while (size != 0) {
        !           665:         l = sizeof(buf);
        !           666:         if (l > size)
        !           667:             l = size;
        !           668:         cpu_memory_rw_debug(env, addr, buf, l, 0);
        !           669:         fwrite(buf, 1, l, f);
        !           670:         addr += l;
        !           671:         size -= l;
        !           672:     }
        !           673:     fclose(f);
        !           674: }
        !           675: 
1.1       root      676: static void do_sum(uint32_t start, uint32_t size)
                    677: {
                    678:     uint32_t addr;
                    679:     uint8_t buf[1];
                    680:     uint16_t sum;
                    681: 
                    682:     sum = 0;
                    683:     for(addr = start; addr < (start + size); addr++) {
                    684:         cpu_physical_memory_rw(addr, buf, 1, 0);
                    685:         /* BSD sum algorithm ('sum' Unix command) */
                    686:         sum = (sum >> 1) | (sum << 15);
                    687:         sum += buf[0];
                    688:     }
                    689:     term_printf("%05d\n", sum);
                    690: }
                    691: 
                    692: typedef struct {
                    693:     int keycode;
                    694:     const char *name;
                    695: } KeyDef;
                    696: 
                    697: static const KeyDef key_defs[] = {
                    698:     { 0x2a, "shift" },
                    699:     { 0x36, "shift_r" },
                    700:     
                    701:     { 0x38, "alt" },
                    702:     { 0xb8, "alt_r" },
                    703:     { 0x1d, "ctrl" },
                    704:     { 0x9d, "ctrl_r" },
                    705: 
                    706:     { 0xdd, "menu" },
                    707: 
                    708:     { 0x01, "esc" },
                    709: 
                    710:     { 0x02, "1" },
                    711:     { 0x03, "2" },
                    712:     { 0x04, "3" },
                    713:     { 0x05, "4" },
                    714:     { 0x06, "5" },
                    715:     { 0x07, "6" },
                    716:     { 0x08, "7" },
                    717:     { 0x09, "8" },
                    718:     { 0x0a, "9" },
                    719:     { 0x0b, "0" },
1.1.1.4   root      720:     { 0x0c, "minus" },
                    721:     { 0x0d, "equal" },
1.1       root      722:     { 0x0e, "backspace" },
                    723: 
                    724:     { 0x0f, "tab" },
                    725:     { 0x10, "q" },
                    726:     { 0x11, "w" },
                    727:     { 0x12, "e" },
                    728:     { 0x13, "r" },
                    729:     { 0x14, "t" },
                    730:     { 0x15, "y" },
                    731:     { 0x16, "u" },
                    732:     { 0x17, "i" },
                    733:     { 0x18, "o" },
                    734:     { 0x19, "p" },
                    735: 
                    736:     { 0x1c, "ret" },
                    737: 
                    738:     { 0x1e, "a" },
                    739:     { 0x1f, "s" },
                    740:     { 0x20, "d" },
                    741:     { 0x21, "f" },
                    742:     { 0x22, "g" },
                    743:     { 0x23, "h" },
                    744:     { 0x24, "j" },
                    745:     { 0x25, "k" },
                    746:     { 0x26, "l" },
                    747: 
                    748:     { 0x2c, "z" },
                    749:     { 0x2d, "x" },
                    750:     { 0x2e, "c" },
                    751:     { 0x2f, "v" },
                    752:     { 0x30, "b" },
                    753:     { 0x31, "n" },
                    754:     { 0x32, "m" },
                    755:     
                    756:     { 0x39, "spc" },
                    757:     { 0x3a, "caps_lock" },
                    758:     { 0x3b, "f1" },
                    759:     { 0x3c, "f2" },
                    760:     { 0x3d, "f3" },
                    761:     { 0x3e, "f4" },
                    762:     { 0x3f, "f5" },
                    763:     { 0x40, "f6" },
                    764:     { 0x41, "f7" },
                    765:     { 0x42, "f8" },
                    766:     { 0x43, "f9" },
                    767:     { 0x44, "f10" },
                    768:     { 0x45, "num_lock" },
                    769:     { 0x46, "scroll_lock" },
                    770: 
1.1.1.4   root      771:     { 0xb5, "kp_divide" },
                    772:     { 0x37, "kp_multiply" },
                    773:     { 0x4a, "kp_substract" },
                    774:     { 0x4e, "kp_add" },
                    775:     { 0x9c, "kp_enter" },
                    776:     { 0x53, "kp_decimal" },
                    777: 
                    778:     { 0x52, "kp_0" },
                    779:     { 0x4f, "kp_1" },
                    780:     { 0x50, "kp_2" },
                    781:     { 0x51, "kp_3" },
                    782:     { 0x4b, "kp_4" },
                    783:     { 0x4c, "kp_5" },
                    784:     { 0x4d, "kp_6" },
                    785:     { 0x47, "kp_7" },
                    786:     { 0x48, "kp_8" },
                    787:     { 0x49, "kp_9" },
                    788:     
1.1       root      789:     { 0x56, "<" },
                    790: 
                    791:     { 0x57, "f11" },
                    792:     { 0x58, "f12" },
                    793: 
                    794:     { 0xb7, "print" },
                    795: 
                    796:     { 0xc7, "home" },
                    797:     { 0xc9, "pgup" },
                    798:     { 0xd1, "pgdn" },
                    799:     { 0xcf, "end" },
                    800: 
                    801:     { 0xcb, "left" },
                    802:     { 0xc8, "up" },
                    803:     { 0xd0, "down" },
                    804:     { 0xcd, "right" },
                    805: 
                    806:     { 0xd2, "insert" },
                    807:     { 0xd3, "delete" },
                    808:     { 0, NULL },
                    809: };
                    810: 
                    811: static int get_keycode(const char *key)
                    812: {
                    813:     const KeyDef *p;
1.1.1.4   root      814:     char *endp;
                    815:     int ret;
1.1       root      816: 
                    817:     for(p = key_defs; p->name != NULL; p++) {
                    818:         if (!strcmp(key, p->name))
                    819:             return p->keycode;
                    820:     }
1.1.1.4   root      821:     if (strstart(key, "0x", NULL)) {
                    822:         ret = strtoul(key, &endp, 0);
                    823:         if (*endp == '\0' && ret >= 0x01 && ret <= 0xff)
                    824:             return ret;
                    825:     }
1.1       root      826:     return -1;
                    827: }
                    828: 
                    829: static void do_send_key(const char *string)
                    830: {
                    831:     char keybuf[16], *q;
                    832:     uint8_t keycodes[16];
                    833:     const char *p;
                    834:     int nb_keycodes, keycode, i;
                    835:     
                    836:     nb_keycodes = 0;
                    837:     p = string;
                    838:     while (*p != '\0') {
                    839:         q = keybuf;
                    840:         while (*p != '\0' && *p != '-') {
                    841:             if ((q - keybuf) < sizeof(keybuf) - 1) {
                    842:                 *q++ = *p;
                    843:             }
                    844:             p++;
                    845:         }
                    846:         *q = '\0';
                    847:         keycode = get_keycode(keybuf);
                    848:         if (keycode < 0) {
                    849:             term_printf("unknown key: '%s'\n", keybuf);
                    850:             return;
                    851:         }
                    852:         keycodes[nb_keycodes++] = keycode;
                    853:         if (*p == '\0')
                    854:             break;
                    855:         p++;
                    856:     }
                    857:     /* key down events */
                    858:     for(i = 0; i < nb_keycodes; i++) {
                    859:         keycode = keycodes[i];
                    860:         if (keycode & 0x80)
                    861:             kbd_put_keycode(0xe0);
                    862:         kbd_put_keycode(keycode & 0x7f);
                    863:     }
                    864:     /* key up events */
                    865:     for(i = nb_keycodes - 1; i >= 0; i--) {
                    866:         keycode = keycodes[i];
                    867:         if (keycode & 0x80)
                    868:             kbd_put_keycode(0xe0);
                    869:         kbd_put_keycode(keycode | 0x80);
                    870:     }
                    871: }
                    872: 
1.1.1.4   root      873: static int mouse_button_state;
                    874: 
                    875: static void do_mouse_move(const char *dx_str, const char *dy_str, 
                    876:                           const char *dz_str)
                    877: {
                    878:     int dx, dy, dz;
                    879:     dx = strtol(dx_str, NULL, 0);
                    880:     dy = strtol(dy_str, NULL, 0);
                    881:     dz = 0;
                    882:     if (dz_str) 
                    883:         dz = strtol(dz_str, NULL, 0);
                    884:     kbd_mouse_event(dx, dy, dz, mouse_button_state);
                    885: }
                    886: 
                    887: static void do_mouse_button(int button_state)
                    888: {
                    889:     mouse_button_state = button_state;
                    890:     kbd_mouse_event(0, 0, 0, mouse_button_state);
                    891: }
                    892: 
1.1       root      893: static void do_ioport_read(int count, int format, int size, int addr, int has_index, int index)
                    894: {
                    895:     uint32_t val;
                    896:     int suffix;
                    897: 
                    898:     if (has_index) {
                    899:         cpu_outb(NULL, addr & 0xffff, index & 0xff);
                    900:         addr++;
                    901:     }
                    902:     addr &= 0xffff;
                    903: 
                    904:     switch(size) {
                    905:     default:
                    906:     case 1:
                    907:         val = cpu_inb(NULL, addr);
                    908:         suffix = 'b';
                    909:         break;
                    910:     case 2:
                    911:         val = cpu_inw(NULL, addr);
                    912:         suffix = 'w';
                    913:         break;
                    914:     case 4:
                    915:         val = cpu_inl(NULL, addr);
                    916:         suffix = 'l';
                    917:         break;
                    918:     }
                    919:     term_printf("port%c[0x%04x] = %#0*x\n",
                    920:                 suffix, addr, size * 2, val);
                    921: }
                    922: 
                    923: static void do_system_reset(void)
                    924: {
                    925:     qemu_system_reset_request();
                    926: }
                    927: 
                    928: static void do_system_powerdown(void)
                    929: {
                    930:     qemu_system_powerdown_request();
                    931: }
                    932: 
                    933: #if defined(TARGET_I386)
                    934: static void print_pte(uint32_t addr, uint32_t pte, uint32_t mask)
                    935: {
                    936:     term_printf("%08x: %08x %c%c%c%c%c%c%c%c\n", 
                    937:                 addr,
                    938:                 pte & mask,
                    939:                 pte & PG_GLOBAL_MASK ? 'G' : '-',
                    940:                 pte & PG_PSE_MASK ? 'P' : '-',
                    941:                 pte & PG_DIRTY_MASK ? 'D' : '-',
                    942:                 pte & PG_ACCESSED_MASK ? 'A' : '-',
                    943:                 pte & PG_PCD_MASK ? 'C' : '-',
                    944:                 pte & PG_PWT_MASK ? 'T' : '-',
                    945:                 pte & PG_USER_MASK ? 'U' : '-',
                    946:                 pte & PG_RW_MASK ? 'W' : '-');
                    947: }
                    948: 
                    949: static void tlb_info(void)
                    950: {
1.1.1.2   root      951:     CPUState *env;
1.1       root      952:     int l1, l2;
                    953:     uint32_t pgd, pde, pte;
                    954: 
1.1.1.2   root      955:     env = mon_get_cpu();
                    956:     if (!env)
                    957:         return;
                    958: 
1.1       root      959:     if (!(env->cr[0] & CR0_PG_MASK)) {
                    960:         term_printf("PG disabled\n");
                    961:         return;
                    962:     }
                    963:     pgd = env->cr[3] & ~0xfff;
                    964:     for(l1 = 0; l1 < 1024; l1++) {
                    965:         cpu_physical_memory_read(pgd + l1 * 4, (uint8_t *)&pde, 4);
                    966:         pde = le32_to_cpu(pde);
                    967:         if (pde & PG_PRESENT_MASK) {
                    968:             if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
                    969:                 print_pte((l1 << 22), pde, ~((1 << 20) - 1));
                    970:             } else {
                    971:                 for(l2 = 0; l2 < 1024; l2++) {
                    972:                     cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, 
                    973:                                              (uint8_t *)&pte, 4);
                    974:                     pte = le32_to_cpu(pte);
                    975:                     if (pte & PG_PRESENT_MASK) {
                    976:                         print_pte((l1 << 22) + (l2 << 12), 
                    977:                                   pte & ~PG_PSE_MASK, 
                    978:                                   ~0xfff);
                    979:                     }
                    980:                 }
                    981:             }
                    982:         }
                    983:     }
                    984: }
                    985: 
                    986: static void mem_print(uint32_t *pstart, int *plast_prot, 
                    987:                       uint32_t end, int prot)
                    988: {
                    989:     int prot1;
                    990:     prot1 = *plast_prot;
                    991:     if (prot != prot1) {
                    992:         if (*pstart != -1) {
                    993:             term_printf("%08x-%08x %08x %c%c%c\n",
                    994:                         *pstart, end, end - *pstart, 
                    995:                         prot1 & PG_USER_MASK ? 'u' : '-',
                    996:                         'r',
                    997:                         prot1 & PG_RW_MASK ? 'w' : '-');
                    998:         }
                    999:         if (prot != 0)
                   1000:             *pstart = end;
                   1001:         else
                   1002:             *pstart = -1;
                   1003:         *plast_prot = prot;
                   1004:     }
                   1005: }
                   1006: 
                   1007: static void mem_info(void)
                   1008: {
1.1.1.2   root     1009:     CPUState *env;
1.1       root     1010:     int l1, l2, prot, last_prot;
                   1011:     uint32_t pgd, pde, pte, start, end;
                   1012: 
1.1.1.2   root     1013:     env = mon_get_cpu();
                   1014:     if (!env)
                   1015:         return;
                   1016: 
1.1       root     1017:     if (!(env->cr[0] & CR0_PG_MASK)) {
                   1018:         term_printf("PG disabled\n");
                   1019:         return;
                   1020:     }
                   1021:     pgd = env->cr[3] & ~0xfff;
                   1022:     last_prot = 0;
                   1023:     start = -1;
                   1024:     for(l1 = 0; l1 < 1024; l1++) {
                   1025:         cpu_physical_memory_read(pgd + l1 * 4, (uint8_t *)&pde, 4);
                   1026:         pde = le32_to_cpu(pde);
                   1027:         end = l1 << 22;
                   1028:         if (pde & PG_PRESENT_MASK) {
                   1029:             if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
                   1030:                 prot = pde & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK);
                   1031:                 mem_print(&start, &last_prot, end, prot);
                   1032:             } else {
                   1033:                 for(l2 = 0; l2 < 1024; l2++) {
                   1034:                     cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, 
                   1035:                                              (uint8_t *)&pte, 4);
                   1036:                     pte = le32_to_cpu(pte);
                   1037:                     end = (l1 << 22) + (l2 << 12);
                   1038:                     if (pte & PG_PRESENT_MASK) {
                   1039:                         prot = pte & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK);
                   1040:                     } else {
                   1041:                         prot = 0;
                   1042:                     }
                   1043:                     mem_print(&start, &last_prot, end, prot);
                   1044:                 }
                   1045:             }
                   1046:         } else {
                   1047:             prot = 0;
                   1048:             mem_print(&start, &last_prot, end, prot);
                   1049:         }
                   1050:     }
                   1051: }
                   1052: #endif
                   1053: 
                   1054: static void do_info_kqemu(void)
                   1055: {
                   1056: #ifdef USE_KQEMU
1.1.1.2   root     1057:     CPUState *env;
1.1       root     1058:     int val;
                   1059:     val = 0;
1.1.1.2   root     1060:     env = mon_get_cpu();
                   1061:     if (!env) {
                   1062:         term_printf("No cpu initialized yet");
                   1063:         return;
                   1064:     }
                   1065:     val = env->kqemu_enabled;
1.1.1.3   root     1066:     term_printf("kqemu support: ");
                   1067:     switch(val) {
                   1068:     default:
                   1069:     case 0:
                   1070:         term_printf("disabled\n");
                   1071:         break;
                   1072:     case 1:
                   1073:         term_printf("enabled for user code\n");
                   1074:         break;
                   1075:     case 2:
                   1076:         term_printf("enabled for user and kernel code\n");
                   1077:         break;
                   1078:     }
1.1       root     1079: #else
1.1.1.3   root     1080:     term_printf("kqemu support: not compiled\n");
1.1       root     1081: #endif
                   1082: } 
                   1083: 
1.1.1.3   root     1084: #ifdef CONFIG_PROFILER
                   1085: 
                   1086: int64_t kqemu_time;
                   1087: int64_t qemu_time;
                   1088: int64_t kqemu_exec_count;
                   1089: int64_t dev_time;
                   1090: int64_t kqemu_ret_int_count;
                   1091: int64_t kqemu_ret_excp_count;
                   1092: int64_t kqemu_ret_intr_count;
                   1093: 
                   1094: static void do_info_profile(void)
                   1095: {
                   1096:     int64_t total;
                   1097:     total = qemu_time;
                   1098:     if (total == 0)
                   1099:         total = 1;
1.1.1.4   root     1100:     term_printf("async time  %" PRId64 " (%0.3f)\n",
1.1.1.3   root     1101:                 dev_time, dev_time / (double)ticks_per_sec);
1.1.1.4   root     1102:     term_printf("qemu time   %" PRId64 " (%0.3f)\n",
1.1.1.3   root     1103:                 qemu_time, qemu_time / (double)ticks_per_sec);
1.1.1.4   root     1104:     term_printf("kqemu time  %" PRId64 " (%0.3f %0.1f%%) count=%" PRId64 " int=%" PRId64 " excp=%" PRId64 " intr=%" PRId64 "\n",
1.1.1.3   root     1105:                 kqemu_time, kqemu_time / (double)ticks_per_sec,
                   1106:                 kqemu_time / (double)total * 100.0,
                   1107:                 kqemu_exec_count,
                   1108:                 kqemu_ret_int_count,
                   1109:                 kqemu_ret_excp_count,
                   1110:                 kqemu_ret_intr_count);
                   1111:     qemu_time = 0;
                   1112:     kqemu_time = 0;
                   1113:     kqemu_exec_count = 0;
                   1114:     dev_time = 0;
                   1115:     kqemu_ret_int_count = 0;
                   1116:     kqemu_ret_excp_count = 0;
                   1117:     kqemu_ret_intr_count = 0;
                   1118: #ifdef USE_KQEMU
                   1119:     kqemu_record_dump();
                   1120: #endif
                   1121: }
                   1122: #else
                   1123: static void do_info_profile(void)
                   1124: {
                   1125:     term_printf("Internal profiler not compiled\n");
                   1126: }
                   1127: #endif
                   1128: 
1.1.1.4   root     1129: /* Capture support */
                   1130: static LIST_HEAD (capture_list_head, CaptureState) capture_head;
                   1131: 
                   1132: static void do_info_capture (void)
                   1133: {
                   1134:     int i;
                   1135:     CaptureState *s;
                   1136: 
                   1137:     for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) {
                   1138:         term_printf ("[%d]: ", i);
                   1139:         s->ops.info (s->opaque);
                   1140:     }
                   1141: }
                   1142: 
                   1143: static void do_stop_capture (int n)
                   1144: {
                   1145:     int i;
                   1146:     CaptureState *s;
                   1147: 
                   1148:     for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) {
                   1149:         if (i == n) {
                   1150:             s->ops.destroy (s->opaque);
                   1151:             LIST_REMOVE (s, entries);
                   1152:             qemu_free (s);
                   1153:             return;
                   1154:         }
                   1155:     }
                   1156: }
                   1157: 
                   1158: #ifdef HAS_AUDIO
                   1159: int wav_start_capture (CaptureState *s, const char *path, int freq,
                   1160:                        int bits, int nchannels);
                   1161: 
                   1162: static void do_wav_capture (const char *path,
                   1163:                             int has_freq, int freq,
                   1164:                             int has_bits, int bits,
                   1165:                             int has_channels, int nchannels)
                   1166: {
                   1167:     CaptureState *s;
                   1168: 
                   1169:     s = qemu_mallocz (sizeof (*s));
                   1170:     if (!s) {
                   1171:         term_printf ("Not enough memory to add wave capture\n");
                   1172:         return;
                   1173:     }
                   1174: 
                   1175:     freq = has_freq ? freq : 44100;
                   1176:     bits = has_bits ? bits : 16;
                   1177:     nchannels = has_channels ? nchannels : 2;
                   1178: 
                   1179:     if (wav_start_capture (s, path, freq, bits, nchannels)) {
                   1180:         term_printf ("Faied to add wave capture\n");
                   1181:         qemu_free (s);
                   1182:     }
                   1183:     LIST_INSERT_HEAD (&capture_head, s, entries);
                   1184: }
                   1185: #endif
                   1186: 
1.1       root     1187: static term_cmd_t term_cmds[] = {
                   1188:     { "help|?", "s?", do_help, 
                   1189:       "[cmd]", "show the help" },
1.1.1.5 ! root     1190:     { "commit", "s", do_commit, 
        !          1191:       "device|all", "commit changes to the disk images (if -snapshot is used) or backing files" },
1.1       root     1192:     { "info", "s?", do_info,
                   1193:       "subcommand", "show various information about the system state" },
                   1194:     { "q|quit", "", do_quit,
                   1195:       "", "quit the emulator" },
                   1196:     { "eject", "-fB", do_eject,
                   1197:       "[-f] device", "eject a removable media (use -f to force it)" },
                   1198:     { "change", "BF", do_change,
                   1199:       "device filename", "change a removable media" },
                   1200:     { "screendump", "F", do_screen_dump, 
                   1201:       "filename", "save screen into PPM image 'filename'" },
                   1202:     { "log", "s", do_log,
                   1203:       "item1[,...]", "activate logging of the specified items to '/tmp/qemu.log'" }, 
1.1.1.5 ! root     1204:     { "savevm", "s?", do_savevm,
        !          1205:       "tag|id", "save a VM snapshot. If no tag or id are provided, a new snapshot is created" }, 
        !          1206:     { "loadvm", "s", do_loadvm,
        !          1207:       "tag|id", "restore a VM snapshot from its tag or id" }, 
        !          1208:     { "delvm", "s", do_delvm,
        !          1209:       "tag|id", "delete a VM snapshot from its tag or id" }, 
1.1       root     1210:     { "stop", "", do_stop, 
                   1211:       "", "stop emulation", },
                   1212:     { "c|cont", "", do_cont, 
                   1213:       "", "resume emulation", },
                   1214: #ifdef CONFIG_GDBSTUB
                   1215:     { "gdbserver", "i?", do_gdbserver, 
                   1216:       "[port]", "start gdbserver session (default port=1234)", },
                   1217: #endif
                   1218:     { "x", "/l", do_memory_dump, 
                   1219:       "/fmt addr", "virtual memory dump starting at 'addr'", },
                   1220:     { "xp", "/l", do_physical_memory_dump, 
                   1221:       "/fmt addr", "physical memory dump starting at 'addr'", },
                   1222:     { "p|print", "/l", do_print, 
                   1223:       "/fmt expr", "print expression value (use $reg for CPU register access)", },
                   1224:     { "i", "/ii.", do_ioport_read, 
                   1225:       "/fmt addr", "I/O port read" },
                   1226: 
                   1227:     { "sendkey", "s", do_send_key, 
                   1228:       "keys", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1')" },
                   1229:     { "system_reset", "", do_system_reset, 
                   1230:       "", "reset the system" },
                   1231:     { "system_powerdown", "", do_system_powerdown, 
                   1232:       "", "send system power down event" },
                   1233:     { "sum", "ii", do_sum, 
                   1234:       "addr size", "compute the checksum of a memory region" },
1.1.1.2   root     1235:     { "usb_add", "s", do_usb_add,
                   1236:       "device", "add USB device (e.g. 'host:bus.addr' or 'host:vendor_id:product_id')" },
                   1237:     { "usb_del", "s", do_usb_del,
                   1238:       "device", "remove USB device 'bus.addr'" },
                   1239:     { "cpu", "i", do_cpu_set, 
                   1240:       "index", "set the default CPU" },
1.1.1.4   root     1241:     { "mouse_move", "sss?", do_mouse_move, 
                   1242:       "dx dy [dz]", "send mouse move events" },
                   1243:     { "mouse_button", "i", do_mouse_button, 
                   1244:       "state", "change mouse button state (1=L, 2=M, 4=R)" },
1.1.1.5 ! root     1245:     { "mouse_set", "i", do_mouse_set,
        !          1246:       "index", "set which mouse device receives events" },
1.1.1.4   root     1247: #ifdef HAS_AUDIO
                   1248:     { "wavcapture", "si?i?i?", do_wav_capture,
                   1249:       "path [frequency bits channels]",
                   1250:       "capture audio to a wave file (default frequency=44100 bits=16 channels=2)" },
                   1251: #endif
                   1252:      { "stopcapture", "i", do_stop_capture,
                   1253:        "capture index", "stop capture" },
1.1.1.5 ! root     1254:     { "memsave", "lis", do_memory_save, 
        !          1255:       "addr size file", "save to disk virtual memory dump starting at 'addr' of size 'size'", },
1.1       root     1256:     { NULL, NULL, }, 
                   1257: };
                   1258: 
                   1259: static term_cmd_t info_cmds[] = {
                   1260:     { "version", "", do_info_version,
                   1261:       "", "show the version of qemu" },
                   1262:     { "network", "", do_info_network,
                   1263:       "", "show the network state" },
                   1264:     { "block", "", do_info_block,
                   1265:       "", "show the block devices" },
                   1266:     { "registers", "", do_info_registers,
                   1267:       "", "show the cpu registers" },
1.1.1.2   root     1268:     { "cpus", "", do_info_cpus,
                   1269:       "", "show infos for each CPU" },
1.1       root     1270:     { "history", "", do_info_history,
                   1271:       "", "show the command line history", },
                   1272:     { "irq", "", irq_info,
                   1273:       "", "show the interrupts statistics (if available)", },
                   1274:     { "pic", "", pic_info,
                   1275:       "", "show i8259 (PIC) state", },
                   1276:     { "pci", "", pci_info,
                   1277:       "", "show PCI info", },
                   1278: #if defined(TARGET_I386)
                   1279:     { "tlb", "", tlb_info,
                   1280:       "", "show virtual to physical memory mappings", },
                   1281:     { "mem", "", mem_info,
                   1282:       "", "show the active virtual memory mappings", },
                   1283: #endif
                   1284:     { "jit", "", do_info_jit,
                   1285:       "", "show dynamic compiler info", },
                   1286:     { "kqemu", "", do_info_kqemu,
                   1287:       "", "show kqemu information", },
1.1.1.2   root     1288:     { "usb", "", usb_info,
                   1289:       "", "show guest USB devices", },
                   1290:     { "usbhost", "", usb_host_info,
                   1291:       "", "show host USB devices", },
1.1.1.3   root     1292:     { "profile", "", do_info_profile,
                   1293:       "", "show profiling information", },
1.1.1.4   root     1294:     { "capture", "", do_info_capture,
1.1.1.5 ! root     1295:       "", "show capture information" },
        !          1296:     { "snapshots", "", do_info_snapshots,
        !          1297:       "", "show the currently saved VM snapshots" },
        !          1298:     { "mice", "", do_info_mice,
        !          1299:       "", "show which guest mouse is receiving events" },
        !          1300:     { "vnc", "", do_info_vnc,
        !          1301:       "", "show the vnc server status"},
1.1       root     1302:     { NULL, NULL, },
                   1303: };
                   1304: 
                   1305: /*******************************************************************/
                   1306: 
                   1307: static const char *pch;
                   1308: static jmp_buf expr_env;
                   1309: 
                   1310: #define MD_TLONG 0
                   1311: #define MD_I32   1
                   1312: 
                   1313: typedef struct MonitorDef {
                   1314:     const char *name;
                   1315:     int offset;
                   1316:     target_long (*get_value)(struct MonitorDef *md, int val);
                   1317:     int type;
                   1318: } MonitorDef;
                   1319: 
                   1320: #if defined(TARGET_I386)
                   1321: static target_long monitor_get_pc (struct MonitorDef *md, int val)
                   1322: {
1.1.1.2   root     1323:     CPUState *env = mon_get_cpu();
                   1324:     if (!env)
                   1325:         return 0;
                   1326:     return env->eip + env->segs[R_CS].base;
1.1       root     1327: }
                   1328: #endif
                   1329: 
                   1330: #if defined(TARGET_PPC)
                   1331: static target_long monitor_get_ccr (struct MonitorDef *md, int val)
                   1332: {
1.1.1.2   root     1333:     CPUState *env = mon_get_cpu();
1.1       root     1334:     unsigned int u;
                   1335:     int i;
                   1336: 
1.1.1.2   root     1337:     if (!env)
                   1338:         return 0;
                   1339: 
1.1       root     1340:     u = 0;
                   1341:     for (i = 0; i < 8; i++)
1.1.1.2   root     1342:        u |= env->crf[i] << (32 - (4 * i));
1.1       root     1343: 
                   1344:     return u;
                   1345: }
                   1346: 
                   1347: static target_long monitor_get_msr (struct MonitorDef *md, int val)
                   1348: {
1.1.1.2   root     1349:     CPUState *env = mon_get_cpu();
                   1350:     if (!env)
                   1351:         return 0;
                   1352:     return (env->msr[MSR_POW] << MSR_POW) |
                   1353:         (env->msr[MSR_ILE] << MSR_ILE) |
                   1354:         (env->msr[MSR_EE] << MSR_EE) |
                   1355:         (env->msr[MSR_PR] << MSR_PR) |
                   1356:         (env->msr[MSR_FP] << MSR_FP) |
                   1357:         (env->msr[MSR_ME] << MSR_ME) |
                   1358:         (env->msr[MSR_FE0] << MSR_FE0) |
                   1359:         (env->msr[MSR_SE] << MSR_SE) |
                   1360:         (env->msr[MSR_BE] << MSR_BE) |
                   1361:         (env->msr[MSR_FE1] << MSR_FE1) |
                   1362:         (env->msr[MSR_IP] << MSR_IP) |
                   1363:         (env->msr[MSR_IR] << MSR_IR) |
                   1364:         (env->msr[MSR_DR] << MSR_DR) |
                   1365:         (env->msr[MSR_RI] << MSR_RI) |
                   1366:         (env->msr[MSR_LE] << MSR_LE);
1.1       root     1367: }
                   1368: 
                   1369: static target_long monitor_get_xer (struct MonitorDef *md, int val)
                   1370: {
1.1.1.2   root     1371:     CPUState *env = mon_get_cpu();
                   1372:     if (!env)
                   1373:         return 0;
                   1374:     return (env->xer[XER_SO] << XER_SO) |
                   1375:         (env->xer[XER_OV] << XER_OV) |
                   1376:         (env->xer[XER_CA] << XER_CA) |
                   1377:         (env->xer[XER_BC] << XER_BC);
1.1       root     1378: }
                   1379: 
                   1380: static target_long monitor_get_decr (struct MonitorDef *md, int val)
                   1381: {
1.1.1.2   root     1382:     CPUState *env = mon_get_cpu();
                   1383:     if (!env)
                   1384:         return 0;
                   1385:     return cpu_ppc_load_decr(env);
1.1       root     1386: }
                   1387: 
                   1388: static target_long monitor_get_tbu (struct MonitorDef *md, int val)
                   1389: {
1.1.1.2   root     1390:     CPUState *env = mon_get_cpu();
                   1391:     if (!env)
                   1392:         return 0;
                   1393:     return cpu_ppc_load_tbu(env);
1.1       root     1394: }
                   1395: 
                   1396: static target_long monitor_get_tbl (struct MonitorDef *md, int val)
                   1397: {
1.1.1.2   root     1398:     CPUState *env = mon_get_cpu();
                   1399:     if (!env)
                   1400:         return 0;
                   1401:     return cpu_ppc_load_tbl(env);
1.1       root     1402: }
                   1403: #endif
                   1404: 
                   1405: #if defined(TARGET_SPARC)
1.1.1.2   root     1406: #ifndef TARGET_SPARC64
1.1       root     1407: static target_long monitor_get_psr (struct MonitorDef *md, int val)
                   1408: {
1.1.1.2   root     1409:     CPUState *env = mon_get_cpu();
                   1410:     if (!env)
                   1411:         return 0;
                   1412:     return GET_PSR(env);
1.1       root     1413: }
1.1.1.2   root     1414: #endif
1.1       root     1415: 
                   1416: static target_long monitor_get_reg(struct MonitorDef *md, int val)
                   1417: {
1.1.1.2   root     1418:     CPUState *env = mon_get_cpu();
                   1419:     if (!env)
                   1420:         return 0;
                   1421:     return env->regwptr[val];
1.1       root     1422: }
                   1423: #endif
                   1424: 
                   1425: static MonitorDef monitor_defs[] = {
                   1426: #ifdef TARGET_I386
                   1427: 
                   1428: #define SEG(name, seg) \
                   1429:     { name, offsetof(CPUState, segs[seg].selector), NULL, MD_I32 },\
                   1430:     { name ".base", offsetof(CPUState, segs[seg].base) },\
                   1431:     { name ".limit", offsetof(CPUState, segs[seg].limit), NULL, MD_I32 },
                   1432: 
                   1433:     { "eax", offsetof(CPUState, regs[0]) },
                   1434:     { "ecx", offsetof(CPUState, regs[1]) },
                   1435:     { "edx", offsetof(CPUState, regs[2]) },
                   1436:     { "ebx", offsetof(CPUState, regs[3]) },
                   1437:     { "esp|sp", offsetof(CPUState, regs[4]) },
                   1438:     { "ebp|fp", offsetof(CPUState, regs[5]) },
                   1439:     { "esi", offsetof(CPUState, regs[6]) },
                   1440:     { "edi", offsetof(CPUState, regs[7]) },
                   1441: #ifdef TARGET_X86_64
                   1442:     { "r8", offsetof(CPUState, regs[8]) },
                   1443:     { "r9", offsetof(CPUState, regs[9]) },
                   1444:     { "r10", offsetof(CPUState, regs[10]) },
                   1445:     { "r11", offsetof(CPUState, regs[11]) },
                   1446:     { "r12", offsetof(CPUState, regs[12]) },
                   1447:     { "r13", offsetof(CPUState, regs[13]) },
                   1448:     { "r14", offsetof(CPUState, regs[14]) },
                   1449:     { "r15", offsetof(CPUState, regs[15]) },
                   1450: #endif
                   1451:     { "eflags", offsetof(CPUState, eflags) },
                   1452:     { "eip", offsetof(CPUState, eip) },
                   1453:     SEG("cs", R_CS)
                   1454:     SEG("ds", R_DS)
                   1455:     SEG("es", R_ES)
                   1456:     SEG("ss", R_SS)
                   1457:     SEG("fs", R_FS)
                   1458:     SEG("gs", R_GS)
                   1459:     { "pc", 0, monitor_get_pc, },
                   1460: #elif defined(TARGET_PPC)
                   1461:     { "r0", offsetof(CPUState, gpr[0]) },
                   1462:     { "r1", offsetof(CPUState, gpr[1]) },
                   1463:     { "r2", offsetof(CPUState, gpr[2]) },
                   1464:     { "r3", offsetof(CPUState, gpr[3]) },
                   1465:     { "r4", offsetof(CPUState, gpr[4]) },
                   1466:     { "r5", offsetof(CPUState, gpr[5]) },
                   1467:     { "r6", offsetof(CPUState, gpr[6]) },
                   1468:     { "r7", offsetof(CPUState, gpr[7]) },
                   1469:     { "r8", offsetof(CPUState, gpr[8]) },
                   1470:     { "r9", offsetof(CPUState, gpr[9]) },
                   1471:     { "r10", offsetof(CPUState, gpr[10]) },
                   1472:     { "r11", offsetof(CPUState, gpr[11]) },
                   1473:     { "r12", offsetof(CPUState, gpr[12]) },
                   1474:     { "r13", offsetof(CPUState, gpr[13]) },
                   1475:     { "r14", offsetof(CPUState, gpr[14]) },
                   1476:     { "r15", offsetof(CPUState, gpr[15]) },
                   1477:     { "r16", offsetof(CPUState, gpr[16]) },
                   1478:     { "r17", offsetof(CPUState, gpr[17]) },
                   1479:     { "r18", offsetof(CPUState, gpr[18]) },
                   1480:     { "r19", offsetof(CPUState, gpr[19]) },
                   1481:     { "r20", offsetof(CPUState, gpr[20]) },
                   1482:     { "r21", offsetof(CPUState, gpr[21]) },
                   1483:     { "r22", offsetof(CPUState, gpr[22]) },
                   1484:     { "r23", offsetof(CPUState, gpr[23]) },
                   1485:     { "r24", offsetof(CPUState, gpr[24]) },
                   1486:     { "r25", offsetof(CPUState, gpr[25]) },
                   1487:     { "r26", offsetof(CPUState, gpr[26]) },
                   1488:     { "r27", offsetof(CPUState, gpr[27]) },
                   1489:     { "r28", offsetof(CPUState, gpr[28]) },
                   1490:     { "r29", offsetof(CPUState, gpr[29]) },
                   1491:     { "r30", offsetof(CPUState, gpr[30]) },
                   1492:     { "r31", offsetof(CPUState, gpr[31]) },
                   1493:     { "nip|pc", offsetof(CPUState, nip) },
                   1494:     { "lr", offsetof(CPUState, lr) },
                   1495:     { "ctr", offsetof(CPUState, ctr) },
                   1496:     { "decr", 0, &monitor_get_decr, },
                   1497:     { "ccr", 0, &monitor_get_ccr, },
                   1498:     { "msr", 0, &monitor_get_msr, },
                   1499:     { "xer", 0, &monitor_get_xer, },
                   1500:     { "tbu", 0, &monitor_get_tbu, },
                   1501:     { "tbl", 0, &monitor_get_tbl, },
                   1502:     { "sdr1", offsetof(CPUState, sdr1) },
                   1503:     { "sr0", offsetof(CPUState, sr[0]) },
                   1504:     { "sr1", offsetof(CPUState, sr[1]) },
                   1505:     { "sr2", offsetof(CPUState, sr[2]) },
                   1506:     { "sr3", offsetof(CPUState, sr[3]) },
                   1507:     { "sr4", offsetof(CPUState, sr[4]) },
                   1508:     { "sr5", offsetof(CPUState, sr[5]) },
                   1509:     { "sr6", offsetof(CPUState, sr[6]) },
                   1510:     { "sr7", offsetof(CPUState, sr[7]) },
                   1511:     { "sr8", offsetof(CPUState, sr[8]) },
                   1512:     { "sr9", offsetof(CPUState, sr[9]) },
                   1513:     { "sr10", offsetof(CPUState, sr[10]) },
                   1514:     { "sr11", offsetof(CPUState, sr[11]) },
                   1515:     { "sr12", offsetof(CPUState, sr[12]) },
                   1516:     { "sr13", offsetof(CPUState, sr[13]) },
                   1517:     { "sr14", offsetof(CPUState, sr[14]) },
                   1518:     { "sr15", offsetof(CPUState, sr[15]) },
                   1519:     /* Too lazy to put BATs and SPRs ... */
                   1520: #elif defined(TARGET_SPARC)
                   1521:     { "g0", offsetof(CPUState, gregs[0]) },
                   1522:     { "g1", offsetof(CPUState, gregs[1]) },
                   1523:     { "g2", offsetof(CPUState, gregs[2]) },
                   1524:     { "g3", offsetof(CPUState, gregs[3]) },
                   1525:     { "g4", offsetof(CPUState, gregs[4]) },
                   1526:     { "g5", offsetof(CPUState, gregs[5]) },
                   1527:     { "g6", offsetof(CPUState, gregs[6]) },
                   1528:     { "g7", offsetof(CPUState, gregs[7]) },
                   1529:     { "o0", 0, monitor_get_reg },
                   1530:     { "o1", 1, monitor_get_reg },
                   1531:     { "o2", 2, monitor_get_reg },
                   1532:     { "o3", 3, monitor_get_reg },
                   1533:     { "o4", 4, monitor_get_reg },
                   1534:     { "o5", 5, monitor_get_reg },
                   1535:     { "o6", 6, monitor_get_reg },
                   1536:     { "o7", 7, monitor_get_reg },
                   1537:     { "l0", 8, monitor_get_reg },
                   1538:     { "l1", 9, monitor_get_reg },
                   1539:     { "l2", 10, monitor_get_reg },
                   1540:     { "l3", 11, monitor_get_reg },
                   1541:     { "l4", 12, monitor_get_reg },
                   1542:     { "l5", 13, monitor_get_reg },
                   1543:     { "l6", 14, monitor_get_reg },
                   1544:     { "l7", 15, monitor_get_reg },
                   1545:     { "i0", 16, monitor_get_reg },
                   1546:     { "i1", 17, monitor_get_reg },
                   1547:     { "i2", 18, monitor_get_reg },
                   1548:     { "i3", 19, monitor_get_reg },
                   1549:     { "i4", 20, monitor_get_reg },
                   1550:     { "i5", 21, monitor_get_reg },
                   1551:     { "i6", 22, monitor_get_reg },
                   1552:     { "i7", 23, monitor_get_reg },
                   1553:     { "pc", offsetof(CPUState, pc) },
                   1554:     { "npc", offsetof(CPUState, npc) },
                   1555:     { "y", offsetof(CPUState, y) },
1.1.1.2   root     1556: #ifndef TARGET_SPARC64
1.1       root     1557:     { "psr", 0, &monitor_get_psr, },
                   1558:     { "wim", offsetof(CPUState, wim) },
1.1.1.2   root     1559: #endif
1.1       root     1560:     { "tbr", offsetof(CPUState, tbr) },
                   1561:     { "fsr", offsetof(CPUState, fsr) },
                   1562:     { "f0", offsetof(CPUState, fpr[0]) },
                   1563:     { "f1", offsetof(CPUState, fpr[1]) },
                   1564:     { "f2", offsetof(CPUState, fpr[2]) },
                   1565:     { "f3", offsetof(CPUState, fpr[3]) },
                   1566:     { "f4", offsetof(CPUState, fpr[4]) },
                   1567:     { "f5", offsetof(CPUState, fpr[5]) },
                   1568:     { "f6", offsetof(CPUState, fpr[6]) },
                   1569:     { "f7", offsetof(CPUState, fpr[7]) },
                   1570:     { "f8", offsetof(CPUState, fpr[8]) },
                   1571:     { "f9", offsetof(CPUState, fpr[9]) },
                   1572:     { "f10", offsetof(CPUState, fpr[10]) },
                   1573:     { "f11", offsetof(CPUState, fpr[11]) },
                   1574:     { "f12", offsetof(CPUState, fpr[12]) },
                   1575:     { "f13", offsetof(CPUState, fpr[13]) },
                   1576:     { "f14", offsetof(CPUState, fpr[14]) },
                   1577:     { "f15", offsetof(CPUState, fpr[15]) },
                   1578:     { "f16", offsetof(CPUState, fpr[16]) },
                   1579:     { "f17", offsetof(CPUState, fpr[17]) },
                   1580:     { "f18", offsetof(CPUState, fpr[18]) },
                   1581:     { "f19", offsetof(CPUState, fpr[19]) },
                   1582:     { "f20", offsetof(CPUState, fpr[20]) },
                   1583:     { "f21", offsetof(CPUState, fpr[21]) },
                   1584:     { "f22", offsetof(CPUState, fpr[22]) },
                   1585:     { "f23", offsetof(CPUState, fpr[23]) },
                   1586:     { "f24", offsetof(CPUState, fpr[24]) },
                   1587:     { "f25", offsetof(CPUState, fpr[25]) },
                   1588:     { "f26", offsetof(CPUState, fpr[26]) },
                   1589:     { "f27", offsetof(CPUState, fpr[27]) },
                   1590:     { "f28", offsetof(CPUState, fpr[28]) },
                   1591:     { "f29", offsetof(CPUState, fpr[29]) },
                   1592:     { "f30", offsetof(CPUState, fpr[30]) },
                   1593:     { "f31", offsetof(CPUState, fpr[31]) },
1.1.1.2   root     1594: #ifdef TARGET_SPARC64
                   1595:     { "f32", offsetof(CPUState, fpr[32]) },
                   1596:     { "f34", offsetof(CPUState, fpr[34]) },
                   1597:     { "f36", offsetof(CPUState, fpr[36]) },
                   1598:     { "f38", offsetof(CPUState, fpr[38]) },
                   1599:     { "f40", offsetof(CPUState, fpr[40]) },
                   1600:     { "f42", offsetof(CPUState, fpr[42]) },
                   1601:     { "f44", offsetof(CPUState, fpr[44]) },
                   1602:     { "f46", offsetof(CPUState, fpr[46]) },
                   1603:     { "f48", offsetof(CPUState, fpr[48]) },
                   1604:     { "f50", offsetof(CPUState, fpr[50]) },
                   1605:     { "f52", offsetof(CPUState, fpr[52]) },
                   1606:     { "f54", offsetof(CPUState, fpr[54]) },
                   1607:     { "f56", offsetof(CPUState, fpr[56]) },
                   1608:     { "f58", offsetof(CPUState, fpr[58]) },
                   1609:     { "f60", offsetof(CPUState, fpr[60]) },
                   1610:     { "f62", offsetof(CPUState, fpr[62]) },
                   1611:     { "asi", offsetof(CPUState, asi) },
                   1612:     { "pstate", offsetof(CPUState, pstate) },
                   1613:     { "cansave", offsetof(CPUState, cansave) },
                   1614:     { "canrestore", offsetof(CPUState, canrestore) },
                   1615:     { "otherwin", offsetof(CPUState, otherwin) },
                   1616:     { "wstate", offsetof(CPUState, wstate) },
                   1617:     { "cleanwin", offsetof(CPUState, cleanwin) },
                   1618:     { "fprs", offsetof(CPUState, fprs) },
                   1619: #endif
1.1       root     1620: #endif
                   1621:     { NULL },
                   1622: };
                   1623: 
                   1624: static void expr_error(const char *fmt) 
                   1625: {
                   1626:     term_printf(fmt);
                   1627:     term_printf("\n");
                   1628:     longjmp(expr_env, 1);
                   1629: }
                   1630: 
1.1.1.2   root     1631: /* return 0 if OK, -1 if not found, -2 if no CPU defined */
1.1       root     1632: static int get_monitor_def(target_long *pval, const char *name)
                   1633: {
                   1634:     MonitorDef *md;
                   1635:     void *ptr;
                   1636: 
                   1637:     for(md = monitor_defs; md->name != NULL; md++) {
                   1638:         if (compare_cmd(name, md->name)) {
                   1639:             if (md->get_value) {
                   1640:                 *pval = md->get_value(md, md->offset);
                   1641:             } else {
1.1.1.2   root     1642:                 CPUState *env = mon_get_cpu();
                   1643:                 if (!env)
                   1644:                     return -2;
                   1645:                 ptr = (uint8_t *)env + md->offset;
1.1       root     1646:                 switch(md->type) {
                   1647:                 case MD_I32:
                   1648:                     *pval = *(int32_t *)ptr;
                   1649:                     break;
                   1650:                 case MD_TLONG:
                   1651:                     *pval = *(target_long *)ptr;
                   1652:                     break;
                   1653:                 default:
                   1654:                     *pval = 0;
                   1655:                     break;
                   1656:                 }
                   1657:             }
                   1658:             return 0;
                   1659:         }
                   1660:     }
                   1661:     return -1;
                   1662: }
                   1663: 
                   1664: static void next(void)
                   1665: {
                   1666:     if (pch != '\0') {
                   1667:         pch++;
                   1668:         while (isspace(*pch))
                   1669:             pch++;
                   1670:     }
                   1671: }
                   1672: 
                   1673: static target_long expr_sum(void);
                   1674: 
                   1675: static target_long expr_unary(void)
                   1676: {
                   1677:     target_long n;
                   1678:     char *p;
1.1.1.2   root     1679:     int ret;
1.1       root     1680: 
                   1681:     switch(*pch) {
                   1682:     case '+':
                   1683:         next();
                   1684:         n = expr_unary();
                   1685:         break;
                   1686:     case '-':
                   1687:         next();
                   1688:         n = -expr_unary();
                   1689:         break;
                   1690:     case '~':
                   1691:         next();
                   1692:         n = ~expr_unary();
                   1693:         break;
                   1694:     case '(':
                   1695:         next();
                   1696:         n = expr_sum();
                   1697:         if (*pch != ')') {
                   1698:             expr_error("')' expected");
                   1699:         }
                   1700:         next();
                   1701:         break;
                   1702:     case '\'':
                   1703:         pch++;
                   1704:         if (*pch == '\0')
                   1705:             expr_error("character constant expected");
                   1706:         n = *pch;
                   1707:         pch++;
                   1708:         if (*pch != '\'')
                   1709:             expr_error("missing terminating \' character");
                   1710:         next();
                   1711:         break;
                   1712:     case '$':
                   1713:         {
                   1714:             char buf[128], *q;
                   1715:             
                   1716:             pch++;
                   1717:             q = buf;
                   1718:             while ((*pch >= 'a' && *pch <= 'z') ||
                   1719:                    (*pch >= 'A' && *pch <= 'Z') ||
                   1720:                    (*pch >= '0' && *pch <= '9') ||
                   1721:                    *pch == '_' || *pch == '.') {
                   1722:                 if ((q - buf) < sizeof(buf) - 1)
                   1723:                     *q++ = *pch;
                   1724:                 pch++;
                   1725:             }
                   1726:             while (isspace(*pch))
                   1727:                 pch++;
                   1728:             *q = 0;
1.1.1.2   root     1729:             ret = get_monitor_def(&n, buf);
                   1730:             if (ret == -1)
1.1       root     1731:                 expr_error("unknown register");
1.1.1.2   root     1732:             else if (ret == -2) 
                   1733:                 expr_error("no cpu defined");
1.1       root     1734:         }
                   1735:         break;
                   1736:     case '\0':
                   1737:         expr_error("unexpected end of expression");
                   1738:         n = 0;
                   1739:         break;
                   1740:     default:
1.1.1.4   root     1741: #if TARGET_LONG_BITS == 64
                   1742:         n = strtoull(pch, &p, 0);
                   1743: #else
1.1       root     1744:         n = strtoul(pch, &p, 0);
1.1.1.4   root     1745: #endif
1.1       root     1746:         if (pch == p) {
                   1747:             expr_error("invalid char in expression");
                   1748:         }
                   1749:         pch = p;
                   1750:         while (isspace(*pch))
                   1751:             pch++;
                   1752:         break;
                   1753:     }
                   1754:     return n;
                   1755: }
                   1756: 
                   1757: 
                   1758: static target_long expr_prod(void)
                   1759: {
                   1760:     target_long val, val2;
                   1761:     int op;
                   1762:     
                   1763:     val = expr_unary();
                   1764:     for(;;) {
                   1765:         op = *pch;
                   1766:         if (op != '*' && op != '/' && op != '%')
                   1767:             break;
                   1768:         next();
                   1769:         val2 = expr_unary();
                   1770:         switch(op) {
                   1771:         default:
                   1772:         case '*':
                   1773:             val *= val2;
                   1774:             break;
                   1775:         case '/':
                   1776:         case '%':
                   1777:             if (val2 == 0) 
                   1778:                 expr_error("division by zero");
                   1779:             if (op == '/')
                   1780:                 val /= val2;
                   1781:             else
                   1782:                 val %= val2;
                   1783:             break;
                   1784:         }
                   1785:     }
                   1786:     return val;
                   1787: }
                   1788: 
                   1789: static target_long expr_logic(void)
                   1790: {
                   1791:     target_long val, val2;
                   1792:     int op;
                   1793: 
                   1794:     val = expr_prod();
                   1795:     for(;;) {
                   1796:         op = *pch;
                   1797:         if (op != '&' && op != '|' && op != '^')
                   1798:             break;
                   1799:         next();
                   1800:         val2 = expr_prod();
                   1801:         switch(op) {
                   1802:         default:
                   1803:         case '&':
                   1804:             val &= val2;
                   1805:             break;
                   1806:         case '|':
                   1807:             val |= val2;
                   1808:             break;
                   1809:         case '^':
                   1810:             val ^= val2;
                   1811:             break;
                   1812:         }
                   1813:     }
                   1814:     return val;
                   1815: }
                   1816: 
                   1817: static target_long expr_sum(void)
                   1818: {
                   1819:     target_long val, val2;
                   1820:     int op;
                   1821: 
                   1822:     val = expr_logic();
                   1823:     for(;;) {
                   1824:         op = *pch;
                   1825:         if (op != '+' && op != '-')
                   1826:             break;
                   1827:         next();
                   1828:         val2 = expr_logic();
                   1829:         if (op == '+')
                   1830:             val += val2;
                   1831:         else
                   1832:             val -= val2;
                   1833:     }
                   1834:     return val;
                   1835: }
                   1836: 
                   1837: static int get_expr(target_long *pval, const char **pp)
                   1838: {
                   1839:     pch = *pp;
                   1840:     if (setjmp(expr_env)) {
                   1841:         *pp = pch;
                   1842:         return -1;
                   1843:     }
                   1844:     while (isspace(*pch))
                   1845:         pch++;
                   1846:     *pval = expr_sum();
                   1847:     *pp = pch;
                   1848:     return 0;
                   1849: }
                   1850: 
                   1851: static int get_str(char *buf, int buf_size, const char **pp)
                   1852: {
                   1853:     const char *p;
                   1854:     char *q;
                   1855:     int c;
                   1856: 
                   1857:     q = buf;
                   1858:     p = *pp;
                   1859:     while (isspace(*p))
                   1860:         p++;
                   1861:     if (*p == '\0') {
                   1862:     fail:
                   1863:         *q = '\0';
                   1864:         *pp = p;
                   1865:         return -1;
                   1866:     }
                   1867:     if (*p == '\"') {
                   1868:         p++;
                   1869:         while (*p != '\0' && *p != '\"') {
                   1870:             if (*p == '\\') {
                   1871:                 p++;
                   1872:                 c = *p++;
                   1873:                 switch(c) {
                   1874:                 case 'n':
                   1875:                     c = '\n';
                   1876:                     break;
                   1877:                 case 'r':
                   1878:                     c = '\r';
                   1879:                     break;
                   1880:                 case '\\':
                   1881:                 case '\'':
                   1882:                 case '\"':
                   1883:                     break;
                   1884:                 default:
                   1885:                     qemu_printf("unsupported escape code: '\\%c'\n", c);
                   1886:                     goto fail;
                   1887:                 }
                   1888:                 if ((q - buf) < buf_size - 1) {
                   1889:                     *q++ = c;
                   1890:                 }
                   1891:             } else {
                   1892:                 if ((q - buf) < buf_size - 1) {
                   1893:                     *q++ = *p;
                   1894:                 }
                   1895:                 p++;
                   1896:             }
                   1897:         }
                   1898:         if (*p != '\"') {
                   1899:             qemu_printf("unterminated string\n");
                   1900:             goto fail;
                   1901:         }
                   1902:         p++;
                   1903:     } else {
                   1904:         while (*p != '\0' && !isspace(*p)) {
                   1905:             if ((q - buf) < buf_size - 1) {
                   1906:                 *q++ = *p;
                   1907:             }
                   1908:             p++;
                   1909:         }
                   1910:     }
                   1911:     *q = '\0';
                   1912:     *pp = p;
                   1913:     return 0;
                   1914: }
                   1915: 
                   1916: static int default_fmt_format = 'x';
                   1917: static int default_fmt_size = 4;
                   1918: 
                   1919: #define MAX_ARGS 16
                   1920: 
                   1921: static void monitor_handle_command(const char *cmdline)
                   1922: {
                   1923:     const char *p, *pstart, *typestr;
                   1924:     char *q;
                   1925:     int c, nb_args, len, i, has_arg;
                   1926:     term_cmd_t *cmd;
                   1927:     char cmdname[256];
                   1928:     char buf[1024];
                   1929:     void *str_allocated[MAX_ARGS];
                   1930:     void *args[MAX_ARGS];
                   1931: 
                   1932: #ifdef DEBUG
                   1933:     term_printf("command='%s'\n", cmdline);
                   1934: #endif
                   1935:     
                   1936:     /* extract the command name */
                   1937:     p = cmdline;
                   1938:     q = cmdname;
                   1939:     while (isspace(*p))
                   1940:         p++;
                   1941:     if (*p == '\0')
                   1942:         return;
                   1943:     pstart = p;
                   1944:     while (*p != '\0' && *p != '/' && !isspace(*p))
                   1945:         p++;
                   1946:     len = p - pstart;
                   1947:     if (len > sizeof(cmdname) - 1)
                   1948:         len = sizeof(cmdname) - 1;
                   1949:     memcpy(cmdname, pstart, len);
                   1950:     cmdname[len] = '\0';
                   1951:     
                   1952:     /* find the command */
                   1953:     for(cmd = term_cmds; cmd->name != NULL; cmd++) {
                   1954:         if (compare_cmd(cmdname, cmd->name)) 
                   1955:             goto found;
                   1956:     }
                   1957:     term_printf("unknown command: '%s'\n", cmdname);
                   1958:     return;
                   1959:  found:
                   1960: 
                   1961:     for(i = 0; i < MAX_ARGS; i++)
                   1962:         str_allocated[i] = NULL;
                   1963:     
                   1964:     /* parse the parameters */
                   1965:     typestr = cmd->args_type;
                   1966:     nb_args = 0;
                   1967:     for(;;) {
                   1968:         c = *typestr;
                   1969:         if (c == '\0')
                   1970:             break;
                   1971:         typestr++;
                   1972:         switch(c) {
                   1973:         case 'F':
                   1974:         case 'B':
                   1975:         case 's':
                   1976:             {
                   1977:                 int ret;
                   1978:                 char *str;
                   1979:                 
                   1980:                 while (isspace(*p)) 
                   1981:                     p++;
                   1982:                 if (*typestr == '?') {
                   1983:                     typestr++;
                   1984:                     if (*p == '\0') {
                   1985:                         /* no optional string: NULL argument */
                   1986:                         str = NULL;
                   1987:                         goto add_str;
                   1988:                     }
                   1989:                 }
                   1990:                 ret = get_str(buf, sizeof(buf), &p);
                   1991:                 if (ret < 0) {
                   1992:                     switch(c) {
                   1993:                     case 'F':
                   1994:                         term_printf("%s: filename expected\n", cmdname);
                   1995:                         break;
                   1996:                     case 'B':
                   1997:                         term_printf("%s: block device name expected\n", cmdname);
                   1998:                         break;
                   1999:                     default:
                   2000:                         term_printf("%s: string expected\n", cmdname);
                   2001:                         break;
                   2002:                     }
                   2003:                     goto fail;
                   2004:                 }
                   2005:                 str = qemu_malloc(strlen(buf) + 1);
                   2006:                 strcpy(str, buf);
                   2007:                 str_allocated[nb_args] = str;
                   2008:             add_str:
                   2009:                 if (nb_args >= MAX_ARGS) {
                   2010:                 error_args:
                   2011:                     term_printf("%s: too many arguments\n", cmdname);
                   2012:                     goto fail;
                   2013:                 }
                   2014:                 args[nb_args++] = str;
                   2015:             }
                   2016:             break;
                   2017:         case '/':
                   2018:             {
                   2019:                 int count, format, size;
                   2020:                 
                   2021:                 while (isspace(*p))
                   2022:                     p++;
                   2023:                 if (*p == '/') {
                   2024:                     /* format found */
                   2025:                     p++;
                   2026:                     count = 1;
                   2027:                     if (isdigit(*p)) {
                   2028:                         count = 0;
                   2029:                         while (isdigit(*p)) {
                   2030:                             count = count * 10 + (*p - '0');
                   2031:                             p++;
                   2032:                         }
                   2033:                     }
                   2034:                     size = -1;
                   2035:                     format = -1;
                   2036:                     for(;;) {
                   2037:                         switch(*p) {
                   2038:                         case 'o':
                   2039:                         case 'd':
                   2040:                         case 'u':
                   2041:                         case 'x':
                   2042:                         case 'i':
                   2043:                         case 'c':
                   2044:                             format = *p++;
                   2045:                             break;
                   2046:                         case 'b':
                   2047:                             size = 1;
                   2048:                             p++;
                   2049:                             break;
                   2050:                         case 'h':
                   2051:                             size = 2;
                   2052:                             p++;
                   2053:                             break;
                   2054:                         case 'w':
                   2055:                             size = 4;
                   2056:                             p++;
                   2057:                             break;
                   2058:                         case 'g':
                   2059:                         case 'L':
                   2060:                             size = 8;
                   2061:                             p++;
                   2062:                             break;
                   2063:                         default:
                   2064:                             goto next;
                   2065:                         }
                   2066:                     }
                   2067:                 next:
                   2068:                     if (*p != '\0' && !isspace(*p)) {
                   2069:                         term_printf("invalid char in format: '%c'\n", *p);
                   2070:                         goto fail;
                   2071:                     }
                   2072:                     if (format < 0)
                   2073:                         format = default_fmt_format;
                   2074:                     if (format != 'i') {
                   2075:                         /* for 'i', not specifying a size gives -1 as size */
                   2076:                         if (size < 0)
                   2077:                             size = default_fmt_size;
                   2078:                     }
                   2079:                     default_fmt_size = size;
                   2080:                     default_fmt_format = format;
                   2081:                 } else {
                   2082:                     count = 1;
                   2083:                     format = default_fmt_format;
                   2084:                     if (format != 'i') {
                   2085:                         size = default_fmt_size;
                   2086:                     } else {
                   2087:                         size = -1;
                   2088:                     }
                   2089:                 }
                   2090:                 if (nb_args + 3 > MAX_ARGS)
                   2091:                     goto error_args;
                   2092:                 args[nb_args++] = (void*)count;
                   2093:                 args[nb_args++] = (void*)format;
                   2094:                 args[nb_args++] = (void*)size;
                   2095:             }
                   2096:             break;
                   2097:         case 'i':
                   2098:         case 'l':
                   2099:             {
                   2100:                 target_long val;
                   2101:                 while (isspace(*p)) 
                   2102:                     p++;
                   2103:                 if (*typestr == '?' || *typestr == '.') {
                   2104:                     if (*typestr == '?') {
                   2105:                         if (*p == '\0')
                   2106:                             has_arg = 0;
                   2107:                         else
                   2108:                             has_arg = 1;
                   2109:                     } else {
                   2110:                         if (*p == '.') {
                   2111:                             p++;
                   2112:                             while (isspace(*p)) 
                   2113:                                 p++;
                   2114:                             has_arg = 1;
                   2115:                         } else {
                   2116:                             has_arg = 0;
                   2117:                         }
                   2118:                     }
1.1.1.4   root     2119:                     typestr++;
1.1       root     2120:                     if (nb_args >= MAX_ARGS)
                   2121:                         goto error_args;
                   2122:                     args[nb_args++] = (void *)has_arg;
                   2123:                     if (!has_arg) {
                   2124:                         if (nb_args >= MAX_ARGS)
                   2125:                             goto error_args;
                   2126:                         val = -1;
                   2127:                         goto add_num;
                   2128:                     }
                   2129:                 }
                   2130:                 if (get_expr(&val, &p))
                   2131:                     goto fail;
                   2132:             add_num:
                   2133:                 if (c == 'i') {
                   2134:                     if (nb_args >= MAX_ARGS)
                   2135:                         goto error_args;
                   2136:                     args[nb_args++] = (void *)(int)val;
                   2137:                 } else {
                   2138:                     if ((nb_args + 1) >= MAX_ARGS)
                   2139:                         goto error_args;
                   2140: #if TARGET_LONG_BITS == 64
                   2141:                     args[nb_args++] = (void *)(int)((val >> 32) & 0xffffffff);
                   2142: #else
                   2143:                     args[nb_args++] = (void *)0;
                   2144: #endif
                   2145:                     args[nb_args++] = (void *)(int)(val & 0xffffffff);
                   2146:                 }
                   2147:             }
                   2148:             break;
                   2149:         case '-':
                   2150:             {
                   2151:                 int has_option;
                   2152:                 /* option */
                   2153:                 
                   2154:                 c = *typestr++;
                   2155:                 if (c == '\0')
                   2156:                     goto bad_type;
                   2157:                 while (isspace(*p)) 
                   2158:                     p++;
                   2159:                 has_option = 0;
                   2160:                 if (*p == '-') {
                   2161:                     p++;
                   2162:                     if (*p != c) {
                   2163:                         term_printf("%s: unsupported option -%c\n", 
                   2164:                                     cmdname, *p);
                   2165:                         goto fail;
                   2166:                     }
                   2167:                     p++;
                   2168:                     has_option = 1;
                   2169:                 }
                   2170:                 if (nb_args >= MAX_ARGS)
                   2171:                     goto error_args;
                   2172:                 args[nb_args++] = (void *)has_option;
                   2173:             }
                   2174:             break;
                   2175:         default:
                   2176:         bad_type:
                   2177:             term_printf("%s: unknown type '%c'\n", cmdname, c);
                   2178:             goto fail;
                   2179:         }
                   2180:     }
                   2181:     /* check that all arguments were parsed */
                   2182:     while (isspace(*p))
                   2183:         p++;
                   2184:     if (*p != '\0') {
                   2185:         term_printf("%s: extraneous characters at the end of line\n", 
                   2186:                     cmdname);
                   2187:         goto fail;
                   2188:     }
                   2189: 
                   2190:     switch(nb_args) {
                   2191:     case 0:
                   2192:         cmd->handler();
                   2193:         break;
                   2194:     case 1:
                   2195:         cmd->handler(args[0]);
                   2196:         break;
                   2197:     case 2:
                   2198:         cmd->handler(args[0], args[1]);
                   2199:         break;
                   2200:     case 3:
                   2201:         cmd->handler(args[0], args[1], args[2]);
                   2202:         break;
                   2203:     case 4:
                   2204:         cmd->handler(args[0], args[1], args[2], args[3]);
                   2205:         break;
                   2206:     case 5:
                   2207:         cmd->handler(args[0], args[1], args[2], args[3], args[4]);
                   2208:         break;
                   2209:     case 6:
                   2210:         cmd->handler(args[0], args[1], args[2], args[3], args[4], args[5]);
                   2211:         break;
1.1.1.4   root     2212:     case 7:
                   2213:         cmd->handler(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
                   2214:         break;
1.1       root     2215:     default:
                   2216:         term_printf("unsupported number of arguments: %d\n", nb_args);
                   2217:         goto fail;
                   2218:     }
                   2219:  fail:
                   2220:     for(i = 0; i < MAX_ARGS; i++)
                   2221:         qemu_free(str_allocated[i]);
                   2222:     return;
                   2223: }
                   2224: 
                   2225: static void cmd_completion(const char *name, const char *list)
                   2226: {
                   2227:     const char *p, *pstart;
                   2228:     char cmd[128];
                   2229:     int len;
                   2230: 
                   2231:     p = list;
                   2232:     for(;;) {
                   2233:         pstart = p;
                   2234:         p = strchr(p, '|');
                   2235:         if (!p)
                   2236:             p = pstart + strlen(pstart);
                   2237:         len = p - pstart;
                   2238:         if (len > sizeof(cmd) - 2)
                   2239:             len = sizeof(cmd) - 2;
                   2240:         memcpy(cmd, pstart, len);
                   2241:         cmd[len] = '\0';
                   2242:         if (name[0] == '\0' || !strncmp(name, cmd, strlen(name))) {
                   2243:             add_completion(cmd);
                   2244:         }
                   2245:         if (*p == '\0')
                   2246:             break;
                   2247:         p++;
                   2248:     }
                   2249: }
                   2250: 
                   2251: static void file_completion(const char *input)
                   2252: {
                   2253:     DIR *ffs;
                   2254:     struct dirent *d;
                   2255:     char path[1024];
                   2256:     char file[1024], file_prefix[1024];
                   2257:     int input_path_len;
                   2258:     const char *p;
                   2259: 
                   2260:     p = strrchr(input, '/'); 
                   2261:     if (!p) {
                   2262:         input_path_len = 0;
                   2263:         pstrcpy(file_prefix, sizeof(file_prefix), input);
                   2264:         strcpy(path, ".");
                   2265:     } else {
                   2266:         input_path_len = p - input + 1;
                   2267:         memcpy(path, input, input_path_len);
                   2268:         if (input_path_len > sizeof(path) - 1)
                   2269:             input_path_len = sizeof(path) - 1;
                   2270:         path[input_path_len] = '\0';
                   2271:         pstrcpy(file_prefix, sizeof(file_prefix), p + 1);
                   2272:     }
                   2273: #ifdef DEBUG_COMPLETION
                   2274:     term_printf("input='%s' path='%s' prefix='%s'\n", input, path, file_prefix);
                   2275: #endif
                   2276:     ffs = opendir(path);
                   2277:     if (!ffs)
                   2278:         return;
                   2279:     for(;;) {
                   2280:         struct stat sb;
                   2281:         d = readdir(ffs);
                   2282:         if (!d)
                   2283:             break;
                   2284:         if (strstart(d->d_name, file_prefix, NULL)) {
                   2285:             memcpy(file, input, input_path_len);
                   2286:             strcpy(file + input_path_len, d->d_name);
                   2287:             /* stat the file to find out if it's a directory.
                   2288:              * In that case add a slash to speed up typing long paths
                   2289:              */
                   2290:             stat(file, &sb);
                   2291:             if(S_ISDIR(sb.st_mode))
                   2292:                 strcat(file, "/");
                   2293:             add_completion(file);
                   2294:         }
                   2295:     }
                   2296:     closedir(ffs);
                   2297: }
                   2298: 
                   2299: static void block_completion_it(void *opaque, const char *name)
                   2300: {
                   2301:     const char *input = opaque;
                   2302: 
                   2303:     if (input[0] == '\0' ||
                   2304:         !strncmp(name, (char *)input, strlen(input))) {
                   2305:         add_completion(name);
                   2306:     }
                   2307: }
                   2308: 
                   2309: /* NOTE: this parser is an approximate form of the real command parser */
                   2310: static void parse_cmdline(const char *cmdline,
                   2311:                          int *pnb_args, char **args)
                   2312: {
                   2313:     const char *p;
                   2314:     int nb_args, ret;
                   2315:     char buf[1024];
                   2316: 
                   2317:     p = cmdline;
                   2318:     nb_args = 0;
                   2319:     for(;;) {
                   2320:         while (isspace(*p))
                   2321:             p++;
                   2322:         if (*p == '\0')
                   2323:             break;
                   2324:         if (nb_args >= MAX_ARGS)
                   2325:             break;
                   2326:         ret = get_str(buf, sizeof(buf), &p);
                   2327:         args[nb_args] = qemu_strdup(buf);
                   2328:         nb_args++;
                   2329:         if (ret < 0)
                   2330:             break;
                   2331:     }
                   2332:     *pnb_args = nb_args;
                   2333: }
                   2334: 
                   2335: void readline_find_completion(const char *cmdline)
                   2336: {
                   2337:     const char *cmdname;
                   2338:     char *args[MAX_ARGS];
                   2339:     int nb_args, i, len;
                   2340:     const char *ptype, *str;
                   2341:     term_cmd_t *cmd;
1.1.1.4   root     2342:     const KeyDef *key;
1.1       root     2343: 
                   2344:     parse_cmdline(cmdline, &nb_args, args);
                   2345: #ifdef DEBUG_COMPLETION
                   2346:     for(i = 0; i < nb_args; i++) {
                   2347:         term_printf("arg%d = '%s'\n", i, (char *)args[i]);
                   2348:     }
                   2349: #endif
                   2350: 
                   2351:     /* if the line ends with a space, it means we want to complete the
                   2352:        next arg */
                   2353:     len = strlen(cmdline);
                   2354:     if (len > 0 && isspace(cmdline[len - 1])) {
                   2355:         if (nb_args >= MAX_ARGS)
                   2356:             return;
                   2357:         args[nb_args++] = qemu_strdup("");
                   2358:     }
                   2359:     if (nb_args <= 1) {
                   2360:         /* command completion */
                   2361:         if (nb_args == 0)
                   2362:             cmdname = "";
                   2363:         else
                   2364:             cmdname = args[0];
                   2365:         completion_index = strlen(cmdname);
                   2366:         for(cmd = term_cmds; cmd->name != NULL; cmd++) {
                   2367:             cmd_completion(cmdname, cmd->name);
                   2368:         }
                   2369:     } else {
                   2370:         /* find the command */
                   2371:         for(cmd = term_cmds; cmd->name != NULL; cmd++) {
                   2372:             if (compare_cmd(args[0], cmd->name))
                   2373:                 goto found;
                   2374:         }
                   2375:         return;
                   2376:     found:
                   2377:         ptype = cmd->args_type;
                   2378:         for(i = 0; i < nb_args - 2; i++) {
                   2379:             if (*ptype != '\0') {
                   2380:                 ptype++;
                   2381:                 while (*ptype == '?')
                   2382:                     ptype++;
                   2383:             }
                   2384:         }
                   2385:         str = args[nb_args - 1];
                   2386:         switch(*ptype) {
                   2387:         case 'F':
                   2388:             /* file completion */
                   2389:             completion_index = strlen(str);
                   2390:             file_completion(str);
                   2391:             break;
                   2392:         case 'B':
                   2393:             /* block device name completion */
                   2394:             completion_index = strlen(str);
                   2395:             bdrv_iterate(block_completion_it, (void *)str);
                   2396:             break;
                   2397:         case 's':
                   2398:             /* XXX: more generic ? */
                   2399:             if (!strcmp(cmd->name, "info")) {
                   2400:                 completion_index = strlen(str);
                   2401:                 for(cmd = info_cmds; cmd->name != NULL; cmd++) {
                   2402:                     cmd_completion(str, cmd->name);
                   2403:                 }
1.1.1.4   root     2404:             } else if (!strcmp(cmd->name, "sendkey")) {
                   2405:                 completion_index = strlen(str);
                   2406:                 for(key = key_defs; key->name != NULL; key++) {
                   2407:                     cmd_completion(str, key->name);
                   2408:                 }
1.1       root     2409:             }
                   2410:             break;
                   2411:         default:
                   2412:             break;
                   2413:         }
                   2414:     }
                   2415:     for(i = 0; i < nb_args; i++)
                   2416:         qemu_free(args[i]);
                   2417: }
                   2418: 
                   2419: static int term_can_read(void *opaque)
                   2420: {
                   2421:     return 128;
                   2422: }
                   2423: 
                   2424: static void term_read(void *opaque, const uint8_t *buf, int size)
                   2425: {
                   2426:     int i;
                   2427:     for(i = 0; i < size; i++)
                   2428:         readline_handle_byte(buf[i]);
                   2429: }
                   2430: 
                   2431: static void monitor_start_input(void);
                   2432: 
                   2433: static void monitor_handle_command1(void *opaque, const char *cmdline)
                   2434: {
                   2435:     monitor_handle_command(cmdline);
                   2436:     monitor_start_input();
                   2437: }
                   2438: 
                   2439: static void monitor_start_input(void)
                   2440: {
                   2441:     readline_start("(qemu) ", 0, monitor_handle_command1, NULL);
                   2442: }
                   2443: 
1.1.1.5 ! root     2444: static void term_event(void *opaque, int event)
        !          2445: {
        !          2446:     if (event != CHR_EVENT_RESET)
        !          2447:        return;
        !          2448: 
        !          2449:     if (!hide_banner)
        !          2450:            term_printf("QEMU %s monitor - type 'help' for more information\n",
        !          2451:                        QEMU_VERSION);
        !          2452:     monitor_start_input();
        !          2453: }
        !          2454: 
1.1       root     2455: void monitor_init(CharDriverState *hd, int show_banner)
                   2456: {
                   2457:     monitor_hd = hd;
1.1.1.5 ! root     2458:     hide_banner = !show_banner;
        !          2459: 
        !          2460:     qemu_chr_add_handlers(hd, term_can_read, term_read, term_event, NULL);
1.1       root     2461: }
                   2462: 
                   2463: /* XXX: use threads ? */
                   2464: /* modal monitor readline */
                   2465: static int monitor_readline_started;
                   2466: static char *monitor_readline_buf;
                   2467: static int monitor_readline_buf_size;
                   2468: 
                   2469: static void monitor_readline_cb(void *opaque, const char *input)
                   2470: {
                   2471:     pstrcpy(monitor_readline_buf, monitor_readline_buf_size, input);
                   2472:     monitor_readline_started = 0;
                   2473: }
                   2474: 
                   2475: void monitor_readline(const char *prompt, int is_password,
                   2476:                       char *buf, int buf_size)
                   2477: {
                   2478:     if (is_password) {
                   2479:         qemu_chr_send_event(monitor_hd, CHR_EVENT_FOCUS);
                   2480:     }
                   2481:     readline_start(prompt, is_password, monitor_readline_cb, NULL);
                   2482:     monitor_readline_buf = buf;
                   2483:     monitor_readline_buf_size = buf_size;
                   2484:     monitor_readline_started = 1;
                   2485:     while (monitor_readline_started) {
                   2486:         main_loop_wait(10);
                   2487:     }
                   2488: }

unix.superglobalmegacorp.com