monitor.c 90.8 KB
Newer Older
B
bellard 已提交
1 2
/*
 * QEMU monitor
3
 *
B
bellard 已提交
4
 * Copyright (c) 2003-2004 Fabrice Bellard
5
 *
B
bellard 已提交
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
24
#include <dirent.h>
P
pbrook 已提交
25
#include "hw/hw.h"
26
#include "hw/qdev.h"
P
pbrook 已提交
27 28 29 30
#include "hw/usb.h"
#include "hw/pcmcia.h"
#include "hw/pc.h"
#include "hw/pci.h"
R
Richard W.M. Jones 已提交
31
#include "hw/watchdog.h"
32
#include "hw/loader.h"
P
pbrook 已提交
33 34 35 36
#include "gdbstub.h"
#include "net.h"
#include "qemu-char.h"
#include "sysemu.h"
A
aliguori 已提交
37 38
#include "monitor.h"
#include "readline.h"
P
pbrook 已提交
39 40 41
#include "console.h"
#include "block.h"
#include "audio/audio.h"
42
#include "disas.h"
A
aliguori 已提交
43
#include "balloon.h"
44
#include "qemu-timer.h"
A
aliguori 已提交
45
#include "migration.h"
A
aliguori 已提交
46
#include "kvm.h"
47
#include "acl.h"
48 49 50
#include "qint.h"
#include "qdict.h"
#include "qstring.h"
T
ths 已提交
51

B
bellard 已提交
52
//#define DEBUG
B
bellard 已提交
53
//#define DEBUG_COMPLETION
B
bellard 已提交
54

55 56
/*
 * Supported types:
57
 *
58
 * 'F'          filename
B
bellard 已提交
59
 * 'B'          block device name
60
 * 's'          string (accept optional quote)
B
bellard 已提交
61 62
 * 'i'          32 bit integer
 * 'l'          target long (32 or 64 bit)
63 64
 * '/'          optional gdb-like print format (like "/10x")
 *
65 66 67
 * '?'          optional type (for all types, except '/')
 * '.'          other form of optional type (for 'i' and 'l')
 * '-'          optional parameter (eg. '-f')
68 69 70
 *
 */

A
Anthony Liguori 已提交
71
typedef struct mon_cmd_t {
B
bellard 已提交
72
    const char *name;
73
    const char *args_type;
B
bellard 已提交
74 75
    const char *params;
    const char *help;
L
Luiz Capitulino 已提交
76 77
    union {
        void (*info)(Monitor *mon);
78
        void (*cmd)(Monitor *mon, const QDict *qdict);
L
Luiz Capitulino 已提交
79
    } mhandler;
A
Anthony Liguori 已提交
80
} mon_cmd_t;
B
bellard 已提交
81

82
/* file descriptors passed via SCM_RIGHTS */
A
Anthony Liguori 已提交
83 84
typedef struct mon_fd_t mon_fd_t;
struct mon_fd_t {
85 86
    char *name;
    int fd;
A
Anthony Liguori 已提交
87
    QLIST_ENTRY(mon_fd_t) next;
88 89
};

90 91
struct Monitor {
    CharDriverState *chr;
G
Gerd Hoffmann 已提交
92 93
    int mux_out;
    int reset_seen;
94 95 96 97 98 99 100 101
    int flags;
    int suspend_cnt;
    uint8_t outbuf[1024];
    int outbuf_index;
    ReadLineState *rs;
    CPUState *mon_cpu;
    BlockDriverCompletionFunc *password_completion_cb;
    void *password_opaque;
A
Anthony Liguori 已提交
102
    QLIST_HEAD(,mon_fd_t) fds;
B
Blue Swirl 已提交
103
    QLIST_ENTRY(Monitor) entry;
104 105
};

B
Blue Swirl 已提交
106
static QLIST_HEAD(mon_list, Monitor) mon_list;
107

A
Anthony Liguori 已提交
108 109
static const mon_cmd_t mon_cmds[];
static const mon_cmd_t info_cmds[];
B
bellard 已提交
110

111
Monitor *cur_mon = NULL;
A
aliguori 已提交
112

113 114
static void monitor_command_cb(Monitor *mon, const char *cmdline,
                               void *opaque);
115

116 117 118 119 120 121
static void monitor_read_command(Monitor *mon, int show_prompt)
{
    readline_start(mon->rs, "(qemu) ", 0, monitor_command_cb, NULL);
    if (show_prompt)
        readline_show_prompt(mon->rs);
}
B
bellard 已提交
122

123 124
static int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
                                 void *opaque)
125
{
126 127 128 129 130 131 132 133
    if (mon->rs) {
        readline_start(mon->rs, "Password: ", 1, readline_func, opaque);
        /* prompt is printed on return from the command handler */
        return 0;
    } else {
        monitor_printf(mon, "terminal does not support password prompting\n");
        return -ENOTTY;
    }
134 135
}

A
aliguori 已提交
136
void monitor_flush(Monitor *mon)
137
{
G
Gerd Hoffmann 已提交
138
    if (mon && mon->outbuf_index != 0 && !mon->mux_out) {
139 140
        qemu_chr_write(mon->chr, mon->outbuf, mon->outbuf_index);
        mon->outbuf_index = 0;
141 142 143 144
    }
}

/* flush at every end of line or if the buffer is full */
A
aliguori 已提交
145
static void monitor_puts(Monitor *mon, const char *str)
146
{
T
ths 已提交
147
    char c;
148 149 150 151

    if (!mon)
        return;

152 153 154 155
    for(;;) {
        c = *str++;
        if (c == '\0')
            break;
B
bellard 已提交
156
        if (c == '\n')
157 158 159 160
            mon->outbuf[mon->outbuf_index++] = '\r';
        mon->outbuf[mon->outbuf_index++] = c;
        if (mon->outbuf_index >= (sizeof(mon->outbuf) - 1)
            || c == '\n')
A
aliguori 已提交
161
            monitor_flush(mon);
162 163 164
    }
}

A
aliguori 已提交
165
void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
B
bellard 已提交
166
{
B
bellard 已提交
167 168
    char buf[4096];
    vsnprintf(buf, sizeof(buf), fmt, ap);
A
aliguori 已提交
169
    monitor_puts(mon, buf);
B
bellard 已提交
170 171
}

A
aliguori 已提交
172
void monitor_printf(Monitor *mon, const char *fmt, ...)
B
bellard 已提交
173
{
174 175
    va_list ap;
    va_start(ap, fmt);
A
aliguori 已提交
176
    monitor_vprintf(mon, fmt, ap);
177
    va_end(ap);
B
bellard 已提交
178 179
}

A
aliguori 已提交
180
void monitor_print_filename(Monitor *mon, const char *filename)
181 182 183 184
{
    int i;

    for (i = 0; filename[i]; i++) {
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
        switch (filename[i]) {
        case ' ':
        case '"':
        case '\\':
            monitor_printf(mon, "\\%c", filename[i]);
            break;
        case '\t':
            monitor_printf(mon, "\\t");
            break;
        case '\r':
            monitor_printf(mon, "\\r");
            break;
        case '\n':
            monitor_printf(mon, "\\n");
            break;
        default:
            monitor_printf(mon, "%c", filename[i]);
            break;
        }
204 205 206
    }
}

B
bellard 已提交
207 208 209 210
static int monitor_fprintf(FILE *stream, const char *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
A
aliguori 已提交
211
    monitor_vprintf((Monitor *)stream, fmt, ap);
B
bellard 已提交
212 213 214 215
    va_end(ap);
    return 0;
}

B
bellard 已提交
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
static int compare_cmd(const char *name, const char *list)
{
    const char *p, *pstart;
    int len;
    len = strlen(name);
    p = list;
    for(;;) {
        pstart = p;
        p = strchr(p, '|');
        if (!p)
            p = pstart + strlen(pstart);
        if ((p - pstart) == len && !memcmp(pstart, name, len))
            return 1;
        if (*p == '\0')
            break;
        p++;
    }
    return 0;
}

A
Anthony Liguori 已提交
236
static void help_cmd_dump(Monitor *mon, const mon_cmd_t *cmds,
A
aliguori 已提交
237
                          const char *prefix, const char *name)
B
bellard 已提交
238
{
A
Anthony Liguori 已提交
239
    const mon_cmd_t *cmd;
B
bellard 已提交
240 241 242

    for(cmd = cmds; cmd->name != NULL; cmd++) {
        if (!name || !strcmp(name, cmd->name))
A
aliguori 已提交
243 244
            monitor_printf(mon, "%s%s %s -- %s\n", prefix, cmd->name,
                           cmd->params, cmd->help);
B
bellard 已提交
245 246 247
    }
}

A
aliguori 已提交
248
static void help_cmd(Monitor *mon, const char *name)
B
bellard 已提交
249 250
{
    if (name && !strcmp(name, "info")) {
A
aliguori 已提交
251
        help_cmd_dump(mon, info_cmds, "info ", NULL);
B
bellard 已提交
252
    } else {
A
aliguori 已提交
253
        help_cmd_dump(mon, mon_cmds, "", name);
254
        if (name && !strcmp(name, "log")) {
B
blueswir1 已提交
255
            const CPULogItem *item;
A
aliguori 已提交
256 257
            monitor_printf(mon, "Log items (comma separated):\n");
            monitor_printf(mon, "%-10s %s\n", "none", "remove all logs");
258
            for(item = cpu_log_items; item->mask != 0; item++) {
A
aliguori 已提交
259
                monitor_printf(mon, "%-10s %s\n", item->name, item->help);
260 261
            }
        }
B
bellard 已提交
262 263 264
    }
}

265
static void do_help_cmd(Monitor *mon, const QDict *qdict)
266
{
267
    help_cmd(mon, qdict_get_try_str(qdict, "name"));
268 269
}

270
static void do_commit(Monitor *mon, const QDict *qdict)
B
bellard 已提交
271
{
G
Gerd Hoffmann 已提交
272 273
    int all_devices;
    DriveInfo *dinfo;
274
    const char *device = qdict_get_str(qdict, "device");
275

B
bellard 已提交
276
    all_devices = !strcmp(device, "all");
B
Blue Swirl 已提交
277
    QTAILQ_FOREACH(dinfo, &drives, next) {
G
Gerd Hoffmann 已提交
278
        if (!all_devices)
L
Luiz Capitulino 已提交
279
            if (strcmp(bdrv_get_device_name(dinfo->bdrv), device))
G
Gerd Hoffmann 已提交
280 281
                continue;
        bdrv_commit(dinfo->bdrv);
B
bellard 已提交
282 283 284
    }
}

285
static void do_info(Monitor *mon, const QDict *qdict)
B
bellard 已提交
286
{
A
Anthony Liguori 已提交
287
    const mon_cmd_t *cmd;
288
    const char *item = qdict_get_try_str(qdict, "item");
B
bellard 已提交
289

290
    if (!item)
B
bellard 已提交
291 292
        goto help;
    for(cmd = info_cmds; cmd->name != NULL; cmd++) {
293
        if (compare_cmd(item, cmd->name))
B
bellard 已提交
294 295 296
            goto found;
    }
 help:
A
aliguori 已提交
297
    help_cmd(mon, "info");
B
bellard 已提交
298 299
    return;
 found:
L
Luiz Capitulino 已提交
300
    cmd->mhandler.info(mon);
B
bellard 已提交
301 302
}

A
aliguori 已提交
303
static void do_info_version(Monitor *mon)
B
bellard 已提交
304
{
P
pbrook 已提交
305
    monitor_printf(mon, "%s\n", QEMU_VERSION QEMU_PKGVERSION);
B
bellard 已提交
306 307
}

A
aliguori 已提交
308
static void do_info_name(Monitor *mon)
T
ths 已提交
309 310
{
    if (qemu_name)
A
aliguori 已提交
311
        monitor_printf(mon, "%s\n", qemu_name);
T
ths 已提交
312 313
}

A
aurel32 已提交
314
#if defined(TARGET_I386)
A
aliguori 已提交
315
static void do_info_hpet(Monitor *mon)
A
aliguori 已提交
316
{
A
aliguori 已提交
317 318
    monitor_printf(mon, "HPET is %s by QEMU\n",
                   (no_hpet) ? "disabled" : "enabled");
A
aliguori 已提交
319
}
A
aurel32 已提交
320
#endif
A
aliguori 已提交
321

A
aliguori 已提交
322
static void do_info_uuid(Monitor *mon)
323
{
A
aliguori 已提交
324 325 326 327 328
    monitor_printf(mon, UUID_FMT "\n", qemu_uuid[0], qemu_uuid[1],
                   qemu_uuid[2], qemu_uuid[3], qemu_uuid[4], qemu_uuid[5],
                   qemu_uuid[6], qemu_uuid[7], qemu_uuid[8], qemu_uuid[9],
                   qemu_uuid[10], qemu_uuid[11], qemu_uuid[12], qemu_uuid[13],
                   qemu_uuid[14], qemu_uuid[15]);
329 330
}

B
bellard 已提交
331
/* get the current CPU defined by the user */
332
static int mon_set_cpu(int cpu_index)
B
bellard 已提交
333 334 335 336 337
{
    CPUState *env;

    for(env = first_cpu; env != NULL; env = env->next_cpu) {
        if (env->cpu_index == cpu_index) {
338
            cur_mon->mon_cpu = env;
B
bellard 已提交
339 340 341 342 343 344
            return 0;
        }
    }
    return -1;
}

345
static CPUState *mon_get_cpu(void)
B
bellard 已提交
346
{
347
    if (!cur_mon->mon_cpu) {
B
bellard 已提交
348 349
        mon_set_cpu(0);
    }
350
    cpu_synchronize_state(cur_mon->mon_cpu);
351
    return cur_mon->mon_cpu;
B
bellard 已提交
352 353
}

A
aliguori 已提交
354
static void do_info_registers(Monitor *mon)
355
{
B
bellard 已提交
356 357 358 359
    CPUState *env;
    env = mon_get_cpu();
    if (!env)
        return;
360
#ifdef TARGET_I386
A
aliguori 已提交
361
    cpu_dump_state(env, (FILE *)mon, monitor_fprintf,
B
bellard 已提交
362
                   X86_DUMP_FPU);
363
#else
A
aliguori 已提交
364
    cpu_dump_state(env, (FILE *)mon, monitor_fprintf,
B
bellard 已提交
365
                   0);
366 367 368
#endif
}

A
aliguori 已提交
369
static void do_info_cpus(Monitor *mon)
B
bellard 已提交
370 371 372 373 374 375 376
{
    CPUState *env;

    /* just to set the default cpu if not already done */
    mon_get_cpu();

    for(env = first_cpu; env != NULL; env = env->next_cpu) {
377
        cpu_synchronize_state(env);
A
aliguori 已提交
378
        monitor_printf(mon, "%c CPU #%d:",
379
                       (env == mon->mon_cpu) ? '*' : ' ',
A
aliguori 已提交
380
                       env->cpu_index);
B
bellard 已提交
381
#if defined(TARGET_I386)
A
aliguori 已提交
382 383
        monitor_printf(mon, " pc=0x" TARGET_FMT_lx,
                       env->eip + env->segs[R_CS].base);
B
bellard 已提交
384
#elif defined(TARGET_PPC)
A
aliguori 已提交
385
        monitor_printf(mon, " nip=0x" TARGET_FMT_lx, env->nip);
B
bellard 已提交
386
#elif defined(TARGET_SPARC)
A
aliguori 已提交
387 388
        monitor_printf(mon, " pc=0x" TARGET_FMT_lx " npc=0x" TARGET_FMT_lx,
                       env->pc, env->npc);
389
#elif defined(TARGET_MIPS)
A
aliguori 已提交
390
        monitor_printf(mon, " PC=0x" TARGET_FMT_lx, env->active_tc.PC);
B
bellard 已提交
391
#endif
392
        if (env->halted)
A
aliguori 已提交
393 394
            monitor_printf(mon, " (halted)");
        monitor_printf(mon, "\n");
B
bellard 已提交
395 396 397
    }
}

398
static void do_cpu_set(Monitor *mon, const QDict *qdict)
B
bellard 已提交
399
{
400
    int index = qdict_get_int(qdict, "index");
B
bellard 已提交
401
    if (mon_set_cpu(index) < 0)
A
aliguori 已提交
402
        monitor_printf(mon, "Invalid CPU index\n");
B
bellard 已提交
403 404
}

A
aliguori 已提交
405
static void do_info_jit(Monitor *mon)
B
bellard 已提交
406
{
A
aliguori 已提交
407
    dump_exec_info((FILE *)mon, monitor_fprintf);
B
bellard 已提交
408 409
}

A
aliguori 已提交
410
static void do_info_history(Monitor *mon)
B
bellard 已提交
411 412
{
    int i;
413
    const char *str;
414

415 416
    if (!mon->rs)
        return;
417 418
    i = 0;
    for(;;) {
419
        str = readline_get_history(mon->rs, i);
420 421
        if (!str)
            break;
A
aliguori 已提交
422
        monitor_printf(mon, "%d: '%s'\n", i, str);
B
bellard 已提交
423
        i++;
B
bellard 已提交
424 425 426
    }
}

427 428
#if defined(TARGET_PPC)
/* XXX: not implemented in other targets */
A
aliguori 已提交
429
static void do_info_cpu_stats(Monitor *mon)
430 431 432 433
{
    CPUState *env;

    env = mon_get_cpu();
A
aliguori 已提交
434
    cpu_dump_statistics(env, (FILE *)mon, &monitor_fprintf, 0);
435 436 437
}
#endif

438
static void do_quit(Monitor *mon, const QDict *qdict)
B
bellard 已提交
439 440 441 442
{
    exit(0);
}

A
aliguori 已提交
443
static int eject_device(Monitor *mon, BlockDriverState *bs, int force)
B
bellard 已提交
444 445 446 447
{
    if (bdrv_is_inserted(bs)) {
        if (!force) {
            if (!bdrv_is_removable(bs)) {
A
aliguori 已提交
448
                monitor_printf(mon, "device is not removable\n");
B
bellard 已提交
449 450 451
                return -1;
            }
            if (bdrv_is_locked(bs)) {
A
aliguori 已提交
452
                monitor_printf(mon, "device is locked\n");
B
bellard 已提交
453 454 455 456 457 458 459 460
                return -1;
            }
        }
        bdrv_close(bs);
    }
    return 0;
}

461
static void do_eject(Monitor *mon, const QDict *qdict)
B
bellard 已提交
462 463
{
    BlockDriverState *bs;
464 465
    int force = qdict_get_int(qdict, "force");
    const char *filename = qdict_get_str(qdict, "filename");
B
bellard 已提交
466

467
    bs = bdrv_find(filename);
B
bellard 已提交
468
    if (!bs) {
A
aliguori 已提交
469
        monitor_printf(mon, "device not found\n");
B
bellard 已提交
470 471
        return;
    }
A
aliguori 已提交
472
    eject_device(mon, bs, force);
B
bellard 已提交
473 474
}

A
aliguori 已提交
475 476
static void do_change_block(Monitor *mon, const char *device,
                            const char *filename, const char *fmt)
B
bellard 已提交
477 478
{
    BlockDriverState *bs;
479
    BlockDriver *drv = NULL;
B
bellard 已提交
480

481
    bs = bdrv_find(device);
B
bellard 已提交
482
    if (!bs) {
A
aliguori 已提交
483
        monitor_printf(mon, "device not found\n");
B
bellard 已提交
484 485
        return;
    }
486 487 488
    if (fmt) {
        drv = bdrv_find_format(fmt);
        if (!drv) {
A
aliguori 已提交
489
            monitor_printf(mon, "invalid format %s\n", fmt);
490 491 492
            return;
        }
    }
A
aliguori 已提交
493
    if (eject_device(mon, bs, 0) < 0)
B
bellard 已提交
494
        return;
495
    bdrv_open2(bs, filename, 0, drv);
A
aliguori 已提交
496
    monitor_read_bdrv_key_start(mon, bs, NULL, NULL);
497 498
}

A
aliguori 已提交
499 500
static void change_vnc_password_cb(Monitor *mon, const char *password,
                                   void *opaque)
501 502
{
    if (vnc_display_password(NULL, password) < 0)
A
aliguori 已提交
503
        monitor_printf(mon, "could not set VNC server password\n");
504

505
    monitor_read_command(mon, 1);
B
bellard 已提交
506 507
}

A
aliguori 已提交
508
static void do_change_vnc(Monitor *mon, const char *target, const char *arg)
509
{
510
    if (strcmp(target, "passwd") == 0 ||
511 512
        strcmp(target, "password") == 0) {
        if (arg) {
513
            char password[9];
514 515
            strncpy(password, arg, sizeof(password));
            password[sizeof(password) - 1] = '\0';
A
aliguori 已提交
516
            change_vnc_password_cb(mon, password, NULL);
517
        } else {
A
aliguori 已提交
518
            monitor_read_password(mon, change_vnc_password_cb, NULL);
519
        }
520
    } else {
521
        if (vnc_display_open(NULL, target) < 0)
A
aliguori 已提交
522
            monitor_printf(mon, "could not start VNC server on %s\n", target);
523
    }
524 525
}

526
static void do_change(Monitor *mon, const QDict *qdict)
527
{
528 529 530
    const char *device = qdict_get_str(qdict, "device");
    const char *target = qdict_get_str(qdict, "target");
    const char *arg = qdict_get_try_str(qdict, "arg");
531
    if (strcmp(device, "vnc") == 0) {
532
        do_change_vnc(mon, target, arg);
533
    } else {
534
        do_change_block(mon, device, target, arg);
535 536 537
    }
}

538
static void do_screen_dump(Monitor *mon, const QDict *qdict)
B
bellard 已提交
539
{
540
    vga_hw_screen_dump(qdict_get_str(qdict, "filename"));
B
bellard 已提交
541 542
}

543
static void do_logfile(Monitor *mon, const QDict *qdict)
P
pbrook 已提交
544
{
545
    cpu_set_log_filename(qdict_get_str(qdict, "filename"));
P
pbrook 已提交
546 547
}

548
static void do_log(Monitor *mon, const QDict *qdict)
549 550
{
    int mask;
551
    const char *items = qdict_get_str(qdict, "items");
552

553
    if (!strcmp(items, "none")) {
554 555
        mask = 0;
    } else {
556
        mask = cpu_str_to_log_mask(items);
557
        if (!mask) {
A
aliguori 已提交
558
            help_cmd(mon, "log");
559 560 561 562 563 564
            return;
        }
    }
    cpu_set_log(mask);
}

565
static void do_singlestep(Monitor *mon, const QDict *qdict)
566
{
567
    const char *option = qdict_get_try_str(qdict, "option");
568 569 570 571 572 573 574 575 576
    if (!option || !strcmp(option, "on")) {
        singlestep = 1;
    } else if (!strcmp(option, "off")) {
        singlestep = 0;
    } else {
        monitor_printf(mon, "unexpected option %s\n", option);
    }
}

577
static void do_stop(Monitor *mon, const QDict *qdict)
578 579 580 581
{
    vm_stop(EXCP_INTERRUPT);
}

582
static void encrypted_bdrv_it(void *opaque, BlockDriverState *bs);
583

A
aliguori 已提交
584 585 586 587 588
struct bdrv_iterate_context {
    Monitor *mon;
    int err;
};

589
static void do_cont(Monitor *mon, const QDict *qdict)
590
{
A
aliguori 已提交
591
    struct bdrv_iterate_context context = { mon, 0 };
592

A
aliguori 已提交
593
    bdrv_iterate(encrypted_bdrv_it, &context);
594
    /* only resume the vm if all keys are set and valid */
A
aliguori 已提交
595
    if (!context.err)
596
        vm_start();
597 598
}

599 600
static void bdrv_key_cb(void *opaque, int err)
{
A
aliguori 已提交
601 602
    Monitor *mon = opaque;

603 604
    /* another key was set successfully, retry to continue */
    if (!err)
605
        do_cont(mon, NULL);
606 607 608 609
}

static void encrypted_bdrv_it(void *opaque, BlockDriverState *bs)
{
A
aliguori 已提交
610
    struct bdrv_iterate_context *context = opaque;
611

A
aliguori 已提交
612 613 614 615
    if (!context->err && bdrv_key_required(bs)) {
        context->err = -EBUSY;
        monitor_read_bdrv_key_start(context->mon, bs, bdrv_key_cb,
                                    context->mon);
616 617 618
    }
}

619
static void do_gdbserver(Monitor *mon, const QDict *qdict)
620
{
621
    const char *device = qdict_get_try_str(qdict, "device");
622 623 624 625 626 627
    if (!device)
        device = "tcp::" DEFAULT_GDBSTUB_PORT;
    if (gdbserver_start(device) < 0) {
        monitor_printf(mon, "Could not open gdbserver on device '%s'\n",
                       device);
    } else if (strcmp(device, "none") == 0) {
628
        monitor_printf(mon, "Disabled gdbserver\n");
629
    } else {
630 631
        monitor_printf(mon, "Waiting for gdb connection on device '%s'\n",
                       device);
632 633 634
    }
}

635
static void do_watchdog_action(Monitor *mon, const QDict *qdict)
R
Richard W.M. Jones 已提交
636
{
637
    const char *action = qdict_get_str(qdict, "action");
R
Richard W.M. Jones 已提交
638 639 640 641 642
    if (select_watchdog_action(action) == -1) {
        monitor_printf(mon, "Unknown watchdog action '%s'\n", action);
    }
}

A
aliguori 已提交
643
static void monitor_printc(Monitor *mon, int c)
644
{
A
aliguori 已提交
645
    monitor_printf(mon, "'");
646 647
    switch(c) {
    case '\'':
A
aliguori 已提交
648
        monitor_printf(mon, "\\'");
649 650
        break;
    case '\\':
A
aliguori 已提交
651
        monitor_printf(mon, "\\\\");
652 653
        break;
    case '\n':
A
aliguori 已提交
654
        monitor_printf(mon, "\\n");
655 656
        break;
    case '\r':
A
aliguori 已提交
657
        monitor_printf(mon, "\\r");
658 659 660
        break;
    default:
        if (c >= 32 && c <= 126) {
A
aliguori 已提交
661
            monitor_printf(mon, "%c", c);
662
        } else {
A
aliguori 已提交
663
            monitor_printf(mon, "\\x%02x", c);
664 665 666
        }
        break;
    }
A
aliguori 已提交
667
    monitor_printf(mon, "'");
668 669
}

A
aliguori 已提交
670
static void memory_dump(Monitor *mon, int count, int format, int wsize,
A
Anthony Liguori 已提交
671
                        target_phys_addr_t addr, int is_physical)
672
{
B
bellard 已提交
673
    CPUState *env;
674 675 676 677 678 679 680
    int nb_per_line, l, line_size, i, max_digits, len;
    uint8_t buf[16];
    uint64_t v;

    if (format == 'i') {
        int flags;
        flags = 0;
B
bellard 已提交
681 682 683
        env = mon_get_cpu();
        if (!env && !is_physical)
            return;
684
#ifdef TARGET_I386
685
        if (wsize == 2) {
686
            flags = 1;
687 688 689
        } else if (wsize == 4) {
            flags = 0;
        } else {
B
bellard 已提交
690
            /* as default we use the current CS size */
691
            flags = 0;
B
bellard 已提交
692 693
            if (env) {
#ifdef TARGET_X86_64
694
                if ((env->efer & MSR_EFER_LMA) &&
B
bellard 已提交
695 696 697 698 699 700 701
                    (env->segs[R_CS].flags & DESC_L_MASK))
                    flags = 2;
                else
#endif
                if (!(env->segs[R_CS].flags & DESC_B_MASK))
                    flags = 1;
            }
702 703
        }
#endif
A
aliguori 已提交
704
        monitor_disas(mon, env, addr, count, is_physical, flags);
705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733
        return;
    }

    len = wsize * count;
    if (wsize == 1)
        line_size = 8;
    else
        line_size = 16;
    nb_per_line = line_size / wsize;
    max_digits = 0;

    switch(format) {
    case 'o':
        max_digits = (wsize * 8 + 2) / 3;
        break;
    default:
    case 'x':
        max_digits = (wsize * 8) / 4;
        break;
    case 'u':
    case 'd':
        max_digits = (wsize * 8 * 10 + 32) / 33;
        break;
    case 'c':
        wsize = 1;
        break;
    }

    while (len > 0) {
734
        if (is_physical)
A
aliguori 已提交
735
            monitor_printf(mon, TARGET_FMT_plx ":", addr);
736
        else
A
aliguori 已提交
737
            monitor_printf(mon, TARGET_FMT_lx ":", (target_ulong)addr);
738 739 740 741 742 743
        l = len;
        if (l > line_size)
            l = line_size;
        if (is_physical) {
            cpu_physical_memory_rw(addr, buf, l, 0);
        } else {
B
bellard 已提交
744 745 746
            env = mon_get_cpu();
            if (!env)
                break;
747
            if (cpu_memory_rw_debug(env, addr, buf, l, 0) < 0) {
A
aliguori 已提交
748
                monitor_printf(mon, " Cannot access memory\n");
749 750
                break;
            }
751
        }
752
        i = 0;
753 754 755 756 757 758 759 760 761 762
        while (i < l) {
            switch(wsize) {
            default:
            case 1:
                v = ldub_raw(buf + i);
                break;
            case 2:
                v = lduw_raw(buf + i);
                break;
            case 4:
B
bellard 已提交
763
                v = (uint32_t)ldl_raw(buf + i);
764 765 766 767 768
                break;
            case 8:
                v = ldq_raw(buf + i);
                break;
            }
A
aliguori 已提交
769
            monitor_printf(mon, " ");
770 771
            switch(format) {
            case 'o':
A
aliguori 已提交
772
                monitor_printf(mon, "%#*" PRIo64, max_digits, v);
773 774
                break;
            case 'x':
A
aliguori 已提交
775
                monitor_printf(mon, "0x%0*" PRIx64, max_digits, v);
776 777
                break;
            case 'u':
A
aliguori 已提交
778
                monitor_printf(mon, "%*" PRIu64, max_digits, v);
779 780
                break;
            case 'd':
A
aliguori 已提交
781
                monitor_printf(mon, "%*" PRId64, max_digits, v);
782 783
                break;
            case 'c':
A
aliguori 已提交
784
                monitor_printc(mon, v);
785 786 787 788
                break;
            }
            i += wsize;
        }
A
aliguori 已提交
789
        monitor_printf(mon, "\n");
790 791 792 793 794
        addr += l;
        len -= l;
    }
}

795
static void do_memory_dump(Monitor *mon, const QDict *qdict)
796
{
797 798 799 800 801
    int count = qdict_get_int(qdict, "count");
    int format = qdict_get_int(qdict, "format");
    int size = qdict_get_int(qdict, "size");
    target_long addr = qdict_get_int(qdict, "addr");

A
aliguori 已提交
802
    memory_dump(mon, count, format, size, addr, 0);
803 804
}

805
static void do_physical_memory_dump(Monitor *mon, const QDict *qdict)
806
{
807 808 809
    int count = qdict_get_int(qdict, "count");
    int format = qdict_get_int(qdict, "format");
    int size = qdict_get_int(qdict, "size");
A
Anthony Liguori 已提交
810
    target_phys_addr_t addr = qdict_get_int(qdict, "addr");
811

A
aliguori 已提交
812
    memory_dump(mon, count, format, size, addr, 1);
813 814
}

815
static void do_print(Monitor *mon, const QDict *qdict)
816
{
817
    int format = qdict_get_int(qdict, "format");
A
Anthony Liguori 已提交
818
    target_phys_addr_t val = qdict_get_int(qdict, "val");
819

820
#if TARGET_PHYS_ADDR_BITS == 32
821 822
    switch(format) {
    case 'o':
A
aliguori 已提交
823
        monitor_printf(mon, "%#o", val);
824 825
        break;
    case 'x':
A
aliguori 已提交
826
        monitor_printf(mon, "%#x", val);
827 828
        break;
    case 'u':
A
aliguori 已提交
829
        monitor_printf(mon, "%u", val);
830 831 832
        break;
    default:
    case 'd':
A
aliguori 已提交
833
        monitor_printf(mon, "%d", val);
834 835
        break;
    case 'c':
A
aliguori 已提交
836
        monitor_printc(mon, val);
837 838
        break;
    }
B
bellard 已提交
839 840 841
#else
    switch(format) {
    case 'o':
A
aliguori 已提交
842
        monitor_printf(mon, "%#" PRIo64, val);
B
bellard 已提交
843 844
        break;
    case 'x':
A
aliguori 已提交
845
        monitor_printf(mon, "%#" PRIx64, val);
B
bellard 已提交
846 847
        break;
    case 'u':
A
aliguori 已提交
848
        monitor_printf(mon, "%" PRIu64, val);
B
bellard 已提交
849 850 851
        break;
    default:
    case 'd':
A
aliguori 已提交
852
        monitor_printf(mon, "%" PRId64, val);
B
bellard 已提交
853 854
        break;
    case 'c':
A
aliguori 已提交
855
        monitor_printc(mon, val);
B
bellard 已提交
856 857 858
        break;
    }
#endif
A
aliguori 已提交
859
    monitor_printf(mon, "\n");
860 861
}

862
static void do_memory_save(Monitor *mon, const QDict *qdict)
B
bellard 已提交
863 864
{
    FILE *f;
865 866 867
    uint32_t size = qdict_get_int(qdict, "size");
    const char *filename = qdict_get_str(qdict, "filename");
    target_long addr = qdict_get_int(qdict, "val");
B
bellard 已提交
868 869 870 871 872 873 874 875 876 877
    uint32_t l;
    CPUState *env;
    uint8_t buf[1024];

    env = mon_get_cpu();
    if (!env)
        return;

    f = fopen(filename, "wb");
    if (!f) {
A
aliguori 已提交
878
        monitor_printf(mon, "could not open '%s'\n", filename);
B
bellard 已提交
879 880 881 882 883 884 885 886 887 888 889 890 891 892
        return;
    }
    while (size != 0) {
        l = sizeof(buf);
        if (l > size)
            l = size;
        cpu_memory_rw_debug(env, addr, buf, l, 0);
        fwrite(buf, 1, l, f);
        addr += l;
        size -= l;
    }
    fclose(f);
}

893
static void do_physical_memory_save(Monitor *mon, const QDict *qdict)
A
aurel32 已提交
894 895 896 897
{
    FILE *f;
    uint32_t l;
    uint8_t buf[1024];
898 899
    uint32_t size = qdict_get_int(qdict, "size");
    const char *filename = qdict_get_str(qdict, "filename");
A
Anthony Liguori 已提交
900
    target_phys_addr_t addr = qdict_get_int(qdict, "val");
A
aurel32 已提交
901 902 903

    f = fopen(filename, "wb");
    if (!f) {
A
aliguori 已提交
904
        monitor_printf(mon, "could not open '%s'\n", filename);
A
aurel32 已提交
905 906 907 908 909 910 911 912 913 914 915 916 917 918 919
        return;
    }
    while (size != 0) {
        l = sizeof(buf);
        if (l > size)
            l = size;
        cpu_physical_memory_rw(addr, buf, l, 0);
        fwrite(buf, 1, l, f);
        fflush(f);
        addr += l;
        size -= l;
    }
    fclose(f);
}

920
static void do_sum(Monitor *mon, const QDict *qdict)
B
bellard 已提交
921 922 923 924
{
    uint32_t addr;
    uint8_t buf[1];
    uint16_t sum;
925 926
    uint32_t start = qdict_get_int(qdict, "start");
    uint32_t size = qdict_get_int(qdict, "size");
B
bellard 已提交
927 928 929 930 931 932 933 934

    sum = 0;
    for(addr = start; addr < (start + size); addr++) {
        cpu_physical_memory_rw(addr, buf, 1, 0);
        /* BSD sum algorithm ('sum' Unix command) */
        sum = (sum >> 1) | (sum << 15);
        sum += buf[0];
    }
A
aliguori 已提交
935
    monitor_printf(mon, "%05d\n", sum);
B
bellard 已提交
936 937
}

B
bellard 已提交
938 939 940 941 942 943 944 945
typedef struct {
    int keycode;
    const char *name;
} KeyDef;

static const KeyDef key_defs[] = {
    { 0x2a, "shift" },
    { 0x36, "shift_r" },
946

B
bellard 已提交
947 948
    { 0x38, "alt" },
    { 0xb8, "alt_r" },
949 950
    { 0x64, "altgr" },
    { 0xe4, "altgr_r" },
B
bellard 已提交
951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967
    { 0x1d, "ctrl" },
    { 0x9d, "ctrl_r" },

    { 0xdd, "menu" },

    { 0x01, "esc" },

    { 0x02, "1" },
    { 0x03, "2" },
    { 0x04, "3" },
    { 0x05, "4" },
    { 0x06, "5" },
    { 0x07, "6" },
    { 0x08, "7" },
    { 0x09, "8" },
    { 0x0a, "9" },
    { 0x0b, "0" },
968 969
    { 0x0c, "minus" },
    { 0x0d, "equal" },
B
bellard 已提交
970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002
    { 0x0e, "backspace" },

    { 0x0f, "tab" },
    { 0x10, "q" },
    { 0x11, "w" },
    { 0x12, "e" },
    { 0x13, "r" },
    { 0x14, "t" },
    { 0x15, "y" },
    { 0x16, "u" },
    { 0x17, "i" },
    { 0x18, "o" },
    { 0x19, "p" },

    { 0x1c, "ret" },

    { 0x1e, "a" },
    { 0x1f, "s" },
    { 0x20, "d" },
    { 0x21, "f" },
    { 0x22, "g" },
    { 0x23, "h" },
    { 0x24, "j" },
    { 0x25, "k" },
    { 0x26, "l" },

    { 0x2c, "z" },
    { 0x2d, "x" },
    { 0x2e, "c" },
    { 0x2f, "v" },
    { 0x30, "b" },
    { 0x31, "n" },
    { 0x32, "m" },
1003 1004 1005
    { 0x33, "comma" },
    { 0x34, "dot" },
    { 0x35, "slash" },
1006

B
balrog 已提交
1007 1008
    { 0x37, "asterisk" },

B
bellard 已提交
1009
    { 0x39, "spc" },
B
bellard 已提交
1010
    { 0x3a, "caps_lock" },
B
bellard 已提交
1011 1012 1013 1014 1015 1016 1017 1018 1019 1020
    { 0x3b, "f1" },
    { 0x3c, "f2" },
    { 0x3d, "f3" },
    { 0x3e, "f4" },
    { 0x3f, "f5" },
    { 0x40, "f6" },
    { 0x41, "f7" },
    { 0x42, "f8" },
    { 0x43, "f9" },
    { 0x44, "f10" },
B
bellard 已提交
1021
    { 0x45, "num_lock" },
B
bellard 已提交
1022 1023
    { 0x46, "scroll_lock" },

1024 1025
    { 0xb5, "kp_divide" },
    { 0x37, "kp_multiply" },
T
ths 已提交
1026
    { 0x4a, "kp_subtract" },
1027 1028 1029
    { 0x4e, "kp_add" },
    { 0x9c, "kp_enter" },
    { 0x53, "kp_decimal" },
1030
    { 0x54, "sysrq" },
1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041

    { 0x52, "kp_0" },
    { 0x4f, "kp_1" },
    { 0x50, "kp_2" },
    { 0x51, "kp_3" },
    { 0x4b, "kp_4" },
    { 0x4c, "kp_5" },
    { 0x4d, "kp_6" },
    { 0x47, "kp_7" },
    { 0x48, "kp_8" },
    { 0x49, "kp_9" },
1042

B
bellard 已提交
1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061
    { 0x56, "<" },

    { 0x57, "f11" },
    { 0x58, "f12" },

    { 0xb7, "print" },

    { 0xc7, "home" },
    { 0xc9, "pgup" },
    { 0xd1, "pgdn" },
    { 0xcf, "end" },

    { 0xcb, "left" },
    { 0xc8, "up" },
    { 0xd0, "down" },
    { 0xcd, "right" },

    { 0xd2, "insert" },
    { 0xd3, "delete" },
1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078
#if defined(TARGET_SPARC) && !defined(TARGET_SPARC64)
    { 0xf0, "stop" },
    { 0xf1, "again" },
    { 0xf2, "props" },
    { 0xf3, "undo" },
    { 0xf4, "front" },
    { 0xf5, "copy" },
    { 0xf6, "open" },
    { 0xf7, "paste" },
    { 0xf8, "find" },
    { 0xf9, "cut" },
    { 0xfa, "lf" },
    { 0xfb, "help" },
    { 0xfc, "meta_l" },
    { 0xfd, "meta_r" },
    { 0xfe, "compose" },
#endif
B
bellard 已提交
1079 1080 1081 1082 1083 1084
    { 0, NULL },
};

static int get_keycode(const char *key)
{
    const KeyDef *p;
1085 1086
    char *endp;
    int ret;
B
bellard 已提交
1087 1088 1089 1090 1091

    for(p = key_defs; p->name != NULL; p++) {
        if (!strcmp(key, p->name))
            return p->keycode;
    }
1092 1093 1094 1095 1096
    if (strstart(key, "0x", NULL)) {
        ret = strtoul(key, &endp, 0);
        if (*endp == '\0' && ret >= 0x01 && ret <= 0xff)
            return ret;
    }
B
bellard 已提交
1097 1098 1099
    return -1;
}

1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117
#define MAX_KEYCODES 16
static uint8_t keycodes[MAX_KEYCODES];
static int nb_pending_keycodes;
static QEMUTimer *key_timer;

static void release_keys(void *opaque)
{
    int keycode;

    while (nb_pending_keycodes > 0) {
        nb_pending_keycodes--;
        keycode = keycodes[nb_pending_keycodes];
        if (keycode & 0x80)
            kbd_put_keycode(0xe0);
        kbd_put_keycode(keycode | 0x80);
    }
}

1118
static void do_sendkey(Monitor *mon, const QDict *qdict)
B
bellard 已提交
1119
{
1120 1121 1122
    char keyname_buf[16];
    char *separator;
    int keyname_len, keycode, i;
1123 1124 1125
    const char *string = qdict_get_str(qdict, "string");
    int has_hold_time = qdict_haskey(qdict, "hold_time");
    int hold_time = qdict_get_try_int(qdict, "hold_time", -1);
1126

1127 1128 1129 1130 1131 1132 1133
    if (nb_pending_keycodes > 0) {
        qemu_del_timer(key_timer);
        release_keys(NULL);
    }
    if (!has_hold_time)
        hold_time = 100;
    i = 0;
1134 1135 1136 1137 1138 1139
    while (1) {
        separator = strchr(string, '-');
        keyname_len = separator ? separator - string : strlen(string);
        if (keyname_len > 0) {
            pstrcpy(keyname_buf, sizeof(keyname_buf), string);
            if (keyname_len > sizeof(keyname_buf) - 1) {
A
aliguori 已提交
1140
                monitor_printf(mon, "invalid key: '%s...'\n", keyname_buf);
1141
                return;
B
bellard 已提交
1142
            }
1143
            if (i == MAX_KEYCODES) {
A
aliguori 已提交
1144
                monitor_printf(mon, "too many keys\n");
1145 1146 1147 1148 1149
                return;
            }
            keyname_buf[keyname_len] = 0;
            keycode = get_keycode(keyname_buf);
            if (keycode < 0) {
A
aliguori 已提交
1150
                monitor_printf(mon, "unknown key: '%s'\n", keyname_buf);
1151 1152
                return;
            }
1153
            keycodes[i++] = keycode;
B
bellard 已提交
1154
        }
1155
        if (!separator)
B
bellard 已提交
1156
            break;
1157
        string = separator + 1;
B
bellard 已提交
1158
    }
1159
    nb_pending_keycodes = i;
B
bellard 已提交
1160
    /* key down events */
1161
    for (i = 0; i < nb_pending_keycodes; i++) {
B
bellard 已提交
1162 1163 1164 1165 1166
        keycode = keycodes[i];
        if (keycode & 0x80)
            kbd_put_keycode(0xe0);
        kbd_put_keycode(keycode & 0x7f);
    }
1167
    /* delayed key up events */
1168
    qemu_mod_timer(key_timer, qemu_get_clock(vm_clock) +
1169
                   muldiv64(get_ticks_per_sec(), hold_time, 1000));
B
bellard 已提交
1170 1171
}

B
bellard 已提交
1172 1173
static int mouse_button_state;

1174
static void do_mouse_move(Monitor *mon, const QDict *qdict)
B
bellard 已提交
1175 1176
{
    int dx, dy, dz;
1177 1178 1179
    const char *dx_str = qdict_get_str(qdict, "dx_str");
    const char *dy_str = qdict_get_str(qdict, "dy_str");
    const char *dz_str = qdict_get_try_str(qdict, "dz_str");
B
bellard 已提交
1180 1181 1182
    dx = strtol(dx_str, NULL, 0);
    dy = strtol(dy_str, NULL, 0);
    dz = 0;
1183
    if (dz_str)
B
bellard 已提交
1184 1185 1186 1187
        dz = strtol(dz_str, NULL, 0);
    kbd_mouse_event(dx, dy, dz, mouse_button_state);
}

1188
static void do_mouse_button(Monitor *mon, const QDict *qdict)
B
bellard 已提交
1189
{
1190
    int button_state = qdict_get_int(qdict, "button_state");
B
bellard 已提交
1191 1192 1193 1194
    mouse_button_state = button_state;
    kbd_mouse_event(0, 0, 0, mouse_button_state);
}

1195
static void do_ioport_read(Monitor *mon, const QDict *qdict)
B
bellard 已提交
1196
{
1197 1198 1199
    int size = qdict_get_int(qdict, "size");
    int addr = qdict_get_int(qdict, "addr");
    int has_index = qdict_haskey(qdict, "index");
B
bellard 已提交
1200 1201 1202 1203
    uint32_t val;
    int suffix;

    if (has_index) {
1204
        int index = qdict_get_int(qdict, "index");
1205
        cpu_outb(addr & IOPORTS_MASK, index & 0xff);
B
bellard 已提交
1206 1207 1208 1209 1210 1211 1212
        addr++;
    }
    addr &= 0xffff;

    switch(size) {
    default:
    case 1:
1213
        val = cpu_inb(addr);
B
bellard 已提交
1214 1215 1216
        suffix = 'b';
        break;
    case 2:
1217
        val = cpu_inw(addr);
B
bellard 已提交
1218 1219 1220
        suffix = 'w';
        break;
    case 4:
1221
        val = cpu_inl(addr);
B
bellard 已提交
1222 1223 1224
        suffix = 'l';
        break;
    }
A
aliguori 已提交
1225 1226
    monitor_printf(mon, "port%c[0x%04x] = %#0*x\n",
                   suffix, addr, size * 2, val);
B
bellard 已提交
1227
}
B
bellard 已提交
1228

1229
static void do_ioport_write(Monitor *mon, const QDict *qdict)
J
Jan Kiszka 已提交
1230
{
1231 1232 1233 1234
    int size = qdict_get_int(qdict, "size");
    int addr = qdict_get_int(qdict, "addr");
    int val = qdict_get_int(qdict, "val");

J
Jan Kiszka 已提交
1235 1236 1237 1238 1239
    addr &= IOPORTS_MASK;

    switch (size) {
    default:
    case 1:
1240
        cpu_outb(addr, val);
J
Jan Kiszka 已提交
1241 1242
        break;
    case 2:
1243
        cpu_outw(addr, val);
J
Jan Kiszka 已提交
1244 1245
        break;
    case 4:
1246
        cpu_outl(addr, val);
J
Jan Kiszka 已提交
1247 1248 1249 1250
        break;
    }
}

1251
static void do_boot_set(Monitor *mon, const QDict *qdict)
1252 1253
{
    int res;
1254
    const char *bootdevice = qdict_get_str(qdict, "bootdevice");
1255

J
Jan Kiszka 已提交
1256 1257 1258 1259 1260
    res = qemu_boot_set(bootdevice);
    if (res == 0) {
        monitor_printf(mon, "boot device list now set to %s\n", bootdevice);
    } else if (res > 0) {
        monitor_printf(mon, "setting boot device list failed\n");
1261
    } else {
A
aliguori 已提交
1262 1263
        monitor_printf(mon, "no function defined to set boot device list for "
                       "this architecture\n");
1264 1265 1266
    }
}

1267
static void do_system_reset(Monitor *mon, const QDict *qdict)
B
bellard 已提交
1268 1269 1270 1271
{
    qemu_system_reset_request();
}

1272
static void do_system_powerdown(Monitor *mon, const QDict *qdict)
B
bellard 已提交
1273 1274 1275 1276
{
    qemu_system_powerdown_request();
}

B
bellard 已提交
1277
#if defined(TARGET_I386)
A
aliguori 已提交
1278
static void print_pte(Monitor *mon, uint32_t addr, uint32_t pte, uint32_t mask)
B
bellard 已提交
1279
{
A
aliguori 已提交
1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290
    monitor_printf(mon, "%08x: %08x %c%c%c%c%c%c%c%c\n",
                   addr,
                   pte & mask,
                   pte & PG_GLOBAL_MASK ? 'G' : '-',
                   pte & PG_PSE_MASK ? 'P' : '-',
                   pte & PG_DIRTY_MASK ? 'D' : '-',
                   pte & PG_ACCESSED_MASK ? 'A' : '-',
                   pte & PG_PCD_MASK ? 'C' : '-',
                   pte & PG_PWT_MASK ? 'T' : '-',
                   pte & PG_USER_MASK ? 'U' : '-',
                   pte & PG_RW_MASK ? 'W' : '-');
B
bellard 已提交
1291 1292
}

A
aliguori 已提交
1293
static void tlb_info(Monitor *mon)
B
bellard 已提交
1294
{
B
bellard 已提交
1295
    CPUState *env;
B
bellard 已提交
1296 1297 1298
    int l1, l2;
    uint32_t pgd, pde, pte;

B
bellard 已提交
1299 1300 1301 1302
    env = mon_get_cpu();
    if (!env)
        return;

B
bellard 已提交
1303
    if (!(env->cr[0] & CR0_PG_MASK)) {
A
aliguori 已提交
1304
        monitor_printf(mon, "PG disabled\n");
B
bellard 已提交
1305 1306 1307 1308 1309 1310 1311 1312
        return;
    }
    pgd = env->cr[3] & ~0xfff;
    for(l1 = 0; l1 < 1024; l1++) {
        cpu_physical_memory_read(pgd + l1 * 4, (uint8_t *)&pde, 4);
        pde = le32_to_cpu(pde);
        if (pde & PG_PRESENT_MASK) {
            if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
A
aliguori 已提交
1313
                print_pte(mon, (l1 << 22), pde, ~((1 << 20) - 1));
B
bellard 已提交
1314 1315
            } else {
                for(l2 = 0; l2 < 1024; l2++) {
1316
                    cpu_physical_memory_read((pde & ~0xfff) + l2 * 4,
B
bellard 已提交
1317 1318 1319
                                             (uint8_t *)&pte, 4);
                    pte = le32_to_cpu(pte);
                    if (pte & PG_PRESENT_MASK) {
A
aliguori 已提交
1320
                        print_pte(mon, (l1 << 22) + (l2 << 12),
1321
                                  pte & ~PG_PSE_MASK,
B
bellard 已提交
1322 1323 1324 1325 1326 1327 1328 1329
                                  ~0xfff);
                    }
                }
            }
        }
    }
}

A
aliguori 已提交
1330
static void mem_print(Monitor *mon, uint32_t *pstart, int *plast_prot,
B
bellard 已提交
1331 1332
                      uint32_t end, int prot)
{
B
bellard 已提交
1333 1334 1335
    int prot1;
    prot1 = *plast_prot;
    if (prot != prot1) {
B
bellard 已提交
1336
        if (*pstart != -1) {
A
aliguori 已提交
1337 1338 1339 1340 1341
            monitor_printf(mon, "%08x-%08x %08x %c%c%c\n",
                           *pstart, end, end - *pstart,
                           prot1 & PG_USER_MASK ? 'u' : '-',
                           'r',
                           prot1 & PG_RW_MASK ? 'w' : '-');
B
bellard 已提交
1342 1343 1344 1345 1346 1347 1348 1349 1350
        }
        if (prot != 0)
            *pstart = end;
        else
            *pstart = -1;
        *plast_prot = prot;
    }
}

A
aliguori 已提交
1351
static void mem_info(Monitor *mon)
B
bellard 已提交
1352
{
B
bellard 已提交
1353
    CPUState *env;
B
bellard 已提交
1354 1355 1356
    int l1, l2, prot, last_prot;
    uint32_t pgd, pde, pte, start, end;

B
bellard 已提交
1357 1358 1359 1360
    env = mon_get_cpu();
    if (!env)
        return;

B
bellard 已提交
1361
    if (!(env->cr[0] & CR0_PG_MASK)) {
A
aliguori 已提交
1362
        monitor_printf(mon, "PG disabled\n");
B
bellard 已提交
1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374
        return;
    }
    pgd = env->cr[3] & ~0xfff;
    last_prot = 0;
    start = -1;
    for(l1 = 0; l1 < 1024; l1++) {
        cpu_physical_memory_read(pgd + l1 * 4, (uint8_t *)&pde, 4);
        pde = le32_to_cpu(pde);
        end = l1 << 22;
        if (pde & PG_PRESENT_MASK) {
            if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
                prot = pde & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK);
A
aliguori 已提交
1375
                mem_print(mon, &start, &last_prot, end, prot);
B
bellard 已提交
1376 1377
            } else {
                for(l2 = 0; l2 < 1024; l2++) {
1378
                    cpu_physical_memory_read((pde & ~0xfff) + l2 * 4,
B
bellard 已提交
1379 1380 1381 1382 1383 1384 1385 1386
                                             (uint8_t *)&pte, 4);
                    pte = le32_to_cpu(pte);
                    end = (l1 << 22) + (l2 << 12);
                    if (pte & PG_PRESENT_MASK) {
                        prot = pte & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK);
                    } else {
                        prot = 0;
                    }
A
aliguori 已提交
1387
                    mem_print(mon, &start, &last_prot, end, prot);
B
bellard 已提交
1388 1389 1390 1391
                }
            }
        } else {
            prot = 0;
A
aliguori 已提交
1392
            mem_print(mon, &start, &last_prot, end, prot);
B
bellard 已提交
1393 1394 1395 1396 1397
        }
    }
}
#endif

A
aurel32 已提交
1398 1399
#if defined(TARGET_SH4)

A
aliguori 已提交
1400
static void print_tlb(Monitor *mon, int idx, tlb_t *tlb)
A
aurel32 已提交
1401
{
A
aliguori 已提交
1402 1403 1404 1405 1406 1407 1408 1409
    monitor_printf(mon, " tlb%i:\t"
                   "asid=%hhu vpn=%x\tppn=%x\tsz=%hhu size=%u\t"
                   "v=%hhu shared=%hhu cached=%hhu prot=%hhu "
                   "dirty=%hhu writethrough=%hhu\n",
                   idx,
                   tlb->asid, tlb->vpn, tlb->ppn, tlb->sz, tlb->size,
                   tlb->v, tlb->sh, tlb->c, tlb->pr,
                   tlb->d, tlb->wt);
A
aurel32 已提交
1410 1411
}

A
aliguori 已提交
1412
static void tlb_info(Monitor *mon)
A
aurel32 已提交
1413 1414 1415 1416
{
    CPUState *env = mon_get_cpu();
    int i;

A
aliguori 已提交
1417
    monitor_printf (mon, "ITLB:\n");
A
aurel32 已提交
1418
    for (i = 0 ; i < ITLB_SIZE ; i++)
A
aliguori 已提交
1419 1420
        print_tlb (mon, i, &env->itlb[i]);
    monitor_printf (mon, "UTLB:\n");
A
aurel32 已提交
1421
    for (i = 0 ; i < UTLB_SIZE ; i++)
A
aliguori 已提交
1422
        print_tlb (mon, i, &env->utlb[i]);
A
aurel32 已提交
1423 1424 1425 1426
}

#endif

A
aliguori 已提交
1427
static void do_info_kvm(Monitor *mon)
A
aliguori 已提交
1428 1429
{
#ifdef CONFIG_KVM
A
aliguori 已提交
1430
    monitor_printf(mon, "kvm support: ");
A
aliguori 已提交
1431
    if (kvm_enabled())
A
aliguori 已提交
1432
        monitor_printf(mon, "enabled\n");
A
aliguori 已提交
1433
    else
A
aliguori 已提交
1434
        monitor_printf(mon, "disabled\n");
A
aliguori 已提交
1435
#else
A
aliguori 已提交
1436
    monitor_printf(mon, "kvm support: not compiled\n");
A
aliguori 已提交
1437 1438 1439
#endif
}

1440 1441
static void do_info_numa(Monitor *mon)
{
1442
    int i;
1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458
    CPUState *env;

    monitor_printf(mon, "%d nodes\n", nb_numa_nodes);
    for (i = 0; i < nb_numa_nodes; i++) {
        monitor_printf(mon, "node %d cpus:", i);
        for (env = first_cpu; env != NULL; env = env->next_cpu) {
            if (env->numa_node == i) {
                monitor_printf(mon, " %d", env->cpu_index);
            }
        }
        monitor_printf(mon, "\n");
        monitor_printf(mon, "node %d size: %" PRId64 " MB\n", i,
            node_mem[i] >> 20);
    }
}

B
bellard 已提交
1459 1460
#ifdef CONFIG_PROFILER

A
Aurelien Jarno 已提交
1461 1462 1463
int64_t qemu_time;
int64_t dev_time;

A
aliguori 已提交
1464
static void do_info_profile(Monitor *mon)
B
bellard 已提交
1465 1466 1467 1468 1469
{
    int64_t total;
    total = qemu_time;
    if (total == 0)
        total = 1;
A
aliguori 已提交
1470
    monitor_printf(mon, "async time  %" PRId64 " (%0.3f)\n",
1471
                   dev_time, dev_time / (double)get_ticks_per_sec());
A
aliguori 已提交
1472
    monitor_printf(mon, "qemu time   %" PRId64 " (%0.3f)\n",
1473
                   qemu_time, qemu_time / (double)get_ticks_per_sec());
B
bellard 已提交
1474 1475 1476 1477
    qemu_time = 0;
    dev_time = 0;
}
#else
A
aliguori 已提交
1478
static void do_info_profile(Monitor *mon)
B
bellard 已提交
1479
{
A
aliguori 已提交
1480
    monitor_printf(mon, "Internal profiler not compiled\n");
B
bellard 已提交
1481 1482 1483
}
#endif

B
bellard 已提交
1484
/* Capture support */
B
Blue Swirl 已提交
1485
static QLIST_HEAD (capture_list_head, CaptureState) capture_head;
B
bellard 已提交
1486

A
aliguori 已提交
1487
static void do_info_capture(Monitor *mon)
B
bellard 已提交
1488 1489 1490 1491 1492
{
    int i;
    CaptureState *s;

    for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) {
A
aliguori 已提交
1493
        monitor_printf(mon, "[%d]: ", i);
B
bellard 已提交
1494 1495 1496 1497
        s->ops.info (s->opaque);
    }
}

1498
#ifdef HAS_AUDIO
1499
static void do_stop_capture(Monitor *mon, const QDict *qdict)
B
bellard 已提交
1500 1501
{
    int i;
1502
    int n = qdict_get_int(qdict, "n");
B
bellard 已提交
1503 1504 1505 1506 1507
    CaptureState *s;

    for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) {
        if (i == n) {
            s->ops.destroy (s->opaque);
B
Blue Swirl 已提交
1508
            QLIST_REMOVE (s, entries);
B
bellard 已提交
1509 1510 1511 1512 1513 1514
            qemu_free (s);
            return;
        }
    }
}

1515 1516 1517 1518 1519 1520 1521 1522 1523
static void do_wav_capture(Monitor *mon, const QDict *qdict)
{
    const char *path = qdict_get_str(qdict, "path");
    int has_freq = qdict_haskey(qdict, "freq");
    int freq = qdict_get_try_int(qdict, "freq", -1);
    int has_bits = qdict_haskey(qdict, "bits");
    int bits = qdict_get_try_int(qdict, "bits", -1);
    int has_channels = qdict_haskey(qdict, "nchannels");
    int nchannels = qdict_get_try_int(qdict, "nchannels", -1);
B
bellard 已提交
1524 1525 1526 1527 1528 1529 1530 1531 1532
    CaptureState *s;

    s = qemu_mallocz (sizeof (*s));

    freq = has_freq ? freq : 44100;
    bits = has_bits ? bits : 16;
    nchannels = has_channels ? nchannels : 2;

    if (wav_start_capture (s, path, freq, bits, nchannels)) {
A
aliguori 已提交
1533
        monitor_printf(mon, "Faied to add wave capture\n");
B
bellard 已提交
1534 1535
        qemu_free (s);
    }
B
Blue Swirl 已提交
1536
    QLIST_INSERT_HEAD (&capture_head, s, entries);
B
bellard 已提交
1537 1538 1539
}
#endif

A
aurel32 已提交
1540
#if defined(TARGET_I386)
1541
static void do_inject_nmi(Monitor *mon, const QDict *qdict)
A
aurel32 已提交
1542 1543
{
    CPUState *env;
1544
    int cpu_index = qdict_get_int(qdict, "cpu_index");
A
aurel32 已提交
1545 1546 1547 1548 1549 1550 1551 1552 1553

    for (env = first_cpu; env != NULL; env = env->next_cpu)
        if (env->cpu_index == cpu_index) {
            cpu_interrupt(env, CPU_INTERRUPT_NMI);
            break;
        }
}
#endif

A
aliguori 已提交
1554
static void do_info_status(Monitor *mon)
A
aurel32 已提交
1555
{
1556 1557 1558 1559 1560 1561 1562
    if (vm_running) {
        if (singlestep) {
            monitor_printf(mon, "VM status: running (single step mode)\n");
        } else {
            monitor_printf(mon, "VM status: running\n");
        }
    } else
A
aliguori 已提交
1563
       monitor_printf(mon, "VM status: paused\n");
A
aurel32 已提交
1564 1565 1566
}


1567
static void do_balloon(Monitor *mon, const QDict *qdict)
A
aliguori 已提交
1568
{
1569
    int value = qdict_get_int(qdict, "value");
A
Anthony Liguori 已提交
1570
    ram_addr_t target = value;
A
aliguori 已提交
1571 1572 1573
    qemu_balloon(target << 20);
}

A
aliguori 已提交
1574
static void do_info_balloon(Monitor *mon)
A
aliguori 已提交
1575
{
A
Anthony Liguori 已提交
1576
    ram_addr_t actual;
A
aliguori 已提交
1577 1578

    actual = qemu_balloon_status();
A
aliguori 已提交
1579
    if (kvm_enabled() && !kvm_has_sync_mmu())
A
aliguori 已提交
1580 1581
        monitor_printf(mon, "Using KVM without synchronous MMU, "
                       "ballooning disabled\n");
A
aliguori 已提交
1582
    else if (actual == 0)
A
aliguori 已提交
1583
        monitor_printf(mon, "Ballooning not activated in VM\n");
A
aliguori 已提交
1584
    else
A
aliguori 已提交
1585
        monitor_printf(mon, "balloon: actual=%d\n", (int)(actual >> 20));
A
aliguori 已提交
1586 1587
}

J
Jan Kiszka 已提交
1588
static qemu_acl *find_acl(Monitor *mon, const char *name)
1589
{
J
Jan Kiszka 已提交
1590
    qemu_acl *acl = qemu_acl_find(name);
1591 1592

    if (!acl) {
J
Jan Kiszka 已提交
1593
        monitor_printf(mon, "acl: unknown list '%s'\n", name);
1594
    }
J
Jan Kiszka 已提交
1595 1596 1597
    return acl;
}

1598
static void do_acl_show(Monitor *mon, const QDict *qdict)
J
Jan Kiszka 已提交
1599
{
1600
    const char *aclname = qdict_get_str(qdict, "aclname");
J
Jan Kiszka 已提交
1601 1602 1603
    qemu_acl *acl = find_acl(mon, aclname);
    qemu_acl_entry *entry;
    int i = 0;
1604

J
Jan Kiszka 已提交
1605
    if (acl) {
1606
        monitor_printf(mon, "policy: %s\n",
1607
                       acl->defaultDeny ? "deny" : "allow");
B
Blue Swirl 已提交
1608
        QTAILQ_FOREACH(entry, &acl->entries, next) {
1609 1610
            i++;
            monitor_printf(mon, "%d: %s %s\n", i,
J
Jan Kiszka 已提交
1611
                           entry->deny ? "deny" : "allow", entry->match);
1612
        }
J
Jan Kiszka 已提交
1613 1614 1615
    }
}

1616
static void do_acl_reset(Monitor *mon, const QDict *qdict)
J
Jan Kiszka 已提交
1617
{
1618
    const char *aclname = qdict_get_str(qdict, "aclname");
J
Jan Kiszka 已提交
1619 1620 1621
    qemu_acl *acl = find_acl(mon, aclname);

    if (acl) {
1622 1623
        qemu_acl_reset(acl);
        monitor_printf(mon, "acl: removed all rules\n");
J
Jan Kiszka 已提交
1624 1625 1626
    }
}

1627
static void do_acl_policy(Monitor *mon, const QDict *qdict)
J
Jan Kiszka 已提交
1628
{
1629 1630
    const char *aclname = qdict_get_str(qdict, "aclname");
    const char *policy = qdict_get_str(qdict, "policy");
J
Jan Kiszka 已提交
1631
    qemu_acl *acl = find_acl(mon, aclname);
1632

J
Jan Kiszka 已提交
1633 1634
    if (acl) {
        if (strcmp(policy, "allow") == 0) {
1635 1636
            acl->defaultDeny = 0;
            monitor_printf(mon, "acl: policy set to 'allow'\n");
J
Jan Kiszka 已提交
1637
        } else if (strcmp(policy, "deny") == 0) {
1638 1639 1640
            acl->defaultDeny = 1;
            monitor_printf(mon, "acl: policy set to 'deny'\n");
        } else {
J
Jan Kiszka 已提交
1641 1642
            monitor_printf(mon, "acl: unknown policy '%s', "
                           "expected 'deny' or 'allow'\n", policy);
1643
        }
J
Jan Kiszka 已提交
1644 1645
    }
}
1646

1647
static void do_acl_add(Monitor *mon, const QDict *qdict)
J
Jan Kiszka 已提交
1648
{
1649 1650 1651 1652 1653
    const char *aclname = qdict_get_str(qdict, "aclname");
    const char *match = qdict_get_str(qdict, "match");
    const char *policy = qdict_get_str(qdict, "policy");
    int has_index = qdict_haskey(qdict, "index");
    int index = qdict_get_try_int(qdict, "index", -1);
J
Jan Kiszka 已提交
1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664
    qemu_acl *acl = find_acl(mon, aclname);
    int deny, ret;

    if (acl) {
        if (strcmp(policy, "allow") == 0) {
            deny = 0;
        } else if (strcmp(policy, "deny") == 0) {
            deny = 1;
        } else {
            monitor_printf(mon, "acl: unknown policy '%s', "
                           "expected 'deny' or 'allow'\n", policy);
1665 1666 1667 1668 1669 1670 1671 1672 1673 1674
            return;
        }
        if (has_index)
            ret = qemu_acl_insert(acl, deny, match, index);
        else
            ret = qemu_acl_append(acl, deny, match);
        if (ret < 0)
            monitor_printf(mon, "acl: unable to add acl entry\n");
        else
            monitor_printf(mon, "acl: added rule at position %d\n", ret);
J
Jan Kiszka 已提交
1675 1676
    }
}
1677

1678
static void do_acl_remove(Monitor *mon, const QDict *qdict)
J
Jan Kiszka 已提交
1679
{
1680 1681
    const char *aclname = qdict_get_str(qdict, "aclname");
    const char *match = qdict_get_str(qdict, "match");
J
Jan Kiszka 已提交
1682 1683
    qemu_acl *acl = find_acl(mon, aclname);
    int ret;
1684

J
Jan Kiszka 已提交
1685
    if (acl) {
1686 1687 1688 1689 1690
        ret = qemu_acl_remove(acl, match);
        if (ret < 0)
            monitor_printf(mon, "acl: no matching acl entry\n");
        else
            monitor_printf(mon, "acl: removed rule at position %d\n", ret);
1691 1692 1693
    }
}

1694
#if defined(TARGET_I386)
1695
static void do_inject_mce(Monitor *mon, const QDict *qdict)
1696 1697
{
    CPUState *cenv;
1698 1699 1700 1701 1702 1703
    int cpu_index = qdict_get_int(qdict, "cpu_index");
    int bank = qdict_get_int(qdict, "bank");
    uint64_t status = qdict_get_int(qdict, "status");
    uint64_t mcg_status = qdict_get_int(qdict, "mcg_status");
    uint64_t addr = qdict_get_int(qdict, "addr");
    uint64_t misc = qdict_get_int(qdict, "misc");
1704 1705 1706 1707 1708 1709 1710 1711 1712

    for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu)
        if (cenv->cpu_index == cpu_index && cenv->mcg_cap) {
            cpu_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc);
            break;
        }
}
#endif

1713
static void do_getfd(Monitor *mon, const QDict *qdict)
1714
{
1715
    const char *fdname = qdict_get_str(qdict, "fdname");
A
Anthony Liguori 已提交
1716
    mon_fd_t *monfd;
1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736
    int fd;

    fd = qemu_chr_get_msgfd(mon->chr);
    if (fd == -1) {
        monitor_printf(mon, "getfd: no file descriptor supplied via SCM_RIGHTS\n");
        return;
    }

    if (qemu_isdigit(fdname[0])) {
        monitor_printf(mon, "getfd: monitor names may not begin with a number\n");
        return;
    }

    fd = dup(fd);
    if (fd == -1) {
        monitor_printf(mon, "Failed to dup() file descriptor: %s\n",
                       strerror(errno));
        return;
    }

B
Blue Swirl 已提交
1737
    QLIST_FOREACH(monfd, &mon->fds, next) {
1738 1739 1740 1741 1742 1743 1744 1745 1746
        if (strcmp(monfd->name, fdname) != 0) {
            continue;
        }

        close(monfd->fd);
        monfd->fd = fd;
        return;
    }

A
Anthony Liguori 已提交
1747
    monfd = qemu_mallocz(sizeof(mon_fd_t));
1748 1749 1750
    monfd->name = qemu_strdup(fdname);
    monfd->fd = fd;

B
Blue Swirl 已提交
1751
    QLIST_INSERT_HEAD(&mon->fds, monfd, next);
1752 1753
}

1754
static void do_closefd(Monitor *mon, const QDict *qdict)
1755
{
1756
    const char *fdname = qdict_get_str(qdict, "fdname");
A
Anthony Liguori 已提交
1757
    mon_fd_t *monfd;
1758

B
Blue Swirl 已提交
1759
    QLIST_FOREACH(monfd, &mon->fds, next) {
1760 1761 1762 1763
        if (strcmp(monfd->name, fdname) != 0) {
            continue;
        }

B
Blue Swirl 已提交
1764
        QLIST_REMOVE(monfd, next);
1765 1766 1767 1768 1769 1770 1771 1772 1773 1774
        close(monfd->fd);
        qemu_free(monfd->name);
        qemu_free(monfd);
        return;
    }

    monitor_printf(mon, "Failed to find file descriptor named %s\n",
                   fdname);
}

1775
static void do_loadvm(Monitor *mon, const QDict *qdict)
J
Juan Quintela 已提交
1776 1777
{
    int saved_vm_running  = vm_running;
1778
    const char *name = qdict_get_str(qdict, "name");
J
Juan Quintela 已提交
1779 1780 1781

    vm_stop(0);

1782
    if (load_vmstate(mon, name) >= 0 && saved_vm_running)
J
Juan Quintela 已提交
1783 1784 1785
        vm_start();
}

1786 1787
int monitor_get_fd(Monitor *mon, const char *fdname)
{
A
Anthony Liguori 已提交
1788
    mon_fd_t *monfd;
1789

B
Blue Swirl 已提交
1790
    QLIST_FOREACH(monfd, &mon->fds, next) {
1791 1792 1793 1794 1795 1796 1797 1798 1799
        int fd;

        if (strcmp(monfd->name, fdname) != 0) {
            continue;
        }

        fd = monfd->fd;

        /* caller takes ownership of fd */
B
Blue Swirl 已提交
1800
        QLIST_REMOVE(monfd, next);
1801 1802 1803 1804 1805 1806 1807 1808 1809
        qemu_free(monfd->name);
        qemu_free(monfd);

        return fd;
    }

    return -1;
}

A
Anthony Liguori 已提交
1810
static const mon_cmd_t mon_cmds[] = {
1811
#include "qemu-monitor.h"
1812
    { NULL, NULL, },
B
bellard 已提交
1813 1814
};

1815
/* Please update qemu-monitor.hx when adding or changing commands */
A
Anthony Liguori 已提交
1816
static const mon_cmd_t info_cmds[] = {
1817 1818 1819 1820 1821
    {
        .name       = "version",
        .args_type  = "",
        .params     = "",
        .help       = "show the version of QEMU",
L
Luiz Capitulino 已提交
1822
        .mhandler.info = do_info_version,
1823 1824 1825 1826 1827 1828
    },
    {
        .name       = "network",
        .args_type  = "",
        .params     = "",
        .help       = "show the network state",
L
Luiz Capitulino 已提交
1829
        .mhandler.info = do_info_network,
1830 1831 1832 1833 1834 1835
    },
    {
        .name       = "chardev",
        .args_type  = "",
        .params     = "",
        .help       = "show the character devices",
L
Luiz Capitulino 已提交
1836
        .mhandler.info = qemu_chr_info,
1837 1838 1839 1840 1841 1842
    },
    {
        .name       = "block",
        .args_type  = "",
        .params     = "",
        .help       = "show the block devices",
L
Luiz Capitulino 已提交
1843
        .mhandler.info = bdrv_info,
1844 1845 1846 1847 1848 1849
    },
    {
        .name       = "blockstats",
        .args_type  = "",
        .params     = "",
        .help       = "show block device statistics",
L
Luiz Capitulino 已提交
1850
        .mhandler.info = bdrv_info_stats,
1851 1852 1853 1854 1855 1856
    },
    {
        .name       = "registers",
        .args_type  = "",
        .params     = "",
        .help       = "show the cpu registers",
L
Luiz Capitulino 已提交
1857
        .mhandler.info = do_info_registers,
1858 1859 1860 1861 1862 1863
    },
    {
        .name       = "cpus",
        .args_type  = "",
        .params     = "",
        .help       = "show infos for each CPU",
L
Luiz Capitulino 已提交
1864
        .mhandler.info = do_info_cpus,
1865 1866 1867 1868 1869 1870
    },
    {
        .name       = "history",
        .args_type  = "",
        .params     = "",
        .help       = "show the command line history",
L
Luiz Capitulino 已提交
1871
        .mhandler.info = do_info_history,
1872 1873 1874 1875 1876 1877
    },
    {
        .name       = "irq",
        .args_type  = "",
        .params     = "",
        .help       = "show the interrupts statistics (if available)",
L
Luiz Capitulino 已提交
1878
        .mhandler.info = irq_info,
1879 1880 1881 1882 1883 1884
    },
    {
        .name       = "pic",
        .args_type  = "",
        .params     = "",
        .help       = "show i8259 (PIC) state",
L
Luiz Capitulino 已提交
1885
        .mhandler.info = pic_info,
1886 1887 1888 1889 1890 1891
    },
    {
        .name       = "pci",
        .args_type  = "",
        .params     = "",
        .help       = "show PCI info",
L
Luiz Capitulino 已提交
1892
        .mhandler.info = pci_info,
1893
    },
A
aurel32 已提交
1894
#if defined(TARGET_I386) || defined(TARGET_SH4)
1895 1896 1897 1898 1899
    {
        .name       = "tlb",
        .args_type  = "",
        .params     = "",
        .help       = "show virtual to physical memory mappings",
L
Luiz Capitulino 已提交
1900
        .mhandler.info = tlb_info,
1901
    },
A
aurel32 已提交
1902 1903
#endif
#if defined(TARGET_I386)
1904 1905 1906 1907 1908
    {
        .name       = "mem",
        .args_type  = "",
        .params     = "",
        .help       = "show the active virtual memory mappings",
L
Luiz Capitulino 已提交
1909
        .mhandler.info = mem_info,
1910 1911 1912 1913 1914 1915
    },
    {
        .name       = "hpet",
        .args_type  = "",
        .params     = "",
        .help       = "show state of HPET",
L
Luiz Capitulino 已提交
1916
        .mhandler.info = do_info_hpet,
1917
    },
B
bellard 已提交
1918
#endif
1919 1920 1921 1922 1923
    {
        .name       = "jit",
        .args_type  = "",
        .params     = "",
        .help       = "show dynamic compiler info",
L
Luiz Capitulino 已提交
1924
        .mhandler.info = do_info_jit,
1925 1926 1927 1928 1929 1930
    },
    {
        .name       = "kvm",
        .args_type  = "",
        .params     = "",
        .help       = "show KVM information",
L
Luiz Capitulino 已提交
1931
        .mhandler.info = do_info_kvm,
1932 1933 1934 1935 1936 1937
    },
    {
        .name       = "numa",
        .args_type  = "",
        .params     = "",
        .help       = "show NUMA information",
L
Luiz Capitulino 已提交
1938
        .mhandler.info = do_info_numa,
1939 1940 1941 1942 1943 1944
    },
    {
        .name       = "usb",
        .args_type  = "",
        .params     = "",
        .help       = "show guest USB devices",
L
Luiz Capitulino 已提交
1945
        .mhandler.info = usb_info,
1946 1947 1948 1949 1950 1951
    },
    {
        .name       = "usbhost",
        .args_type  = "",
        .params     = "",
        .help       = "show host USB devices",
L
Luiz Capitulino 已提交
1952
        .mhandler.info = usb_host_info,
1953 1954 1955 1956 1957 1958
    },
    {
        .name       = "profile",
        .args_type  = "",
        .params     = "",
        .help       = "show profiling information",
L
Luiz Capitulino 已提交
1959
        .mhandler.info = do_info_profile,
1960 1961 1962 1963 1964 1965
    },
    {
        .name       = "capture",
        .args_type  = "",
        .params     = "",
        .help       = "show capture information",
L
Luiz Capitulino 已提交
1966
        .mhandler.info = do_info_capture,
1967 1968 1969 1970 1971 1972
    },
    {
        .name       = "snapshots",
        .args_type  = "",
        .params     = "",
        .help       = "show the currently saved VM snapshots",
L
Luiz Capitulino 已提交
1973
        .mhandler.info = do_info_snapshots,
1974 1975 1976 1977 1978 1979
    },
    {
        .name       = "status",
        .args_type  = "",
        .params     = "",
        .help       = "show the current VM status (running|paused)",
L
Luiz Capitulino 已提交
1980
        .mhandler.info = do_info_status,
1981 1982 1983 1984 1985 1986
    },
    {
        .name       = "pcmcia",
        .args_type  = "",
        .params     = "",
        .help       = "show guest PCMCIA status",
L
Luiz Capitulino 已提交
1987
        .mhandler.info = pcmcia_info,
1988 1989 1990 1991 1992 1993
    },
    {
        .name       = "mice",
        .args_type  = "",
        .params     = "",
        .help       = "show which guest mouse is receiving events",
L
Luiz Capitulino 已提交
1994
        .mhandler.info = do_info_mice,
1995 1996 1997 1998 1999 2000
    },
    {
        .name       = "vnc",
        .args_type  = "",
        .params     = "",
        .help       = "show the vnc server status",
L
Luiz Capitulino 已提交
2001
        .mhandler.info = do_info_vnc,
2002 2003 2004 2005 2006 2007
    },
    {
        .name       = "name",
        .args_type  = "",
        .params     = "",
        .help       = "show the current VM name",
L
Luiz Capitulino 已提交
2008
        .mhandler.info = do_info_name,
2009 2010 2011 2012 2013 2014
    },
    {
        .name       = "uuid",
        .args_type  = "",
        .params     = "",
        .help       = "show the current VM UUID",
L
Luiz Capitulino 已提交
2015
        .mhandler.info = do_info_uuid,
2016
    },
2017
#if defined(TARGET_PPC)
2018 2019 2020 2021 2022
    {
        .name       = "cpustats",
        .args_type  = "",
        .params     = "",
        .help       = "show CPU statistics",
L
Luiz Capitulino 已提交
2023
        .mhandler.info = do_info_cpu_stats,
2024
    },
2025
#endif
2026
#if defined(CONFIG_SLIRP)
2027 2028 2029 2030 2031
    {
        .name       = "usernet",
        .args_type  = "",
        .params     = "",
        .help       = "show user network stack connection states",
L
Luiz Capitulino 已提交
2032
        .mhandler.info = do_info_usernet,
2033
    },
2034
#endif
2035 2036 2037 2038 2039
    {
        .name       = "migrate",
        .args_type  = "",
        .params     = "",
        .help       = "show migration status",
L
Luiz Capitulino 已提交
2040
        .mhandler.info = do_info_migrate,
2041 2042 2043 2044 2045 2046
    },
    {
        .name       = "balloon",
        .args_type  = "",
        .params     = "",
        .help       = "show balloon information",
L
Luiz Capitulino 已提交
2047
        .mhandler.info = do_info_balloon,
2048 2049 2050 2051 2052 2053
    },
    {
        .name       = "qtree",
        .args_type  = "",
        .params     = "",
        .help       = "show device tree",
L
Luiz Capitulino 已提交
2054
        .mhandler.info = do_info_qtree,
2055 2056 2057 2058 2059 2060
    },
    {
        .name       = "qdm",
        .args_type  = "",
        .params     = "",
        .help       = "show qdev device model list",
L
Luiz Capitulino 已提交
2061
        .mhandler.info = do_info_qdm,
2062 2063 2064 2065 2066 2067
    },
    {
        .name       = "roms",
        .args_type  = "",
        .params     = "",
        .help       = "show roms",
L
Luiz Capitulino 已提交
2068
        .mhandler.info = do_info_roms,
2069 2070 2071 2072
    },
    {
        .name       = NULL,
    },
B
bellard 已提交
2073 2074
};

2075 2076 2077 2078 2079
/*******************************************************************/

static const char *pch;
static jmp_buf expr_env;

B
bellard 已提交
2080 2081 2082
#define MD_TLONG 0
#define MD_I32   1

2083 2084 2085
typedef struct MonitorDef {
    const char *name;
    int offset;
B
blueswir1 已提交
2086
    target_long (*get_value)(const struct MonitorDef *md, int val);
B
bellard 已提交
2087
    int type;
2088 2089
} MonitorDef;

B
bellard 已提交
2090
#if defined(TARGET_I386)
B
blueswir1 已提交
2091
static target_long monitor_get_pc (const struct MonitorDef *md, int val)
B
bellard 已提交
2092
{
B
bellard 已提交
2093 2094 2095 2096
    CPUState *env = mon_get_cpu();
    if (!env)
        return 0;
    return env->eip + env->segs[R_CS].base;
B
bellard 已提交
2097 2098 2099
}
#endif

2100
#if defined(TARGET_PPC)
B
blueswir1 已提交
2101
static target_long monitor_get_ccr (const struct MonitorDef *md, int val)
2102
{
B
bellard 已提交
2103
    CPUState *env = mon_get_cpu();
2104 2105 2106
    unsigned int u;
    int i;

B
bellard 已提交
2107 2108 2109
    if (!env)
        return 0;

2110 2111
    u = 0;
    for (i = 0; i < 8; i++)
2112
        u |= env->crf[i] << (32 - (4 * i));
2113 2114 2115 2116

    return u;
}

B
blueswir1 已提交
2117
static target_long monitor_get_msr (const struct MonitorDef *md, int val)
2118
{
B
bellard 已提交
2119 2120 2121
    CPUState *env = mon_get_cpu();
    if (!env)
        return 0;
2122
    return env->msr;
2123 2124
}

B
blueswir1 已提交
2125
static target_long monitor_get_xer (const struct MonitorDef *md, int val)
2126
{
B
bellard 已提交
2127 2128 2129
    CPUState *env = mon_get_cpu();
    if (!env)
        return 0;
A
aurel32 已提交
2130
    return env->xer;
2131
}
2132

B
blueswir1 已提交
2133
static target_long monitor_get_decr (const struct MonitorDef *md, int val)
2134
{
B
bellard 已提交
2135 2136 2137 2138
    CPUState *env = mon_get_cpu();
    if (!env)
        return 0;
    return cpu_ppc_load_decr(env);
2139 2140
}

B
blueswir1 已提交
2141
static target_long monitor_get_tbu (const struct MonitorDef *md, int val)
2142
{
B
bellard 已提交
2143 2144 2145 2146
    CPUState *env = mon_get_cpu();
    if (!env)
        return 0;
    return cpu_ppc_load_tbu(env);
2147 2148
}

B
blueswir1 已提交
2149
static target_long monitor_get_tbl (const struct MonitorDef *md, int val)
2150
{
B
bellard 已提交
2151 2152 2153 2154
    CPUState *env = mon_get_cpu();
    if (!env)
        return 0;
    return cpu_ppc_load_tbl(env);
2155
}
2156 2157
#endif

2158
#if defined(TARGET_SPARC)
B
bellard 已提交
2159
#ifndef TARGET_SPARC64
B
blueswir1 已提交
2160
static target_long monitor_get_psr (const struct MonitorDef *md, int val)
2161
{
B
bellard 已提交
2162 2163 2164 2165
    CPUState *env = mon_get_cpu();
    if (!env)
        return 0;
    return GET_PSR(env);
2166
}
B
bellard 已提交
2167
#endif
2168

B
blueswir1 已提交
2169
static target_long monitor_get_reg(const struct MonitorDef *md, int val)
2170
{
B
bellard 已提交
2171 2172 2173 2174
    CPUState *env = mon_get_cpu();
    if (!env)
        return 0;
    return env->regwptr[val];
2175 2176 2177
}
#endif

B
blueswir1 已提交
2178
static const MonitorDef monitor_defs[] = {
2179
#ifdef TARGET_I386
B
bellard 已提交
2180 2181

#define SEG(name, seg) \
B
bellard 已提交
2182
    { name, offsetof(CPUState, segs[seg].selector), NULL, MD_I32 },\
B
bellard 已提交
2183
    { name ".base", offsetof(CPUState, segs[seg].base) },\
B
bellard 已提交
2184
    { name ".limit", offsetof(CPUState, segs[seg].limit), NULL, MD_I32 },
B
bellard 已提交
2185

2186 2187 2188 2189 2190 2191 2192
    { "eax", offsetof(CPUState, regs[0]) },
    { "ecx", offsetof(CPUState, regs[1]) },
    { "edx", offsetof(CPUState, regs[2]) },
    { "ebx", offsetof(CPUState, regs[3]) },
    { "esp|sp", offsetof(CPUState, regs[4]) },
    { "ebp|fp", offsetof(CPUState, regs[5]) },
    { "esi", offsetof(CPUState, regs[6]) },
B
bellard 已提交
2193
    { "edi", offsetof(CPUState, regs[7]) },
B
bellard 已提交
2194 2195 2196 2197 2198 2199 2200 2201 2202 2203
#ifdef TARGET_X86_64
    { "r8", offsetof(CPUState, regs[8]) },
    { "r9", offsetof(CPUState, regs[9]) },
    { "r10", offsetof(CPUState, regs[10]) },
    { "r11", offsetof(CPUState, regs[11]) },
    { "r12", offsetof(CPUState, regs[12]) },
    { "r13", offsetof(CPUState, regs[13]) },
    { "r14", offsetof(CPUState, regs[14]) },
    { "r15", offsetof(CPUState, regs[15]) },
#endif
2204
    { "eflags", offsetof(CPUState, eflags) },
B
bellard 已提交
2205 2206 2207 2208
    { "eip", offsetof(CPUState, eip) },
    SEG("cs", R_CS)
    SEG("ds", R_DS)
    SEG("es", R_ES)
B
bellard 已提交
2209
    SEG("ss", R_SS)
B
bellard 已提交
2210 2211 2212
    SEG("fs", R_FS)
    SEG("gs", R_GS)
    { "pc", 0, monitor_get_pc, },
2213
#elif defined(TARGET_PPC)
J
j_mayer 已提交
2214
    /* General purpose registers */
2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246
    { "r0", offsetof(CPUState, gpr[0]) },
    { "r1", offsetof(CPUState, gpr[1]) },
    { "r2", offsetof(CPUState, gpr[2]) },
    { "r3", offsetof(CPUState, gpr[3]) },
    { "r4", offsetof(CPUState, gpr[4]) },
    { "r5", offsetof(CPUState, gpr[5]) },
    { "r6", offsetof(CPUState, gpr[6]) },
    { "r7", offsetof(CPUState, gpr[7]) },
    { "r8", offsetof(CPUState, gpr[8]) },
    { "r9", offsetof(CPUState, gpr[9]) },
    { "r10", offsetof(CPUState, gpr[10]) },
    { "r11", offsetof(CPUState, gpr[11]) },
    { "r12", offsetof(CPUState, gpr[12]) },
    { "r13", offsetof(CPUState, gpr[13]) },
    { "r14", offsetof(CPUState, gpr[14]) },
    { "r15", offsetof(CPUState, gpr[15]) },
    { "r16", offsetof(CPUState, gpr[16]) },
    { "r17", offsetof(CPUState, gpr[17]) },
    { "r18", offsetof(CPUState, gpr[18]) },
    { "r19", offsetof(CPUState, gpr[19]) },
    { "r20", offsetof(CPUState, gpr[20]) },
    { "r21", offsetof(CPUState, gpr[21]) },
    { "r22", offsetof(CPUState, gpr[22]) },
    { "r23", offsetof(CPUState, gpr[23]) },
    { "r24", offsetof(CPUState, gpr[24]) },
    { "r25", offsetof(CPUState, gpr[25]) },
    { "r26", offsetof(CPUState, gpr[26]) },
    { "r27", offsetof(CPUState, gpr[27]) },
    { "r28", offsetof(CPUState, gpr[28]) },
    { "r29", offsetof(CPUState, gpr[29]) },
    { "r30", offsetof(CPUState, gpr[30]) },
    { "r31", offsetof(CPUState, gpr[31]) },
J
j_mayer 已提交
2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281
    /* Floating point registers */
    { "f0", offsetof(CPUState, fpr[0]) },
    { "f1", offsetof(CPUState, fpr[1]) },
    { "f2", offsetof(CPUState, fpr[2]) },
    { "f3", offsetof(CPUState, fpr[3]) },
    { "f4", offsetof(CPUState, fpr[4]) },
    { "f5", offsetof(CPUState, fpr[5]) },
    { "f6", offsetof(CPUState, fpr[6]) },
    { "f7", offsetof(CPUState, fpr[7]) },
    { "f8", offsetof(CPUState, fpr[8]) },
    { "f9", offsetof(CPUState, fpr[9]) },
    { "f10", offsetof(CPUState, fpr[10]) },
    { "f11", offsetof(CPUState, fpr[11]) },
    { "f12", offsetof(CPUState, fpr[12]) },
    { "f13", offsetof(CPUState, fpr[13]) },
    { "f14", offsetof(CPUState, fpr[14]) },
    { "f15", offsetof(CPUState, fpr[15]) },
    { "f16", offsetof(CPUState, fpr[16]) },
    { "f17", offsetof(CPUState, fpr[17]) },
    { "f18", offsetof(CPUState, fpr[18]) },
    { "f19", offsetof(CPUState, fpr[19]) },
    { "f20", offsetof(CPUState, fpr[20]) },
    { "f21", offsetof(CPUState, fpr[21]) },
    { "f22", offsetof(CPUState, fpr[22]) },
    { "f23", offsetof(CPUState, fpr[23]) },
    { "f24", offsetof(CPUState, fpr[24]) },
    { "f25", offsetof(CPUState, fpr[25]) },
    { "f26", offsetof(CPUState, fpr[26]) },
    { "f27", offsetof(CPUState, fpr[27]) },
    { "f28", offsetof(CPUState, fpr[28]) },
    { "f29", offsetof(CPUState, fpr[29]) },
    { "f30", offsetof(CPUState, fpr[30]) },
    { "f31", offsetof(CPUState, fpr[31]) },
    { "fpscr", offsetof(CPUState, fpscr) },
    /* Next instruction pointer */
B
bellard 已提交
2282
    { "nip|pc", offsetof(CPUState, nip) },
2283 2284
    { "lr", offsetof(CPUState, lr) },
    { "ctr", offsetof(CPUState, ctr) },
2285
    { "decr", 0, &monitor_get_decr, },
2286
    { "ccr", 0, &monitor_get_ccr, },
J
j_mayer 已提交
2287
    /* Machine state register */
2288 2289
    { "msr", 0, &monitor_get_msr, },
    { "xer", 0, &monitor_get_xer, },
2290 2291
    { "tbu", 0, &monitor_get_tbu, },
    { "tbl", 0, &monitor_get_tbl, },
J
j_mayer 已提交
2292 2293 2294 2295 2296
#if defined(TARGET_PPC64)
    /* Address space register */
    { "asr", offsetof(CPUState, asr) },
#endif
    /* Segment registers */
2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314
    { "sdr1", offsetof(CPUState, sdr1) },
    { "sr0", offsetof(CPUState, sr[0]) },
    { "sr1", offsetof(CPUState, sr[1]) },
    { "sr2", offsetof(CPUState, sr[2]) },
    { "sr3", offsetof(CPUState, sr[3]) },
    { "sr4", offsetof(CPUState, sr[4]) },
    { "sr5", offsetof(CPUState, sr[5]) },
    { "sr6", offsetof(CPUState, sr[6]) },
    { "sr7", offsetof(CPUState, sr[7]) },
    { "sr8", offsetof(CPUState, sr[8]) },
    { "sr9", offsetof(CPUState, sr[9]) },
    { "sr10", offsetof(CPUState, sr[10]) },
    { "sr11", offsetof(CPUState, sr[11]) },
    { "sr12", offsetof(CPUState, sr[12]) },
    { "sr13", offsetof(CPUState, sr[13]) },
    { "sr14", offsetof(CPUState, sr[14]) },
    { "sr15", offsetof(CPUState, sr[15]) },
    /* Too lazy to put BATs and SPRs ... */
2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350
#elif defined(TARGET_SPARC)
    { "g0", offsetof(CPUState, gregs[0]) },
    { "g1", offsetof(CPUState, gregs[1]) },
    { "g2", offsetof(CPUState, gregs[2]) },
    { "g3", offsetof(CPUState, gregs[3]) },
    { "g4", offsetof(CPUState, gregs[4]) },
    { "g5", offsetof(CPUState, gregs[5]) },
    { "g6", offsetof(CPUState, gregs[6]) },
    { "g7", offsetof(CPUState, gregs[7]) },
    { "o0", 0, monitor_get_reg },
    { "o1", 1, monitor_get_reg },
    { "o2", 2, monitor_get_reg },
    { "o3", 3, monitor_get_reg },
    { "o4", 4, monitor_get_reg },
    { "o5", 5, monitor_get_reg },
    { "o6", 6, monitor_get_reg },
    { "o7", 7, monitor_get_reg },
    { "l0", 8, monitor_get_reg },
    { "l1", 9, monitor_get_reg },
    { "l2", 10, monitor_get_reg },
    { "l3", 11, monitor_get_reg },
    { "l4", 12, monitor_get_reg },
    { "l5", 13, monitor_get_reg },
    { "l6", 14, monitor_get_reg },
    { "l7", 15, monitor_get_reg },
    { "i0", 16, monitor_get_reg },
    { "i1", 17, monitor_get_reg },
    { "i2", 18, monitor_get_reg },
    { "i3", 19, monitor_get_reg },
    { "i4", 20, monitor_get_reg },
    { "i5", 21, monitor_get_reg },
    { "i6", 22, monitor_get_reg },
    { "i7", 23, monitor_get_reg },
    { "pc", offsetof(CPUState, pc) },
    { "npc", offsetof(CPUState, npc) },
    { "y", offsetof(CPUState, y) },
B
bellard 已提交
2351
#ifndef TARGET_SPARC64
2352 2353
    { "psr", 0, &monitor_get_psr, },
    { "wim", offsetof(CPUState, wim) },
B
bellard 已提交
2354
#endif
2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388
    { "tbr", offsetof(CPUState, tbr) },
    { "fsr", offsetof(CPUState, fsr) },
    { "f0", offsetof(CPUState, fpr[0]) },
    { "f1", offsetof(CPUState, fpr[1]) },
    { "f2", offsetof(CPUState, fpr[2]) },
    { "f3", offsetof(CPUState, fpr[3]) },
    { "f4", offsetof(CPUState, fpr[4]) },
    { "f5", offsetof(CPUState, fpr[5]) },
    { "f6", offsetof(CPUState, fpr[6]) },
    { "f7", offsetof(CPUState, fpr[7]) },
    { "f8", offsetof(CPUState, fpr[8]) },
    { "f9", offsetof(CPUState, fpr[9]) },
    { "f10", offsetof(CPUState, fpr[10]) },
    { "f11", offsetof(CPUState, fpr[11]) },
    { "f12", offsetof(CPUState, fpr[12]) },
    { "f13", offsetof(CPUState, fpr[13]) },
    { "f14", offsetof(CPUState, fpr[14]) },
    { "f15", offsetof(CPUState, fpr[15]) },
    { "f16", offsetof(CPUState, fpr[16]) },
    { "f17", offsetof(CPUState, fpr[17]) },
    { "f18", offsetof(CPUState, fpr[18]) },
    { "f19", offsetof(CPUState, fpr[19]) },
    { "f20", offsetof(CPUState, fpr[20]) },
    { "f21", offsetof(CPUState, fpr[21]) },
    { "f22", offsetof(CPUState, fpr[22]) },
    { "f23", offsetof(CPUState, fpr[23]) },
    { "f24", offsetof(CPUState, fpr[24]) },
    { "f25", offsetof(CPUState, fpr[25]) },
    { "f26", offsetof(CPUState, fpr[26]) },
    { "f27", offsetof(CPUState, fpr[27]) },
    { "f28", offsetof(CPUState, fpr[28]) },
    { "f29", offsetof(CPUState, fpr[29]) },
    { "f30", offsetof(CPUState, fpr[30]) },
    { "f31", offsetof(CPUState, fpr[31]) },
B
bellard 已提交
2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414
#ifdef TARGET_SPARC64
    { "f32", offsetof(CPUState, fpr[32]) },
    { "f34", offsetof(CPUState, fpr[34]) },
    { "f36", offsetof(CPUState, fpr[36]) },
    { "f38", offsetof(CPUState, fpr[38]) },
    { "f40", offsetof(CPUState, fpr[40]) },
    { "f42", offsetof(CPUState, fpr[42]) },
    { "f44", offsetof(CPUState, fpr[44]) },
    { "f46", offsetof(CPUState, fpr[46]) },
    { "f48", offsetof(CPUState, fpr[48]) },
    { "f50", offsetof(CPUState, fpr[50]) },
    { "f52", offsetof(CPUState, fpr[52]) },
    { "f54", offsetof(CPUState, fpr[54]) },
    { "f56", offsetof(CPUState, fpr[56]) },
    { "f58", offsetof(CPUState, fpr[58]) },
    { "f60", offsetof(CPUState, fpr[60]) },
    { "f62", offsetof(CPUState, fpr[62]) },
    { "asi", offsetof(CPUState, asi) },
    { "pstate", offsetof(CPUState, pstate) },
    { "cansave", offsetof(CPUState, cansave) },
    { "canrestore", offsetof(CPUState, canrestore) },
    { "otherwin", offsetof(CPUState, otherwin) },
    { "wstate", offsetof(CPUState, wstate) },
    { "cleanwin", offsetof(CPUState, cleanwin) },
    { "fprs", offsetof(CPUState, fprs) },
#endif
2415 2416 2417 2418
#endif
    { NULL },
};

A
aliguori 已提交
2419
static void expr_error(Monitor *mon, const char *msg)
B
bellard 已提交
2420
{
A
aliguori 已提交
2421
    monitor_printf(mon, "%s\n", msg);
2422 2423 2424
    longjmp(expr_env, 1);
}

B
bellard 已提交
2425
/* return 0 if OK, -1 if not found, -2 if no CPU defined */
B
bellard 已提交
2426
static int get_monitor_def(target_long *pval, const char *name)
2427
{
B
blueswir1 已提交
2428
    const MonitorDef *md;
B
bellard 已提交
2429 2430
    void *ptr;

2431 2432 2433
    for(md = monitor_defs; md->name != NULL; md++) {
        if (compare_cmd(name, md->name)) {
            if (md->get_value) {
2434
                *pval = md->get_value(md, md->offset);
2435
            } else {
B
bellard 已提交
2436 2437 2438 2439
                CPUState *env = mon_get_cpu();
                if (!env)
                    return -2;
                ptr = (uint8_t *)env + md->offset;
B
bellard 已提交
2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450
                switch(md->type) {
                case MD_I32:
                    *pval = *(int32_t *)ptr;
                    break;
                case MD_TLONG:
                    *pval = *(target_long *)ptr;
                    break;
                default:
                    *pval = 0;
                    break;
                }
2451 2452 2453 2454 2455 2456 2457 2458 2459
            }
            return 0;
        }
    }
    return -1;
}

static void next(void)
{
2460
    if (*pch != '\0') {
2461
        pch++;
2462
        while (qemu_isspace(*pch))
2463 2464 2465 2466
            pch++;
    }
}

A
aliguori 已提交
2467
static int64_t expr_sum(Monitor *mon);
2468

A
aliguori 已提交
2469
static int64_t expr_unary(Monitor *mon)
2470
{
B
blueswir1 已提交
2471
    int64_t n;
2472
    char *p;
B
bellard 已提交
2473
    int ret;
2474 2475 2476 2477

    switch(*pch) {
    case '+':
        next();
A
aliguori 已提交
2478
        n = expr_unary(mon);
2479 2480 2481
        break;
    case '-':
        next();
A
aliguori 已提交
2482
        n = -expr_unary(mon);
2483 2484 2485
        break;
    case '~':
        next();
A
aliguori 已提交
2486
        n = ~expr_unary(mon);
2487 2488 2489
        break;
    case '(':
        next();
A
aliguori 已提交
2490
        n = expr_sum(mon);
2491
        if (*pch != ')') {
A
aliguori 已提交
2492
            expr_error(mon, "')' expected");
2493 2494 2495
        }
        next();
        break;
B
bellard 已提交
2496 2497 2498
    case '\'':
        pch++;
        if (*pch == '\0')
A
aliguori 已提交
2499
            expr_error(mon, "character constant expected");
B
bellard 已提交
2500 2501 2502
        n = *pch;
        pch++;
        if (*pch != '\'')
A
aliguori 已提交
2503
            expr_error(mon, "missing terminating \' character");
B
bellard 已提交
2504 2505
        next();
        break;
2506 2507 2508
    case '$':
        {
            char buf[128], *q;
2509
            target_long reg=0;
2510

2511 2512 2513 2514 2515
            pch++;
            q = buf;
            while ((*pch >= 'a' && *pch <= 'z') ||
                   (*pch >= 'A' && *pch <= 'Z') ||
                   (*pch >= '0' && *pch <= '9') ||
B
bellard 已提交
2516
                   *pch == '_' || *pch == '.') {
2517 2518 2519 2520
                if ((q - buf) < sizeof(buf) - 1)
                    *q++ = *pch;
                pch++;
            }
2521
            while (qemu_isspace(*pch))
2522 2523
                pch++;
            *q = 0;
2524
            ret = get_monitor_def(&reg, buf);
B
bellard 已提交
2525
            if (ret == -1)
A
aliguori 已提交
2526
                expr_error(mon, "unknown register");
2527
            else if (ret == -2)
A
aliguori 已提交
2528
                expr_error(mon, "no cpu defined");
2529
            n = reg;
2530 2531 2532
        }
        break;
    case '\0':
A
aliguori 已提交
2533
        expr_error(mon, "unexpected end of expression");
2534 2535 2536
        n = 0;
        break;
    default:
2537
#if TARGET_PHYS_ADDR_BITS > 32
B
bellard 已提交
2538 2539
        n = strtoull(pch, &p, 0);
#else
2540
        n = strtoul(pch, &p, 0);
B
bellard 已提交
2541
#endif
2542
        if (pch == p) {
A
aliguori 已提交
2543
            expr_error(mon, "invalid char in expression");
2544 2545
        }
        pch = p;
2546
        while (qemu_isspace(*pch))
2547 2548 2549 2550 2551 2552 2553
            pch++;
        break;
    }
    return n;
}


A
aliguori 已提交
2554
static int64_t expr_prod(Monitor *mon)
2555
{
B
blueswir1 已提交
2556
    int64_t val, val2;
B
bellard 已提交
2557
    int op;
2558

A
aliguori 已提交
2559
    val = expr_unary(mon);
2560 2561 2562 2563 2564
    for(;;) {
        op = *pch;
        if (op != '*' && op != '/' && op != '%')
            break;
        next();
A
aliguori 已提交
2565
        val2 = expr_unary(mon);
2566 2567 2568 2569 2570 2571 2572
        switch(op) {
        default:
        case '*':
            val *= val2;
            break;
        case '/':
        case '%':
2573
            if (val2 == 0)
A
aliguori 已提交
2574
                expr_error(mon, "division by zero");
2575 2576 2577 2578 2579 2580 2581 2582 2583 2584
            if (op == '/')
                val /= val2;
            else
                val %= val2;
            break;
        }
    }
    return val;
}

A
aliguori 已提交
2585
static int64_t expr_logic(Monitor *mon)
2586
{
B
blueswir1 已提交
2587
    int64_t val, val2;
B
bellard 已提交
2588
    int op;
2589

A
aliguori 已提交
2590
    val = expr_prod(mon);
2591 2592 2593 2594 2595
    for(;;) {
        op = *pch;
        if (op != '&' && op != '|' && op != '^')
            break;
        next();
A
aliguori 已提交
2596
        val2 = expr_prod(mon);
2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612
        switch(op) {
        default:
        case '&':
            val &= val2;
            break;
        case '|':
            val |= val2;
            break;
        case '^':
            val ^= val2;
            break;
        }
    }
    return val;
}

A
aliguori 已提交
2613
static int64_t expr_sum(Monitor *mon)
2614
{
B
blueswir1 已提交
2615
    int64_t val, val2;
B
bellard 已提交
2616
    int op;
2617

A
aliguori 已提交
2618
    val = expr_logic(mon);
2619 2620 2621 2622 2623
    for(;;) {
        op = *pch;
        if (op != '+' && op != '-')
            break;
        next();
A
aliguori 已提交
2624
        val2 = expr_logic(mon);
2625 2626 2627 2628 2629 2630 2631 2632
        if (op == '+')
            val += val2;
        else
            val -= val2;
    }
    return val;
}

A
aliguori 已提交
2633
static int get_expr(Monitor *mon, int64_t *pval, const char **pp)
2634 2635 2636 2637 2638 2639
{
    pch = *pp;
    if (setjmp(expr_env)) {
        *pp = pch;
        return -1;
    }
2640
    while (qemu_isspace(*pch))
2641
        pch++;
A
aliguori 已提交
2642
    *pval = expr_sum(mon);
2643 2644 2645 2646 2647 2648 2649 2650 2651 2652
    *pp = pch;
    return 0;
}

static int get_str(char *buf, int buf_size, const char **pp)
{
    const char *p;
    char *q;
    int c;

B
bellard 已提交
2653
    q = buf;
2654
    p = *pp;
2655
    while (qemu_isspace(*p))
2656 2657 2658
        p++;
    if (*p == '\0') {
    fail:
B
bellard 已提交
2659
        *q = '\0';
2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694
        *pp = p;
        return -1;
    }
    if (*p == '\"') {
        p++;
        while (*p != '\0' && *p != '\"') {
            if (*p == '\\') {
                p++;
                c = *p++;
                switch(c) {
                case 'n':
                    c = '\n';
                    break;
                case 'r':
                    c = '\r';
                    break;
                case '\\':
                case '\'':
                case '\"':
                    break;
                default:
                    qemu_printf("unsupported escape code: '\\%c'\n", c);
                    goto fail;
                }
                if ((q - buf) < buf_size - 1) {
                    *q++ = c;
                }
            } else {
                if ((q - buf) < buf_size - 1) {
                    *q++ = *p;
                }
                p++;
            }
        }
        if (*p != '\"') {
B
bellard 已提交
2695
            qemu_printf("unterminated string\n");
2696 2697 2698 2699
            goto fail;
        }
        p++;
    } else {
2700
        while (*p != '\0' && !qemu_isspace(*p)) {
2701 2702 2703 2704 2705 2706
            if ((q - buf) < buf_size - 1) {
                *q++ = *p;
            }
            p++;
        }
    }
B
bellard 已提交
2707
    *q = '\0';
2708 2709 2710 2711
    *pp = p;
    return 0;
}

2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737
/*
 * Store the command-name in cmdname, and return a pointer to
 * the remaining of the command string.
 */
static const char *get_command_name(const char *cmdline,
                                    char *cmdname, size_t nlen)
{
    size_t len;
    const char *p, *pstart;

    p = cmdline;
    while (qemu_isspace(*p))
        p++;
    if (*p == '\0')
        return NULL;
    pstart = p;
    while (*p != '\0' && *p != '/' && !qemu_isspace(*p))
        p++;
    len = p - pstart;
    if (len > nlen - 1)
        len = nlen - 1;
    memcpy(cmdname, pstart, len);
    cmdname[len] = '\0';
    return p;
}

2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764
/**
 * Read key of 'type' into 'key' and return the current
 * 'type' pointer.
 */
static char *key_get_info(const char *type, char **key)
{
    size_t len;
    char *p, *str;

    if (*type == ',')
        type++;

    p = strchr(type, ':');
    if (!p) {
        *key = NULL;
        return NULL;
    }
    len = p - type;

    str = qemu_malloc(len + 1);
    memcpy(str, type, len);
    str[len] = '\0';

    *key = str;
    return ++p;
}

2765 2766 2767 2768 2769
static int default_fmt_format = 'x';
static int default_fmt_size = 4;

#define MAX_ARGS 16

A
Anthony Liguori 已提交
2770
static const mon_cmd_t *monitor_parse_command(Monitor *mon,
2771 2772
                                              const char *cmdline,
                                              QDict *qdict)
2773
{
2774
    const char *p, *typestr;
2775
    int c;
A
Anthony Liguori 已提交
2776
    const mon_cmd_t *cmd;
2777 2778
    char cmdname[256];
    char buf[1024];
2779
    char *key;
B
bellard 已提交
2780 2781

#ifdef DEBUG
A
aliguori 已提交
2782
    monitor_printf(mon, "command='%s'\n", cmdline);
B
bellard 已提交
2783
#endif
2784

2785
    /* extract the command name */
2786 2787
    p = get_command_name(cmdline, cmdname, sizeof(cmdname));
    if (!p)
2788
        return NULL;
2789

2790
    /* find the command */
A
aliguori 已提交
2791
    for(cmd = mon_cmds; cmd->name != NULL; cmd++) {
2792
        if (compare_cmd(cmdname, cmd->name))
L
Luiz Capitulino 已提交
2793 2794 2795 2796 2797
            break;
    }

    if (cmd->name == NULL) {
        monitor_printf(mon, "unknown command: '%s'\n", cmdname);
2798
        return NULL;
2799 2800 2801 2802
    }

    /* parse the parameters */
    typestr = cmd->args_type;
B
bellard 已提交
2803
    for(;;) {
2804 2805
        typestr = key_get_info(typestr, &key);
        if (!typestr)
B
bellard 已提交
2806
            break;
2807
        c = *typestr;
2808 2809 2810
        typestr++;
        switch(c) {
        case 'F':
B
bellard 已提交
2811
        case 'B':
2812 2813 2814
        case 's':
            {
                int ret;
2815

2816
                while (qemu_isspace(*p))
2817 2818 2819 2820 2821
                    p++;
                if (*typestr == '?') {
                    typestr++;
                    if (*p == '\0') {
                        /* no optional string: NULL argument */
2822
                        break;
2823 2824 2825 2826
                    }
                }
                ret = get_str(buf, sizeof(buf), &p);
                if (ret < 0) {
B
bellard 已提交
2827 2828
                    switch(c) {
                    case 'F':
A
aliguori 已提交
2829 2830
                        monitor_printf(mon, "%s: filename expected\n",
                                       cmdname);
B
bellard 已提交
2831 2832
                        break;
                    case 'B':
A
aliguori 已提交
2833 2834
                        monitor_printf(mon, "%s: block device name expected\n",
                                       cmdname);
B
bellard 已提交
2835 2836
                        break;
                    default:
A
aliguori 已提交
2837
                        monitor_printf(mon, "%s: string expected\n", cmdname);
B
bellard 已提交
2838 2839
                        break;
                    }
2840 2841
                    goto fail;
                }
2842
                qdict_put(qdict, key, qstring_from_str(buf));
2843
            }
B
bellard 已提交
2844
            break;
2845 2846 2847
        case '/':
            {
                int count, format, size;
2848

2849
                while (qemu_isspace(*p))
2850 2851 2852 2853 2854
                    p++;
                if (*p == '/') {
                    /* format found */
                    p++;
                    count = 1;
2855
                    if (qemu_isdigit(*p)) {
2856
                        count = 0;
2857
                        while (qemu_isdigit(*p)) {
2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895
                            count = count * 10 + (*p - '0');
                            p++;
                        }
                    }
                    size = -1;
                    format = -1;
                    for(;;) {
                        switch(*p) {
                        case 'o':
                        case 'd':
                        case 'u':
                        case 'x':
                        case 'i':
                        case 'c':
                            format = *p++;
                            break;
                        case 'b':
                            size = 1;
                            p++;
                            break;
                        case 'h':
                            size = 2;
                            p++;
                            break;
                        case 'w':
                            size = 4;
                            p++;
                            break;
                        case 'g':
                        case 'L':
                            size = 8;
                            p++;
                            break;
                        default:
                            goto next;
                        }
                    }
                next:
2896
                    if (*p != '\0' && !qemu_isspace(*p)) {
A
aliguori 已提交
2897 2898
                        monitor_printf(mon, "invalid char in format: '%c'\n",
                                       *p);
2899 2900 2901 2902
                        goto fail;
                    }
                    if (format < 0)
                        format = default_fmt_format;
2903 2904 2905 2906
                    if (format != 'i') {
                        /* for 'i', not specifying a size gives -1 as size */
                        if (size < 0)
                            size = default_fmt_size;
A
aurel32 已提交
2907
                        default_fmt_size = size;
2908
                    }
2909 2910 2911 2912
                    default_fmt_format = format;
                } else {
                    count = 1;
                    format = default_fmt_format;
2913 2914 2915 2916 2917
                    if (format != 'i') {
                        size = default_fmt_size;
                    } else {
                        size = -1;
                    }
2918
                }
2919 2920 2921
                qdict_put(qdict, "count", qint_from_int(count));
                qdict_put(qdict, "format", qint_from_int(format));
                qdict_put(qdict, "size", qint_from_int(size));
2922
            }
B
bellard 已提交
2923
            break;
2924
        case 'i':
B
bellard 已提交
2925
        case 'l':
2926
            {
B
blueswir1 已提交
2927
                int64_t val;
2928

2929
                while (qemu_isspace(*p))
2930
                    p++;
B
bellard 已提交
2931 2932
                if (*typestr == '?' || *typestr == '.') {
                    if (*typestr == '?') {
2933 2934 2935 2936
                        if (*p == '\0') {
                            typestr++;
                            break;
                        }
B
bellard 已提交
2937 2938 2939
                    } else {
                        if (*p == '.') {
                            p++;
2940
                            while (qemu_isspace(*p))
B
bellard 已提交
2941 2942
                                p++;
                        } else {
2943 2944
                            typestr++;
                            break;
B
bellard 已提交
2945 2946
                        }
                    }
B
bellard 已提交
2947
                    typestr++;
2948
                }
A
aliguori 已提交
2949
                if (get_expr(mon, &val, &p))
2950
                    goto fail;
2951 2952 2953 2954 2955 2956
                /* Check if 'i' is greater than 32-bit */
                if ((c == 'i') && ((val >> 32) & 0xffffffff)) {
                    monitor_printf(mon, "\'%s\' has failed: ", cmdname);
                    monitor_printf(mon, "integer is for 32-bit values\n");
                    goto fail;
                }
2957
                qdict_put(qdict, key, qint_from_int(val));
2958 2959 2960 2961 2962 2963
            }
            break;
        case '-':
            {
                int has_option;
                /* option */
2964

2965 2966 2967
                c = *typestr++;
                if (c == '\0')
                    goto bad_type;
2968
                while (qemu_isspace(*p))
2969 2970 2971 2972 2973
                    p++;
                has_option = 0;
                if (*p == '-') {
                    p++;
                    if (*p != c) {
A
aliguori 已提交
2974 2975
                        monitor_printf(mon, "%s: unsupported option -%c\n",
                                       cmdname, *p);
2976 2977 2978 2979 2980
                        goto fail;
                    }
                    p++;
                    has_option = 1;
                }
2981
                qdict_put(qdict, key, qint_from_int(has_option));
2982 2983 2984 2985
            }
            break;
        default:
        bad_type:
A
aliguori 已提交
2986
            monitor_printf(mon, "%s: unknown type '%c'\n", cmdname, c);
2987 2988
            goto fail;
        }
2989 2990
        qemu_free(key);
        key = NULL;
B
bellard 已提交
2991
    }
2992
    /* check that all arguments were parsed */
2993
    while (qemu_isspace(*p))
2994 2995
        p++;
    if (*p != '\0') {
A
aliguori 已提交
2996 2997
        monitor_printf(mon, "%s: extraneous characters at the end of line\n",
                       cmdname);
2998
        goto fail;
B
bellard 已提交
2999
    }
3000

3001
    return cmd;
G
Gerd Hoffmann 已提交
3002

3003
fail:
3004
    qemu_free(key);
3005 3006 3007 3008 3009 3010
    return NULL;
}

static void monitor_handle_command(Monitor *mon, const char *cmdline)
{
    QDict *qdict;
A
Anthony Liguori 已提交
3011
    const mon_cmd_t *cmd;
3012 3013 3014

    qdict = qdict_new();

L
Luiz Capitulino 已提交
3015
    cmd = monitor_parse_command(mon, cmdline, qdict);
3016 3017
    if (cmd) {
        qemu_errors_to_mon(mon);
3018
        cmd->mhandler.cmd(mon, qdict);
3019 3020 3021
        qemu_errors_to_previous();
    }

3022
    QDECREF(qdict);
B
bellard 已提交
3023 3024
}

B
bellard 已提交
3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042
static void cmd_completion(const char *name, const char *list)
{
    const char *p, *pstart;
    char cmd[128];
    int len;

    p = list;
    for(;;) {
        pstart = p;
        p = strchr(p, '|');
        if (!p)
            p = pstart + strlen(pstart);
        len = p - pstart;
        if (len > sizeof(cmd) - 2)
            len = sizeof(cmd) - 2;
        memcpy(cmd, pstart, len);
        cmd[len] = '\0';
        if (name[0] == '\0' || !strncmp(name, cmd, strlen(name))) {
3043
            readline_add_completion(cur_mon->rs, cmd);
B
bellard 已提交
3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059
        }
        if (*p == '\0')
            break;
        p++;
    }
}

static void file_completion(const char *input)
{
    DIR *ffs;
    struct dirent *d;
    char path[1024];
    char file[1024], file_prefix[1024];
    int input_path_len;
    const char *p;

3060
    p = strrchr(input, '/');
B
bellard 已提交
3061 3062 3063
    if (!p) {
        input_path_len = 0;
        pstrcpy(file_prefix, sizeof(file_prefix), input);
B
blueswir1 已提交
3064
        pstrcpy(path, sizeof(path), ".");
B
bellard 已提交
3065 3066 3067 3068 3069 3070 3071 3072 3073
    } else {
        input_path_len = p - input + 1;
        memcpy(path, input, input_path_len);
        if (input_path_len > sizeof(path) - 1)
            input_path_len = sizeof(path) - 1;
        path[input_path_len] = '\0';
        pstrcpy(file_prefix, sizeof(file_prefix), p + 1);
    }
#ifdef DEBUG_COMPLETION
A
aliguori 已提交
3074 3075
    monitor_printf(cur_mon, "input='%s' path='%s' prefix='%s'\n",
                   input, path, file_prefix);
B
bellard 已提交
3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086
#endif
    ffs = opendir(path);
    if (!ffs)
        return;
    for(;;) {
        struct stat sb;
        d = readdir(ffs);
        if (!d)
            break;
        if (strstart(d->d_name, file_prefix, NULL)) {
            memcpy(file, input, input_path_len);
B
blueswir1 已提交
3087 3088 3089
            if (input_path_len < sizeof(file))
                pstrcpy(file + input_path_len, sizeof(file) - input_path_len,
                        d->d_name);
B
bellard 已提交
3090 3091 3092 3093 3094
            /* stat the file to find out if it's a directory.
             * In that case add a slash to speed up typing long paths
             */
            stat(file, &sb);
            if(S_ISDIR(sb.st_mode))
B
blueswir1 已提交
3095
                pstrcat(file, sizeof(file), "/");
3096
            readline_add_completion(cur_mon->rs, file);
B
bellard 已提交
3097 3098 3099 3100 3101
        }
    }
    closedir(ffs);
}

3102
static void block_completion_it(void *opaque, BlockDriverState *bs)
B
bellard 已提交
3103
{
3104
    const char *name = bdrv_get_device_name(bs);
B
bellard 已提交
3105 3106 3107 3108
    const char *input = opaque;

    if (input[0] == '\0' ||
        !strncmp(name, (char *)input, strlen(input))) {
3109
        readline_add_completion(cur_mon->rs, name);
B
bellard 已提交
3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123
    }
}

/* NOTE: this parser is an approximate form of the real command parser */
static void parse_cmdline(const char *cmdline,
                         int *pnb_args, char **args)
{
    const char *p;
    int nb_args, ret;
    char buf[1024];

    p = cmdline;
    nb_args = 0;
    for(;;) {
3124
        while (qemu_isspace(*p))
B
bellard 已提交
3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138
            p++;
        if (*p == '\0')
            break;
        if (nb_args >= MAX_ARGS)
            break;
        ret = get_str(buf, sizeof(buf), &p);
        args[nb_args] = qemu_strdup(buf);
        nb_args++;
        if (ret < 0)
            break;
    }
    *pnb_args = nb_args;
}

3139 3140 3141 3142 3143 3144
static const char *next_arg_type(const char *typestr)
{
    const char *p = strchr(typestr, ':');
    return (p != NULL ? ++p : typestr);
}

3145
static void monitor_find_completion(const char *cmdline)
B
bellard 已提交
3146 3147 3148 3149 3150
{
    const char *cmdname;
    char *args[MAX_ARGS];
    int nb_args, i, len;
    const char *ptype, *str;
A
Anthony Liguori 已提交
3151
    const mon_cmd_t *cmd;
3152
    const KeyDef *key;
B
bellard 已提交
3153 3154 3155 3156

    parse_cmdline(cmdline, &nb_args, args);
#ifdef DEBUG_COMPLETION
    for(i = 0; i < nb_args; i++) {
A
aliguori 已提交
3157
        monitor_printf(cur_mon, "arg%d = '%s'\n", i, (char *)args[i]);
B
bellard 已提交
3158 3159 3160 3161 3162 3163
    }
#endif

    /* if the line ends with a space, it means we want to complete the
       next arg */
    len = strlen(cmdline);
3164
    if (len > 0 && qemu_isspace(cmdline[len - 1])) {
B
bellard 已提交
3165 3166 3167 3168 3169 3170 3171 3172 3173 3174
        if (nb_args >= MAX_ARGS)
            return;
        args[nb_args++] = qemu_strdup("");
    }
    if (nb_args <= 1) {
        /* command completion */
        if (nb_args == 0)
            cmdname = "";
        else
            cmdname = args[0];
3175
        readline_set_completion_index(cur_mon->rs, strlen(cmdname));
A
aliguori 已提交
3176
        for(cmd = mon_cmds; cmd->name != NULL; cmd++) {
B
bellard 已提交
3177 3178 3179 3180
            cmd_completion(cmdname, cmd->name);
        }
    } else {
        /* find the command */
A
aliguori 已提交
3181
        for(cmd = mon_cmds; cmd->name != NULL; cmd++) {
B
bellard 已提交
3182 3183 3184 3185 3186
            if (compare_cmd(args[0], cmd->name))
                goto found;
        }
        return;
    found:
3187
        ptype = next_arg_type(cmd->args_type);
B
bellard 已提交
3188 3189
        for(i = 0; i < nb_args - 2; i++) {
            if (*ptype != '\0') {
3190
                ptype = next_arg_type(ptype);
B
bellard 已提交
3191
                while (*ptype == '?')
3192
                    ptype = next_arg_type(ptype);
B
bellard 已提交
3193 3194 3195
            }
        }
        str = args[nb_args - 1];
3196 3197 3198
        if (*ptype == '-' && ptype[1] != '\0') {
            ptype += 2;
        }
B
bellard 已提交
3199 3200 3201
        switch(*ptype) {
        case 'F':
            /* file completion */
3202
            readline_set_completion_index(cur_mon->rs, strlen(str));
B
bellard 已提交
3203 3204 3205 3206
            file_completion(str);
            break;
        case 'B':
            /* block device name completion */
3207
            readline_set_completion_index(cur_mon->rs, strlen(str));
B
bellard 已提交
3208 3209
            bdrv_iterate(block_completion_it, (void *)str);
            break;
B
bellard 已提交
3210 3211 3212
        case 's':
            /* XXX: more generic ? */
            if (!strcmp(cmd->name, "info")) {
3213
                readline_set_completion_index(cur_mon->rs, strlen(str));
B
bellard 已提交
3214 3215 3216
                for(cmd = info_cmds; cmd->name != NULL; cmd++) {
                    cmd_completion(str, cmd->name);
                }
3217
            } else if (!strcmp(cmd->name, "sendkey")) {
B
blueswir1 已提交
3218 3219 3220
                char *sep = strrchr(str, '-');
                if (sep)
                    str = sep + 1;
3221
                readline_set_completion_index(cur_mon->rs, strlen(str));
3222 3223 3224
                for(key = key_defs; key->name != NULL; key++) {
                    cmd_completion(str, key->name);
                }
3225 3226 3227 3228 3229
            } else if (!strcmp(cmd->name, "help|?")) {
                readline_set_completion_index(cur_mon->rs, strlen(str));
                for (cmd = mon_cmds; cmd->name != NULL; cmd++) {
                    cmd_completion(str, cmd->name);
                }
B
bellard 已提交
3230 3231
            }
            break;
B
bellard 已提交
3232 3233 3234 3235 3236 3237 3238 3239
        default:
            break;
        }
    }
    for(i = 0; i < nb_args; i++)
        qemu_free(args[i]);
}

3240
static int monitor_can_read(void *opaque)
B
bellard 已提交
3241
{
3242 3243 3244
    Monitor *mon = opaque;

    return (mon->suspend_cnt == 0) ? 128 : 0;
B
bellard 已提交
3245 3246
}

3247
static void monitor_read(void *opaque, const uint8_t *buf, int size)
B
bellard 已提交
3248
{
3249
    Monitor *old_mon = cur_mon;
3250
    int i;
A
aliguori 已提交
3251

3252 3253
    cur_mon = opaque;

3254 3255 3256 3257 3258 3259 3260 3261 3262
    if (cur_mon->rs) {
        for (i = 0; i < size; i++)
            readline_handle_byte(cur_mon->rs, buf[i]);
    } else {
        if (size == 0 || buf[size - 1] != 0)
            monitor_printf(cur_mon, "corrupted command\n");
        else
            monitor_handle_command(cur_mon, (char *)buf);
    }
B
bellard 已提交
3263

3264 3265
    cur_mon = old_mon;
}
3266

A
aliguori 已提交
3267
static void monitor_command_cb(Monitor *mon, const char *cmdline, void *opaque)
B
bellard 已提交
3268
{
3269
    monitor_suspend(mon);
A
aliguori 已提交
3270
    monitor_handle_command(mon, cmdline);
3271
    monitor_resume(mon);
3272 3273
}

3274
int monitor_suspend(Monitor *mon)
3275
{
3276 3277
    if (!mon->rs)
        return -ENOTTY;
3278
    mon->suspend_cnt++;
3279
    return 0;
3280 3281
}

A
aliguori 已提交
3282
void monitor_resume(Monitor *mon)
3283
{
3284 3285
    if (!mon->rs)
        return;
3286 3287
    if (--mon->suspend_cnt == 0)
        readline_show_prompt(mon->rs);
B
bellard 已提交
3288 3289
}

3290
static void monitor_event(void *opaque, int event)
3291
{
A
aliguori 已提交
3292 3293
    Monitor *mon = opaque;

3294 3295
    switch (event) {
    case CHR_EVENT_MUX_IN:
G
Gerd Hoffmann 已提交
3296 3297 3298 3299 3300 3301 3302 3303
        mon->mux_out = 0;
        if (mon->reset_seen) {
            readline_restart(mon->rs);
            monitor_resume(mon);
            monitor_flush(mon);
        } else {
            mon->suspend_cnt = 0;
        }
3304 3305 3306
        break;

    case CHR_EVENT_MUX_OUT:
G
Gerd Hoffmann 已提交
3307 3308 3309 3310 3311 3312 3313 3314 3315 3316
        if (mon->reset_seen) {
            if (mon->suspend_cnt == 0) {
                monitor_printf(mon, "\n");
            }
            monitor_flush(mon);
            monitor_suspend(mon);
        } else {
            mon->suspend_cnt++;
        }
        mon->mux_out = 1;
3317
        break;
3318

3319 3320 3321
    case CHR_EVENT_RESET:
        monitor_printf(mon, "QEMU %s monitor - type 'help' for more "
                       "information\n", QEMU_VERSION);
G
Gerd Hoffmann 已提交
3322
        if (!mon->mux_out) {
3323
            readline_show_prompt(mon->rs);
G
Gerd Hoffmann 已提交
3324 3325
        }
        mon->reset_seen = 1;
3326 3327
        break;
    }
3328 3329
}

3330 3331 3332 3333 3334 3335 3336 3337 3338

/*
 * Local variables:
 *  c-indent-level: 4
 *  c-basic-offset: 4
 *  tab-width: 8
 * End:
 */

3339
void monitor_init(CharDriverState *chr, int flags)
B
bellard 已提交
3340
{
3341
    static int is_first_init = 1;
3342
    Monitor *mon;
T
ths 已提交
3343 3344

    if (is_first_init) {
3345
        key_timer = qemu_new_timer(vm_clock, release_keys, NULL);
T
ths 已提交
3346 3347
        is_first_init = 0;
    }
3348 3349

    mon = qemu_mallocz(sizeof(*mon));
T
ths 已提交
3350

3351
    mon->chr = chr;
3352
    mon->flags = flags;
3353 3354 3355 3356
    if (flags & MONITOR_USE_READLINE) {
        mon->rs = readline_init(mon, monitor_find_completion);
        monitor_read_command(mon, 0);
    }
3357

3358 3359
    qemu_chr_add_handlers(chr, monitor_can_read, monitor_read, monitor_event,
                          mon);
3360

B
Blue Swirl 已提交
3361
    QLIST_INSERT_HEAD(&mon_list, mon, entry);
3362
    if (!cur_mon || (flags & MONITOR_IS_DEFAULT))
3363
        cur_mon = mon;
B
bellard 已提交
3364 3365
}

A
aliguori 已提交
3366
static void bdrv_password_cb(Monitor *mon, const char *password, void *opaque)
B
bellard 已提交
3367
{
3368 3369
    BlockDriverState *bs = opaque;
    int ret = 0;
B
bellard 已提交
3370

3371
    if (bdrv_set_key(bs, password) != 0) {
A
aliguori 已提交
3372
        monitor_printf(mon, "invalid password\n");
3373
        ret = -EPERM;
B
bellard 已提交
3374
    }
3375 3376
    if (mon->password_completion_cb)
        mon->password_completion_cb(mon->password_opaque, ret);
3377

3378
    monitor_read_command(mon, 1);
B
bellard 已提交
3379
}
3380

A
aliguori 已提交
3381
void monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
3382 3383
                                 BlockDriverCompletionFunc *completion_cb,
                                 void *opaque)
3384
{
3385 3386
    int err;

3387 3388 3389 3390 3391
    if (!bdrv_key_required(bs)) {
        if (completion_cb)
            completion_cb(opaque, 0);
        return;
    }
3392

A
aliguori 已提交
3393 3394
    monitor_printf(mon, "%s (%s) is encrypted.\n", bdrv_get_device_name(bs),
                   bdrv_get_encrypted_filename(bs));
3395

3396 3397
    mon->password_completion_cb = completion_cb;
    mon->password_opaque = opaque;
3398

3399 3400 3401 3402
    err = monitor_read_password(mon, bdrv_password_cb, bs);

    if (err && completion_cb)
        completion_cb(opaque, err);
3403
}
G
Gerd Hoffmann 已提交
3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417

typedef struct QemuErrorSink QemuErrorSink;
struct QemuErrorSink {
    enum {
        ERR_SINK_FILE,
        ERR_SINK_MONITOR,
    } dest;
    union {
        FILE    *fp;
        Monitor *mon;
    };
    QemuErrorSink *previous;
};

B
Blue Swirl 已提交
3418
static QemuErrorSink *qemu_error_sink;
G
Gerd Hoffmann 已提交
3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469

void qemu_errors_to_file(FILE *fp)
{
    QemuErrorSink *sink;

    sink = qemu_mallocz(sizeof(*sink));
    sink->dest = ERR_SINK_FILE;
    sink->fp = fp;
    sink->previous = qemu_error_sink;
    qemu_error_sink = sink;
}

void qemu_errors_to_mon(Monitor *mon)
{
    QemuErrorSink *sink;

    sink = qemu_mallocz(sizeof(*sink));
    sink->dest = ERR_SINK_MONITOR;
    sink->mon = mon;
    sink->previous = qemu_error_sink;
    qemu_error_sink = sink;
}

void qemu_errors_to_previous(void)
{
    QemuErrorSink *sink;

    assert(qemu_error_sink != NULL);
    sink = qemu_error_sink;
    qemu_error_sink = sink->previous;
    qemu_free(sink);
}

void qemu_error(const char *fmt, ...)
{
    va_list args;

    assert(qemu_error_sink != NULL);
    switch (qemu_error_sink->dest) {
    case ERR_SINK_FILE:
        va_start(args, fmt);
        vfprintf(qemu_error_sink->fp, fmt, args);
        va_end(args);
        break;
    case ERR_SINK_MONITOR:
        va_start(args, fmt);
        monitor_vprintf(qemu_error_sink->mon, fmt, args);
        va_end(args);
        break;
    }
}