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 "system/address-spaces.h"
  18#include "system/ioport.h"
  19#include "exec/gdbstub.h"
  20#include "gdbstub/enums.h"
  21#include "monitor/hmp.h"
  22#include "qemu/help_option.h"
  23#include "monitor/monitor-internal.h"
  24#include "qapi/error.h"
  25#include "qapi/qapi-commands-control.h"
  26#include "qapi/qapi-commands-machine.h"
  27#include "qapi/qapi-commands-misc.h"
  28#include "qobject/qdict.h"
  29#include "qemu/cutils.h"
  30#include "qemu/log.h"
  31#include "system/system.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
  85void hmp_quit(Monitor *mon, const QDict *qdict)
  86{
  87    monitor_suspend(mon);
  88    qmp_quit(NULL);
  89}
  90
  91void hmp_stop(Monitor *mon, const QDict *qdict)
  92{
  93    qmp_stop(NULL);
  94}
  95
  96void hmp_sync_profile(Monitor *mon, const QDict *qdict)
  97{
  98    const char *op = qdict_get_try_str(qdict, "op");
  99
 100    if (op == NULL) {
 101        bool on = qsp_is_enabled();
 102
 103        monitor_printf(mon, "sync-profile is %s\n", on ? "on" : "off");
 104        return;
 105    }
 106    if (!strcmp(op, "on")) {
 107        qsp_enable();
 108    } else if (!strcmp(op, "off")) {
 109        qsp_disable();
 110    } else if (!strcmp(op, "reset")) {
 111        qsp_reset();
 112    } else {
 113        Error *err = NULL;
 114
 115        error_setg(&err, "invalid parameter '%s',"
 116                   " expecting 'on', 'off', or 'reset'", op);
 117        hmp_handle_error(mon, err);
 118    }
 119}
 120
 121void hmp_exit_preconfig(Monitor *mon, const QDict *qdict)
 122{
 123    Error *err = NULL;
 124
 125    qmp_x_exit_preconfig(&err);
 126    hmp_handle_error(mon, err);
 127}
 128
 129void hmp_cpu(Monitor *mon, const QDict *qdict)
 130{
 131    int64_t cpu_index;
 132
 133    /* XXX: drop the monitor_set_cpu() usage when all HMP commands that
 134            use it are converted to the QAPI */
 135    cpu_index = qdict_get_int(qdict, "index");
 136    if (monitor_set_cpu(mon, cpu_index) < 0) {
 137        monitor_printf(mon, "invalid CPU index\n");
 138    }
 139}
 140
 141void hmp_cont(Monitor *mon, const QDict *qdict)
 142{
 143    Error *err = NULL;
 144
 145    qmp_cont(&err);
 146    hmp_handle_error(mon, err);
 147}
 148
 149void hmp_change(Monitor *mon, const QDict *qdict)
 150{
 151    const char *device = qdict_get_str(qdict, "device");
 152    const char *target = qdict_get_str(qdict, "target");
 153    const char *arg = qdict_get_try_str(qdict, "arg");
 154    const char *read_only = qdict_get_try_str(qdict, "read-only-mode");
 155    bool force = qdict_get_try_bool(qdict, "force", false);
 156    Error *err = NULL;
 157
 158#ifdef CONFIG_VNC
 159    if (strcmp(device, "vnc") == 0) {
 160        hmp_change_vnc(mon, device, target, arg, read_only, force, &err);
 161    } else
 162#endif
 163    {
 164        hmp_change_medium(mon, device, target, arg, read_only, force, &err);
 165    }
 166
 167    hmp_handle_error(mon, err);
 168}
 169
 170#ifdef CONFIG_POSIX
 171void hmp_getfd(Monitor *mon, const QDict *qdict)
 172{
 173    const char *fdname = qdict_get_str(qdict, "fdname");
 174    Error *err = NULL;
 175
 176    qmp_getfd(fdname, &err);
 177    hmp_handle_error(mon, err);
 178}
 179#endif
 180
 181void hmp_closefd(Monitor *mon, const QDict *qdict)
 182{
 183    const char *fdname = qdict_get_str(qdict, "fdname");
 184    Error *err = NULL;
 185
 186    qmp_closefd(fdname, &err);
 187    hmp_handle_error(mon, err);
 188}
 189
 190void hmp_info_iothreads(Monitor *mon, const QDict *qdict)
 191{
 192    IOThreadInfoList *info_list = qmp_query_iothreads(NULL);
 193    IOThreadInfoList *info;
 194    IOThreadInfo *value;
 195
 196    for (info = info_list; info; info = info->next) {
 197        value = info->value;
 198        monitor_printf(mon, "%s:\n", value->id);
 199        monitor_printf(mon, "  thread_id=%" PRId64 "\n", value->thread_id);
 200        monitor_printf(mon, "  poll-max-ns=%" PRId64 "\n", value->poll_max_ns);
 201        monitor_printf(mon, "  poll-grow=%" PRId64 "\n", value->poll_grow);
 202        monitor_printf(mon, "  poll-shrink=%" PRId64 "\n", value->poll_shrink);
 203        monitor_printf(mon, "  aio-max-batch=%" PRId64 "\n",
 204                       value->aio_max_batch);
 205    }
 206
 207    qapi_free_IOThreadInfoList(info_list);
 208}
 209
 210void hmp_help(Monitor *mon, const QDict *qdict)
 211{
 212    hmp_help_cmd(mon, qdict_get_try_str(qdict, "name"));
 213}
 214
 215void hmp_info_help(Monitor *mon, const QDict *qdict)
 216{
 217    hmp_help_cmd(mon, "info");
 218}
 219
 220void hmp_info_sync_profile(Monitor *mon, const QDict *qdict)
 221{
 222    int64_t max = qdict_get_try_int(qdict, "max", 10);
 223    bool mean = qdict_get_try_bool(qdict, "mean", false);
 224    bool coalesce = !qdict_get_try_bool(qdict, "no_coalesce", false);
 225    enum QSPSortBy sort_by;
 226
 227    sort_by = mean ? QSP_SORT_BY_AVG_WAIT_TIME : QSP_SORT_BY_TOTAL_WAIT_TIME;
 228    qsp_report(max, sort_by, coalesce);
 229}
 230
 231void hmp_info_history(Monitor *mon, const QDict *qdict)
 232{
 233    MonitorHMP *hmp_mon = container_of(mon, MonitorHMP, common);
 234    int i;
 235    const char *str;
 236
 237    if (!hmp_mon->rs) {
 238        return;
 239    }
 240    i = 0;
 241    for(;;) {
 242        str = readline_get_history(hmp_mon->rs, i);
 243        if (!str) {
 244            break;
 245        }
 246        monitor_printf(mon, "%d: '%s'\n", i, str);
 247        i++;
 248    }
 249}
 250
 251void hmp_logfile(Monitor *mon, const QDict *qdict)
 252{
 253    Error *err = NULL;
 254
 255    if (!qemu_set_log_filename(qdict_get_str(qdict, "filename"), &err)) {
 256        error_report_err(err);
 257    }
 258}
 259
 260void hmp_log(Monitor *mon, const QDict *qdict)
 261{
 262    int mask;
 263    const char *items = qdict_get_str(qdict, "items");
 264    Error *err = NULL;
 265
 266    if (!strcmp(items, "none")) {
 267        mask = 0;
 268    } else {
 269        mask = qemu_str_to_log_mask(items);
 270        if (!mask) {
 271            hmp_help_cmd(mon, "log");
 272            return;
 273        }
 274    }
 275
 276    if (!qemu_set_log(mask, &err)) {
 277        error_report_err(err);
 278    }
 279}
 280
 281void hmp_gdbserver(Monitor *mon, const QDict *qdict)
 282{
 283    const char *device = qdict_get_try_str(qdict, "device");
 284    if (!device) {
 285        device = "tcp::" DEFAULT_GDBSTUB_PORT;
 286    }
 287
 288    if (!gdbserver_start(device, &error_warn)) {
 289        monitor_printf(mon, "Could not open gdbserver on device '%s'\n",
 290                       device);
 291    } else if (strcmp(device, "none") == 0) {
 292        monitor_printf(mon, "Disabled gdbserver\n");
 293    } else {
 294        monitor_printf(mon, "Waiting for gdb connection on device '%s'\n",
 295                       device);
 296    }
 297}
 298
 299void hmp_print(Monitor *mon, const QDict *qdict)
 300{
 301    int format = qdict_get_int(qdict, "format");
 302    hwaddr val = qdict_get_int(qdict, "val");
 303
 304    switch(format) {
 305    case 'o':
 306        monitor_printf(mon, "%#" HWADDR_PRIo, val);
 307        break;
 308    case 'x':
 309        monitor_printf(mon, "%#" HWADDR_PRIx, val);
 310        break;
 311    case 'u':
 312        monitor_printf(mon, "%" HWADDR_PRIu, val);
 313        break;
 314    default:
 315    case 'd':
 316        monitor_printf(mon, "%" HWADDR_PRId, val);
 317        break;
 318    case 'c':
 319        monitor_printc(mon, val);
 320        break;
 321    }
 322    monitor_printf(mon, "\n");
 323}
 324
 325void hmp_sum(Monitor *mon, const QDict *qdict)
 326{
 327    uint32_t addr;
 328    uint16_t sum;
 329    uint32_t start = qdict_get_int(qdict, "start");
 330    uint32_t size = qdict_get_int(qdict, "size");
 331
 332    sum = 0;
 333    for(addr = start; addr < (start + size); addr++) {
 334        uint8_t val = address_space_ldub(&address_space_memory, addr,
 335                                         MEMTXATTRS_UNSPECIFIED, NULL);
 336        /* BSD sum algorithm ('sum' Unix command) */
 337        sum = (sum >> 1) | (sum << 15);
 338        sum += val;
 339    }
 340    monitor_printf(mon, "%05d\n", sum);
 341}
 342
 343void hmp_ioport_read(Monitor *mon, const QDict *qdict)
 344{
 345    int size = qdict_get_int(qdict, "size");
 346    int addr = qdict_get_int(qdict, "addr");
 347    int has_index = qdict_haskey(qdict, "index");
 348    uint32_t val;
 349    int suffix;
 350
 351    if (has_index) {
 352        int index = qdict_get_int(qdict, "index");
 353        cpu_outb(addr & IOPORTS_MASK, index & 0xff);
 354        addr++;
 355    }
 356    addr &= 0xffff;
 357
 358    switch(size) {
 359    default:
 360    case 1:
 361        val = cpu_inb(addr);
 362        suffix = 'b';
 363        break;
 364    case 2:
 365        val = cpu_inw(addr);
 366        suffix = 'w';
 367        break;
 368    case 4:
 369        val = cpu_inl(addr);
 370        suffix = 'l';
 371        break;
 372    }
 373    monitor_printf(mon, "port%c[0x%04x] = 0x%0*x\n",
 374                   suffix, addr, size * 2, val);
 375}
 376
 377void hmp_ioport_write(Monitor *mon, const QDict *qdict)
 378{
 379    int size = qdict_get_int(qdict, "size");
 380    int addr = qdict_get_int(qdict, "addr");
 381    int val = qdict_get_int(qdict, "val");
 382
 383    addr &= IOPORTS_MASK;
 384
 385    switch (size) {
 386    default:
 387    case 1:
 388        cpu_outb(addr, val);
 389        break;
 390    case 2:
 391        cpu_outw(addr, val);
 392        break;
 393    case 4:
 394        cpu_outl(addr, val);
 395        break;
 396    }
 397}
 398
 399void hmp_boot_set(Monitor *mon, const QDict *qdict)
 400{
 401    Error *local_err = NULL;
 402    const char *bootdevice = qdict_get_str(qdict, "bootdevice");
 403
 404    qemu_boot_set(bootdevice, &local_err);
 405    if (local_err) {
 406        error_report_err(local_err);
 407    } else {
 408        monitor_printf(mon, "boot device list now set to %s\n", bootdevice);
 409    }
 410}
 411
 412void hmp_info_mtree(Monitor *mon, const QDict *qdict)
 413{
 414    bool flatview = qdict_get_try_bool(qdict, "flatview", false);
 415    bool dispatch_tree = qdict_get_try_bool(qdict, "dispatch_tree", false);
 416    bool owner = qdict_get_try_bool(qdict, "owner", false);
 417    bool disabled = qdict_get_try_bool(qdict, "disabled", false);
 418
 419    mtree_info(flatview, dispatch_tree, owner, disabled);
 420}
 421
 422#if defined(CONFIG_FDT)
 423void hmp_dumpdtb(Monitor *mon, const QDict *qdict)
 424{
 425    const char *filename = qdict_get_str(qdict, "filename");
 426    Error *local_err = NULL;
 427
 428    qmp_dumpdtb(filename, &local_err);
 429
 430    if (hmp_handle_error(mon, local_err)) {
 431        return;
 432    }
 433
 434    monitor_printf(mon, "DTB dumped to '%s'\n", filename);
 435}
 436#endif
 437