File:  [Qemu by Fabrice Bellard] / qemu / monitor.c
Revision 1.1.1.8 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 16:56:42 2018 UTC (3 years, 6 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu0105, qemu0104, qemu0103, qemu0102, qemu0101, HEAD
qemu 0.10.1

    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 "hw/hw.h"
   25: #include "hw/usb.h"
   26: #include "hw/pcmcia.h"
   27: #include "hw/pc.h"
   28: #include "hw/pci.h"
   29: #include "gdbstub.h"
   30: #include "net.h"
   31: #include "qemu-char.h"
   32: #include "sysemu.h"
   33: #include "console.h"
   34: #include "block.h"
   35: #include "audio/audio.h"
   36: #include "disas.h"
   37: #include "balloon.h"
   38: #include <dirent.h>
   39: #include "qemu-timer.h"
   40: #include "migration.h"
   41: #include "kvm.h"
   42: 
   43: //#define DEBUG
   44: //#define DEBUG_COMPLETION
   45: 
   46: /*
   47:  * Supported types:
   48:  *
   49:  * 'F'          filename
   50:  * 'B'          block device name
   51:  * 's'          string (accept optional quote)
   52:  * 'i'          32 bit integer
   53:  * 'l'          target long (32 or 64 bit)
   54:  * '/'          optional gdb-like print format (like "/10x")
   55:  *
   56:  * '?'          optional type (for 'F', 's' and 'i')
   57:  *
   58:  */
   59: 
   60: typedef struct term_cmd_t {
   61:     const char *name;
   62:     const char *args_type;
   63:     void *handler;
   64:     const char *params;
   65:     const char *help;
   66: } term_cmd_t;
   67: 
   68: #define MAX_MON 4
   69: static CharDriverState *monitor_hd[MAX_MON];
   70: static int hide_banner;
   71: 
   72: static const term_cmd_t term_cmds[];
   73: static const term_cmd_t info_cmds[];
   74: 
   75: static uint8_t term_outbuf[1024];
   76: static int term_outbuf_index;
   77: 
   78: static void monitor_start_input(void);
   79: static void monitor_readline(const char *prompt, int is_password,
   80:                              char *buf, int buf_size);
   81: 
   82: static CPUState *mon_cpu = NULL;
   83: 
   84: void term_flush(void)
   85: {
   86:     int i;
   87:     if (term_outbuf_index > 0) {
   88:         for (i = 0; i < MAX_MON; i++)
   89:             if (monitor_hd[i] && monitor_hd[i]->focus == 0)
   90:                 qemu_chr_write(monitor_hd[i], term_outbuf, term_outbuf_index);
   91:         term_outbuf_index = 0;
   92:     }
   93: }
   94: 
   95: /* flush at every end of line or if the buffer is full */
   96: void term_puts(const char *str)
   97: {
   98:     char c;
   99:     for(;;) {
  100:         c = *str++;
  101:         if (c == '\0')
  102:             break;
  103:         if (c == '\n')
  104:             term_outbuf[term_outbuf_index++] = '\r';
  105:         term_outbuf[term_outbuf_index++] = c;
  106:         if (term_outbuf_index >= (sizeof(term_outbuf) - 1) ||
  107:             c == '\n')
  108:             term_flush();
  109:     }
  110: }
  111: 
  112: void term_vprintf(const char *fmt, va_list ap)
  113: {
  114:     char buf[4096];
  115:     vsnprintf(buf, sizeof(buf), fmt, ap);
  116:     term_puts(buf);
  117: }
  118: 
  119: void term_printf(const char *fmt, ...)
  120: {
  121:     va_list ap;
  122:     va_start(ap, fmt);
  123:     term_vprintf(fmt, ap);
  124:     va_end(ap);
  125: }
  126: 
  127: void term_print_filename(const char *filename)
  128: {
  129:     int i;
  130: 
  131:     for (i = 0; filename[i]; i++) {
  132: 	switch (filename[i]) {
  133: 	case ' ':
  134: 	case '"':
  135: 	case '\\':
  136: 	    term_printf("\\%c", filename[i]);
  137: 	    break;
  138: 	case '\t':
  139: 	    term_printf("\\t");
  140: 	    break;
  141: 	case '\r':
  142: 	    term_printf("\\r");
  143: 	    break;
  144: 	case '\n':
  145: 	    term_printf("\\n");
  146: 	    break;
  147: 	default:
  148: 	    term_printf("%c", filename[i]);
  149: 	    break;
  150: 	}
  151:     }
  152: }
  153: 
  154: static int monitor_fprintf(FILE *stream, const char *fmt, ...)
  155: {
  156:     va_list ap;
  157:     va_start(ap, fmt);
  158:     term_vprintf(fmt, ap);
  159:     va_end(ap);
  160:     return 0;
  161: }
  162: 
  163: static int compare_cmd(const char *name, const char *list)
  164: {
  165:     const char *p, *pstart;
  166:     int len;
  167:     len = strlen(name);
  168:     p = list;
  169:     for(;;) {
  170:         pstart = p;
  171:         p = strchr(p, '|');
  172:         if (!p)
  173:             p = pstart + strlen(pstart);
  174:         if ((p - pstart) == len && !memcmp(pstart, name, len))
  175:             return 1;
  176:         if (*p == '\0')
  177:             break;
  178:         p++;
  179:     }
  180:     return 0;
  181: }
  182: 
  183: static void help_cmd1(const term_cmd_t *cmds, const char *prefix, const char *name)
  184: {
  185:     const term_cmd_t *cmd;
  186: 
  187:     for(cmd = cmds; cmd->name != NULL; cmd++) {
  188:         if (!name || !strcmp(name, cmd->name))
  189:             term_printf("%s%s %s -- %s\n", prefix, cmd->name, cmd->params, cmd->help);
  190:     }
  191: }
  192: 
  193: static void help_cmd(const char *name)
  194: {
  195:     if (name && !strcmp(name, "info")) {
  196:         help_cmd1(info_cmds, "info ", NULL);
  197:     } else {
  198:         help_cmd1(term_cmds, "", name);
  199:         if (name && !strcmp(name, "log")) {
  200:             const CPULogItem *item;
  201:             term_printf("Log items (comma separated):\n");
  202:             term_printf("%-10s %s\n", "none", "remove all logs");
  203:             for(item = cpu_log_items; item->mask != 0; item++) {
  204:                 term_printf("%-10s %s\n", item->name, item->help);
  205:             }
  206:         }
  207:     }
  208: }
  209: 
  210: static void do_help(const char *name)
  211: {
  212:     help_cmd(name);
  213: }
  214: 
  215: static void do_commit(const char *device)
  216: {
  217:     int i, all_devices;
  218: 
  219:     all_devices = !strcmp(device, "all");
  220:     for (i = 0; i < nb_drives; i++) {
  221:             if (all_devices ||
  222:                 !strcmp(bdrv_get_device_name(drives_table[i].bdrv), device))
  223:                 bdrv_commit(drives_table[i].bdrv);
  224:     }
  225: }
  226: 
  227: static void do_info(const char *item)
  228: {
  229:     const term_cmd_t *cmd;
  230:     void (*handler)(void);
  231: 
  232:     if (!item)
  233:         goto help;
  234:     for(cmd = info_cmds; cmd->name != NULL; cmd++) {
  235:         if (compare_cmd(item, cmd->name))
  236:             goto found;
  237:     }
  238:  help:
  239:     help_cmd("info");
  240:     return;
  241:  found:
  242:     handler = cmd->handler;
  243:     handler();
  244: }
  245: 
  246: static void do_info_version(void)
  247: {
  248:   term_printf("%s\n", QEMU_VERSION);
  249: }
  250: 
  251: static void do_info_name(void)
  252: {
  253:     if (qemu_name)
  254:         term_printf("%s\n", qemu_name);
  255: }
  256: 
  257: #if defined(TARGET_I386)
  258: static void do_info_hpet(void)
  259: {
  260:     term_printf("HPET is %s by QEMU\n", (no_hpet) ? "disabled" : "enabled");
  261: }
  262: #endif
  263: 
  264: static void do_info_uuid(void)
  265: {
  266:     term_printf(UUID_FMT "\n", qemu_uuid[0], qemu_uuid[1], qemu_uuid[2],
  267:             qemu_uuid[3], qemu_uuid[4], qemu_uuid[5], qemu_uuid[6],
  268:             qemu_uuid[7], qemu_uuid[8], qemu_uuid[9], qemu_uuid[10],
  269:             qemu_uuid[11], qemu_uuid[12], qemu_uuid[13], qemu_uuid[14],
  270:             qemu_uuid[15]);
  271: }
  272: 
  273: static void do_info_block(void)
  274: {
  275:     bdrv_info();
  276: }
  277: 
  278: static void do_info_blockstats(void)
  279: {
  280:     bdrv_info_stats();
  281: }
  282: 
  283: /* get the current CPU defined by the user */
  284: static int mon_set_cpu(int cpu_index)
  285: {
  286:     CPUState *env;
  287: 
  288:     for(env = first_cpu; env != NULL; env = env->next_cpu) {
  289:         if (env->cpu_index == cpu_index) {
  290:             mon_cpu = env;
  291:             return 0;
  292:         }
  293:     }
  294:     return -1;
  295: }
  296: 
  297: static CPUState *mon_get_cpu(void)
  298: {
  299:     if (!mon_cpu) {
  300:         mon_set_cpu(0);
  301:     }
  302:     return mon_cpu;
  303: }
  304: 
  305: static void do_info_registers(void)
  306: {
  307:     CPUState *env;
  308:     env = mon_get_cpu();
  309:     if (!env)
  310:         return;
  311: #ifdef TARGET_I386
  312:     cpu_dump_state(env, NULL, monitor_fprintf,
  313:                    X86_DUMP_FPU);
  314: #else
  315:     cpu_dump_state(env, NULL, monitor_fprintf,
  316:                    0);
  317: #endif
  318: }
  319: 
  320: static void do_info_cpus(void)
  321: {
  322:     CPUState *env;
  323: 
  324:     /* just to set the default cpu if not already done */
  325:     mon_get_cpu();
  326: 
  327:     for(env = first_cpu; env != NULL; env = env->next_cpu) {
  328:         term_printf("%c CPU #%d:",
  329:                     (env == mon_cpu) ? '*' : ' ',
  330:                     env->cpu_index);
  331: #if defined(TARGET_I386)
  332:         term_printf(" pc=0x" TARGET_FMT_lx, env->eip + env->segs[R_CS].base);
  333: #elif defined(TARGET_PPC)
  334:         term_printf(" nip=0x" TARGET_FMT_lx, env->nip);
  335: #elif defined(TARGET_SPARC)
  336:         term_printf(" pc=0x" TARGET_FMT_lx " npc=0x" TARGET_FMT_lx, env->pc, env->npc);
  337: #elif defined(TARGET_MIPS)
  338:         term_printf(" PC=0x" TARGET_FMT_lx, env->active_tc.PC);
  339: #endif
  340:         if (env->halted)
  341:             term_printf(" (halted)");
  342:         term_printf("\n");
  343:     }
  344: }
  345: 
  346: static void do_cpu_set(int index)
  347: {
  348:     if (mon_set_cpu(index) < 0)
  349:         term_printf("Invalid CPU index\n");
  350: }
  351: 
  352: static void do_info_jit(void)
  353: {
  354:     dump_exec_info(NULL, monitor_fprintf);
  355: }
  356: 
  357: static void do_info_history (void)
  358: {
  359:     int i;
  360:     const char *str;
  361: 
  362:     i = 0;
  363:     for(;;) {
  364:         str = readline_get_history(i);
  365:         if (!str)
  366:             break;
  367: 	term_printf("%d: '%s'\n", i, str);
  368:         i++;
  369:     }
  370: }
  371: 
  372: #if defined(TARGET_PPC)
  373: /* XXX: not implemented in other targets */
  374: static void do_info_cpu_stats (void)
  375: {
  376:     CPUState *env;
  377: 
  378:     env = mon_get_cpu();
  379:     cpu_dump_statistics(env, NULL, &monitor_fprintf, 0);
  380: }
  381: #endif
  382: 
  383: static void do_quit(void)
  384: {
  385:     exit(0);
  386: }
  387: 
  388: static int eject_device(BlockDriverState *bs, int force)
  389: {
  390:     if (bdrv_is_inserted(bs)) {
  391:         if (!force) {
  392:             if (!bdrv_is_removable(bs)) {
  393:                 term_printf("device is not removable\n");
  394:                 return -1;
  395:             }
  396:             if (bdrv_is_locked(bs)) {
  397:                 term_printf("device is locked\n");
  398:                 return -1;
  399:             }
  400:         }
  401:         bdrv_close(bs);
  402:     }
  403:     return 0;
  404: }
  405: 
  406: static void do_eject(int force, const char *filename)
  407: {
  408:     BlockDriverState *bs;
  409: 
  410:     bs = bdrv_find(filename);
  411:     if (!bs) {
  412:         term_printf("device not found\n");
  413:         return;
  414:     }
  415:     eject_device(bs, force);
  416: }
  417: 
  418: static void do_change_block(const char *device, const char *filename, const char *fmt)
  419: {
  420:     BlockDriverState *bs;
  421:     BlockDriver *drv = NULL;
  422: 
  423:     bs = bdrv_find(device);
  424:     if (!bs) {
  425:         term_printf("device not found\n");
  426:         return;
  427:     }
  428:     if (fmt) {
  429:         drv = bdrv_find_format(fmt);
  430:         if (!drv) {
  431:             term_printf("invalid format %s\n", fmt);
  432:             return;
  433:         }
  434:     }
  435:     if (eject_device(bs, 0) < 0)
  436:         return;
  437:     bdrv_open2(bs, filename, 0, drv);
  438:     monitor_read_bdrv_key(bs);
  439: }
  440: 
  441: static void do_change_vnc(const char *target, const char *arg)
  442: {
  443:     if (strcmp(target, "passwd") == 0 ||
  444: 	strcmp(target, "password") == 0) {
  445: 	char password[9];
  446: 	if (arg) {
  447: 	    strncpy(password, arg, sizeof(password));
  448: 	    password[sizeof(password) - 1] = '\0';
  449: 	} else
  450: 	    monitor_readline("Password: ", 1, password, sizeof(password));
  451: 	if (vnc_display_password(NULL, password) < 0)
  452: 	    term_printf("could not set VNC server password\n");
  453:     } else {
  454: 	if (vnc_display_open(NULL, target) < 0)
  455: 	    term_printf("could not start VNC server on %s\n", target);
  456:     }
  457: }
  458: 
  459: static void do_change(const char *device, const char *target, const char *arg)
  460: {
  461:     if (strcmp(device, "vnc") == 0) {
  462: 	do_change_vnc(target, arg);
  463:     } else {
  464: 	do_change_block(device, target, arg);
  465:     }
  466: }
  467: 
  468: static void do_screen_dump(const char *filename)
  469: {
  470:     vga_hw_screen_dump(filename);
  471: }
  472: 
  473: static void do_logfile(const char *filename)
  474: {
  475:     cpu_set_log_filename(filename);
  476: }
  477: 
  478: static void do_log(const char *items)
  479: {
  480:     int mask;
  481: 
  482:     if (!strcmp(items, "none")) {
  483:         mask = 0;
  484:     } else {
  485:         mask = cpu_str_to_log_mask(items);
  486:         if (!mask) {
  487:             help_cmd("log");
  488:             return;
  489:         }
  490:     }
  491:     cpu_set_log(mask);
  492: }
  493: 
  494: static void do_stop(void)
  495: {
  496:     vm_stop(EXCP_INTERRUPT);
  497: }
  498: 
  499: static void encrypted_bdrv_it(void *opaque, BlockDriverState *bs)
  500: {
  501:     int *err = opaque;
  502: 
  503:     if (bdrv_key_required(bs))
  504:         *err = monitor_read_bdrv_key(bs);
  505:     else
  506:         *err = 0;
  507: }
  508: 
  509: static void do_cont(void)
  510: {
  511:     int err = 0;
  512: 
  513:     bdrv_iterate(encrypted_bdrv_it, &err);
  514:     /* only resume the vm if all keys are set and valid */
  515:     if (!err)
  516:         vm_start();
  517: }
  518: 
  519: #ifdef CONFIG_GDBSTUB
  520: static void do_gdbserver(const char *port)
  521: {
  522:     if (!port)
  523:         port = DEFAULT_GDBSTUB_PORT;
  524:     if (gdbserver_start(port) < 0) {
  525:         qemu_printf("Could not open gdbserver socket on port '%s'\n", port);
  526:     } else {
  527:         qemu_printf("Waiting gdb connection on port '%s'\n", port);
  528:     }
  529: }
  530: #endif
  531: 
  532: static void term_printc(int c)
  533: {
  534:     term_printf("'");
  535:     switch(c) {
  536:     case '\'':
  537:         term_printf("\\'");
  538:         break;
  539:     case '\\':
  540:         term_printf("\\\\");
  541:         break;
  542:     case '\n':
  543:         term_printf("\\n");
  544:         break;
  545:     case '\r':
  546:         term_printf("\\r");
  547:         break;
  548:     default:
  549:         if (c >= 32 && c <= 126) {
  550:             term_printf("%c", c);
  551:         } else {
  552:             term_printf("\\x%02x", c);
  553:         }
  554:         break;
  555:     }
  556:     term_printf("'");
  557: }
  558: 
  559: static void memory_dump(int count, int format, int wsize,
  560:                         target_phys_addr_t addr, int is_physical)
  561: {
  562:     CPUState *env;
  563:     int nb_per_line, l, line_size, i, max_digits, len;
  564:     uint8_t buf[16];
  565:     uint64_t v;
  566: 
  567:     if (format == 'i') {
  568:         int flags;
  569:         flags = 0;
  570:         env = mon_get_cpu();
  571:         if (!env && !is_physical)
  572:             return;
  573: #ifdef TARGET_I386
  574:         if (wsize == 2) {
  575:             flags = 1;
  576:         } else if (wsize == 4) {
  577:             flags = 0;
  578:         } else {
  579:             /* as default we use the current CS size */
  580:             flags = 0;
  581:             if (env) {
  582: #ifdef TARGET_X86_64
  583:                 if ((env->efer & MSR_EFER_LMA) &&
  584:                     (env->segs[R_CS].flags & DESC_L_MASK))
  585:                     flags = 2;
  586:                 else
  587: #endif
  588:                 if (!(env->segs[R_CS].flags & DESC_B_MASK))
  589:                     flags = 1;
  590:             }
  591:         }
  592: #endif
  593:         monitor_disas(env, addr, count, is_physical, flags);
  594:         return;
  595:     }
  596: 
  597:     len = wsize * count;
  598:     if (wsize == 1)
  599:         line_size = 8;
  600:     else
  601:         line_size = 16;
  602:     nb_per_line = line_size / wsize;
  603:     max_digits = 0;
  604: 
  605:     switch(format) {
  606:     case 'o':
  607:         max_digits = (wsize * 8 + 2) / 3;
  608:         break;
  609:     default:
  610:     case 'x':
  611:         max_digits = (wsize * 8) / 4;
  612:         break;
  613:     case 'u':
  614:     case 'd':
  615:         max_digits = (wsize * 8 * 10 + 32) / 33;
  616:         break;
  617:     case 'c':
  618:         wsize = 1;
  619:         break;
  620:     }
  621: 
  622:     while (len > 0) {
  623:         if (is_physical)
  624:             term_printf(TARGET_FMT_plx ":", addr);
  625:         else
  626:             term_printf(TARGET_FMT_lx ":", (target_ulong)addr);
  627:         l = len;
  628:         if (l > line_size)
  629:             l = line_size;
  630:         if (is_physical) {
  631:             cpu_physical_memory_rw(addr, buf, l, 0);
  632:         } else {
  633:             env = mon_get_cpu();
  634:             if (!env)
  635:                 break;
  636:             if (cpu_memory_rw_debug(env, addr, buf, l, 0) < 0) {
  637:                 term_printf(" Cannot access memory\n");
  638:                 break;
  639:             }
  640:         }
  641:         i = 0;
  642:         while (i < l) {
  643:             switch(wsize) {
  644:             default:
  645:             case 1:
  646:                 v = ldub_raw(buf + i);
  647:                 break;
  648:             case 2:
  649:                 v = lduw_raw(buf + i);
  650:                 break;
  651:             case 4:
  652:                 v = (uint32_t)ldl_raw(buf + i);
  653:                 break;
  654:             case 8:
  655:                 v = ldq_raw(buf + i);
  656:                 break;
  657:             }
  658:             term_printf(" ");
  659:             switch(format) {
  660:             case 'o':
  661:                 term_printf("%#*" PRIo64, max_digits, v);
  662:                 break;
  663:             case 'x':
  664:                 term_printf("0x%0*" PRIx64, max_digits, v);
  665:                 break;
  666:             case 'u':
  667:                 term_printf("%*" PRIu64, max_digits, v);
  668:                 break;
  669:             case 'd':
  670:                 term_printf("%*" PRId64, max_digits, v);
  671:                 break;
  672:             case 'c':
  673:                 term_printc(v);
  674:                 break;
  675:             }
  676:             i += wsize;
  677:         }
  678:         term_printf("\n");
  679:         addr += l;
  680:         len -= l;
  681:     }
  682: }
  683: 
  684: #if TARGET_LONG_BITS == 64
  685: #define GET_TLONG(h, l) (((uint64_t)(h) << 32) | (l))
  686: #else
  687: #define GET_TLONG(h, l) (l)
  688: #endif
  689: 
  690: static void do_memory_dump(int count, int format, int size,
  691:                            uint32_t addrh, uint32_t addrl)
  692: {
  693:     target_long addr = GET_TLONG(addrh, addrl);
  694:     memory_dump(count, format, size, addr, 0);
  695: }
  696: 
  697: #if TARGET_PHYS_ADDR_BITS > 32
  698: #define GET_TPHYSADDR(h, l) (((uint64_t)(h) << 32) | (l))
  699: #else
  700: #define GET_TPHYSADDR(h, l) (l)
  701: #endif
  702: 
  703: static void do_physical_memory_dump(int count, int format, int size,
  704:                                     uint32_t addrh, uint32_t addrl)
  705: 
  706: {
  707:     target_phys_addr_t addr = GET_TPHYSADDR(addrh, addrl);
  708:     memory_dump(count, format, size, addr, 1);
  709: }
  710: 
  711: static void do_print(int count, int format, int size, unsigned int valh, unsigned int vall)
  712: {
  713:     target_phys_addr_t val = GET_TPHYSADDR(valh, vall);
  714: #if TARGET_PHYS_ADDR_BITS == 32
  715:     switch(format) {
  716:     case 'o':
  717:         term_printf("%#o", val);
  718:         break;
  719:     case 'x':
  720:         term_printf("%#x", val);
  721:         break;
  722:     case 'u':
  723:         term_printf("%u", val);
  724:         break;
  725:     default:
  726:     case 'd':
  727:         term_printf("%d", val);
  728:         break;
  729:     case 'c':
  730:         term_printc(val);
  731:         break;
  732:     }
  733: #else
  734:     switch(format) {
  735:     case 'o':
  736:         term_printf("%#" PRIo64, val);
  737:         break;
  738:     case 'x':
  739:         term_printf("%#" PRIx64, val);
  740:         break;
  741:     case 'u':
  742:         term_printf("%" PRIu64, val);
  743:         break;
  744:     default:
  745:     case 'd':
  746:         term_printf("%" PRId64, val);
  747:         break;
  748:     case 'c':
  749:         term_printc(val);
  750:         break;
  751:     }
  752: #endif
  753:     term_printf("\n");
  754: }
  755: 
  756: static void do_memory_save(unsigned int valh, unsigned int vall,
  757:                            uint32_t size, const char *filename)
  758: {
  759:     FILE *f;
  760:     target_long addr = GET_TLONG(valh, vall);
  761:     uint32_t l;
  762:     CPUState *env;
  763:     uint8_t buf[1024];
  764: 
  765:     env = mon_get_cpu();
  766:     if (!env)
  767:         return;
  768: 
  769:     f = fopen(filename, "wb");
  770:     if (!f) {
  771:         term_printf("could not open '%s'\n", filename);
  772:         return;
  773:     }
  774:     while (size != 0) {
  775:         l = sizeof(buf);
  776:         if (l > size)
  777:             l = size;
  778:         cpu_memory_rw_debug(env, addr, buf, l, 0);
  779:         fwrite(buf, 1, l, f);
  780:         addr += l;
  781:         size -= l;
  782:     }
  783:     fclose(f);
  784: }
  785: 
  786: static void do_physical_memory_save(unsigned int valh, unsigned int vall,
  787:                                     uint32_t size, const char *filename)
  788: {
  789:     FILE *f;
  790:     uint32_t l;
  791:     uint8_t buf[1024];
  792:     target_phys_addr_t addr = GET_TPHYSADDR(valh, vall); 
  793: 
  794:     f = fopen(filename, "wb");
  795:     if (!f) {
  796:         term_printf("could not open '%s'\n", filename);
  797:         return;
  798:     }
  799:     while (size != 0) {
  800:         l = sizeof(buf);
  801:         if (l > size)
  802:             l = size;
  803:         cpu_physical_memory_rw(addr, buf, l, 0);
  804:         fwrite(buf, 1, l, f);
  805:         fflush(f);
  806:         addr += l;
  807:         size -= l;
  808:     }
  809:     fclose(f);
  810: }
  811: 
  812: static void do_sum(uint32_t start, uint32_t size)
  813: {
  814:     uint32_t addr;
  815:     uint8_t buf[1];
  816:     uint16_t sum;
  817: 
  818:     sum = 0;
  819:     for(addr = start; addr < (start + size); addr++) {
  820:         cpu_physical_memory_rw(addr, buf, 1, 0);
  821:         /* BSD sum algorithm ('sum' Unix command) */
  822:         sum = (sum >> 1) | (sum << 15);
  823:         sum += buf[0];
  824:     }
  825:     term_printf("%05d\n", sum);
  826: }
  827: 
  828: typedef struct {
  829:     int keycode;
  830:     const char *name;
  831: } KeyDef;
  832: 
  833: static const KeyDef key_defs[] = {
  834:     { 0x2a, "shift" },
  835:     { 0x36, "shift_r" },
  836: 
  837:     { 0x38, "alt" },
  838:     { 0xb8, "alt_r" },
  839:     { 0x64, "altgr" },
  840:     { 0xe4, "altgr_r" },
  841:     { 0x1d, "ctrl" },
  842:     { 0x9d, "ctrl_r" },
  843: 
  844:     { 0xdd, "menu" },
  845: 
  846:     { 0x01, "esc" },
  847: 
  848:     { 0x02, "1" },
  849:     { 0x03, "2" },
  850:     { 0x04, "3" },
  851:     { 0x05, "4" },
  852:     { 0x06, "5" },
  853:     { 0x07, "6" },
  854:     { 0x08, "7" },
  855:     { 0x09, "8" },
  856:     { 0x0a, "9" },
  857:     { 0x0b, "0" },
  858:     { 0x0c, "minus" },
  859:     { 0x0d, "equal" },
  860:     { 0x0e, "backspace" },
  861: 
  862:     { 0x0f, "tab" },
  863:     { 0x10, "q" },
  864:     { 0x11, "w" },
  865:     { 0x12, "e" },
  866:     { 0x13, "r" },
  867:     { 0x14, "t" },
  868:     { 0x15, "y" },
  869:     { 0x16, "u" },
  870:     { 0x17, "i" },
  871:     { 0x18, "o" },
  872:     { 0x19, "p" },
  873: 
  874:     { 0x1c, "ret" },
  875: 
  876:     { 0x1e, "a" },
  877:     { 0x1f, "s" },
  878:     { 0x20, "d" },
  879:     { 0x21, "f" },
  880:     { 0x22, "g" },
  881:     { 0x23, "h" },
  882:     { 0x24, "j" },
  883:     { 0x25, "k" },
  884:     { 0x26, "l" },
  885: 
  886:     { 0x2c, "z" },
  887:     { 0x2d, "x" },
  888:     { 0x2e, "c" },
  889:     { 0x2f, "v" },
  890:     { 0x30, "b" },
  891:     { 0x31, "n" },
  892:     { 0x32, "m" },
  893:     { 0x33, "comma" },
  894:     { 0x34, "dot" },
  895:     { 0x35, "slash" },
  896: 
  897:     { 0x37, "asterisk" },
  898: 
  899:     { 0x39, "spc" },
  900:     { 0x3a, "caps_lock" },
  901:     { 0x3b, "f1" },
  902:     { 0x3c, "f2" },
  903:     { 0x3d, "f3" },
  904:     { 0x3e, "f4" },
  905:     { 0x3f, "f5" },
  906:     { 0x40, "f6" },
  907:     { 0x41, "f7" },
  908:     { 0x42, "f8" },
  909:     { 0x43, "f9" },
  910:     { 0x44, "f10" },
  911:     { 0x45, "num_lock" },
  912:     { 0x46, "scroll_lock" },
  913: 
  914:     { 0xb5, "kp_divide" },
  915:     { 0x37, "kp_multiply" },
  916:     { 0x4a, "kp_subtract" },
  917:     { 0x4e, "kp_add" },
  918:     { 0x9c, "kp_enter" },
  919:     { 0x53, "kp_decimal" },
  920:     { 0x54, "sysrq" },
  921: 
  922:     { 0x52, "kp_0" },
  923:     { 0x4f, "kp_1" },
  924:     { 0x50, "kp_2" },
  925:     { 0x51, "kp_3" },
  926:     { 0x4b, "kp_4" },
  927:     { 0x4c, "kp_5" },
  928:     { 0x4d, "kp_6" },
  929:     { 0x47, "kp_7" },
  930:     { 0x48, "kp_8" },
  931:     { 0x49, "kp_9" },
  932: 
  933:     { 0x56, "<" },
  934: 
  935:     { 0x57, "f11" },
  936:     { 0x58, "f12" },
  937: 
  938:     { 0xb7, "print" },
  939: 
  940:     { 0xc7, "home" },
  941:     { 0xc9, "pgup" },
  942:     { 0xd1, "pgdn" },
  943:     { 0xcf, "end" },
  944: 
  945:     { 0xcb, "left" },
  946:     { 0xc8, "up" },
  947:     { 0xd0, "down" },
  948:     { 0xcd, "right" },
  949: 
  950:     { 0xd2, "insert" },
  951:     { 0xd3, "delete" },
  952: #if defined(TARGET_SPARC) && !defined(TARGET_SPARC64)
  953:     { 0xf0, "stop" },
  954:     { 0xf1, "again" },
  955:     { 0xf2, "props" },
  956:     { 0xf3, "undo" },
  957:     { 0xf4, "front" },
  958:     { 0xf5, "copy" },
  959:     { 0xf6, "open" },
  960:     { 0xf7, "paste" },
  961:     { 0xf8, "find" },
  962:     { 0xf9, "cut" },
  963:     { 0xfa, "lf" },
  964:     { 0xfb, "help" },
  965:     { 0xfc, "meta_l" },
  966:     { 0xfd, "meta_r" },
  967:     { 0xfe, "compose" },
  968: #endif
  969:     { 0, NULL },
  970: };
  971: 
  972: static int get_keycode(const char *key)
  973: {
  974:     const KeyDef *p;
  975:     char *endp;
  976:     int ret;
  977: 
  978:     for(p = key_defs; p->name != NULL; p++) {
  979:         if (!strcmp(key, p->name))
  980:             return p->keycode;
  981:     }
  982:     if (strstart(key, "0x", NULL)) {
  983:         ret = strtoul(key, &endp, 0);
  984:         if (*endp == '\0' && ret >= 0x01 && ret <= 0xff)
  985:             return ret;
  986:     }
  987:     return -1;
  988: }
  989: 
  990: #define MAX_KEYCODES 16
  991: static uint8_t keycodes[MAX_KEYCODES];
  992: static int nb_pending_keycodes;
  993: static QEMUTimer *key_timer;
  994: 
  995: static void release_keys(void *opaque)
  996: {
  997:     int keycode;
  998: 
  999:     while (nb_pending_keycodes > 0) {
 1000:         nb_pending_keycodes--;
 1001:         keycode = keycodes[nb_pending_keycodes];
 1002:         if (keycode & 0x80)
 1003:             kbd_put_keycode(0xe0);
 1004:         kbd_put_keycode(keycode | 0x80);
 1005:     }
 1006: }
 1007: 
 1008: static void do_sendkey(const char *string, int has_hold_time, int hold_time)
 1009: {
 1010:     char keyname_buf[16];
 1011:     char *separator;
 1012:     int keyname_len, keycode, i;
 1013: 
 1014:     if (nb_pending_keycodes > 0) {
 1015:         qemu_del_timer(key_timer);
 1016:         release_keys(NULL);
 1017:     }
 1018:     if (!has_hold_time)
 1019:         hold_time = 100;
 1020:     i = 0;
 1021:     while (1) {
 1022:         separator = strchr(string, '-');
 1023:         keyname_len = separator ? separator - string : strlen(string);
 1024:         if (keyname_len > 0) {
 1025:             pstrcpy(keyname_buf, sizeof(keyname_buf), string);
 1026:             if (keyname_len > sizeof(keyname_buf) - 1) {
 1027:                 term_printf("invalid key: '%s...'\n", keyname_buf);
 1028:                 return;
 1029:             }
 1030:             if (i == MAX_KEYCODES) {
 1031:                 term_printf("too many keys\n");
 1032:                 return;
 1033:             }
 1034:             keyname_buf[keyname_len] = 0;
 1035:             keycode = get_keycode(keyname_buf);
 1036:             if (keycode < 0) {
 1037:                 term_printf("unknown key: '%s'\n", keyname_buf);
 1038:                 return;
 1039:             }
 1040:             keycodes[i++] = keycode;
 1041:         }
 1042:         if (!separator)
 1043:             break;
 1044:         string = separator + 1;
 1045:     }
 1046:     nb_pending_keycodes = i;
 1047:     /* key down events */
 1048:     for (i = 0; i < nb_pending_keycodes; i++) {
 1049:         keycode = keycodes[i];
 1050:         if (keycode & 0x80)
 1051:             kbd_put_keycode(0xe0);
 1052:         kbd_put_keycode(keycode & 0x7f);
 1053:     }
 1054:     /* delayed key up events */
 1055:     qemu_mod_timer(key_timer, qemu_get_clock(vm_clock) +
 1056:                     muldiv64(ticks_per_sec, hold_time, 1000));
 1057: }
 1058: 
 1059: static int mouse_button_state;
 1060: 
 1061: static void do_mouse_move(const char *dx_str, const char *dy_str,
 1062:                           const char *dz_str)
 1063: {
 1064:     int dx, dy, dz;
 1065:     dx = strtol(dx_str, NULL, 0);
 1066:     dy = strtol(dy_str, NULL, 0);
 1067:     dz = 0;
 1068:     if (dz_str)
 1069:         dz = strtol(dz_str, NULL, 0);
 1070:     kbd_mouse_event(dx, dy, dz, mouse_button_state);
 1071: }
 1072: 
 1073: static void do_mouse_button(int button_state)
 1074: {
 1075:     mouse_button_state = button_state;
 1076:     kbd_mouse_event(0, 0, 0, mouse_button_state);
 1077: }
 1078: 
 1079: static void do_ioport_read(int count, int format, int size, int addr, int has_index, int index)
 1080: {
 1081:     uint32_t val;
 1082:     int suffix;
 1083: 
 1084:     if (has_index) {
 1085:         cpu_outb(NULL, addr & 0xffff, index & 0xff);
 1086:         addr++;
 1087:     }
 1088:     addr &= 0xffff;
 1089: 
 1090:     switch(size) {
 1091:     default:
 1092:     case 1:
 1093:         val = cpu_inb(NULL, addr);
 1094:         suffix = 'b';
 1095:         break;
 1096:     case 2:
 1097:         val = cpu_inw(NULL, addr);
 1098:         suffix = 'w';
 1099:         break;
 1100:     case 4:
 1101:         val = cpu_inl(NULL, addr);
 1102:         suffix = 'l';
 1103:         break;
 1104:     }
 1105:     term_printf("port%c[0x%04x] = %#0*x\n",
 1106:                 suffix, addr, size * 2, val);
 1107: }
 1108: 
 1109: /* boot_set handler */
 1110: static QEMUBootSetHandler *qemu_boot_set_handler = NULL;
 1111: static void *boot_opaque;
 1112: 
 1113: void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque)
 1114: {
 1115:     qemu_boot_set_handler = func;
 1116:     boot_opaque = opaque;
 1117: }
 1118: 
 1119: static void do_boot_set(const char *bootdevice)
 1120: {
 1121:     int res;
 1122: 
 1123:     if (qemu_boot_set_handler)  {
 1124:         res = qemu_boot_set_handler(boot_opaque, bootdevice);
 1125:         if (res == 0)
 1126:             term_printf("boot device list now set to %s\n", bootdevice);
 1127:         else
 1128:             term_printf("setting boot device list failed with error %i\n", res);
 1129:     } else {
 1130:         term_printf("no function defined to set boot device list for this architecture\n");
 1131:     }
 1132: }
 1133: 
 1134: static void do_system_reset(void)
 1135: {
 1136:     qemu_system_reset_request();
 1137: }
 1138: 
 1139: static void do_system_powerdown(void)
 1140: {
 1141:     qemu_system_powerdown_request();
 1142: }
 1143: 
 1144: #if defined(TARGET_I386)
 1145: static void print_pte(uint32_t addr, uint32_t pte, uint32_t mask)
 1146: {
 1147:     term_printf("%08x: %08x %c%c%c%c%c%c%c%c\n",
 1148:                 addr,
 1149:                 pte & mask,
 1150:                 pte & PG_GLOBAL_MASK ? 'G' : '-',
 1151:                 pte & PG_PSE_MASK ? 'P' : '-',
 1152:                 pte & PG_DIRTY_MASK ? 'D' : '-',
 1153:                 pte & PG_ACCESSED_MASK ? 'A' : '-',
 1154:                 pte & PG_PCD_MASK ? 'C' : '-',
 1155:                 pte & PG_PWT_MASK ? 'T' : '-',
 1156:                 pte & PG_USER_MASK ? 'U' : '-',
 1157:                 pte & PG_RW_MASK ? 'W' : '-');
 1158: }
 1159: 
 1160: static void tlb_info(void)
 1161: {
 1162:     CPUState *env;
 1163:     int l1, l2;
 1164:     uint32_t pgd, pde, pte;
 1165: 
 1166:     env = mon_get_cpu();
 1167:     if (!env)
 1168:         return;
 1169: 
 1170:     if (!(env->cr[0] & CR0_PG_MASK)) {
 1171:         term_printf("PG disabled\n");
 1172:         return;
 1173:     }
 1174:     pgd = env->cr[3] & ~0xfff;
 1175:     for(l1 = 0; l1 < 1024; l1++) {
 1176:         cpu_physical_memory_read(pgd + l1 * 4, (uint8_t *)&pde, 4);
 1177:         pde = le32_to_cpu(pde);
 1178:         if (pde & PG_PRESENT_MASK) {
 1179:             if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
 1180:                 print_pte((l1 << 22), pde, ~((1 << 20) - 1));
 1181:             } else {
 1182:                 for(l2 = 0; l2 < 1024; l2++) {
 1183:                     cpu_physical_memory_read((pde & ~0xfff) + l2 * 4,
 1184:                                              (uint8_t *)&pte, 4);
 1185:                     pte = le32_to_cpu(pte);
 1186:                     if (pte & PG_PRESENT_MASK) {
 1187:                         print_pte((l1 << 22) + (l2 << 12),
 1188:                                   pte & ~PG_PSE_MASK,
 1189:                                   ~0xfff);
 1190:                     }
 1191:                 }
 1192:             }
 1193:         }
 1194:     }
 1195: }
 1196: 
 1197: static void mem_print(uint32_t *pstart, int *plast_prot,
 1198:                       uint32_t end, int prot)
 1199: {
 1200:     int prot1;
 1201:     prot1 = *plast_prot;
 1202:     if (prot != prot1) {
 1203:         if (*pstart != -1) {
 1204:             term_printf("%08x-%08x %08x %c%c%c\n",
 1205:                         *pstart, end, end - *pstart,
 1206:                         prot1 & PG_USER_MASK ? 'u' : '-',
 1207:                         'r',
 1208:                         prot1 & PG_RW_MASK ? 'w' : '-');
 1209:         }
 1210:         if (prot != 0)
 1211:             *pstart = end;
 1212:         else
 1213:             *pstart = -1;
 1214:         *plast_prot = prot;
 1215:     }
 1216: }
 1217: 
 1218: static void mem_info(void)
 1219: {
 1220:     CPUState *env;
 1221:     int l1, l2, prot, last_prot;
 1222:     uint32_t pgd, pde, pte, start, end;
 1223: 
 1224:     env = mon_get_cpu();
 1225:     if (!env)
 1226:         return;
 1227: 
 1228:     if (!(env->cr[0] & CR0_PG_MASK)) {
 1229:         term_printf("PG disabled\n");
 1230:         return;
 1231:     }
 1232:     pgd = env->cr[3] & ~0xfff;
 1233:     last_prot = 0;
 1234:     start = -1;
 1235:     for(l1 = 0; l1 < 1024; l1++) {
 1236:         cpu_physical_memory_read(pgd + l1 * 4, (uint8_t *)&pde, 4);
 1237:         pde = le32_to_cpu(pde);
 1238:         end = l1 << 22;
 1239:         if (pde & PG_PRESENT_MASK) {
 1240:             if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
 1241:                 prot = pde & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK);
 1242:                 mem_print(&start, &last_prot, end, prot);
 1243:             } else {
 1244:                 for(l2 = 0; l2 < 1024; l2++) {
 1245:                     cpu_physical_memory_read((pde & ~0xfff) + l2 * 4,
 1246:                                              (uint8_t *)&pte, 4);
 1247:                     pte = le32_to_cpu(pte);
 1248:                     end = (l1 << 22) + (l2 << 12);
 1249:                     if (pte & PG_PRESENT_MASK) {
 1250:                         prot = pte & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK);
 1251:                     } else {
 1252:                         prot = 0;
 1253:                     }
 1254:                     mem_print(&start, &last_prot, end, prot);
 1255:                 }
 1256:             }
 1257:         } else {
 1258:             prot = 0;
 1259:             mem_print(&start, &last_prot, end, prot);
 1260:         }
 1261:     }
 1262: }
 1263: #endif
 1264: 
 1265: #if defined(TARGET_SH4)
 1266: 
 1267: static void print_tlb(int idx, tlb_t *tlb)
 1268: {
 1269:     term_printf(" tlb%i:\t"
 1270:                 "asid=%hhu vpn=%x\tppn=%x\tsz=%hhu size=%u\t"
 1271:                 "v=%hhu shared=%hhu cached=%hhu prot=%hhu "
 1272:                 "dirty=%hhu writethrough=%hhu\n",
 1273:                 idx,
 1274:                 tlb->asid, tlb->vpn, tlb->ppn, tlb->sz, tlb->size,
 1275:                 tlb->v, tlb->sh, tlb->c, tlb->pr,
 1276:                 tlb->d, tlb->wt);
 1277: }
 1278: 
 1279: static void tlb_info(void)
 1280: {
 1281:     CPUState *env = mon_get_cpu();
 1282:     int i;
 1283: 
 1284:     term_printf ("ITLB:\n");
 1285:     for (i = 0 ; i < ITLB_SIZE ; i++)
 1286:         print_tlb (i, &env->itlb[i]);
 1287:     term_printf ("UTLB:\n");
 1288:     for (i = 0 ; i < UTLB_SIZE ; i++)
 1289:         print_tlb (i, &env->utlb[i]);
 1290: }
 1291: 
 1292: #endif
 1293: 
 1294: static void do_info_kqemu(void)
 1295: {
 1296: #ifdef USE_KQEMU
 1297:     CPUState *env;
 1298:     int val;
 1299:     val = 0;
 1300:     env = mon_get_cpu();
 1301:     if (!env) {
 1302:         term_printf("No cpu initialized yet");
 1303:         return;
 1304:     }
 1305:     val = env->kqemu_enabled;
 1306:     term_printf("kqemu support: ");
 1307:     switch(val) {
 1308:     default:
 1309:     case 0:
 1310:         term_printf("disabled\n");
 1311:         break;
 1312:     case 1:
 1313:         term_printf("enabled for user code\n");
 1314:         break;
 1315:     case 2:
 1316:         term_printf("enabled for user and kernel code\n");
 1317:         break;
 1318:     }
 1319: #else
 1320:     term_printf("kqemu support: not compiled\n");
 1321: #endif
 1322: }
 1323: 
 1324: static void do_info_kvm(void)
 1325: {
 1326: #ifdef CONFIG_KVM
 1327:     term_printf("kvm support: ");
 1328:     if (kvm_enabled())
 1329: 	term_printf("enabled\n");
 1330:     else
 1331: 	term_printf("disabled\n");
 1332: #else
 1333:     term_printf("kvm support: not compiled\n");
 1334: #endif
 1335: }
 1336: 
 1337: #ifdef CONFIG_PROFILER
 1338: 
 1339: int64_t kqemu_time;
 1340: int64_t qemu_time;
 1341: int64_t kqemu_exec_count;
 1342: int64_t dev_time;
 1343: int64_t kqemu_ret_int_count;
 1344: int64_t kqemu_ret_excp_count;
 1345: int64_t kqemu_ret_intr_count;
 1346: 
 1347: static void do_info_profile(void)
 1348: {
 1349:     int64_t total;
 1350:     total = qemu_time;
 1351:     if (total == 0)
 1352:         total = 1;
 1353:     term_printf("async time  %" PRId64 " (%0.3f)\n",
 1354:                 dev_time, dev_time / (double)ticks_per_sec);
 1355:     term_printf("qemu time   %" PRId64 " (%0.3f)\n",
 1356:                 qemu_time, qemu_time / (double)ticks_per_sec);
 1357:     term_printf("kqemu time  %" PRId64 " (%0.3f %0.1f%%) count=%" PRId64 " int=%" PRId64 " excp=%" PRId64 " intr=%" PRId64 "\n",
 1358:                 kqemu_time, kqemu_time / (double)ticks_per_sec,
 1359:                 kqemu_time / (double)total * 100.0,
 1360:                 kqemu_exec_count,
 1361:                 kqemu_ret_int_count,
 1362:                 kqemu_ret_excp_count,
 1363:                 kqemu_ret_intr_count);
 1364:     qemu_time = 0;
 1365:     kqemu_time = 0;
 1366:     kqemu_exec_count = 0;
 1367:     dev_time = 0;
 1368:     kqemu_ret_int_count = 0;
 1369:     kqemu_ret_excp_count = 0;
 1370:     kqemu_ret_intr_count = 0;
 1371: #ifdef USE_KQEMU
 1372:     kqemu_record_dump();
 1373: #endif
 1374: }
 1375: #else
 1376: static void do_info_profile(void)
 1377: {
 1378:     term_printf("Internal profiler not compiled\n");
 1379: }
 1380: #endif
 1381: 
 1382: /* Capture support */
 1383: static LIST_HEAD (capture_list_head, CaptureState) capture_head;
 1384: 
 1385: static void do_info_capture (void)
 1386: {
 1387:     int i;
 1388:     CaptureState *s;
 1389: 
 1390:     for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) {
 1391:         term_printf ("[%d]: ", i);
 1392:         s->ops.info (s->opaque);
 1393:     }
 1394: }
 1395: 
 1396: static void do_stop_capture (int n)
 1397: {
 1398:     int i;
 1399:     CaptureState *s;
 1400: 
 1401:     for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) {
 1402:         if (i == n) {
 1403:             s->ops.destroy (s->opaque);
 1404:             LIST_REMOVE (s, entries);
 1405:             qemu_free (s);
 1406:             return;
 1407:         }
 1408:     }
 1409: }
 1410: 
 1411: #ifdef HAS_AUDIO
 1412: static void do_wav_capture (const char *path,
 1413:                             int has_freq, int freq,
 1414:                             int has_bits, int bits,
 1415:                             int has_channels, int nchannels)
 1416: {
 1417:     CaptureState *s;
 1418: 
 1419:     s = qemu_mallocz (sizeof (*s));
 1420: 
 1421:     freq = has_freq ? freq : 44100;
 1422:     bits = has_bits ? bits : 16;
 1423:     nchannels = has_channels ? nchannels : 2;
 1424: 
 1425:     if (wav_start_capture (s, path, freq, bits, nchannels)) {
 1426:         term_printf ("Faied to add wave capture\n");
 1427:         qemu_free (s);
 1428:     }
 1429:     LIST_INSERT_HEAD (&capture_head, s, entries);
 1430: }
 1431: #endif
 1432: 
 1433: #if defined(TARGET_I386)
 1434: static void do_inject_nmi(int cpu_index)
 1435: {
 1436:     CPUState *env;
 1437: 
 1438:     for (env = first_cpu; env != NULL; env = env->next_cpu)
 1439:         if (env->cpu_index == cpu_index) {
 1440:             cpu_interrupt(env, CPU_INTERRUPT_NMI);
 1441:             break;
 1442:         }
 1443: }
 1444: #endif
 1445: 
 1446: static void do_info_status(void)
 1447: {
 1448:     if (vm_running)
 1449:        term_printf("VM status: running\n");
 1450:     else
 1451:        term_printf("VM status: paused\n");
 1452: }
 1453: 
 1454: 
 1455: static void do_balloon(int value)
 1456: {
 1457:     ram_addr_t target = value;
 1458:     qemu_balloon(target << 20);
 1459: }
 1460: 
 1461: static void do_info_balloon(void)
 1462: {
 1463:     ram_addr_t actual;
 1464: 
 1465:     actual = qemu_balloon_status();
 1466:     if (kvm_enabled() && !kvm_has_sync_mmu())
 1467:         term_printf("Using KVM without synchronous MMU, ballooning disabled\n");
 1468:     else if (actual == 0)
 1469:         term_printf("Ballooning not activated in VM\n");
 1470:     else
 1471:         term_printf("balloon: actual=%d\n", (int)(actual >> 20));
 1472: }
 1473: 
 1474: /* Please update qemu-doc.texi when adding or changing commands */
 1475: static const term_cmd_t term_cmds[] = {
 1476:     { "help|?", "s?", do_help,
 1477:       "[cmd]", "show the help" },
 1478:     { "commit", "s", do_commit,
 1479:       "device|all", "commit changes to the disk images (if -snapshot is used) or backing files" },
 1480:     { "info", "s?", do_info,
 1481:       "subcommand", "show various information about the system state" },
 1482:     { "q|quit", "", do_quit,
 1483:       "", "quit the emulator" },
 1484:     { "eject", "-fB", do_eject,
 1485:       "[-f] device", "eject a removable medium (use -f to force it)" },
 1486:     { "change", "BFs?", do_change,
 1487:       "device filename [format]", "change a removable medium, optional format" },
 1488:     { "screendump", "F", do_screen_dump,
 1489:       "filename", "save screen into PPM image 'filename'" },
 1490:     { "logfile", "F", do_logfile,
 1491:       "filename", "output logs to 'filename'" },
 1492:     { "log", "s", do_log,
 1493:       "item1[,...]", "activate logging of the specified items to '/tmp/qemu.log'" },
 1494:     { "savevm", "s?", do_savevm,
 1495:       "tag|id", "save a VM snapshot. If no tag or id are provided, a new snapshot is created" },
 1496:     { "loadvm", "s", do_loadvm,
 1497:       "tag|id", "restore a VM snapshot from its tag or id" },
 1498:     { "delvm", "s", do_delvm,
 1499:       "tag|id", "delete a VM snapshot from its tag or id" },
 1500:     { "stop", "", do_stop,
 1501:       "", "stop emulation", },
 1502:     { "c|cont", "", do_cont,
 1503:       "", "resume emulation", },
 1504: #ifdef CONFIG_GDBSTUB
 1505:     { "gdbserver", "s?", do_gdbserver,
 1506:       "[port]", "start gdbserver session (default port=1234)", },
 1507: #endif
 1508:     { "x", "/l", do_memory_dump,
 1509:       "/fmt addr", "virtual memory dump starting at 'addr'", },
 1510:     { "xp", "/l", do_physical_memory_dump,
 1511:       "/fmt addr", "physical memory dump starting at 'addr'", },
 1512:     { "p|print", "/l", do_print,
 1513:       "/fmt expr", "print expression value (use $reg for CPU register access)", },
 1514:     { "i", "/ii.", do_ioport_read,
 1515:       "/fmt addr", "I/O port read" },
 1516: 
 1517:     { "sendkey", "si?", do_sendkey,
 1518:       "keys [hold_ms]", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1', default hold time=100 ms)" },
 1519:     { "system_reset", "", do_system_reset,
 1520:       "", "reset the system" },
 1521:     { "system_powerdown", "", do_system_powerdown,
 1522:       "", "send system power down event" },
 1523:     { "sum", "ii", do_sum,
 1524:       "addr size", "compute the checksum of a memory region" },
 1525:     { "usb_add", "s", do_usb_add,
 1526:       "device", "add USB device (e.g. 'host:bus.addr' or 'host:vendor_id:product_id')" },
 1527:     { "usb_del", "s", do_usb_del,
 1528:       "device", "remove USB device 'bus.addr'" },
 1529:     { "cpu", "i", do_cpu_set,
 1530:       "index", "set the default CPU" },
 1531:     { "mouse_move", "sss?", do_mouse_move,
 1532:       "dx dy [dz]", "send mouse move events" },
 1533:     { "mouse_button", "i", do_mouse_button,
 1534:       "state", "change mouse button state (1=L, 2=M, 4=R)" },
 1535:     { "mouse_set", "i", do_mouse_set,
 1536:       "index", "set which mouse device receives events" },
 1537: #ifdef HAS_AUDIO
 1538:     { "wavcapture", "si?i?i?", do_wav_capture,
 1539:       "path [frequency bits channels]",
 1540:       "capture audio to a wave file (default frequency=44100 bits=16 channels=2)" },
 1541: #endif
 1542:     { "stopcapture", "i", do_stop_capture,
 1543:       "capture index", "stop capture" },
 1544:     { "memsave", "lis", do_memory_save,
 1545:       "addr size file", "save to disk virtual memory dump starting at 'addr' of size 'size'", },
 1546:     { "pmemsave", "lis", do_physical_memory_save,
 1547:       "addr size file", "save to disk physical memory dump starting at 'addr' of size 'size'", },
 1548:     { "boot_set", "s", do_boot_set,
 1549:       "bootdevice", "define new values for the boot device list" },
 1550: #if defined(TARGET_I386)
 1551:     { "nmi", "i", do_inject_nmi,
 1552:       "cpu", "inject an NMI on the given CPU", },
 1553: #endif
 1554:     { "migrate", "-ds", do_migrate,
 1555:       "[-d] uri", "migrate to URI (using -d to not wait for completion)" },
 1556:     { "migrate_cancel", "", do_migrate_cancel,
 1557:       "", "cancel the current VM migration" },
 1558:     { "migrate_set_speed", "s", do_migrate_set_speed,
 1559:       "value", "set maximum speed (in bytes) for migrations" },
 1560: #if defined(TARGET_I386)
 1561:     { "drive_add", "ss", drive_hot_add, "pci_addr=[[<domain>:]<bus>:]<slot>\n"
 1562:                                          "[file=file][,if=type][,bus=n]\n"
 1563:                                         "[,unit=m][,media=d][index=i]\n"
 1564:                                         "[,cyls=c,heads=h,secs=s[,trans=t]]\n"
 1565:                                         "[snapshot=on|off][,cache=on|off]",
 1566:                                         "add drive to PCI storage controller" },
 1567:     { "pci_add", "sss", pci_device_hot_add, "pci_addr=auto|[[<domain>:]<bus>:]<slot> nic|storage [[vlan=n][,macaddr=addr][,model=type]] [file=file][,if=type][,bus=nr]...", "hot-add PCI device" },
 1568:     { "pci_del", "s", pci_device_hot_remove, "pci_addr=[[<domain>:]<bus>:]<slot>", "hot remove PCI device" },
 1569:     { "host_net_add", "ss", net_host_device_add,
 1570:       "[tap,user,socket,vde] options", "add host VLAN client" },
 1571:     { "host_net_remove", "is", net_host_device_remove,
 1572:       "vlan_id name", "remove host VLAN client" },
 1573: #endif
 1574:     { "balloon", "i", do_balloon,
 1575:       "target", "request VM to change it's memory allocation (in MB)" },
 1576:     { "set_link", "ss", do_set_link,
 1577:       "name [up|down]", "change the link status of a network adapter" },
 1578:     { NULL, NULL, },
 1579: };
 1580: 
 1581: /* Please update qemu-doc.texi when adding or changing commands */
 1582: static const term_cmd_t info_cmds[] = {
 1583:     { "version", "", do_info_version,
 1584:       "", "show the version of QEMU" },
 1585:     { "network", "", do_info_network,
 1586:       "", "show the network state" },
 1587:     { "chardev", "", qemu_chr_info,
 1588:       "", "show the character devices" },
 1589:     { "block", "", do_info_block,
 1590:       "", "show the block devices" },
 1591:     { "blockstats", "", do_info_blockstats,
 1592:       "", "show block device statistics" },
 1593:     { "registers", "", do_info_registers,
 1594:       "", "show the cpu registers" },
 1595:     { "cpus", "", do_info_cpus,
 1596:       "", "show infos for each CPU" },
 1597:     { "history", "", do_info_history,
 1598:       "", "show the command line history", },
 1599:     { "irq", "", irq_info,
 1600:       "", "show the interrupts statistics (if available)", },
 1601:     { "pic", "", pic_info,
 1602:       "", "show i8259 (PIC) state", },
 1603:     { "pci", "", pci_info,
 1604:       "", "show PCI info", },
 1605: #if defined(TARGET_I386) || defined(TARGET_SH4)
 1606:     { "tlb", "", tlb_info,
 1607:       "", "show virtual to physical memory mappings", },
 1608: #endif
 1609: #if defined(TARGET_I386)
 1610:     { "mem", "", mem_info,
 1611:       "", "show the active virtual memory mappings", },
 1612:     { "hpet", "", do_info_hpet,
 1613:       "", "show state of HPET", },
 1614: #endif
 1615:     { "jit", "", do_info_jit,
 1616:       "", "show dynamic compiler info", },
 1617:     { "kqemu", "", do_info_kqemu,
 1618:       "", "show KQEMU information", },
 1619:     { "kvm", "", do_info_kvm,
 1620:       "", "show KVM information", },
 1621:     { "usb", "", usb_info,
 1622:       "", "show guest USB devices", },
 1623:     { "usbhost", "", usb_host_info,
 1624:       "", "show host USB devices", },
 1625:     { "profile", "", do_info_profile,
 1626:       "", "show profiling information", },
 1627:     { "capture", "", do_info_capture,
 1628:       "", "show capture information" },
 1629:     { "snapshots", "", do_info_snapshots,
 1630:       "", "show the currently saved VM snapshots" },
 1631:     { "status", "", do_info_status,
 1632:       "", "show the current VM status (running|paused)" },
 1633:     { "pcmcia", "", pcmcia_info,
 1634:       "", "show guest PCMCIA status" },
 1635:     { "mice", "", do_info_mice,
 1636:       "", "show which guest mouse is receiving events" },
 1637:     { "vnc", "", do_info_vnc,
 1638:       "", "show the vnc server status"},
 1639:     { "name", "", do_info_name,
 1640:       "", "show the current VM name" },
 1641:     { "uuid", "", do_info_uuid,
 1642:       "", "show the current VM UUID" },
 1643: #if defined(TARGET_PPC)
 1644:     { "cpustats", "", do_info_cpu_stats,
 1645:       "", "show CPU statistics", },
 1646: #endif
 1647: #if defined(CONFIG_SLIRP)
 1648:     { "slirp", "", do_info_slirp,
 1649:       "", "show SLIRP statistics", },
 1650: #endif
 1651:     { "migrate", "", do_info_migrate, "", "show migration status" },
 1652:     { "balloon", "", do_info_balloon,
 1653:       "", "show balloon information" },
 1654:     { NULL, NULL, },
 1655: };
 1656: 
 1657: /*******************************************************************/
 1658: 
 1659: static const char *pch;
 1660: static jmp_buf expr_env;
 1661: 
 1662: #define MD_TLONG 0
 1663: #define MD_I32   1
 1664: 
 1665: typedef struct MonitorDef {
 1666:     const char *name;
 1667:     int offset;
 1668:     target_long (*get_value)(const struct MonitorDef *md, int val);
 1669:     int type;
 1670: } MonitorDef;
 1671: 
 1672: #if defined(TARGET_I386)
 1673: static target_long monitor_get_pc (const struct MonitorDef *md, int val)
 1674: {
 1675:     CPUState *env = mon_get_cpu();
 1676:     if (!env)
 1677:         return 0;
 1678:     return env->eip + env->segs[R_CS].base;
 1679: }
 1680: #endif
 1681: 
 1682: #if defined(TARGET_PPC)
 1683: static target_long monitor_get_ccr (const struct MonitorDef *md, int val)
 1684: {
 1685:     CPUState *env = mon_get_cpu();
 1686:     unsigned int u;
 1687:     int i;
 1688: 
 1689:     if (!env)
 1690:         return 0;
 1691: 
 1692:     u = 0;
 1693:     for (i = 0; i < 8; i++)
 1694: 	u |= env->crf[i] << (32 - (4 * i));
 1695: 
 1696:     return u;
 1697: }
 1698: 
 1699: static target_long monitor_get_msr (const struct MonitorDef *md, int val)
 1700: {
 1701:     CPUState *env = mon_get_cpu();
 1702:     if (!env)
 1703:         return 0;
 1704:     return env->msr;
 1705: }
 1706: 
 1707: static target_long monitor_get_xer (const struct MonitorDef *md, int val)
 1708: {
 1709:     CPUState *env = mon_get_cpu();
 1710:     if (!env)
 1711:         return 0;
 1712:     return env->xer;
 1713: }
 1714: 
 1715: static target_long monitor_get_decr (const struct MonitorDef *md, int val)
 1716: {
 1717:     CPUState *env = mon_get_cpu();
 1718:     if (!env)
 1719:         return 0;
 1720:     return cpu_ppc_load_decr(env);
 1721: }
 1722: 
 1723: static target_long monitor_get_tbu (const struct MonitorDef *md, int val)
 1724: {
 1725:     CPUState *env = mon_get_cpu();
 1726:     if (!env)
 1727:         return 0;
 1728:     return cpu_ppc_load_tbu(env);
 1729: }
 1730: 
 1731: static target_long monitor_get_tbl (const struct MonitorDef *md, int val)
 1732: {
 1733:     CPUState *env = mon_get_cpu();
 1734:     if (!env)
 1735:         return 0;
 1736:     return cpu_ppc_load_tbl(env);
 1737: }
 1738: #endif
 1739: 
 1740: #if defined(TARGET_SPARC)
 1741: #ifndef TARGET_SPARC64
 1742: static target_long monitor_get_psr (const struct MonitorDef *md, int val)
 1743: {
 1744:     CPUState *env = mon_get_cpu();
 1745:     if (!env)
 1746:         return 0;
 1747:     return GET_PSR(env);
 1748: }
 1749: #endif
 1750: 
 1751: static target_long monitor_get_reg(const struct MonitorDef *md, int val)
 1752: {
 1753:     CPUState *env = mon_get_cpu();
 1754:     if (!env)
 1755:         return 0;
 1756:     return env->regwptr[val];
 1757: }
 1758: #endif
 1759: 
 1760: static const MonitorDef monitor_defs[] = {
 1761: #ifdef TARGET_I386
 1762: 
 1763: #define SEG(name, seg) \
 1764:     { name, offsetof(CPUState, segs[seg].selector), NULL, MD_I32 },\
 1765:     { name ".base", offsetof(CPUState, segs[seg].base) },\
 1766:     { name ".limit", offsetof(CPUState, segs[seg].limit), NULL, MD_I32 },
 1767: 
 1768:     { "eax", offsetof(CPUState, regs[0]) },
 1769:     { "ecx", offsetof(CPUState, regs[1]) },
 1770:     { "edx", offsetof(CPUState, regs[2]) },
 1771:     { "ebx", offsetof(CPUState, regs[3]) },
 1772:     { "esp|sp", offsetof(CPUState, regs[4]) },
 1773:     { "ebp|fp", offsetof(CPUState, regs[5]) },
 1774:     { "esi", offsetof(CPUState, regs[6]) },
 1775:     { "edi", offsetof(CPUState, regs[7]) },
 1776: #ifdef TARGET_X86_64
 1777:     { "r8", offsetof(CPUState, regs[8]) },
 1778:     { "r9", offsetof(CPUState, regs[9]) },
 1779:     { "r10", offsetof(CPUState, regs[10]) },
 1780:     { "r11", offsetof(CPUState, regs[11]) },
 1781:     { "r12", offsetof(CPUState, regs[12]) },
 1782:     { "r13", offsetof(CPUState, regs[13]) },
 1783:     { "r14", offsetof(CPUState, regs[14]) },
 1784:     { "r15", offsetof(CPUState, regs[15]) },
 1785: #endif
 1786:     { "eflags", offsetof(CPUState, eflags) },
 1787:     { "eip", offsetof(CPUState, eip) },
 1788:     SEG("cs", R_CS)
 1789:     SEG("ds", R_DS)
 1790:     SEG("es", R_ES)
 1791:     SEG("ss", R_SS)
 1792:     SEG("fs", R_FS)
 1793:     SEG("gs", R_GS)
 1794:     { "pc", 0, monitor_get_pc, },
 1795: #elif defined(TARGET_PPC)
 1796:     /* General purpose registers */
 1797:     { "r0", offsetof(CPUState, gpr[0]) },
 1798:     { "r1", offsetof(CPUState, gpr[1]) },
 1799:     { "r2", offsetof(CPUState, gpr[2]) },
 1800:     { "r3", offsetof(CPUState, gpr[3]) },
 1801:     { "r4", offsetof(CPUState, gpr[4]) },
 1802:     { "r5", offsetof(CPUState, gpr[5]) },
 1803:     { "r6", offsetof(CPUState, gpr[6]) },
 1804:     { "r7", offsetof(CPUState, gpr[7]) },
 1805:     { "r8", offsetof(CPUState, gpr[8]) },
 1806:     { "r9", offsetof(CPUState, gpr[9]) },
 1807:     { "r10", offsetof(CPUState, gpr[10]) },
 1808:     { "r11", offsetof(CPUState, gpr[11]) },
 1809:     { "r12", offsetof(CPUState, gpr[12]) },
 1810:     { "r13", offsetof(CPUState, gpr[13]) },
 1811:     { "r14", offsetof(CPUState, gpr[14]) },
 1812:     { "r15", offsetof(CPUState, gpr[15]) },
 1813:     { "r16", offsetof(CPUState, gpr[16]) },
 1814:     { "r17", offsetof(CPUState, gpr[17]) },
 1815:     { "r18", offsetof(CPUState, gpr[18]) },
 1816:     { "r19", offsetof(CPUState, gpr[19]) },
 1817:     { "r20", offsetof(CPUState, gpr[20]) },
 1818:     { "r21", offsetof(CPUState, gpr[21]) },
 1819:     { "r22", offsetof(CPUState, gpr[22]) },
 1820:     { "r23", offsetof(CPUState, gpr[23]) },
 1821:     { "r24", offsetof(CPUState, gpr[24]) },
 1822:     { "r25", offsetof(CPUState, gpr[25]) },
 1823:     { "r26", offsetof(CPUState, gpr[26]) },
 1824:     { "r27", offsetof(CPUState, gpr[27]) },
 1825:     { "r28", offsetof(CPUState, gpr[28]) },
 1826:     { "r29", offsetof(CPUState, gpr[29]) },
 1827:     { "r30", offsetof(CPUState, gpr[30]) },
 1828:     { "r31", offsetof(CPUState, gpr[31]) },
 1829:     /* Floating point registers */
 1830:     { "f0", offsetof(CPUState, fpr[0]) },
 1831:     { "f1", offsetof(CPUState, fpr[1]) },
 1832:     { "f2", offsetof(CPUState, fpr[2]) },
 1833:     { "f3", offsetof(CPUState, fpr[3]) },
 1834:     { "f4", offsetof(CPUState, fpr[4]) },
 1835:     { "f5", offsetof(CPUState, fpr[5]) },
 1836:     { "f6", offsetof(CPUState, fpr[6]) },
 1837:     { "f7", offsetof(CPUState, fpr[7]) },
 1838:     { "f8", offsetof(CPUState, fpr[8]) },
 1839:     { "f9", offsetof(CPUState, fpr[9]) },
 1840:     { "f10", offsetof(CPUState, fpr[10]) },
 1841:     { "f11", offsetof(CPUState, fpr[11]) },
 1842:     { "f12", offsetof(CPUState, fpr[12]) },
 1843:     { "f13", offsetof(CPUState, fpr[13]) },
 1844:     { "f14", offsetof(CPUState, fpr[14]) },
 1845:     { "f15", offsetof(CPUState, fpr[15]) },
 1846:     { "f16", offsetof(CPUState, fpr[16]) },
 1847:     { "f17", offsetof(CPUState, fpr[17]) },
 1848:     { "f18", offsetof(CPUState, fpr[18]) },
 1849:     { "f19", offsetof(CPUState, fpr[19]) },
 1850:     { "f20", offsetof(CPUState, fpr[20]) },
 1851:     { "f21", offsetof(CPUState, fpr[21]) },
 1852:     { "f22", offsetof(CPUState, fpr[22]) },
 1853:     { "f23", offsetof(CPUState, fpr[23]) },
 1854:     { "f24", offsetof(CPUState, fpr[24]) },
 1855:     { "f25", offsetof(CPUState, fpr[25]) },
 1856:     { "f26", offsetof(CPUState, fpr[26]) },
 1857:     { "f27", offsetof(CPUState, fpr[27]) },
 1858:     { "f28", offsetof(CPUState, fpr[28]) },
 1859:     { "f29", offsetof(CPUState, fpr[29]) },
 1860:     { "f30", offsetof(CPUState, fpr[30]) },
 1861:     { "f31", offsetof(CPUState, fpr[31]) },
 1862:     { "fpscr", offsetof(CPUState, fpscr) },
 1863:     /* Next instruction pointer */
 1864:     { "nip|pc", offsetof(CPUState, nip) },
 1865:     { "lr", offsetof(CPUState, lr) },
 1866:     { "ctr", offsetof(CPUState, ctr) },
 1867:     { "decr", 0, &monitor_get_decr, },
 1868:     { "ccr", 0, &monitor_get_ccr, },
 1869:     /* Machine state register */
 1870:     { "msr", 0, &monitor_get_msr, },
 1871:     { "xer", 0, &monitor_get_xer, },
 1872:     { "tbu", 0, &monitor_get_tbu, },
 1873:     { "tbl", 0, &monitor_get_tbl, },
 1874: #if defined(TARGET_PPC64)
 1875:     /* Address space register */
 1876:     { "asr", offsetof(CPUState, asr) },
 1877: #endif
 1878:     /* Segment registers */
 1879:     { "sdr1", offsetof(CPUState, sdr1) },
 1880:     { "sr0", offsetof(CPUState, sr[0]) },
 1881:     { "sr1", offsetof(CPUState, sr[1]) },
 1882:     { "sr2", offsetof(CPUState, sr[2]) },
 1883:     { "sr3", offsetof(CPUState, sr[3]) },
 1884:     { "sr4", offsetof(CPUState, sr[4]) },
 1885:     { "sr5", offsetof(CPUState, sr[5]) },
 1886:     { "sr6", offsetof(CPUState, sr[6]) },
 1887:     { "sr7", offsetof(CPUState, sr[7]) },
 1888:     { "sr8", offsetof(CPUState, sr[8]) },
 1889:     { "sr9", offsetof(CPUState, sr[9]) },
 1890:     { "sr10", offsetof(CPUState, sr[10]) },
 1891:     { "sr11", offsetof(CPUState, sr[11]) },
 1892:     { "sr12", offsetof(CPUState, sr[12]) },
 1893:     { "sr13", offsetof(CPUState, sr[13]) },
 1894:     { "sr14", offsetof(CPUState, sr[14]) },
 1895:     { "sr15", offsetof(CPUState, sr[15]) },
 1896:     /* Too lazy to put BATs and SPRs ... */
 1897: #elif defined(TARGET_SPARC)
 1898:     { "g0", offsetof(CPUState, gregs[0]) },
 1899:     { "g1", offsetof(CPUState, gregs[1]) },
 1900:     { "g2", offsetof(CPUState, gregs[2]) },
 1901:     { "g3", offsetof(CPUState, gregs[3]) },
 1902:     { "g4", offsetof(CPUState, gregs[4]) },
 1903:     { "g5", offsetof(CPUState, gregs[5]) },
 1904:     { "g6", offsetof(CPUState, gregs[6]) },
 1905:     { "g7", offsetof(CPUState, gregs[7]) },
 1906:     { "o0", 0, monitor_get_reg },
 1907:     { "o1", 1, monitor_get_reg },
 1908:     { "o2", 2, monitor_get_reg },
 1909:     { "o3", 3, monitor_get_reg },
 1910:     { "o4", 4, monitor_get_reg },
 1911:     { "o5", 5, monitor_get_reg },
 1912:     { "o6", 6, monitor_get_reg },
 1913:     { "o7", 7, monitor_get_reg },
 1914:     { "l0", 8, monitor_get_reg },
 1915:     { "l1", 9, monitor_get_reg },
 1916:     { "l2", 10, monitor_get_reg },
 1917:     { "l3", 11, monitor_get_reg },
 1918:     { "l4", 12, monitor_get_reg },
 1919:     { "l5", 13, monitor_get_reg },
 1920:     { "l6", 14, monitor_get_reg },
 1921:     { "l7", 15, monitor_get_reg },
 1922:     { "i0", 16, monitor_get_reg },
 1923:     { "i1", 17, monitor_get_reg },
 1924:     { "i2", 18, monitor_get_reg },
 1925:     { "i3", 19, monitor_get_reg },
 1926:     { "i4", 20, monitor_get_reg },
 1927:     { "i5", 21, monitor_get_reg },
 1928:     { "i6", 22, monitor_get_reg },
 1929:     { "i7", 23, monitor_get_reg },
 1930:     { "pc", offsetof(CPUState, pc) },
 1931:     { "npc", offsetof(CPUState, npc) },
 1932:     { "y", offsetof(CPUState, y) },
 1933: #ifndef TARGET_SPARC64
 1934:     { "psr", 0, &monitor_get_psr, },
 1935:     { "wim", offsetof(CPUState, wim) },
 1936: #endif
 1937:     { "tbr", offsetof(CPUState, tbr) },
 1938:     { "fsr", offsetof(CPUState, fsr) },
 1939:     { "f0", offsetof(CPUState, fpr[0]) },
 1940:     { "f1", offsetof(CPUState, fpr[1]) },
 1941:     { "f2", offsetof(CPUState, fpr[2]) },
 1942:     { "f3", offsetof(CPUState, fpr[3]) },
 1943:     { "f4", offsetof(CPUState, fpr[4]) },
 1944:     { "f5", offsetof(CPUState, fpr[5]) },
 1945:     { "f6", offsetof(CPUState, fpr[6]) },
 1946:     { "f7", offsetof(CPUState, fpr[7]) },
 1947:     { "f8", offsetof(CPUState, fpr[8]) },
 1948:     { "f9", offsetof(CPUState, fpr[9]) },
 1949:     { "f10", offsetof(CPUState, fpr[10]) },
 1950:     { "f11", offsetof(CPUState, fpr[11]) },
 1951:     { "f12", offsetof(CPUState, fpr[12]) },
 1952:     { "f13", offsetof(CPUState, fpr[13]) },
 1953:     { "f14", offsetof(CPUState, fpr[14]) },
 1954:     { "f15", offsetof(CPUState, fpr[15]) },
 1955:     { "f16", offsetof(CPUState, fpr[16]) },
 1956:     { "f17", offsetof(CPUState, fpr[17]) },
 1957:     { "f18", offsetof(CPUState, fpr[18]) },
 1958:     { "f19", offsetof(CPUState, fpr[19]) },
 1959:     { "f20", offsetof(CPUState, fpr[20]) },
 1960:     { "f21", offsetof(CPUState, fpr[21]) },
 1961:     { "f22", offsetof(CPUState, fpr[22]) },
 1962:     { "f23", offsetof(CPUState, fpr[23]) },
 1963:     { "f24", offsetof(CPUState, fpr[24]) },
 1964:     { "f25", offsetof(CPUState, fpr[25]) },
 1965:     { "f26", offsetof(CPUState, fpr[26]) },
 1966:     { "f27", offsetof(CPUState, fpr[27]) },
 1967:     { "f28", offsetof(CPUState, fpr[28]) },
 1968:     { "f29", offsetof(CPUState, fpr[29]) },
 1969:     { "f30", offsetof(CPUState, fpr[30]) },
 1970:     { "f31", offsetof(CPUState, fpr[31]) },
 1971: #ifdef TARGET_SPARC64
 1972:     { "f32", offsetof(CPUState, fpr[32]) },
 1973:     { "f34", offsetof(CPUState, fpr[34]) },
 1974:     { "f36", offsetof(CPUState, fpr[36]) },
 1975:     { "f38", offsetof(CPUState, fpr[38]) },
 1976:     { "f40", offsetof(CPUState, fpr[40]) },
 1977:     { "f42", offsetof(CPUState, fpr[42]) },
 1978:     { "f44", offsetof(CPUState, fpr[44]) },
 1979:     { "f46", offsetof(CPUState, fpr[46]) },
 1980:     { "f48", offsetof(CPUState, fpr[48]) },
 1981:     { "f50", offsetof(CPUState, fpr[50]) },
 1982:     { "f52", offsetof(CPUState, fpr[52]) },
 1983:     { "f54", offsetof(CPUState, fpr[54]) },
 1984:     { "f56", offsetof(CPUState, fpr[56]) },
 1985:     { "f58", offsetof(CPUState, fpr[58]) },
 1986:     { "f60", offsetof(CPUState, fpr[60]) },
 1987:     { "f62", offsetof(CPUState, fpr[62]) },
 1988:     { "asi", offsetof(CPUState, asi) },
 1989:     { "pstate", offsetof(CPUState, pstate) },
 1990:     { "cansave", offsetof(CPUState, cansave) },
 1991:     { "canrestore", offsetof(CPUState, canrestore) },
 1992:     { "otherwin", offsetof(CPUState, otherwin) },
 1993:     { "wstate", offsetof(CPUState, wstate) },
 1994:     { "cleanwin", offsetof(CPUState, cleanwin) },
 1995:     { "fprs", offsetof(CPUState, fprs) },
 1996: #endif
 1997: #endif
 1998:     { NULL },
 1999: };
 2000: 
 2001: static void expr_error(const char *msg)
 2002: {
 2003:     term_printf("%s\n", msg);
 2004:     longjmp(expr_env, 1);
 2005: }
 2006: 
 2007: /* return 0 if OK, -1 if not found, -2 if no CPU defined */
 2008: static int get_monitor_def(target_long *pval, const char *name)
 2009: {
 2010:     const MonitorDef *md;
 2011:     void *ptr;
 2012: 
 2013:     for(md = monitor_defs; md->name != NULL; md++) {
 2014:         if (compare_cmd(name, md->name)) {
 2015:             if (md->get_value) {
 2016:                 *pval = md->get_value(md, md->offset);
 2017:             } else {
 2018:                 CPUState *env = mon_get_cpu();
 2019:                 if (!env)
 2020:                     return -2;
 2021:                 ptr = (uint8_t *)env + md->offset;
 2022:                 switch(md->type) {
 2023:                 case MD_I32:
 2024:                     *pval = *(int32_t *)ptr;
 2025:                     break;
 2026:                 case MD_TLONG:
 2027:                     *pval = *(target_long *)ptr;
 2028:                     break;
 2029:                 default:
 2030:                     *pval = 0;
 2031:                     break;
 2032:                 }
 2033:             }
 2034:             return 0;
 2035:         }
 2036:     }
 2037:     return -1;
 2038: }
 2039: 
 2040: static void next(void)
 2041: {
 2042:     if (pch != '\0') {
 2043:         pch++;
 2044:         while (qemu_isspace(*pch))
 2045:             pch++;
 2046:     }
 2047: }
 2048: 
 2049: static int64_t expr_sum(void);
 2050: 
 2051: static int64_t expr_unary(void)
 2052: {
 2053:     int64_t n;
 2054:     char *p;
 2055:     int ret;
 2056: 
 2057:     switch(*pch) {
 2058:     case '+':
 2059:         next();
 2060:         n = expr_unary();
 2061:         break;
 2062:     case '-':
 2063:         next();
 2064:         n = -expr_unary();
 2065:         break;
 2066:     case '~':
 2067:         next();
 2068:         n = ~expr_unary();
 2069:         break;
 2070:     case '(':
 2071:         next();
 2072:         n = expr_sum();
 2073:         if (*pch != ')') {
 2074:             expr_error("')' expected");
 2075:         }
 2076:         next();
 2077:         break;
 2078:     case '\'':
 2079:         pch++;
 2080:         if (*pch == '\0')
 2081:             expr_error("character constant expected");
 2082:         n = *pch;
 2083:         pch++;
 2084:         if (*pch != '\'')
 2085:             expr_error("missing terminating \' character");
 2086:         next();
 2087:         break;
 2088:     case '$':
 2089:         {
 2090:             char buf[128], *q;
 2091:             target_long reg=0;
 2092: 
 2093:             pch++;
 2094:             q = buf;
 2095:             while ((*pch >= 'a' && *pch <= 'z') ||
 2096:                    (*pch >= 'A' && *pch <= 'Z') ||
 2097:                    (*pch >= '0' && *pch <= '9') ||
 2098:                    *pch == '_' || *pch == '.') {
 2099:                 if ((q - buf) < sizeof(buf) - 1)
 2100:                     *q++ = *pch;
 2101:                 pch++;
 2102:             }
 2103:             while (qemu_isspace(*pch))
 2104:                 pch++;
 2105:             *q = 0;
 2106:             ret = get_monitor_def(&reg, buf);
 2107:             if (ret == -1)
 2108:                 expr_error("unknown register");
 2109:             else if (ret == -2)
 2110:                 expr_error("no cpu defined");
 2111:             n = reg;
 2112:         }
 2113:         break;
 2114:     case '\0':
 2115:         expr_error("unexpected end of expression");
 2116:         n = 0;
 2117:         break;
 2118:     default:
 2119: #if TARGET_PHYS_ADDR_BITS > 32
 2120:         n = strtoull(pch, &p, 0);
 2121: #else
 2122:         n = strtoul(pch, &p, 0);
 2123: #endif
 2124:         if (pch == p) {
 2125:             expr_error("invalid char in expression");
 2126:         }
 2127:         pch = p;
 2128:         while (qemu_isspace(*pch))
 2129:             pch++;
 2130:         break;
 2131:     }
 2132:     return n;
 2133: }
 2134: 
 2135: 
 2136: static int64_t expr_prod(void)
 2137: {
 2138:     int64_t val, val2;
 2139:     int op;
 2140: 
 2141:     val = expr_unary();
 2142:     for(;;) {
 2143:         op = *pch;
 2144:         if (op != '*' && op != '/' && op != '%')
 2145:             break;
 2146:         next();
 2147:         val2 = expr_unary();
 2148:         switch(op) {
 2149:         default:
 2150:         case '*':
 2151:             val *= val2;
 2152:             break;
 2153:         case '/':
 2154:         case '%':
 2155:             if (val2 == 0)
 2156:                 expr_error("division by zero");
 2157:             if (op == '/')
 2158:                 val /= val2;
 2159:             else
 2160:                 val %= val2;
 2161:             break;
 2162:         }
 2163:     }
 2164:     return val;
 2165: }
 2166: 
 2167: static int64_t expr_logic(void)
 2168: {
 2169:     int64_t val, val2;
 2170:     int op;
 2171: 
 2172:     val = expr_prod();
 2173:     for(;;) {
 2174:         op = *pch;
 2175:         if (op != '&' && op != '|' && op != '^')
 2176:             break;
 2177:         next();
 2178:         val2 = expr_prod();
 2179:         switch(op) {
 2180:         default:
 2181:         case '&':
 2182:             val &= val2;
 2183:             break;
 2184:         case '|':
 2185:             val |= val2;
 2186:             break;
 2187:         case '^':
 2188:             val ^= val2;
 2189:             break;
 2190:         }
 2191:     }
 2192:     return val;
 2193: }
 2194: 
 2195: static int64_t expr_sum(void)
 2196: {
 2197:     int64_t val, val2;
 2198:     int op;
 2199: 
 2200:     val = expr_logic();
 2201:     for(;;) {
 2202:         op = *pch;
 2203:         if (op != '+' && op != '-')
 2204:             break;
 2205:         next();
 2206:         val2 = expr_logic();
 2207:         if (op == '+')
 2208:             val += val2;
 2209:         else
 2210:             val -= val2;
 2211:     }
 2212:     return val;
 2213: }
 2214: 
 2215: static int get_expr(int64_t *pval, const char **pp)
 2216: {
 2217:     pch = *pp;
 2218:     if (setjmp(expr_env)) {
 2219:         *pp = pch;
 2220:         return -1;
 2221:     }
 2222:     while (qemu_isspace(*pch))
 2223:         pch++;
 2224:     *pval = expr_sum();
 2225:     *pp = pch;
 2226:     return 0;
 2227: }
 2228: 
 2229: static int get_str(char *buf, int buf_size, const char **pp)
 2230: {
 2231:     const char *p;
 2232:     char *q;
 2233:     int c;
 2234: 
 2235:     q = buf;
 2236:     p = *pp;
 2237:     while (qemu_isspace(*p))
 2238:         p++;
 2239:     if (*p == '\0') {
 2240:     fail:
 2241:         *q = '\0';
 2242:         *pp = p;
 2243:         return -1;
 2244:     }
 2245:     if (*p == '\"') {
 2246:         p++;
 2247:         while (*p != '\0' && *p != '\"') {
 2248:             if (*p == '\\') {
 2249:                 p++;
 2250:                 c = *p++;
 2251:                 switch(c) {
 2252:                 case 'n':
 2253:                     c = '\n';
 2254:                     break;
 2255:                 case 'r':
 2256:                     c = '\r';
 2257:                     break;
 2258:                 case '\\':
 2259:                 case '\'':
 2260:                 case '\"':
 2261:                     break;
 2262:                 default:
 2263:                     qemu_printf("unsupported escape code: '\\%c'\n", c);
 2264:                     goto fail;
 2265:                 }
 2266:                 if ((q - buf) < buf_size - 1) {
 2267:                     *q++ = c;
 2268:                 }
 2269:             } else {
 2270:                 if ((q - buf) < buf_size - 1) {
 2271:                     *q++ = *p;
 2272:                 }
 2273:                 p++;
 2274:             }
 2275:         }
 2276:         if (*p != '\"') {
 2277:             qemu_printf("unterminated string\n");
 2278:             goto fail;
 2279:         }
 2280:         p++;
 2281:     } else {
 2282:         while (*p != '\0' && !qemu_isspace(*p)) {
 2283:             if ((q - buf) < buf_size - 1) {
 2284:                 *q++ = *p;
 2285:             }
 2286:             p++;
 2287:         }
 2288:     }
 2289:     *q = '\0';
 2290:     *pp = p;
 2291:     return 0;
 2292: }
 2293: 
 2294: static int default_fmt_format = 'x';
 2295: static int default_fmt_size = 4;
 2296: 
 2297: #define MAX_ARGS 16
 2298: 
 2299: static void monitor_handle_command(const char *cmdline)
 2300: {
 2301:     const char *p, *pstart, *typestr;
 2302:     char *q;
 2303:     int c, nb_args, len, i, has_arg;
 2304:     const term_cmd_t *cmd;
 2305:     char cmdname[256];
 2306:     char buf[1024];
 2307:     void *str_allocated[MAX_ARGS];
 2308:     void *args[MAX_ARGS];
 2309:     void (*handler_0)(void);
 2310:     void (*handler_1)(void *arg0);
 2311:     void (*handler_2)(void *arg0, void *arg1);
 2312:     void (*handler_3)(void *arg0, void *arg1, void *arg2);
 2313:     void (*handler_4)(void *arg0, void *arg1, void *arg2, void *arg3);
 2314:     void (*handler_5)(void *arg0, void *arg1, void *arg2, void *arg3,
 2315:                       void *arg4);
 2316:     void (*handler_6)(void *arg0, void *arg1, void *arg2, void *arg3,
 2317:                       void *arg4, void *arg5);
 2318:     void (*handler_7)(void *arg0, void *arg1, void *arg2, void *arg3,
 2319:                       void *arg4, void *arg5, void *arg6);
 2320: 
 2321: #ifdef DEBUG
 2322:     term_printf("command='%s'\n", cmdline);
 2323: #endif
 2324: 
 2325:     /* extract the command name */
 2326:     p = cmdline;
 2327:     q = cmdname;
 2328:     while (qemu_isspace(*p))
 2329:         p++;
 2330:     if (*p == '\0')
 2331:         return;
 2332:     pstart = p;
 2333:     while (*p != '\0' && *p != '/' && !qemu_isspace(*p))
 2334:         p++;
 2335:     len = p - pstart;
 2336:     if (len > sizeof(cmdname) - 1)
 2337:         len = sizeof(cmdname) - 1;
 2338:     memcpy(cmdname, pstart, len);
 2339:     cmdname[len] = '\0';
 2340: 
 2341:     /* find the command */
 2342:     for(cmd = term_cmds; cmd->name != NULL; cmd++) {
 2343:         if (compare_cmd(cmdname, cmd->name))
 2344:             goto found;
 2345:     }
 2346:     term_printf("unknown command: '%s'\n", cmdname);
 2347:     return;
 2348:  found:
 2349: 
 2350:     for(i = 0; i < MAX_ARGS; i++)
 2351:         str_allocated[i] = NULL;
 2352: 
 2353:     /* parse the parameters */
 2354:     typestr = cmd->args_type;
 2355:     nb_args = 0;
 2356:     for(;;) {
 2357:         c = *typestr;
 2358:         if (c == '\0')
 2359:             break;
 2360:         typestr++;
 2361:         switch(c) {
 2362:         case 'F':
 2363:         case 'B':
 2364:         case 's':
 2365:             {
 2366:                 int ret;
 2367:                 char *str;
 2368: 
 2369:                 while (qemu_isspace(*p))
 2370:                     p++;
 2371:                 if (*typestr == '?') {
 2372:                     typestr++;
 2373:                     if (*p == '\0') {
 2374:                         /* no optional string: NULL argument */
 2375:                         str = NULL;
 2376:                         goto add_str;
 2377:                     }
 2378:                 }
 2379:                 ret = get_str(buf, sizeof(buf), &p);
 2380:                 if (ret < 0) {
 2381:                     switch(c) {
 2382:                     case 'F':
 2383:                         term_printf("%s: filename expected\n", cmdname);
 2384:                         break;
 2385:                     case 'B':
 2386:                         term_printf("%s: block device name expected\n", cmdname);
 2387:                         break;
 2388:                     default:
 2389:                         term_printf("%s: string expected\n", cmdname);
 2390:                         break;
 2391:                     }
 2392:                     goto fail;
 2393:                 }
 2394:                 str = qemu_malloc(strlen(buf) + 1);
 2395:                 pstrcpy(str, sizeof(buf), buf);
 2396:                 str_allocated[nb_args] = str;
 2397:             add_str:
 2398:                 if (nb_args >= MAX_ARGS) {
 2399:                 error_args:
 2400:                     term_printf("%s: too many arguments\n", cmdname);
 2401:                     goto fail;
 2402:                 }
 2403:                 args[nb_args++] = str;
 2404:             }
 2405:             break;
 2406:         case '/':
 2407:             {
 2408:                 int count, format, size;
 2409: 
 2410:                 while (qemu_isspace(*p))
 2411:                     p++;
 2412:                 if (*p == '/') {
 2413:                     /* format found */
 2414:                     p++;
 2415:                     count = 1;
 2416:                     if (qemu_isdigit(*p)) {
 2417:                         count = 0;
 2418:                         while (qemu_isdigit(*p)) {
 2419:                             count = count * 10 + (*p - '0');
 2420:                             p++;
 2421:                         }
 2422:                     }
 2423:                     size = -1;
 2424:                     format = -1;
 2425:                     for(;;) {
 2426:                         switch(*p) {
 2427:                         case 'o':
 2428:                         case 'd':
 2429:                         case 'u':
 2430:                         case 'x':
 2431:                         case 'i':
 2432:                         case 'c':
 2433:                             format = *p++;
 2434:                             break;
 2435:                         case 'b':
 2436:                             size = 1;
 2437:                             p++;
 2438:                             break;
 2439:                         case 'h':
 2440:                             size = 2;
 2441:                             p++;
 2442:                             break;
 2443:                         case 'w':
 2444:                             size = 4;
 2445:                             p++;
 2446:                             break;
 2447:                         case 'g':
 2448:                         case 'L':
 2449:                             size = 8;
 2450:                             p++;
 2451:                             break;
 2452:                         default:
 2453:                             goto next;
 2454:                         }
 2455:                     }
 2456:                 next:
 2457:                     if (*p != '\0' && !qemu_isspace(*p)) {
 2458:                         term_printf("invalid char in format: '%c'\n", *p);
 2459:                         goto fail;
 2460:                     }
 2461:                     if (format < 0)
 2462:                         format = default_fmt_format;
 2463:                     if (format != 'i') {
 2464:                         /* for 'i', not specifying a size gives -1 as size */
 2465:                         if (size < 0)
 2466:                             size = default_fmt_size;
 2467:                         default_fmt_size = size;
 2468:                     }
 2469:                     default_fmt_format = format;
 2470:                 } else {
 2471:                     count = 1;
 2472:                     format = default_fmt_format;
 2473:                     if (format != 'i') {
 2474:                         size = default_fmt_size;
 2475:                     } else {
 2476:                         size = -1;
 2477:                     }
 2478:                 }
 2479:                 if (nb_args + 3 > MAX_ARGS)
 2480:                     goto error_args;
 2481:                 args[nb_args++] = (void*)(long)count;
 2482:                 args[nb_args++] = (void*)(long)format;
 2483:                 args[nb_args++] = (void*)(long)size;
 2484:             }
 2485:             break;
 2486:         case 'i':
 2487:         case 'l':
 2488:             {
 2489:                 int64_t val;
 2490: 
 2491:                 while (qemu_isspace(*p))
 2492:                     p++;
 2493:                 if (*typestr == '?' || *typestr == '.') {
 2494:                     if (*typestr == '?') {
 2495:                         if (*p == '\0')
 2496:                             has_arg = 0;
 2497:                         else
 2498:                             has_arg = 1;
 2499:                     } else {
 2500:                         if (*p == '.') {
 2501:                             p++;
 2502:                             while (qemu_isspace(*p))
 2503:                                 p++;
 2504:                             has_arg = 1;
 2505:                         } else {
 2506:                             has_arg = 0;
 2507:                         }
 2508:                     }
 2509:                     typestr++;
 2510:                     if (nb_args >= MAX_ARGS)
 2511:                         goto error_args;
 2512:                     args[nb_args++] = (void *)(long)has_arg;
 2513:                     if (!has_arg) {
 2514:                         if (nb_args >= MAX_ARGS)
 2515:                             goto error_args;
 2516:                         val = -1;
 2517:                         goto add_num;
 2518:                     }
 2519:                 }
 2520:                 if (get_expr(&val, &p))
 2521:                     goto fail;
 2522:             add_num:
 2523:                 if (c == 'i') {
 2524:                     if (nb_args >= MAX_ARGS)
 2525:                         goto error_args;
 2526:                     args[nb_args++] = (void *)(long)val;
 2527:                 } else {
 2528:                     if ((nb_args + 1) >= MAX_ARGS)
 2529:                         goto error_args;
 2530: #if TARGET_PHYS_ADDR_BITS > 32
 2531:                     args[nb_args++] = (void *)(long)((val >> 32) & 0xffffffff);
 2532: #else
 2533:                     args[nb_args++] = (void *)0;
 2534: #endif
 2535:                     args[nb_args++] = (void *)(long)(val & 0xffffffff);
 2536:                 }
 2537:             }
 2538:             break;
 2539:         case '-':
 2540:             {
 2541:                 int has_option;
 2542:                 /* option */
 2543: 
 2544:                 c = *typestr++;
 2545:                 if (c == '\0')
 2546:                     goto bad_type;
 2547:                 while (qemu_isspace(*p))
 2548:                     p++;
 2549:                 has_option = 0;
 2550:                 if (*p == '-') {
 2551:                     p++;
 2552:                     if (*p != c) {
 2553:                         term_printf("%s: unsupported option -%c\n",
 2554:                                     cmdname, *p);
 2555:                         goto fail;
 2556:                     }
 2557:                     p++;
 2558:                     has_option = 1;
 2559:                 }
 2560:                 if (nb_args >= MAX_ARGS)
 2561:                     goto error_args;
 2562:                 args[nb_args++] = (void *)(long)has_option;
 2563:             }
 2564:             break;
 2565:         default:
 2566:         bad_type:
 2567:             term_printf("%s: unknown type '%c'\n", cmdname, c);
 2568:             goto fail;
 2569:         }
 2570:     }
 2571:     /* check that all arguments were parsed */
 2572:     while (qemu_isspace(*p))
 2573:         p++;
 2574:     if (*p != '\0') {
 2575:         term_printf("%s: extraneous characters at the end of line\n",
 2576:                     cmdname);
 2577:         goto fail;
 2578:     }
 2579: 
 2580:     switch(nb_args) {
 2581:     case 0:
 2582:         handler_0 = cmd->handler;
 2583:         handler_0();
 2584:         break;
 2585:     case 1:
 2586:         handler_1 = cmd->handler;
 2587:         handler_1(args[0]);
 2588:         break;
 2589:     case 2:
 2590:         handler_2 = cmd->handler;
 2591:         handler_2(args[0], args[1]);
 2592:         break;
 2593:     case 3:
 2594:         handler_3 = cmd->handler;
 2595:         handler_3(args[0], args[1], args[2]);
 2596:         break;
 2597:     case 4:
 2598:         handler_4 = cmd->handler;
 2599:         handler_4(args[0], args[1], args[2], args[3]);
 2600:         break;
 2601:     case 5:
 2602:         handler_5 = cmd->handler;
 2603:         handler_5(args[0], args[1], args[2], args[3], args[4]);
 2604:         break;
 2605:     case 6:
 2606:         handler_6 = cmd->handler;
 2607:         handler_6(args[0], args[1], args[2], args[3], args[4], args[5]);
 2608:         break;
 2609:     case 7:
 2610:         handler_7 = cmd->handler;
 2611:         handler_7(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
 2612:         break;
 2613:     default:
 2614:         term_printf("unsupported number of arguments: %d\n", nb_args);
 2615:         goto fail;
 2616:     }
 2617:  fail:
 2618:     for(i = 0; i < MAX_ARGS; i++)
 2619:         qemu_free(str_allocated[i]);
 2620:     return;
 2621: }
 2622: 
 2623: static void cmd_completion(const char *name, const char *list)
 2624: {
 2625:     const char *p, *pstart;
 2626:     char cmd[128];
 2627:     int len;
 2628: 
 2629:     p = list;
 2630:     for(;;) {
 2631:         pstart = p;
 2632:         p = strchr(p, '|');
 2633:         if (!p)
 2634:             p = pstart + strlen(pstart);
 2635:         len = p - pstart;
 2636:         if (len > sizeof(cmd) - 2)
 2637:             len = sizeof(cmd) - 2;
 2638:         memcpy(cmd, pstart, len);
 2639:         cmd[len] = '\0';
 2640:         if (name[0] == '\0' || !strncmp(name, cmd, strlen(name))) {
 2641:             add_completion(cmd);
 2642:         }
 2643:         if (*p == '\0')
 2644:             break;
 2645:         p++;
 2646:     }
 2647: }
 2648: 
 2649: static void file_completion(const char *input)
 2650: {
 2651:     DIR *ffs;
 2652:     struct dirent *d;
 2653:     char path[1024];
 2654:     char file[1024], file_prefix[1024];
 2655:     int input_path_len;
 2656:     const char *p;
 2657: 
 2658:     p = strrchr(input, '/');
 2659:     if (!p) {
 2660:         input_path_len = 0;
 2661:         pstrcpy(file_prefix, sizeof(file_prefix), input);
 2662:         pstrcpy(path, sizeof(path), ".");
 2663:     } else {
 2664:         input_path_len = p - input + 1;
 2665:         memcpy(path, input, input_path_len);
 2666:         if (input_path_len > sizeof(path) - 1)
 2667:             input_path_len = sizeof(path) - 1;
 2668:         path[input_path_len] = '\0';
 2669:         pstrcpy(file_prefix, sizeof(file_prefix), p + 1);
 2670:     }
 2671: #ifdef DEBUG_COMPLETION
 2672:     term_printf("input='%s' path='%s' prefix='%s'\n", input, path, file_prefix);
 2673: #endif
 2674:     ffs = opendir(path);
 2675:     if (!ffs)
 2676:         return;
 2677:     for(;;) {
 2678:         struct stat sb;
 2679:         d = readdir(ffs);
 2680:         if (!d)
 2681:             break;
 2682:         if (strstart(d->d_name, file_prefix, NULL)) {
 2683:             memcpy(file, input, input_path_len);
 2684:             if (input_path_len < sizeof(file))
 2685:                 pstrcpy(file + input_path_len, sizeof(file) - input_path_len,
 2686:                         d->d_name);
 2687:             /* stat the file to find out if it's a directory.
 2688:              * In that case add a slash to speed up typing long paths
 2689:              */
 2690:             stat(file, &sb);
 2691:             if(S_ISDIR(sb.st_mode))
 2692:                 pstrcat(file, sizeof(file), "/");
 2693:             add_completion(file);
 2694:         }
 2695:     }
 2696:     closedir(ffs);
 2697: }
 2698: 
 2699: static void block_completion_it(void *opaque, BlockDriverState *bs)
 2700: {
 2701:     const char *name = bdrv_get_device_name(bs);
 2702:     const char *input = opaque;
 2703: 
 2704:     if (input[0] == '\0' ||
 2705:         !strncmp(name, (char *)input, strlen(input))) {
 2706:         add_completion(name);
 2707:     }
 2708: }
 2709: 
 2710: /* NOTE: this parser is an approximate form of the real command parser */
 2711: static void parse_cmdline(const char *cmdline,
 2712:                          int *pnb_args, char **args)
 2713: {
 2714:     const char *p;
 2715:     int nb_args, ret;
 2716:     char buf[1024];
 2717: 
 2718:     p = cmdline;
 2719:     nb_args = 0;
 2720:     for(;;) {
 2721:         while (qemu_isspace(*p))
 2722:             p++;
 2723:         if (*p == '\0')
 2724:             break;
 2725:         if (nb_args >= MAX_ARGS)
 2726:             break;
 2727:         ret = get_str(buf, sizeof(buf), &p);
 2728:         args[nb_args] = qemu_strdup(buf);
 2729:         nb_args++;
 2730:         if (ret < 0)
 2731:             break;
 2732:     }
 2733:     *pnb_args = nb_args;
 2734: }
 2735: 
 2736: void readline_find_completion(const char *cmdline)
 2737: {
 2738:     const char *cmdname;
 2739:     char *args[MAX_ARGS];
 2740:     int nb_args, i, len;
 2741:     const char *ptype, *str;
 2742:     const term_cmd_t *cmd;
 2743:     const KeyDef *key;
 2744: 
 2745:     parse_cmdline(cmdline, &nb_args, args);
 2746: #ifdef DEBUG_COMPLETION
 2747:     for(i = 0; i < nb_args; i++) {
 2748:         term_printf("arg%d = '%s'\n", i, (char *)args[i]);
 2749:     }
 2750: #endif
 2751: 
 2752:     /* if the line ends with a space, it means we want to complete the
 2753:        next arg */
 2754:     len = strlen(cmdline);
 2755:     if (len > 0 && qemu_isspace(cmdline[len - 1])) {
 2756:         if (nb_args >= MAX_ARGS)
 2757:             return;
 2758:         args[nb_args++] = qemu_strdup("");
 2759:     }
 2760:     if (nb_args <= 1) {
 2761:         /* command completion */
 2762:         if (nb_args == 0)
 2763:             cmdname = "";
 2764:         else
 2765:             cmdname = args[0];
 2766:         completion_index = strlen(cmdname);
 2767:         for(cmd = term_cmds; cmd->name != NULL; cmd++) {
 2768:             cmd_completion(cmdname, cmd->name);
 2769:         }
 2770:     } else {
 2771:         /* find the command */
 2772:         for(cmd = term_cmds; cmd->name != NULL; cmd++) {
 2773:             if (compare_cmd(args[0], cmd->name))
 2774:                 goto found;
 2775:         }
 2776:         return;
 2777:     found:
 2778:         ptype = cmd->args_type;
 2779:         for(i = 0; i < nb_args - 2; i++) {
 2780:             if (*ptype != '\0') {
 2781:                 ptype++;
 2782:                 while (*ptype == '?')
 2783:                     ptype++;
 2784:             }
 2785:         }
 2786:         str = args[nb_args - 1];
 2787:         switch(*ptype) {
 2788:         case 'F':
 2789:             /* file completion */
 2790:             completion_index = strlen(str);
 2791:             file_completion(str);
 2792:             break;
 2793:         case 'B':
 2794:             /* block device name completion */
 2795:             completion_index = strlen(str);
 2796:             bdrv_iterate(block_completion_it, (void *)str);
 2797:             break;
 2798:         case 's':
 2799:             /* XXX: more generic ? */
 2800:             if (!strcmp(cmd->name, "info")) {
 2801:                 completion_index = strlen(str);
 2802:                 for(cmd = info_cmds; cmd->name != NULL; cmd++) {
 2803:                     cmd_completion(str, cmd->name);
 2804:                 }
 2805:             } else if (!strcmp(cmd->name, "sendkey")) {
 2806:                 completion_index = strlen(str);
 2807:                 for(key = key_defs; key->name != NULL; key++) {
 2808:                     cmd_completion(str, key->name);
 2809:                 }
 2810:             }
 2811:             break;
 2812:         default:
 2813:             break;
 2814:         }
 2815:     }
 2816:     for(i = 0; i < nb_args; i++)
 2817:         qemu_free(args[i]);
 2818: }
 2819: 
 2820: static int term_can_read(void *opaque)
 2821: {
 2822:     return 128;
 2823: }
 2824: 
 2825: static void term_read(void *opaque, const uint8_t *buf, int size)
 2826: {
 2827:     int i;
 2828:     for(i = 0; i < size; i++)
 2829:         readline_handle_byte(buf[i]);
 2830: }
 2831: 
 2832: static int monitor_suspended;
 2833: 
 2834: static void monitor_handle_command1(void *opaque, const char *cmdline)
 2835: {
 2836:     monitor_handle_command(cmdline);
 2837:     if (!monitor_suspended)
 2838:         monitor_start_input();
 2839:     else
 2840:         monitor_suspended = 2;
 2841: }
 2842: 
 2843: void monitor_suspend(void)
 2844: {
 2845:     monitor_suspended = 1;
 2846: }
 2847: 
 2848: void monitor_resume(void)
 2849: {
 2850:     if (monitor_suspended == 2)
 2851:         monitor_start_input();
 2852:     monitor_suspended = 0;
 2853: }
 2854: 
 2855: static void monitor_start_input(void)
 2856: {
 2857:     readline_start("(qemu) ", 0, monitor_handle_command1, NULL);
 2858: }
 2859: 
 2860: static void term_event(void *opaque, int event)
 2861: {
 2862:     if (event != CHR_EVENT_RESET)
 2863: 	return;
 2864: 
 2865:     if (!hide_banner)
 2866: 	    term_printf("QEMU %s monitor - type 'help' for more information\n",
 2867: 			QEMU_VERSION);
 2868:     monitor_start_input();
 2869: }
 2870: 
 2871: static int is_first_init = 1;
 2872: 
 2873: void monitor_init(CharDriverState *hd, int show_banner)
 2874: {
 2875:     int i;
 2876: 
 2877:     if (is_first_init) {
 2878:         key_timer = qemu_new_timer(vm_clock, release_keys, NULL);
 2879:         if (!key_timer)
 2880:             return;
 2881:         for (i = 0; i < MAX_MON; i++) {
 2882:             monitor_hd[i] = NULL;
 2883:         }
 2884:         is_first_init = 0;
 2885:     }
 2886:     for (i = 0; i < MAX_MON; i++) {
 2887:         if (monitor_hd[i] == NULL) {
 2888:             monitor_hd[i] = hd;
 2889:             break;
 2890:         }
 2891:     }
 2892: 
 2893:     hide_banner = !show_banner;
 2894: 
 2895:     qemu_chr_add_handlers(hd, term_can_read, term_read, term_event, NULL);
 2896: 
 2897:     readline_start("", 0, monitor_handle_command1, NULL);
 2898: }
 2899: 
 2900: /* XXX: use threads ? */
 2901: /* modal monitor readline */
 2902: static int monitor_readline_started;
 2903: static char *monitor_readline_buf;
 2904: static int monitor_readline_buf_size;
 2905: 
 2906: static void monitor_readline_cb(void *opaque, const char *input)
 2907: {
 2908:     pstrcpy(monitor_readline_buf, monitor_readline_buf_size, input);
 2909:     monitor_readline_started = 0;
 2910: }
 2911: 
 2912: static void monitor_readline(const char *prompt, int is_password,
 2913:                              char *buf, int buf_size)
 2914: {
 2915:     int i;
 2916:     int old_focus[MAX_MON];
 2917: 
 2918:     if (is_password) {
 2919:         for (i = 0; i < MAX_MON; i++) {
 2920:             old_focus[i] = 0;
 2921:             if (monitor_hd[i]) {
 2922:                 old_focus[i] = monitor_hd[i]->focus;
 2923:                 monitor_hd[i]->focus = 0;
 2924:                 qemu_chr_send_event(monitor_hd[i], CHR_EVENT_FOCUS);
 2925:             }
 2926:         }
 2927:     }
 2928: 
 2929:     readline_start(prompt, is_password, monitor_readline_cb, NULL);
 2930:     monitor_readline_buf = buf;
 2931:     monitor_readline_buf_size = buf_size;
 2932:     monitor_readline_started = 1;
 2933:     while (monitor_readline_started) {
 2934:         main_loop_wait(10);
 2935:     }
 2936:     /* restore original focus */
 2937:     if (is_password) {
 2938:         for (i = 0; i < MAX_MON; i++)
 2939:             if (old_focus[i])
 2940:                 monitor_hd[i]->focus = old_focus[i];
 2941:     }
 2942: }
 2943: 
 2944: int monitor_read_bdrv_key(BlockDriverState *bs)
 2945: {
 2946:     char password[256];
 2947:     int i;
 2948: 
 2949:     if (!bdrv_is_encrypted(bs))
 2950:         return 0;
 2951: 
 2952:     term_printf("%s (%s) is encrypted.\n", bdrv_get_device_name(bs),
 2953:                 bdrv_get_encrypted_filename(bs));
 2954:     for(i = 0; i < 3; i++) {
 2955:         monitor_readline("Password: ", 1, password, sizeof(password));
 2956:         if (bdrv_set_key(bs, password) == 0)
 2957:             return 0;
 2958:         term_printf("invalid password\n");
 2959:     }
 2960:     return -EPERM;
 2961: }

unix.superglobalmegacorp.com