qemu/monitor/hmp-cmds.c
<<
>>
Prefs
   1/*
   2 * Human Monitor Interface commands
   3 *
   4 * Copyright IBM, Corp. 2011
   5 *
   6 * Authors:
   7 *  Anthony Liguori   <aliguori@us.ibm.com>
   8 *
   9 * This work is licensed under the terms of the GNU GPL, version 2.  See
  10 * the COPYING file in the top-level directory.
  11 *
  12 * Contributions after 2012-01-13 are licensed under the terms of the
  13 * GNU GPL, version 2 or (at your option) any later version.
  14 */
  15
  16#include "qemu/osdep.h"
  17#include "exec/address-spaces.h"
  18#include "exec/gdbstub.h"
  19#include "exec/ioport.h"
  20#include "monitor/hmp.h"
  21#include "qemu/help_option.h"
  22#include "monitor/monitor-internal.h"
  23#include "qapi/error.h"
  24#include "qapi/qapi-commands-control.h"
  25#include "qapi/qapi-commands-misc.h"
  26#include "qapi/qmp/qdict.h"
  27#include "qapi/qmp/qerror.h"
  28#include "qemu/cutils.h"
  29#include "hw/intc/intc.h"
  30#include "qemu/log.h"
  31#include "sysemu/sysemu.h"
  32
  33bool hmp_handle_error(Monitor *mon, Error *err)
  34{
  35    if (err) {
  36        error_reportf_err(err, "Error: ");
  37        return true;
  38    }
  39    return false;
  40}
  41
  42/*
  43 * Split @str at comma.
  44 * A null @str defaults to "".
  45 */
  46strList *hmp_split_at_comma(const char *str)
  47{
  48    char **split = g_strsplit(str ?: "", ",", -1);
  49    strList *res = NULL;
  50    strList **tail = &res;
  51    int i;
  52
  53    for (i = 0; split[i]; i++) {
  54        QAPI_LIST_APPEND(tail, split[i]);
  55    }
  56
  57    g_free(split);
  58    return res;
  59}
  60
  61void hmp_info_name(Monitor *mon, const QDict *qdict)
  62{
  63    NameInfo *info;
  64
  65    info = qmp_query_name(NULL);
  66    if (info->name) {
  67        monitor_printf(mon, "%s\n", info->name);
  68    }
  69    qapi_free_NameInfo(info);
  70}
  71
  72void hmp_info_version(Monitor *mon, const QDict *qdict)
  73{
  74    VersionInfo *info;
  75
  76    info = qmp_query_version(NULL);
  77
  78    monitor_printf(mon, "%" PRId64 ".%" PRId64 ".%" PRId64 "%s\n",
  79                   info->qemu->major, info->qemu->minor, info->qemu->micro,
  80                   info->package);
  81
  82    qapi_free_VersionInfo(info);
  83}
  84
  85static int hmp_info_pic_foreach(Object *obj, void *opaque)
  86{
  87    InterruptStatsProvider *intc;
  88    InterruptStatsProviderClass *k;
  89    Monitor *mon = opaque;
  90
  91    if (object_dynamic_cast(obj, TYPE_INTERRUPT_STATS_PROVIDER)) {
  92        intc = INTERRUPT_STATS_PROVIDER(obj);
  93        k = INTERRUPT_STATS_PROVIDER_GET_CLASS(obj);
  94        if (k->print_info) {
  95            k->print_info(intc, mon);
  96        } else {
  97            monitor_printf(mon, "Interrupt controller information not available for %s.\n",
  98                           object_get_typename(obj));
  99        }
 100    }
 101
 102    return 0;
 103}
 104
 105void hmp_info_pic(Monitor *mon, const QDict *qdict)
 106{
 107    object_child_foreach_recursive(object_get_root(),
 108                                   hmp_info_pic_foreach, mon);
 109}
 110
 111void hmp_quit(Monitor *mon, const QDict *qdict)
 112{
 113    monitor_suspend(mon);
 114    qmp_quit(NULL);
 115}
 116
 117void hmp_stop(Monitor *mon, const QDict *qdict)
 118{
 119    qmp_stop(NULL);
 120}
 121
 122void hmp_sync_profile(Monitor *mon, const QDict *qdict)
 123{
 124    const char *op = qdict_get_try_str(qdict, "op");
 125
 126    if (op == NULL) {
 127        bool on = qsp_is_enabled();
 128
 129        monitor_printf(mon, "sync-profile is %s\n", on ? "on" : "off");
 130        return;
 131    }
 132    if (!strcmp(op, "on")) {
 133        qsp_enable();
 134    } else if (!strcmp(op, "off")) {
 135        qsp_disable();
 136    } else if (!strcmp(op, "reset")) {
 137        qsp_reset();
 138    } else {
 139        Error *err = NULL;
 140
 141        error_setg(&err, QERR_INVALID_PARAMETER, op);
 142        hmp_handle_error(mon, err);
 143    }
 144}
 145
 146void hmp_exit_preconfig(Monitor *mon, const QDict *qdict)
 147{
 148    Error *err = NULL;
 149
 150    qmp_x_exit_preconfig(&err);
 151    hmp_handle_error(mon, err);
 152}
 153
 154void hmp_cpu(Monitor *mon, const QDict *qdict)
 155{
 156    int64_t cpu_index;
 157
 158    /* XXX: drop the monitor_set_cpu() usage when all HMP commands that
 159            use it are converted to the QAPI */
 160    cpu_index = qdict_get_int(qdict, "index");
 161    if (monitor_set_cpu(mon, cpu_index) < 0) {
 162        monitor_printf(mon, "invalid CPU index\n");
 163    }
 164}
 165
 166void hmp_cont(Monitor *mon, const QDict *qdict)
 167{
 168    Error *err = NULL;
 169
 170    qmp_cont(&err);
 171    hmp_handle_error(mon, err);
 172}
 173
 174void hmp_change(Monitor *mon, const QDict *qdict)
 175{
 176    const char *device = qdict_get_str(qdict, "device");
 177    const char *target = qdict_get_str(qdict, "target");
 178    const char *arg = qdict_get_try_str(qdict, "arg");
 179    const char *read_only = qdict_get_try_str(qdict, "read-only-mode");
 180    bool force = qdict_get_try_bool(qdict, "force", false);
 181    Error *err = NULL;
 182
 183#ifdef CONFIG_VNC
 184    if (strcmp(device, "vnc") == 0) {
 185        hmp_change_vnc(mon, device, target, arg, read_only, force, &err);
 186    } else
 187#endif
 188    {
 189        hmp_change_medium(mon, device, target, arg, read_only, force, &err);
 190    }
 191
 192    hmp_handle_error(mon, err);
 193}
 194
 195#ifdef CONFIG_POSIX
 196void hmp_getfd(Monitor *mon, const QDict *qdict)
 197{
 198    const char *fdname = qdict_get_str(qdict, "fdname");
 199    Error *err = NULL;
 200
 201    qmp_getfd(fdname, &err);
 202    hmp_handle_error(mon, err);
 203}
 204#endif
 205
 206void hmp_closefd(Monitor *mon, const QDict *qdict)
 207{
 208    const char *fdname = qdict_get_str(qdict, "fdname");
 209    Error *err = NULL;
 210
 211    qmp_closefd(fdname, &err);
 212    hmp_handle_error(mon, err);
 213}
 214
 215void hmp_info_iothreads(Monitor *mon, const QDict *qdict)
 216{
 217    IOThreadInfoList *info_list = qmp_query_iothreads(NULL);
 218    IOThreadInfoList *info;
 219    IOThreadInfo *value;
 220
 221    for (info = info_list; info; info = info->next) {
 222        value = info->value;
 223        monitor_printf(mon, "%s:\n", value->id);
 224        monitor_printf(mon, "  thread_id=%" PRId64 "\n", value->thread_id);
 225        monitor_printf(mon, "  poll-max-ns=%" PRId64 "\n", value->poll_max_ns);
 226        monitor_printf(mon, "  poll-grow=%" PRId64 "\n", value->poll_grow);
 227        monitor_printf(mon, "  poll-shrink=%" PRId64 "\n", value->poll_shrink);
 228        monitor_printf(mon, "  aio-max-batch=%" PRId64 "\n",
 229                       value->aio_max_batch);
 230    }
 231
 232    qapi_free_IOThreadInfoList(info_list);
 233}
 234
 235void hmp_help(Monitor *mon, const QDict *qdict)
 236{
 237    hmp_help_cmd(mon, qdict_get_try_str(qdict, "name"));
 238}
 239
 240void hmp_info_help(Monitor *mon, const QDict *qdict)
 241{
 242    hmp_help_cmd(mon, "info");
 243}
 244
 245void hmp_info_sync_profile(Monitor *mon, const QDict *qdict)
 246{
 247    int64_t max = qdict_get_try_int(qdict, "max", 10);
 248    bool mean = qdict_get_try_bool(qdict, "mean", false);
 249    bool coalesce = !qdict_get_try_bool(qdict, "no_coalesce", false);
 250    enum QSPSortBy sort_by;
 251
 252    sort_by = mean ? QSP_SORT_BY_AVG_WAIT_TIME : QSP_SORT_BY_TOTAL_WAIT_TIME;
 253    qsp_report(max, sort_by, coalesce);
 254}
 255
 256void hmp_info_history(Monitor *mon, const QDict *qdict)
 257{
 258    MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common);
 259    int i;
 260    const char *str;
 261
 262    if (!hmp_mon->rs) {
 263        return;
 264    }
 265    i = 0;
 266    for(;;) {
 267        str = readline_get_history(hmp_mon->rs, i);
 268        if (!str) {
 269            break;
 270        }
 271        monitor_printf(mon, "%d: '%s'\n", i, str);
 272        i++;
 273    }
 274}
 275
 276void hmp_logfile(Monitor *mon, const QDict *qdict)
 277{
 278    Error *err = NULL;
 279
 280    if (!qemu_set_log_filename(qdict_get_str(qdict, "filename"), &err)) {
 281        error_report_err(err);
 282    }
 283}
 284
 285void hmp_log(Monitor *mon, const QDict *qdict)
 286{
 287    int mask;
 288    const char *items = qdict_get_str(qdict, "items");
 289    Error *err = NULL;
 290
 291    if (!strcmp(items, "none")) {
 292        mask = 0;
 293    } else {
 294        mask = qemu_str_to_log_mask(items);
 295        if (!mask) {
 296            hmp_help_cmd(mon, "log");
 297            return;
 298        }
 299    }
 300
 301    if (!qemu_set_log(mask, &err)) {
 302        error_report_err(err);
 303    }
 304}
 305
 306void hmp_gdbserver(Monitor *mon, const QDict *qdict)
 307{
 308    const char *device = qdict_get_try_str(qdict, "device");
 309    if (!device) {
 310        device = "tcp::" DEFAULT_GDBSTUB_PORT;
 311    }
 312
 313    if (gdbserver_start(device) < 0) {
 314        monitor_printf(mon, "Could not open gdbserver on device '%s'\n",
 315                       device);
 316    } else if (strcmp(device, "none") == 0) {
 317        monitor_printf(mon, "Disabled gdbserver\n");
 318    } else {
 319        monitor_printf(mon, "Waiting for gdb connection on device '%s'\n",
 320                       device);
 321    }
 322}
 323
 324void hmp_print(Monitor *mon, const QDict *qdict)
 325{
 326    int format = qdict_get_int(qdict, "format");
 327    hwaddr val = qdict_get_int(qdict, "val");
 328
 329    switch(format) {
 330    case 'o':
 331        monitor_printf(mon, "%#" HWADDR_PRIo, val);
 332        break;
 333    case 'x':
 334        monitor_printf(mon, "%#" HWADDR_PRIx, val);
 335        break;
 336    case 'u':
 337        monitor_printf(mon, "%" HWADDR_PRIu, val);
 338        break;
 339    default:
 340    case 'd':
 341        monitor_printf(mon, "%" HWADDR_PRId, val);
 342        break;
 343    case 'c':
 344        monitor_printc(mon, val);
 345        break;
 346    }
 347    monitor_printf(mon, "\n");
 348}
 349
 350void hmp_sum(Monitor *mon, const QDict *qdict)
 351{
 352    uint32_t addr;
 353    uint16_t sum;
 354    uint32_t start = qdict_get_int(qdict, "start");
 355    uint32_t size = qdict_get_int(qdict, "size");
 356
 357    sum = 0;
 358    for(addr = start; addr < (start + size); addr++) {
 359        uint8_t val = address_space_ldub(&address_space_memory, addr,
 360                                         MEMTXATTRS_UNSPECIFIED, NULL);
 361        /* BSD sum algorithm ('sum' Unix command) */
 362        sum = (sum >> 1) | (sum << 15);
 363        sum += val;
 364    }
 365    monitor_printf(mon, "%05d\n", sum);
 366}
 367
 368void hmp_ioport_read(Monitor *mon, const QDict *qdict)
 369{
 370    int size = qdict_get_int(qdict, "size");
 371    int addr = qdict_get_int(qdict, "addr");
 372    int has_index = qdict_haskey(qdict, "index");
 373    uint32_t val;
 374    int suffix;
 375
 376    if (has_index) {
 377        int index = qdict_get_int(qdict, "index");
 378        cpu_outb(addr & IOPORTS_MASK, index & 0xff);
 379        addr++;
 380    }
 381    addr &= 0xffff;
 382
 383    switch(size) {
 384    default:
 385    case 1:
 386        val = cpu_inb(addr);
 387        suffix = 'b';
 388        break;
 389    case 2:
 390        val = cpu_inw(addr);
 391        suffix = 'w';
 392        break;
 393    case 4:
 394        val = cpu_inl(addr);
 395        suffix = 'l';
 396        break;
 397    }
 398    monitor_printf(mon, "port%c[0x%04x] = 0x%0*x\n",
 399                   suffix, addr, size * 2, val);
 400}
 401
 402void hmp_ioport_write(Monitor *mon, const QDict *qdict)
 403{
 404    int size = qdict_get_int(qdict, "size");
 405    int addr = qdict_get_int(qdict, "addr");
 406    int val = qdict_get_int(qdict, "val");
 407
 408    addr &= IOPORTS_MASK;
 409
 410    switch (size) {
 411    default:
 412    case 1:
 413        cpu_outb(addr, val);
 414        break;
 415    case 2:
 416        cpu_outw(addr, val);
 417        break;
 418    case 4:
 419        cpu_outl(addr, val);
 420        break;
 421    }
 422}
 423
 424void hmp_boot_set(Monitor *mon, const QDict *qdict)
 425{
 426    Error *local_err = NULL;
 427    const char *bootdevice = qdict_get_str(qdict, "bootdevice");
 428
 429    qemu_boot_set(bootdevice, &local_err);
 430    if (local_err) {
 431        error_report_err(local_err);
 432    } else {
 433        monitor_printf(mon, "boot device list now set to %s\n", bootdevice);
 434    }
 435}
 436
 437void hmp_info_mtree(Monitor *mon, const QDict *qdict)
 438{
 439    bool flatview = qdict_get_try_bool(qdict, "flatview", false);
 440    bool dispatch_tree = qdict_get_try_bool(qdict, "dispatch_tree", false);
 441    bool owner = qdict_get_try_bool(qdict, "owner", false);
 442    bool disabled = qdict_get_try_bool(qdict, "disabled", false);
 443
 444    mtree_info(flatview, dispatch_tree, owner, disabled);
 445}
 446