Annotation of qemu/monitor.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com