blob: 56564d5bef34cdc5af26c50a82afcc7ea5b8651e [file] [log] [blame]
bellard9dc39cb2004-03-14 21:38:27 +00001/*
2 * QEMU monitor
ths5fafdf22007-09-16 21:08:06 +00003 *
bellard9dc39cb2004-03-14 21:38:27 +00004 * Copyright (c) 2003-2004 Fabrice Bellard
ths5fafdf22007-09-16 21:08:06 +00005 *
bellard9dc39cb2004-03-14 21:38:27 +00006 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
blueswir1511d2b12009-03-07 15:32:56 +000024#include <dirent.h>
pbrook87ecb682007-11-17 17:14:51 +000025#include "hw/hw.h"
Paolo Bonzinib4a42f82013-02-04 11:37:52 +010026#include "monitor/qdev.h"
pbrook87ecb682007-11-17 17:14:51 +000027#include "hw/usb.h"
Paolo Bonzini0d09e412013-02-05 17:06:20 +010028#include "hw/i386/pc.h"
Michael S. Tsirkina2cb15b2012-12-12 14:24:50 +020029#include "hw/pci/pci.h"
Paolo Bonzini0d09e412013-02-05 17:06:20 +010030#include "sysemu/watchdog.h"
Gerd Hoffmann45a50b12009-10-01 16:42:33 +020031#include "hw/loader.h"
Paolo Bonzini022c62c2012-12-17 18:19:49 +010032#include "exec/gdbstub.h"
Paolo Bonzini1422e322012-10-24 08:43:34 +020033#include "net/net.h"
Mark McLoughlin68ac40d2009-11-25 18:48:54 +000034#include "net/slirp.h"
Paolo Bonzinidccfcd02013-04-08 16:55:25 +020035#include "sysemu/char.h"
Gerd Hoffmann75721502010-10-07 12:22:54 +020036#include "ui/qemu-spice.h"
Paolo Bonzini9c17d612012-12-17 18:20:04 +010037#include "sysemu/sysemu.h"
Eduardo Habkoste35704b2015-02-08 16:51:16 -020038#include "sysemu/numa.h"
Paolo Bonzini83c90892012-12-17 18:19:49 +010039#include "monitor/monitor.h"
Stefan Hajnoczi0150cd82013-11-14 11:54:15 +010040#include "qemu/readline.h"
Paolo Bonzini28ecbae2012-11-28 12:06:30 +010041#include "ui/console.h"
Gerd Hoffmannc751a742013-12-04 15:02:28 +010042#include "ui/input.h"
Paolo Bonzini9c17d612012-12-17 18:20:04 +010043#include "sysemu/blockdev.h"
pbrook87ecb682007-11-17 17:14:51 +000044#include "audio/audio.h"
Paolo Bonzini76cad712012-10-24 11:12:21 +020045#include "disas/disas.h"
Paolo Bonzini9c17d612012-12-17 18:20:04 +010046#include "sysemu/balloon.h"
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010047#include "qemu/timer.h"
Paolo Bonzinicaf71f82012-12-17 18:19:50 +010048#include "migration/migration.h"
Paolo Bonzini9c17d612012-12-17 18:20:04 +010049#include "sysemu/kvm.h"
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010050#include "qemu/acl.h"
Paolo Bonzinibdee56f2013-04-02 18:28:41 +020051#include "sysemu/tpm.h"
Paolo Bonzini7b1b5d12012-12-17 18:19:43 +010052#include "qapi/qmp/qint.h"
53#include "qapi/qmp/qfloat.h"
54#include "qapi/qmp/qlist.h"
55#include "qapi/qmp/qbool.h"
56#include "qapi/qmp/qstring.h"
57#include "qapi/qmp/qjson.h"
58#include "qapi/qmp/json-streamer.h"
59#include "qapi/qmp/json-parser.h"
Hani Benhabiles1094fd32014-02-06 23:30:13 +010060#include <qom/object_interfaces.h>
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010061#include "qemu/osdep.h"
Blue Swirl2b41f102011-06-19 20:38:22 +000062#include "cpu.h"
Stefan Hajnoczi89bd8202011-09-23 08:23:06 +010063#include "trace.h"
Lluís31965ae2011-08-31 20:31:24 +020064#include "trace/control.h"
Lluís6d8a7642011-08-31 20:30:43 +020065#ifdef CONFIG_TRACE_SIMPLE
Lluís31965ae2011-08-31 20:31:24 +020066#include "trace/simple.h"
Prerna Saxena22890ab2010-06-24 17:04:53 +053067#endif
Paolo Bonzini022c62c2012-12-17 18:19:49 +010068#include "exec/memory.h"
Paolo Bonzinif08b6172014-03-28 19:42:10 +010069#include "exec/cpu_ldst.h"
Anthony Liguori48a32be2011-09-02 12:34:48 -050070#include "qmp-commands.h"
71#include "hmp.h"
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010072#include "qemu/thread.h"
Hani Benhabilesb21631f2014-05-27 23:39:37 +010073#include "block/qapi.h"
Wenchao Xia43a14cf2014-06-18 08:43:31 +020074#include "qapi/qmp-event.h"
75#include "qapi-event.h"
Fam Zheng55606252015-03-02 19:36:46 +080076#include "sysemu/block-backend.h"
ths6a5bd302007-12-03 17:05:38 +000077
Markus Armbruster1ce6be22015-02-06 14:18:24 +010078/* for hmp_info_irq/pic */
Jan Kiszka661f1922011-10-16 11:53:13 +020079#if defined(TARGET_SPARC)
Paolo Bonzini0d09e412013-02-05 17:06:20 +010080#include "hw/sparc/sun4m.h"
Jan Kiszka661f1922011-10-16 11:53:13 +020081#endif
Paolo Bonzini0d09e412013-02-05 17:06:20 +010082#include "hw/lm32/lm32_pic.h"
Jan Kiszka661f1922011-10-16 11:53:13 +020083
bellard9dc39cb2004-03-14 21:38:27 +000084//#define DEBUG
bellard81d09122004-07-14 17:21:37 +000085//#define DEBUG_COMPLETION
bellard9dc39cb2004-03-14 21:38:27 +000086
bellard9307c4c2004-04-04 12:57:25 +000087/*
88 * Supported types:
ths5fafdf22007-09-16 21:08:06 +000089 *
bellard9307c4c2004-04-04 12:57:25 +000090 * 'F' filename
bellard81d09122004-07-14 17:21:37 +000091 * 'B' block device name
bellard9307c4c2004-04-04 12:57:25 +000092 * 's' string (accept optional quote)
Wenchao Xia129be002013-08-27 20:38:26 +080093 * 'S' it just appends the rest of the string (accept optional quote)
Markus Armbruster361127d2010-02-10 20:24:35 +010094 * 'O' option string of the form NAME=VALUE,...
95 * parsed according to QemuOptsList given by its name
96 * Example: 'device:O' uses qemu_device_opts.
97 * Restriction: only lists with empty desc are supported
98 * TODO lift the restriction
bellard92a31b12005-02-10 22:00:52 +000099 * 'i' 32 bit integer
100 * 'l' target long (32 or 64 bit)
Luiz Capitulino91162842012-04-26 17:34:30 -0300101 * 'M' Non-negative target long (32 or 64 bit), in user mode the
102 * value is multiplied by 2^20 (think Mebibyte)
Jes Sorensendbc0c672010-10-21 17:15:47 +0200103 * 'o' octets (aka bytes)
Kevin Wolf5e009842013-06-05 14:19:27 +0200104 * user mode accepts an optional E, e, P, p, T, t, G, g, M, m,
105 * K, k suffix, which multiplies the value by 2^60 for suffixes E
106 * and e, 2^50 for suffixes P and p, 2^40 for suffixes T and t,
107 * 2^30 for suffixes G and g, 2^20 for M and m, 2^10 for K and k
Markus Armbrusterfccfb11e2010-01-25 14:23:06 +0100108 * 'T' double
109 * user mode accepts an optional ms, us, ns suffix,
110 * which divides the value by 1e3, 1e6, 1e9, respectively
bellard9307c4c2004-04-04 12:57:25 +0000111 * '/' optional gdb-like print format (like "/10x")
112 *
Luiz Capitulinofb466602009-08-28 15:27:27 -0300113 * '?' optional type (for all types, except '/')
114 * '.' other form of optional type (for 'i' and 'l')
Markus Armbruster942cd1f2010-03-26 09:07:09 +0100115 * 'b' boolean
116 * user mode accepts "on" or "off"
Luiz Capitulinofb466602009-08-28 15:27:27 -0300117 * '-' optional parameter (eg. '-f')
bellard9307c4c2004-04-04 12:57:25 +0000118 *
119 */
120
Anthony Liguoric227f092009-10-01 16:12:16 -0500121typedef struct mon_cmd_t {
bellard9dc39cb2004-03-14 21:38:27 +0000122 const char *name;
bellard9307c4c2004-04-04 12:57:25 +0000123 const char *args_type;
bellard9dc39cb2004-03-14 21:38:27 +0000124 const char *params;
125 const char *help;
Luiz Capitulino910df892009-10-07 13:41:51 -0300126 union {
Luiz Capitulinoaf4ce882009-10-07 13:41:52 -0300127 void (*cmd)(Monitor *mon, const QDict *qdict);
Luiz Capitulino261394d2010-02-10 23:50:02 -0200128 int (*cmd_new)(Monitor *mon, const QDict *params, QObject **ret_data);
Luiz Capitulino910df892009-10-07 13:41:51 -0300129 } mhandler;
Wenchao Xia5f3d3352013-01-14 14:06:27 +0800130 /* @sub_table is a list of 2nd level of commands. If it do not exist,
131 * mhandler should be used. If it exist, sub_table[?].mhandler should be
132 * used, and mhandler of 1st level plays the role of help function.
133 */
134 struct mon_cmd_t *sub_table;
Hani Benhabilesbfa40f72014-04-13 16:25:06 +0100135 void (*command_completion)(ReadLineState *rs, int nb_args, const char *str);
Anthony Liguoric227f092009-10-01 16:12:16 -0500136} mon_cmd_t;
bellard9dc39cb2004-03-14 21:38:27 +0000137
Mark McLoughlinf07918f2009-07-22 09:11:40 +0100138/* file descriptors passed via SCM_RIGHTS */
Anthony Liguoric227f092009-10-01 16:12:16 -0500139typedef struct mon_fd_t mon_fd_t;
140struct mon_fd_t {
Mark McLoughlinf07918f2009-07-22 09:11:40 +0100141 char *name;
142 int fd;
Anthony Liguoric227f092009-10-01 16:12:16 -0500143 QLIST_ENTRY(mon_fd_t) next;
Mark McLoughlinf07918f2009-07-22 09:11:40 +0100144};
145
Corey Bryantba1c0482012-08-14 16:43:43 -0400146/* file descriptor associated with a file descriptor set */
147typedef struct MonFdsetFd MonFdsetFd;
148struct MonFdsetFd {
149 int fd;
150 bool removed;
151 char *opaque;
152 QLIST_ENTRY(MonFdsetFd) next;
153};
154
155/* file descriptor set containing fds passed via SCM_RIGHTS */
156typedef struct MonFdset MonFdset;
157struct MonFdset {
158 int64_t id;
159 QLIST_HEAD(, MonFdsetFd) fds;
Corey Bryantadb696f2012-08-14 16:43:47 -0400160 QLIST_HEAD(, MonFdsetFd) dup_fds;
Corey Bryantba1c0482012-08-14 16:43:43 -0400161 QLIST_ENTRY(MonFdset) next;
162};
163
Luiz Capitulino5fa737a2009-11-26 22:59:01 -0200164typedef struct MonitorControl {
165 QObject *id;
166 JSONMessageParser parser;
Luiz Capitulino4a7e1192010-02-04 18:10:05 -0200167 int command_mode;
Luiz Capitulino5fa737a2009-11-26 22:59:01 -0200168} MonitorControl;
169
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100170/*
171 * To prevent flooding clients, events can be throttled. The
172 * throttling is calculated globally, rather than per-Monitor
173 * instance.
174 */
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200175typedef struct MonitorQAPIEventState {
176 QAPIEvent event; /* Event being tracked */
177 int64_t rate; /* Minimum time (in ns) between two events */
178 int64_t last; /* QEMU_CLOCK_REALTIME value at last emission */
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100179 QEMUTimer *timer; /* Timer for handling delayed events */
180 QObject *data; /* Event pending delayed dispatch */
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200181} MonitorQAPIEventState;
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100182
aliguori87127162009-03-05 23:01:29 +0000183struct Monitor {
184 CharDriverState *chr;
Gerd Hoffmanna7aec5d2009-09-10 10:58:54 +0200185 int reset_seen;
aliguori731b0362009-03-05 23:01:42 +0000186 int flags;
187 int suspend_cnt;
Luiz Capitulino48c043d2013-04-02 15:07:33 -0400188 bool skip_flush;
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200189
190 QemuMutex out_lock;
Luiz Capitulinoe1f26412013-03-25 13:52:26 -0400191 QString *outbuf;
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200192 guint out_watch;
193
194 /* Read under either BQL or out_lock, written with BQL+out_lock. */
195 int mux_out;
196
aliguori731b0362009-03-05 23:01:42 +0000197 ReadLineState *rs;
Luiz Capitulino5fa737a2009-11-26 22:59:01 -0200198 MonitorControl *mc;
Andreas Färbercb446ec2013-05-01 14:24:52 +0200199 CPUState *mon_cpu;
Markus Armbruster097310b2014-10-07 13:59:15 +0200200 BlockCompletionFunc *password_completion_cb;
aliguori731b0362009-03-05 23:01:42 +0000201 void *password_opaque;
Wenchao Xia77172392013-08-27 20:38:20 +0800202 mon_cmd_t *cmd_table;
Luiz Capitulino8204a912009-11-18 23:05:31 -0200203 QError *error;
Anthony Liguoric227f092009-10-01 16:12:16 -0500204 QLIST_HEAD(,mon_fd_t) fds;
Blue Swirl72cf2d42009-09-12 07:36:22 +0000205 QLIST_ENTRY(Monitor) entry;
aliguori87127162009-03-05 23:01:29 +0000206};
207
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -0300208/* QMP checker flags */
209#define QMP_ACCEPT_UNKNOWNS 1
210
Paolo Bonzinid622cb52014-06-18 08:44:00 +0200211/* Protects mon_list, monitor_event_state. */
212static QemuMutex monitor_lock;
213
Blue Swirl72cf2d42009-09-12 07:36:22 +0000214static QLIST_HEAD(mon_list, Monitor) mon_list;
Corey Bryantba1c0482012-08-14 16:43:43 -0400215static QLIST_HEAD(mon_fdsets, MonFdset) mon_fdsets;
Corey Bryantefb87c12012-08-14 16:43:48 -0400216static int mon_refcount;
bellard7e2515e2004-08-01 21:52:19 +0000217
Wayne Xia816f8922011-10-12 11:32:41 +0800218static mon_cmd_t mon_cmds[];
219static mon_cmd_t info_cmds[];
bellard9dc39cb2004-03-14 21:38:27 +0000220
Luiz Capitulinof36b4af2010-09-15 17:17:45 -0300221static const mon_cmd_t qmp_cmds[];
222
Markus Armbruster8631b602010-02-18 11:41:55 +0100223Monitor *cur_mon;
224Monitor *default_mon;
aliguori376253e2009-03-05 23:01:23 +0000225
Stefan Hajnoczic60bf332013-11-14 11:54:14 +0100226static void monitor_command_cb(void *opaque, const char *cmdline,
227 void *readline_opaque);
aliguori83ab7952008-08-19 14:44:22 +0000228
Luiz Capitulino09069b12010-02-04 18:10:06 -0200229static inline int qmp_cmd_mode(const Monitor *mon)
230{
231 return (mon->mc ? mon->mc->command_mode : 0);
232}
233
Luiz Capitulino418173c2009-11-26 22:58:51 -0200234/* Return true if in control mode, false otherwise */
235static inline int monitor_ctrl_mode(const Monitor *mon)
236{
237 return (mon->flags & MONITOR_USE_CONTROL);
238}
239
Markus Armbruster6620d3c2010-02-11 17:05:43 +0100240/* Return non-zero iff we have a current monitor, and it is in QMP mode. */
241int monitor_cur_is_qmp(void)
242{
243 return cur_mon && monitor_ctrl_mode(cur_mon);
244}
245
Anthony Liguori7060b472011-09-02 12:34:50 -0500246void monitor_read_command(Monitor *mon, int show_prompt)
aliguori731b0362009-03-05 23:01:42 +0000247{
Luiz Capitulino183e6e52009-12-14 18:53:23 -0200248 if (!mon->rs)
249 return;
250
aliguori731b0362009-03-05 23:01:42 +0000251 readline_start(mon->rs, "(qemu) ", 0, monitor_command_cb, NULL);
252 if (show_prompt)
253 readline_show_prompt(mon->rs);
254}
bellard6a00d602005-11-21 23:25:50 +0000255
Anthony Liguori7060b472011-09-02 12:34:50 -0500256int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
257 void *opaque)
aliguoribb5fc202009-03-05 23:01:15 +0000258{
Markus Armbrusterbcf5d192015-03-12 17:26:46 +0100259 if (mon->rs) {
aliguoricde76ee2009-03-05 23:01:51 +0000260 readline_start(mon->rs, "Password: ", 1, readline_func, opaque);
261 /* prompt is printed on return from the command handler */
262 return 0;
263 } else {
264 monitor_printf(mon, "terminal does not support password prompting\n");
265 return -ENOTTY;
266 }
aliguoribb5fc202009-03-05 23:01:15 +0000267}
268
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200269static void monitor_flush_locked(Monitor *mon);
270
Gerd Hoffmannf6289262013-03-19 10:57:56 +0100271static gboolean monitor_unblocked(GIOChannel *chan, GIOCondition cond,
272 void *opaque)
273{
Laszlo Ersek293d2a02013-07-16 20:19:41 +0200274 Monitor *mon = opaque;
275
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200276 qemu_mutex_lock(&mon->out_lock);
277 mon->out_watch = 0;
278 monitor_flush_locked(mon);
279 qemu_mutex_unlock(&mon->out_lock);
Gerd Hoffmannf6289262013-03-19 10:57:56 +0100280 return FALSE;
281}
282
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200283/* Called with mon->out_lock held. */
284static void monitor_flush_locked(Monitor *mon)
bellard9dc39cb2004-03-14 21:38:27 +0000285{
Gerd Hoffmannf6289262013-03-19 10:57:56 +0100286 int rc;
Luiz Capitulinoe1f26412013-03-25 13:52:26 -0400287 size_t len;
288 const char *buf;
Gerd Hoffmannf6289262013-03-19 10:57:56 +0100289
Luiz Capitulino48c043d2013-04-02 15:07:33 -0400290 if (mon->skip_flush) {
291 return;
292 }
293
Luiz Capitulinoe1f26412013-03-25 13:52:26 -0400294 buf = qstring_get_str(mon->outbuf);
295 len = qstring_get_length(mon->outbuf);
296
Paolo Bonzinia4cc73d2013-05-31 14:00:27 +0200297 if (len && !mon->mux_out) {
Luiz Capitulinoe1f26412013-03-25 13:52:26 -0400298 rc = qemu_chr_fe_write(mon->chr, (const uint8_t *) buf, len);
Stratos Psomadakis056f49f2014-01-27 12:30:15 +0200299 if ((rc < 0 && errno != EAGAIN) || (rc == len)) {
300 /* all flushed or error */
Luiz Capitulinoe1f26412013-03-25 13:52:26 -0400301 QDECREF(mon->outbuf);
302 mon->outbuf = qstring_new();
Gerd Hoffmannf6289262013-03-19 10:57:56 +0100303 return;
304 }
305 if (rc > 0) {
306 /* partinal write */
Luiz Capitulinoe1f26412013-03-25 13:52:26 -0400307 QString *tmp = qstring_from_str(buf + rc);
308 QDECREF(mon->outbuf);
309 mon->outbuf = tmp;
Gerd Hoffmannf6289262013-03-19 10:57:56 +0100310 }
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200311 if (mon->out_watch == 0) {
Roger Pau Monnee02bc6d2014-05-23 17:57:49 +0200312 mon->out_watch = qemu_chr_fe_add_watch(mon->chr, G_IO_OUT|G_IO_HUP,
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200313 monitor_unblocked, mon);
Laszlo Ersek293d2a02013-07-16 20:19:41 +0200314 }
bellard7e2515e2004-08-01 21:52:19 +0000315 }
316}
317
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200318void monitor_flush(Monitor *mon)
319{
320 qemu_mutex_lock(&mon->out_lock);
321 monitor_flush_locked(mon);
322 qemu_mutex_unlock(&mon->out_lock);
323}
324
Luiz Capitulinoe1f26412013-03-25 13:52:26 -0400325/* flush at every end of line */
aliguori376253e2009-03-05 23:01:23 +0000326static void monitor_puts(Monitor *mon, const char *str)
bellard7e2515e2004-08-01 21:52:19 +0000327{
ths60fe76f2007-12-16 03:02:09 +0000328 char c;
aliguori731b0362009-03-05 23:01:42 +0000329
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200330 qemu_mutex_lock(&mon->out_lock);
bellard7e2515e2004-08-01 21:52:19 +0000331 for(;;) {
332 c = *str++;
333 if (c == '\0')
334 break;
Luiz Capitulinoe1f26412013-03-25 13:52:26 -0400335 if (c == '\n') {
336 qstring_append_chr(mon->outbuf, '\r');
337 }
338 qstring_append_chr(mon->outbuf, c);
339 if (c == '\n') {
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200340 monitor_flush_locked(mon);
Luiz Capitulinoe1f26412013-03-25 13:52:26 -0400341 }
bellard7e2515e2004-08-01 21:52:19 +0000342 }
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200343 qemu_mutex_unlock(&mon->out_lock);
bellard7e2515e2004-08-01 21:52:19 +0000344}
345
aliguori376253e2009-03-05 23:01:23 +0000346void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
bellard7e2515e2004-08-01 21:52:19 +0000347{
Luiz Capitulinoe1f26412013-03-25 13:52:26 -0400348 char *buf;
Luiz Capitulinob8b08262010-02-10 23:50:04 -0200349
Luiz Capitulino2daa1192009-12-14 18:53:24 -0200350 if (!mon)
351 return;
352
Luiz Capitulinob8b08262010-02-10 23:50:04 -0200353 if (monitor_ctrl_mode(mon)) {
Luiz Capitulinob8b08262010-02-10 23:50:04 -0200354 return;
Luiz Capitulino4a29a852009-11-26 22:59:05 -0200355 }
Luiz Capitulinob8b08262010-02-10 23:50:04 -0200356
Luiz Capitulinoe1f26412013-03-25 13:52:26 -0400357 buf = g_strdup_vprintf(fmt, ap);
Luiz Capitulinob8b08262010-02-10 23:50:04 -0200358 monitor_puts(mon, buf);
Luiz Capitulinoe1f26412013-03-25 13:52:26 -0400359 g_free(buf);
bellard7e2515e2004-08-01 21:52:19 +0000360}
361
aliguori376253e2009-03-05 23:01:23 +0000362void monitor_printf(Monitor *mon, const char *fmt, ...)
bellard7e2515e2004-08-01 21:52:19 +0000363{
364 va_list ap;
365 va_start(ap, fmt);
aliguori376253e2009-03-05 23:01:23 +0000366 monitor_vprintf(mon, fmt, ap);
bellard7e2515e2004-08-01 21:52:19 +0000367 va_end(ap);
bellard9dc39cb2004-03-14 21:38:27 +0000368}
369
Stefan Weil8b7968f2010-09-23 21:28:05 +0200370static int GCC_FMT_ATTR(2, 3) monitor_fprintf(FILE *stream,
371 const char *fmt, ...)
bellard7fe48482004-10-09 18:08:01 +0000372{
373 va_list ap;
374 va_start(ap, fmt);
aliguori376253e2009-03-05 23:01:23 +0000375 monitor_vprintf((Monitor *)stream, fmt, ap);
bellard7fe48482004-10-09 18:08:01 +0000376 va_end(ap);
377 return 0;
378}
379
Luiz Capitulino8204a912009-11-18 23:05:31 -0200380static inline int monitor_has_error(const Monitor *mon)
381{
382 return mon->error != NULL;
383}
384
Luiz Capitulino9b57c022009-11-26 22:58:58 -0200385static void monitor_json_emitter(Monitor *mon, const QObject *data)
386{
387 QString *json;
388
Luiz Capitulino83a27d42010-11-22 17:10:37 -0200389 json = mon->flags & MONITOR_USE_PRETTY ? qobject_to_json_pretty(data) :
390 qobject_to_json(data);
Luiz Capitulino9b57c022009-11-26 22:58:58 -0200391 assert(json != NULL);
392
Luiz Capitulinob8b08262010-02-10 23:50:04 -0200393 qstring_append_chr(json, '\n');
394 monitor_puts(mon, qstring_get_str(json));
Luiz Capitulino4a29a852009-11-26 22:59:05 -0200395
Luiz Capitulino9b57c022009-11-26 22:58:58 -0200396 QDECREF(json);
397}
398
Luiz Capitulinode253f12012-07-27 16:18:16 -0300399static QDict *build_qmp_error_dict(const QError *err)
400{
401 QObject *obj;
402
403 obj = qobject_from_jsonf("{ 'error': { 'class': %s, 'desc': %p } }",
404 ErrorClass_lookup[err->err_class],
405 qerror_human(err));
406
407 return qobject_to_qdict(obj);
408}
409
Markus Armbruster70ea0c52015-03-06 10:47:08 +0100410static void monitor_protocol_emitter(Monitor *mon, QObject *data,
411 QError *err)
Luiz Capitulino25b422e2009-11-26 22:58:59 -0200412{
413 QDict *qmp;
414
Stefan Hajnoczi89bd8202011-09-23 08:23:06 +0100415 trace_monitor_protocol_emitter(mon);
416
Markus Armbruster70ea0c52015-03-06 10:47:08 +0100417 if (!err) {
Luiz Capitulino25b422e2009-11-26 22:58:59 -0200418 /* success response */
Luiz Capitulinode253f12012-07-27 16:18:16 -0300419 qmp = qdict_new();
Luiz Capitulino25b422e2009-11-26 22:58:59 -0200420 if (data) {
421 qobject_incref(data);
422 qdict_put_obj(qmp, "return", data);
423 } else {
Luiz Capitulino0abc6572009-12-18 13:25:00 -0200424 /* return an empty QDict by default */
425 qdict_put(qmp, "return", qdict_new());
Luiz Capitulino25b422e2009-11-26 22:58:59 -0200426 }
427 } else {
428 /* error response */
Markus Armbruster70ea0c52015-03-06 10:47:08 +0100429 qmp = build_qmp_error_dict(err);
Luiz Capitulino25b422e2009-11-26 22:58:59 -0200430 }
431
Luiz Capitulino5fa737a2009-11-26 22:59:01 -0200432 if (mon->mc->id) {
433 qdict_put_obj(qmp, "id", mon->mc->id);
434 mon->mc->id = NULL;
435 }
436
Luiz Capitulino25b422e2009-11-26 22:58:59 -0200437 monitor_json_emitter(mon, QOBJECT(qmp));
438 QDECREF(qmp);
439}
440
Luiz Capitulino0d1ea872009-11-26 22:59:03 -0200441
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200442static MonitorQAPIEventState monitor_qapi_event_state[QAPI_EVENT_MAX];
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100443
444/*
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200445 * Emits the event to every monitor instance, @event is only used for trace
Paolo Bonzinid622cb52014-06-18 08:44:00 +0200446 * Called with monitor_lock held.
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100447 */
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200448static void monitor_qapi_event_emit(QAPIEvent event, QObject *data)
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100449{
450 Monitor *mon;
451
452 trace_monitor_protocol_event_emit(event, data);
453 QLIST_FOREACH(mon, &mon_list, entry) {
454 if (monitor_ctrl_mode(mon) && qmp_cmd_mode(mon)) {
455 monitor_json_emitter(mon, data);
456 }
457 }
458}
459
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100460/*
461 * Queue a new event for emission to Monitor instances,
462 * applying any rate limiting if required.
463 */
464static void
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200465monitor_qapi_event_queue(QAPIEvent event, QDict *data, Error **errp)
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100466{
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200467 MonitorQAPIEventState *evstate;
468 assert(event < QAPI_EVENT_MAX);
Alex Blighbc72ad62013-08-21 16:03:08 +0100469 int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100470
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200471 evstate = &(monitor_qapi_event_state[event]);
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100472 trace_monitor_protocol_event_queue(event,
473 data,
474 evstate->rate,
475 evstate->last,
476 now);
477
478 /* Rate limit of 0 indicates no throttling */
Paolo Bonzinid622cb52014-06-18 08:44:00 +0200479 qemu_mutex_lock(&monitor_lock);
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100480 if (!evstate->rate) {
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200481 monitor_qapi_event_emit(event, QOBJECT(data));
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100482 evstate->last = now;
483 } else {
484 int64_t delta = now - evstate->last;
485 if (evstate->data ||
486 delta < evstate->rate) {
487 /* If there's an existing event pending, replace
488 * it with the new event, otherwise schedule a
489 * timer for delayed emission
490 */
491 if (evstate->data) {
492 qobject_decref(evstate->data);
493 } else {
494 int64_t then = evstate->last + evstate->rate;
Alex Blighbc72ad62013-08-21 16:03:08 +0100495 timer_mod_ns(evstate->timer, then);
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100496 }
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200497 evstate->data = QOBJECT(data);
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100498 qobject_incref(evstate->data);
499 } else {
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200500 monitor_qapi_event_emit(event, QOBJECT(data));
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100501 evstate->last = now;
502 }
503 }
Paolo Bonzinid622cb52014-06-18 08:44:00 +0200504 qemu_mutex_unlock(&monitor_lock);
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100505}
506
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100507/*
508 * The callback invoked by QemuTimer when a delayed
509 * event is ready to be emitted
510 */
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200511static void monitor_qapi_event_handler(void *opaque)
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100512{
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200513 MonitorQAPIEventState *evstate = opaque;
Alex Blighbc72ad62013-08-21 16:03:08 +0100514 int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100515
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100516 trace_monitor_protocol_event_handler(evstate->event,
517 evstate->data,
518 evstate->last,
519 now);
Paolo Bonzinid622cb52014-06-18 08:44:00 +0200520 qemu_mutex_lock(&monitor_lock);
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100521 if (evstate->data) {
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200522 monitor_qapi_event_emit(evstate->event, evstate->data);
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100523 qobject_decref(evstate->data);
524 evstate->data = NULL;
525 }
526 evstate->last = now;
Paolo Bonzinid622cb52014-06-18 08:44:00 +0200527 qemu_mutex_unlock(&monitor_lock);
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100528}
529
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100530/*
531 * @event: the event ID to be limited
532 * @rate: the rate limit in milliseconds
533 *
534 * Sets a rate limit on a particular event, so no
535 * more than 1 event will be emitted within @rate
536 * milliseconds
537 */
538static void
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200539monitor_qapi_event_throttle(QAPIEvent event, int64_t rate)
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100540{
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200541 MonitorQAPIEventState *evstate;
542 assert(event < QAPI_EVENT_MAX);
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100543
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200544 evstate = &(monitor_qapi_event_state[event]);
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100545
546 trace_monitor_protocol_event_throttle(event, rate);
547 evstate->event = event;
Wenchao Xia2f44a082014-06-24 16:34:00 -0700548 assert(rate * SCALE_MS <= INT64_MAX);
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100549 evstate->rate = rate * SCALE_MS;
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100550 evstate->last = 0;
551 evstate->data = NULL;
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200552 evstate->timer = timer_new(QEMU_CLOCK_REALTIME,
553 SCALE_MS,
554 monitor_qapi_event_handler,
555 evstate);
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100556}
557
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200558static void monitor_qapi_event_init(void)
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100559{
Wenchao Xiae010ad82014-06-18 08:43:41 +0200560 /* Limit guest-triggerable events to 1 per second */
561 monitor_qapi_event_throttle(QAPI_EVENT_RTC_CHANGE, 1000);
Wenchao Xia99eaf092014-06-18 08:43:42 +0200562 monitor_qapi_event_throttle(QAPI_EVENT_WATCHDOG, 1000);
Wenchao Xiaaef9d312014-06-18 08:43:51 +0200563 monitor_qapi_event_throttle(QAPI_EVENT_BALLOON_CHANGE, 1000);
Wenchao Xiafe069d92014-06-18 08:43:53 +0200564 monitor_qapi_event_throttle(QAPI_EVENT_QUORUM_REPORT_BAD, 1000);
565 monitor_qapi_event_throttle(QAPI_EVENT_QUORUM_FAILURE, 1000);
Laszlo Erseke2ae6152014-06-26 17:50:02 +0200566 monitor_qapi_event_throttle(QAPI_EVENT_VSERPORT_CHANGE, 1000);
Daniel P. Berrangeafeecec2012-06-14 18:12:57 +0100567
Wenchao Xia43a14cf2014-06-18 08:43:31 +0200568 qmp_event_set_func_emit(monitor_qapi_event_queue);
Luiz Capitulino0d1ea872009-11-26 22:59:03 -0200569}
570
Luiz Capitulinoef4b7ee2010-02-10 23:49:48 -0200571static int do_qmp_capabilities(Monitor *mon, const QDict *params,
572 QObject **ret_data)
Luiz Capitulino4a7e1192010-02-04 18:10:05 -0200573{
574 /* Will setup QMP capabilities in the future */
575 if (monitor_ctrl_mode(mon)) {
576 mon->mc->command_mode = 1;
577 }
Luiz Capitulinoef4b7ee2010-02-10 23:49:48 -0200578
579 return 0;
Luiz Capitulino4a7e1192010-02-04 18:10:05 -0200580}
581
Luiz Capitulino0268d972010-10-22 10:08:02 -0200582static void handle_user_command(Monitor *mon, const char *cmdline);
583
Wenchao Xiab01fe892013-08-27 20:38:19 +0800584static void monitor_data_init(Monitor *mon)
585{
586 memset(mon, 0, sizeof(Monitor));
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200587 qemu_mutex_init(&mon->out_lock);
Wenchao Xiab01fe892013-08-27 20:38:19 +0800588 mon->outbuf = qstring_new();
Wenchao Xia77172392013-08-27 20:38:20 +0800589 /* Use *mon_cmds by default. */
590 mon->cmd_table = mon_cmds;
Wenchao Xiab01fe892013-08-27 20:38:19 +0800591}
592
593static void monitor_data_destroy(Monitor *mon)
594{
595 QDECREF(mon->outbuf);
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200596 qemu_mutex_destroy(&mon->out_lock);
Wenchao Xiab01fe892013-08-27 20:38:19 +0800597}
598
Luiz Capitulinod51a67b2011-11-25 17:52:45 -0200599char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index,
600 int64_t cpu_index, Error **errp)
Luiz Capitulino0268d972010-10-22 10:08:02 -0200601{
Luiz Capitulinod51a67b2011-11-25 17:52:45 -0200602 char *output = NULL;
Luiz Capitulino0268d972010-10-22 10:08:02 -0200603 Monitor *old_mon, hmp;
Luiz Capitulino0268d972010-10-22 10:08:02 -0200604
Wenchao Xiab01fe892013-08-27 20:38:19 +0800605 monitor_data_init(&hmp);
Luiz Capitulino48c043d2013-04-02 15:07:33 -0400606 hmp.skip_flush = true;
Luiz Capitulino0268d972010-10-22 10:08:02 -0200607
608 old_mon = cur_mon;
609 cur_mon = &hmp;
610
Luiz Capitulinod51a67b2011-11-25 17:52:45 -0200611 if (has_cpu_index) {
612 int ret = monitor_set_cpu(cpu_index);
Luiz Capitulino0268d972010-10-22 10:08:02 -0200613 if (ret < 0) {
614 cur_mon = old_mon;
Luiz Capitulinod51a67b2011-11-25 17:52:45 -0200615 error_set(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index",
616 "a CPU number");
Luiz Capitulino0268d972010-10-22 10:08:02 -0200617 goto out;
618 }
619 }
620
Luiz Capitulinod51a67b2011-11-25 17:52:45 -0200621 handle_user_command(&hmp, command_line);
Luiz Capitulino0268d972010-10-22 10:08:02 -0200622 cur_mon = old_mon;
623
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200624 qemu_mutex_lock(&hmp.out_lock);
Luiz Capitulino48c043d2013-04-02 15:07:33 -0400625 if (qstring_get_length(hmp.outbuf) > 0) {
626 output = g_strdup(qstring_get_str(hmp.outbuf));
Luiz Capitulinod51a67b2011-11-25 17:52:45 -0200627 } else {
628 output = g_strdup("");
Luiz Capitulino0268d972010-10-22 10:08:02 -0200629 }
Paolo Bonzini6cff3e82014-06-18 08:43:59 +0200630 qemu_mutex_unlock(&hmp.out_lock);
Luiz Capitulino0268d972010-10-22 10:08:02 -0200631
632out:
Wenchao Xiab01fe892013-08-27 20:38:19 +0800633 monitor_data_destroy(&hmp);
Luiz Capitulinod51a67b2011-11-25 17:52:45 -0200634 return output;
Luiz Capitulino0268d972010-10-22 10:08:02 -0200635}
636
bellard9dc39cb2004-03-14 21:38:27 +0000637static int compare_cmd(const char *name, const char *list)
638{
639 const char *p, *pstart;
640 int len;
641 len = strlen(name);
642 p = list;
643 for(;;) {
644 pstart = p;
645 p = strchr(p, '|');
646 if (!p)
647 p = pstart + strlen(pstart);
648 if ((p - pstart) == len && !memcmp(pstart, name, len))
649 return 1;
650 if (*p == '\0')
651 break;
652 p++;
653 }
654 return 0;
655}
656
Wenchao Xiaf5438c02013-08-27 20:38:21 +0800657static int get_str(char *buf, int buf_size, const char **pp)
658{
659 const char *p;
660 char *q;
661 int c;
662
663 q = buf;
664 p = *pp;
665 while (qemu_isspace(*p)) {
666 p++;
667 }
668 if (*p == '\0') {
669 fail:
670 *q = '\0';
671 *pp = p;
672 return -1;
673 }
674 if (*p == '\"') {
675 p++;
676 while (*p != '\0' && *p != '\"') {
677 if (*p == '\\') {
678 p++;
679 c = *p++;
680 switch (c) {
681 case 'n':
682 c = '\n';
683 break;
684 case 'r':
685 c = '\r';
686 break;
687 case '\\':
688 case '\'':
689 case '\"':
690 break;
691 default:
692 qemu_printf("unsupported escape code: '\\%c'\n", c);
693 goto fail;
694 }
695 if ((q - buf) < buf_size - 1) {
696 *q++ = c;
697 }
698 } else {
699 if ((q - buf) < buf_size - 1) {
700 *q++ = *p;
701 }
702 p++;
703 }
704 }
705 if (*p != '\"') {
706 qemu_printf("unterminated string\n");
707 goto fail;
708 }
709 p++;
710 } else {
711 while (*p != '\0' && !qemu_isspace(*p)) {
712 if ((q - buf) < buf_size - 1) {
713 *q++ = *p;
714 }
715 p++;
716 }
717 }
718 *q = '\0';
719 *pp = p;
720 return 0;
721}
722
723#define MAX_ARGS 16
724
Wenchao Xiadcc70cd2013-08-27 20:38:22 +0800725static void free_cmdline_args(char **args, int nb_args)
726{
727 int i;
728
729 assert(nb_args <= MAX_ARGS);
730
731 for (i = 0; i < nb_args; i++) {
732 g_free(args[i]);
733 }
734
735}
736
737/*
738 * Parse the command line to get valid args.
739 * @cmdline: command line to be parsed.
740 * @pnb_args: location to store the number of args, must NOT be NULL.
741 * @args: location to store the args, which should be freed by caller, must
742 * NOT be NULL.
743 *
744 * Returns 0 on success, negative on failure.
745 *
746 * NOTE: this parser is an approximate form of the real command parser. Number
747 * of args have a limit of MAX_ARGS. If cmdline contains more, it will
748 * return with failure.
749 */
750static int parse_cmdline(const char *cmdline,
751 int *pnb_args, char **args)
Wenchao Xiaf5438c02013-08-27 20:38:21 +0800752{
753 const char *p;
754 int nb_args, ret;
755 char buf[1024];
756
757 p = cmdline;
758 nb_args = 0;
759 for (;;) {
760 while (qemu_isspace(*p)) {
761 p++;
762 }
763 if (*p == '\0') {
764 break;
765 }
766 if (nb_args >= MAX_ARGS) {
Wenchao Xiadcc70cd2013-08-27 20:38:22 +0800767 goto fail;
Wenchao Xiaf5438c02013-08-27 20:38:21 +0800768 }
769 ret = get_str(buf, sizeof(buf), &p);
Wenchao Xiadcc70cd2013-08-27 20:38:22 +0800770 if (ret < 0) {
771 goto fail;
772 }
Wenchao Xiaf5438c02013-08-27 20:38:21 +0800773 args[nb_args] = g_strdup(buf);
774 nb_args++;
Wenchao Xiaf5438c02013-08-27 20:38:21 +0800775 }
776 *pnb_args = nb_args;
Wenchao Xiadcc70cd2013-08-27 20:38:22 +0800777 return 0;
778
779 fail:
780 free_cmdline_args(args, nb_args);
781 return -1;
Wenchao Xiaf5438c02013-08-27 20:38:21 +0800782}
783
Wenchao Xia66855492013-08-27 20:38:23 +0800784static void help_cmd_dump_one(Monitor *mon,
785 const mon_cmd_t *cmd,
786 char **prefix_args,
787 int prefix_args_nb)
788{
789 int i;
790
791 for (i = 0; i < prefix_args_nb; i++) {
792 monitor_printf(mon, "%s ", prefix_args[i]);
793 }
794 monitor_printf(mon, "%s %s -- %s\n", cmd->name, cmd->params, cmd->help);
795}
796
797/* @args[@arg_index] is the valid command need to find in @cmds */
Anthony Liguoric227f092009-10-01 16:12:16 -0500798static void help_cmd_dump(Monitor *mon, const mon_cmd_t *cmds,
Wenchao Xia66855492013-08-27 20:38:23 +0800799 char **args, int nb_args, int arg_index)
bellard9dc39cb2004-03-14 21:38:27 +0000800{
Anthony Liguoric227f092009-10-01 16:12:16 -0500801 const mon_cmd_t *cmd;
bellard9dc39cb2004-03-14 21:38:27 +0000802
Wenchao Xia66855492013-08-27 20:38:23 +0800803 /* No valid arg need to compare with, dump all in *cmds */
804 if (arg_index >= nb_args) {
805 for (cmd = cmds; cmd->name != NULL; cmd++) {
806 help_cmd_dump_one(mon, cmd, args, arg_index);
807 }
808 return;
809 }
810
811 /* Find one entry to dump */
812 for (cmd = cmds; cmd->name != NULL; cmd++) {
813 if (compare_cmd(args[arg_index], cmd->name)) {
814 if (cmd->sub_table) {
815 /* continue with next arg */
816 help_cmd_dump(mon, cmd->sub_table,
817 args, nb_args, arg_index + 1);
818 } else {
819 help_cmd_dump_one(mon, cmd, args, arg_index);
820 }
821 break;
822 }
bellard9dc39cb2004-03-14 21:38:27 +0000823 }
824}
825
aliguori376253e2009-03-05 23:01:23 +0000826static void help_cmd(Monitor *mon, const char *name)
bellard9dc39cb2004-03-14 21:38:27 +0000827{
Wenchao Xia66855492013-08-27 20:38:23 +0800828 char *args[MAX_ARGS];
829 int nb_args = 0;
830
831 /* 1. parse user input */
832 if (name) {
833 /* special case for log, directly dump and return */
834 if (!strcmp(name, "log")) {
Peter Maydell38dad9e2013-02-11 16:41:25 +0000835 const QEMULogItem *item;
aliguori376253e2009-03-05 23:01:23 +0000836 monitor_printf(mon, "Log items (comma separated):\n");
837 monitor_printf(mon, "%-10s %s\n", "none", "remove all logs");
Peter Maydell38dad9e2013-02-11 16:41:25 +0000838 for (item = qemu_log_items; item->mask != 0; item++) {
aliguori376253e2009-03-05 23:01:23 +0000839 monitor_printf(mon, "%-10s %s\n", item->name, item->help);
bellardf193c792004-03-21 17:06:25 +0000840 }
Wenchao Xia66855492013-08-27 20:38:23 +0800841 return;
842 }
843
844 if (parse_cmdline(name, &nb_args, args) < 0) {
845 return;
bellardf193c792004-03-21 17:06:25 +0000846 }
bellard9dc39cb2004-03-14 21:38:27 +0000847 }
Wenchao Xia66855492013-08-27 20:38:23 +0800848
849 /* 2. dump the contents according to parsed args */
850 help_cmd_dump(mon, mon->cmd_table, args, nb_args, 0);
851
852 free_cmdline_args(args, nb_args);
bellard9dc39cb2004-03-14 21:38:27 +0000853}
854
Luiz Capitulinod54908a2009-08-28 15:27:13 -0300855static void do_help_cmd(Monitor *mon, const QDict *qdict)
Luiz Capitulino38183182009-08-28 15:27:08 -0300856{
Luiz Capitulinod54908a2009-08-28 15:27:13 -0300857 help_cmd(mon, qdict_get_try_str(qdict, "name"));
Luiz Capitulino38183182009-08-28 15:27:08 -0300858}
859
Markus Armbruster3e5a50d2015-02-06 13:55:43 +0100860static void hmp_trace_event(Monitor *mon, const QDict *qdict)
Prerna Saxena22890ab2010-06-24 17:04:53 +0530861{
862 const char *tp_name = qdict_get_str(qdict, "name");
863 bool new_state = qdict_get_bool(qdict, "option");
Lluís Vilanova14101d02014-08-25 13:20:03 +0200864 Error *local_err = NULL;
Blue Swirlf871d682010-10-13 19:14:29 +0000865
Lluís Vilanova14101d02014-08-25 13:20:03 +0200866 qmp_trace_event_set_state(tp_name, new_state, true, true, &local_err);
867 if (local_err) {
Markus Armbruster091e38b2015-02-10 15:15:43 +0100868 error_report_err(local_err);
Blue Swirlf871d682010-10-13 19:14:29 +0000869 }
Prerna Saxena22890ab2010-06-24 17:04:53 +0530870}
Stefan Hajnoczic5ceb522010-07-13 09:26:33 +0100871
Michael Rothc45a8162011-10-02 08:44:37 -0500872#ifdef CONFIG_TRACE_SIMPLE
Markus Armbruster3e5a50d2015-02-06 13:55:43 +0100873static void hmp_trace_file(Monitor *mon, const QDict *qdict)
Stefan Hajnoczic5ceb522010-07-13 09:26:33 +0100874{
875 const char *op = qdict_get_try_str(qdict, "op");
876 const char *arg = qdict_get_try_str(qdict, "arg");
877
878 if (!op) {
879 st_print_trace_file_status((FILE *)mon, &monitor_fprintf);
880 } else if (!strcmp(op, "on")) {
881 st_set_trace_file_enabled(true);
882 } else if (!strcmp(op, "off")) {
883 st_set_trace_file_enabled(false);
884 } else if (!strcmp(op, "flush")) {
885 st_flush_trace_buffer();
886 } else if (!strcmp(op, "set")) {
887 if (arg) {
888 st_set_trace_file(arg);
889 }
890 } else {
891 monitor_printf(mon, "unexpected argument \"%s\"\n", op);
892 help_cmd(mon, "trace-file");
893 }
894}
Prerna Saxena22890ab2010-06-24 17:04:53 +0530895#endif
896
Markus Armbruster3e5a50d2015-02-06 13:55:43 +0100897static void hmp_info_help(Monitor *mon, const QDict *qdict)
bellard9dc39cb2004-03-14 21:38:27 +0000898{
Luiz Capitulino13c74252009-10-07 13:41:55 -0300899 help_cmd(mon, "info");
bellard9dc39cb2004-03-14 21:38:27 +0000900}
901
Luiz Capitulinoaa9b79b2011-09-21 14:31:51 -0300902CommandInfoList *qmp_query_commands(Error **errp)
bellard9bc9d1c2004-10-10 15:15:51 +0000903{
Luiz Capitulinoaa9b79b2011-09-21 14:31:51 -0300904 CommandInfoList *info, *cmd_list = NULL;
Luiz Capitulinoe3bba9d2009-11-26 22:58:56 -0200905 const mon_cmd_t *cmd;
906
Luiz Capitulinof36b4af2010-09-15 17:17:45 -0300907 for (cmd = qmp_cmds; cmd->name != NULL; cmd++) {
Luiz Capitulino40e5a012011-10-21 16:15:31 -0200908 info = g_malloc0(sizeof(*info));
909 info->value = g_malloc0(sizeof(*info->value));
910 info->value->name = g_strdup(cmd->name);
Luiz Capitulinoe3bba9d2009-11-26 22:58:56 -0200911
Luiz Capitulinoaa9b79b2011-09-21 14:31:51 -0300912 info->next = cmd_list;
913 cmd_list = info;
Luiz Capitulinoe3bba9d2009-11-26 22:58:56 -0200914 }
915
Luiz Capitulinoaa9b79b2011-09-21 14:31:51 -0300916 return cmd_list;
thsa36e69d2007-12-02 05:18:19 +0000917}
918
Daniel P. Berrange48608532012-05-21 17:59:51 +0100919EventInfoList *qmp_query_events(Error **errp)
920{
921 EventInfoList *info, *ev_list = NULL;
Wenchao Xia75175172014-06-18 08:43:54 +0200922 QAPIEvent e;
Daniel P. Berrange48608532012-05-21 17:59:51 +0100923
Wenchao Xia75175172014-06-18 08:43:54 +0200924 for (e = 0 ; e < QAPI_EVENT_MAX ; e++) {
925 const char *event_name = QAPIEvent_lookup[e];
Daniel P. Berrange48608532012-05-21 17:59:51 +0100926 assert(event_name != NULL);
927 info = g_malloc0(sizeof(*info));
928 info->value = g_malloc0(sizeof(*info->value));
929 info->value->name = g_strdup(event_name);
930
931 info->next = ev_list;
932 ev_list = info;
933 }
934
935 return ev_list;
936}
937
Luiz Capitulinob025c8b2011-10-06 14:02:57 -0300938/* set the current CPU defined by the user */
939int monitor_set_cpu(int cpu_index)
bellard6a00d602005-11-21 23:25:50 +0000940{
Andreas Färber55e5c282012-12-17 06:18:02 +0100941 CPUState *cpu;
bellard6a00d602005-11-21 23:25:50 +0000942
Andreas Färber1c8bb3c2013-02-15 17:01:09 +0100943 cpu = qemu_get_cpu(cpu_index);
944 if (cpu == NULL) {
945 return -1;
bellard6a00d602005-11-21 23:25:50 +0000946 }
Andreas Färbercb446ec2013-05-01 14:24:52 +0200947 cur_mon->mon_cpu = cpu;
Andreas Färber1c8bb3c2013-02-15 17:01:09 +0100948 return 0;
bellard6a00d602005-11-21 23:25:50 +0000949}
950
Andreas Färber9349b4f2012-03-14 01:38:32 +0100951static CPUArchState *mon_get_cpu(void)
bellard6a00d602005-11-21 23:25:50 +0000952{
aliguori731b0362009-03-05 23:01:42 +0000953 if (!cur_mon->mon_cpu) {
Luiz Capitulinob025c8b2011-10-06 14:02:57 -0300954 monitor_set_cpu(0);
bellard6a00d602005-11-21 23:25:50 +0000955 }
Avi Kivity4c0960c2009-08-17 23:19:53 +0300956 cpu_synchronize_state(cur_mon->mon_cpu);
Andreas Färbercb446ec2013-05-01 14:24:52 +0200957 return cur_mon->mon_cpu->env_ptr;
bellard6a00d602005-11-21 23:25:50 +0000958}
959
Luiz Capitulino99b77962011-10-24 10:53:44 -0200960int monitor_get_cpu_index(void)
961{
Andreas Färber55e5c282012-12-17 06:18:02 +0100962 CPUState *cpu = ENV_GET_CPU(mon_get_cpu());
963 return cpu->cpu_index;
Luiz Capitulino99b77962011-10-24 10:53:44 -0200964}
965
Markus Armbruster1ce6be22015-02-06 14:18:24 +0100966static void hmp_info_registers(Monitor *mon, const QDict *qdict)
bellard9307c4c2004-04-04 12:57:25 +0000967{
Andreas Färber878096e2013-05-27 01:33:50 +0200968 CPUState *cpu;
Andreas Färber9349b4f2012-03-14 01:38:32 +0100969 CPUArchState *env;
bellard6a00d602005-11-21 23:25:50 +0000970 env = mon_get_cpu();
Andreas Färber878096e2013-05-27 01:33:50 +0200971 cpu = ENV_GET_CPU(env);
972 cpu_dump_state(cpu, (FILE *)mon, monitor_fprintf, CPU_DUMP_FPU);
bellard9307c4c2004-04-04 12:57:25 +0000973}
974
Markus Armbruster1ce6be22015-02-06 14:18:24 +0100975static void hmp_info_jit(Monitor *mon, const QDict *qdict)
bellarde3db7222005-01-26 22:00:47 +0000976{
aliguori376253e2009-03-05 23:01:23 +0000977 dump_exec_info((FILE *)mon, monitor_fprintf);
Sebastian Tanase27498be2014-07-25 11:56:33 +0200978 dump_drift_info((FILE *)mon, monitor_fprintf);
bellarde3db7222005-01-26 22:00:47 +0000979}
980
Markus Armbruster1ce6be22015-02-06 14:18:24 +0100981static void hmp_info_opcount(Monitor *mon, const QDict *qdict)
Max Filippov246ae242014-11-02 11:04:18 +0300982{
983 dump_opcount_info((FILE *)mon, monitor_fprintf);
984}
985
Markus Armbruster1ce6be22015-02-06 14:18:24 +0100986static void hmp_info_history(Monitor *mon, const QDict *qdict)
bellardaa455482004-04-04 13:07:25 +0000987{
988 int i;
bellard7e2515e2004-08-01 21:52:19 +0000989 const char *str;
ths3b46e622007-09-17 08:09:54 +0000990
aliguoricde76ee2009-03-05 23:01:51 +0000991 if (!mon->rs)
992 return;
bellard7e2515e2004-08-01 21:52:19 +0000993 i = 0;
994 for(;;) {
aliguori731b0362009-03-05 23:01:42 +0000995 str = readline_get_history(mon->rs, i);
bellard7e2515e2004-08-01 21:52:19 +0000996 if (!str)
997 break;
aliguori376253e2009-03-05 23:01:23 +0000998 monitor_printf(mon, "%d: '%s'\n", i, str);
bellard8e3a9fd2004-10-09 17:32:58 +0000999 i++;
bellardaa455482004-04-04 13:07:25 +00001000 }
1001}
1002
Markus Armbruster1ce6be22015-02-06 14:18:24 +01001003static void hmp_info_cpustats(Monitor *mon, const QDict *qdict)
j_mayer76a66252007-03-07 08:32:30 +00001004{
Andreas Färber878096e2013-05-27 01:33:50 +02001005 CPUState *cpu;
Andreas Färber9349b4f2012-03-14 01:38:32 +01001006 CPUArchState *env;
j_mayer76a66252007-03-07 08:32:30 +00001007
1008 env = mon_get_cpu();
Andreas Färber878096e2013-05-27 01:33:50 +02001009 cpu = ENV_GET_CPU(env);
1010 cpu_dump_statistics(cpu, (FILE *)mon, &monitor_fprintf, 0);
j_mayer76a66252007-03-07 08:32:30 +00001011}
j_mayer76a66252007-03-07 08:32:30 +00001012
Markus Armbruster1ce6be22015-02-06 14:18:24 +01001013static void hmp_info_trace_events(Monitor *mon, const QDict *qdict)
Prerna Saxena22890ab2010-06-24 17:04:53 +05301014{
Lluís Vilanova14101d02014-08-25 13:20:03 +02001015 TraceEventInfoList *events = qmp_trace_event_get_state("*", NULL);
1016 TraceEventInfoList *elem;
1017
1018 for (elem = events; elem != NULL; elem = elem->next) {
1019 monitor_printf(mon, "%s : state %u\n",
1020 elem->value->name,
1021 elem->value->state == TRACE_EVENT_STATE_ENABLED ? 1 : 0);
1022 }
1023 qapi_free_TraceEventInfoList(events);
Prerna Saxena22890ab2010-06-24 17:04:53 +05301024}
Prerna Saxena22890ab2010-06-24 17:04:53 +05301025
Markus Armbrusterb8a185b2015-03-05 17:29:02 +01001026void qmp_client_migrate_info(const char *protocol, const char *hostname,
1027 bool has_port, int64_t port,
1028 bool has_tls_port, int64_t tls_port,
1029 bool has_cert_subject, const char *cert_subject,
1030 Error **errp)
Gerd Hoffmanne866e232010-04-23 13:28:21 +02001031{
Gerd Hoffmanne866e232010-04-23 13:28:21 +02001032 if (strcmp(protocol, "spice") == 0) {
Markus Armbrusterb8a185b2015-03-05 17:29:02 +01001033 if (!qemu_using_spice(errp)) {
1034 return;
Gerd Hoffmanne866e232010-04-23 13:28:21 +02001035 }
1036
Markus Armbrusterb8a185b2015-03-05 17:29:02 +01001037 if (!has_port && !has_tls_port) {
1038 error_set(errp, QERR_MISSING_PARAMETER, "port/tls-port");
1039 return;
Yonit Halperin6ec5dae2012-03-18 09:42:39 +02001040 }
1041
Markus Armbrusterb8a185b2015-03-05 17:29:02 +01001042 if (qemu_spice_migrate_info(hostname,
1043 has_port ? port : -1,
1044 has_tls_port ? tls_port : -1,
1045 cert_subject)) {
1046 error_set(errp, QERR_UNDEFINED_ERROR);
1047 return;
Gerd Hoffmanne866e232010-04-23 13:28:21 +02001048 }
Markus Armbrusterb8a185b2015-03-05 17:29:02 +01001049 return;
Gerd Hoffmanne866e232010-04-23 13:28:21 +02001050 }
1051
Markus Armbrusterb8a185b2015-03-05 17:29:02 +01001052 error_set(errp, QERR_INVALID_PARAMETER_VALUE, "protocol", "spice");
Gerd Hoffmanne866e232010-04-23 13:28:21 +02001053}
1054
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001055static void hmp_logfile(Monitor *mon, const QDict *qdict)
pbrooke735b912007-06-30 13:53:24 +00001056{
Peter Maydell9a7e5422013-02-11 16:41:20 +00001057 qemu_set_log_filename(qdict_get_str(qdict, "filename"));
pbrooke735b912007-06-30 13:53:24 +00001058}
1059
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001060static void hmp_log(Monitor *mon, const QDict *qdict)
bellardf193c792004-03-21 17:06:25 +00001061{
1062 int mask;
Luiz Capitulinod54908a2009-08-28 15:27:13 -03001063 const char *items = qdict_get_str(qdict, "items");
ths3b46e622007-09-17 08:09:54 +00001064
bellard9307c4c2004-04-04 12:57:25 +00001065 if (!strcmp(items, "none")) {
bellardf193c792004-03-21 17:06:25 +00001066 mask = 0;
1067 } else {
Peter Maydell4fde1eb2013-02-11 16:41:22 +00001068 mask = qemu_str_to_log_mask(items);
bellardf193c792004-03-21 17:06:25 +00001069 if (!mask) {
aliguori376253e2009-03-05 23:01:23 +00001070 help_cmd(mon, "log");
bellardf193c792004-03-21 17:06:25 +00001071 return;
1072 }
1073 }
Peter Maydell24537a02013-02-11 16:41:23 +00001074 qemu_set_log(mask);
bellardf193c792004-03-21 17:06:25 +00001075}
1076
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001077static void hmp_singlestep(Monitor *mon, const QDict *qdict)
aurel321b530a62009-04-05 20:08:59 +00001078{
Luiz Capitulinod54908a2009-08-28 15:27:13 -03001079 const char *option = qdict_get_try_str(qdict, "option");
aurel321b530a62009-04-05 20:08:59 +00001080 if (!option || !strcmp(option, "on")) {
1081 singlestep = 1;
1082 } else if (!strcmp(option, "off")) {
1083 singlestep = 0;
1084 } else {
1085 monitor_printf(mon, "unexpected option %s\n", option);
1086 }
1087}
1088
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001089static void hmp_gdbserver(Monitor *mon, const QDict *qdict)
bellard8a7ddc32004-03-31 19:00:16 +00001090{
Luiz Capitulinod54908a2009-08-28 15:27:13 -03001091 const char *device = qdict_get_try_str(qdict, "device");
aliguori59030a82009-04-05 18:43:41 +00001092 if (!device)
1093 device = "tcp::" DEFAULT_GDBSTUB_PORT;
1094 if (gdbserver_start(device) < 0) {
1095 monitor_printf(mon, "Could not open gdbserver on device '%s'\n",
1096 device);
1097 } else if (strcmp(device, "none") == 0) {
aliguori36556b22009-03-28 18:05:53 +00001098 monitor_printf(mon, "Disabled gdbserver\n");
bellard8a7ddc32004-03-31 19:00:16 +00001099 } else {
aliguori59030a82009-04-05 18:43:41 +00001100 monitor_printf(mon, "Waiting for gdb connection on device '%s'\n",
1101 device);
bellard8a7ddc32004-03-31 19:00:16 +00001102 }
1103}
1104
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001105static void hmp_watchdog_action(Monitor *mon, const QDict *qdict)
Richard W.M. Jones9dd986c2009-04-25 13:56:19 +01001106{
Luiz Capitulinod54908a2009-08-28 15:27:13 -03001107 const char *action = qdict_get_str(qdict, "action");
Richard W.M. Jones9dd986c2009-04-25 13:56:19 +01001108 if (select_watchdog_action(action) == -1) {
1109 monitor_printf(mon, "Unknown watchdog action '%s'\n", action);
1110 }
1111}
1112
aliguori376253e2009-03-05 23:01:23 +00001113static void monitor_printc(Monitor *mon, int c)
bellard9307c4c2004-04-04 12:57:25 +00001114{
aliguori376253e2009-03-05 23:01:23 +00001115 monitor_printf(mon, "'");
bellard9307c4c2004-04-04 12:57:25 +00001116 switch(c) {
1117 case '\'':
aliguori376253e2009-03-05 23:01:23 +00001118 monitor_printf(mon, "\\'");
bellard9307c4c2004-04-04 12:57:25 +00001119 break;
1120 case '\\':
aliguori376253e2009-03-05 23:01:23 +00001121 monitor_printf(mon, "\\\\");
bellard9307c4c2004-04-04 12:57:25 +00001122 break;
1123 case '\n':
aliguori376253e2009-03-05 23:01:23 +00001124 monitor_printf(mon, "\\n");
bellard9307c4c2004-04-04 12:57:25 +00001125 break;
1126 case '\r':
aliguori376253e2009-03-05 23:01:23 +00001127 monitor_printf(mon, "\\r");
bellard9307c4c2004-04-04 12:57:25 +00001128 break;
1129 default:
1130 if (c >= 32 && c <= 126) {
aliguori376253e2009-03-05 23:01:23 +00001131 monitor_printf(mon, "%c", c);
bellard9307c4c2004-04-04 12:57:25 +00001132 } else {
aliguori376253e2009-03-05 23:01:23 +00001133 monitor_printf(mon, "\\x%02x", c);
bellard9307c4c2004-04-04 12:57:25 +00001134 }
1135 break;
1136 }
aliguori376253e2009-03-05 23:01:23 +00001137 monitor_printf(mon, "'");
bellard9307c4c2004-04-04 12:57:25 +00001138}
1139
aliguori376253e2009-03-05 23:01:23 +00001140static void memory_dump(Monitor *mon, int count, int format, int wsize,
Avi Kivitya8170e52012-10-23 12:30:10 +02001141 hwaddr addr, int is_physical)
bellard9307c4c2004-04-04 12:57:25 +00001142{
Andreas Färber9349b4f2012-03-14 01:38:32 +01001143 CPUArchState *env;
Blue Swirl23842aa2010-01-12 20:27:43 +00001144 int l, line_size, i, max_digits, len;
bellard9307c4c2004-04-04 12:57:25 +00001145 uint8_t buf[16];
1146 uint64_t v;
1147
1148 if (format == 'i') {
1149 int flags;
1150 flags = 0;
bellard6a00d602005-11-21 23:25:50 +00001151 env = mon_get_cpu();
bellard9307c4c2004-04-04 12:57:25 +00001152#ifdef TARGET_I386
bellard4c27ba22004-04-25 18:05:08 +00001153 if (wsize == 2) {
bellard9307c4c2004-04-04 12:57:25 +00001154 flags = 1;
bellard4c27ba22004-04-25 18:05:08 +00001155 } else if (wsize == 4) {
1156 flags = 0;
1157 } else {
bellard6a15fd12006-04-12 21:07:07 +00001158 /* as default we use the current CS size */
bellard4c27ba22004-04-25 18:05:08 +00001159 flags = 0;
bellard6a15fd12006-04-12 21:07:07 +00001160 if (env) {
1161#ifdef TARGET_X86_64
ths5fafdf22007-09-16 21:08:06 +00001162 if ((env->efer & MSR_EFER_LMA) &&
bellard6a15fd12006-04-12 21:07:07 +00001163 (env->segs[R_CS].flags & DESC_L_MASK))
1164 flags = 2;
1165 else
1166#endif
1167 if (!(env->segs[R_CS].flags & DESC_B_MASK))
1168 flags = 1;
1169 }
bellard4c27ba22004-04-25 18:05:08 +00001170 }
1171#endif
Tom Musta1c38f842014-04-09 14:53:24 -05001172#ifdef TARGET_PPC
1173 flags = msr_le << 16;
1174 flags |= env->bfd_mach;
1175#endif
aliguori376253e2009-03-05 23:01:23 +00001176 monitor_disas(mon, env, addr, count, is_physical, flags);
bellard9307c4c2004-04-04 12:57:25 +00001177 return;
1178 }
1179
1180 len = wsize * count;
1181 if (wsize == 1)
1182 line_size = 8;
1183 else
1184 line_size = 16;
bellard9307c4c2004-04-04 12:57:25 +00001185 max_digits = 0;
1186
1187 switch(format) {
1188 case 'o':
1189 max_digits = (wsize * 8 + 2) / 3;
1190 break;
1191 default:
1192 case 'x':
1193 max_digits = (wsize * 8) / 4;
1194 break;
1195 case 'u':
1196 case 'd':
1197 max_digits = (wsize * 8 * 10 + 32) / 33;
1198 break;
1199 case 'c':
1200 wsize = 1;
1201 break;
1202 }
1203
1204 while (len > 0) {
blueswir17743e582007-09-24 18:39:04 +00001205 if (is_physical)
aliguori376253e2009-03-05 23:01:23 +00001206 monitor_printf(mon, TARGET_FMT_plx ":", addr);
blueswir17743e582007-09-24 18:39:04 +00001207 else
aliguori376253e2009-03-05 23:01:23 +00001208 monitor_printf(mon, TARGET_FMT_lx ":", (target_ulong)addr);
bellard9307c4c2004-04-04 12:57:25 +00001209 l = len;
1210 if (l > line_size)
1211 l = line_size;
1212 if (is_physical) {
Stefan Weil54f7b4a2011-04-10 18:23:39 +02001213 cpu_physical_memory_read(addr, buf, l);
bellard9307c4c2004-04-04 12:57:25 +00001214 } else {
bellard6a00d602005-11-21 23:25:50 +00001215 env = mon_get_cpu();
Andreas Färberf17ec442013-06-29 19:40:58 +02001216 if (cpu_memory_rw_debug(ENV_GET_CPU(env), addr, buf, l, 0) < 0) {
aliguori376253e2009-03-05 23:01:23 +00001217 monitor_printf(mon, " Cannot access memory\n");
aliguoric8f79b62008-08-18 14:00:20 +00001218 break;
1219 }
bellard9307c4c2004-04-04 12:57:25 +00001220 }
ths5fafdf22007-09-16 21:08:06 +00001221 i = 0;
bellard9307c4c2004-04-04 12:57:25 +00001222 while (i < l) {
1223 switch(wsize) {
1224 default:
1225 case 1:
Peter Maydell24e60302015-01-20 15:19:32 +00001226 v = ldub_p(buf + i);
bellard9307c4c2004-04-04 12:57:25 +00001227 break;
1228 case 2:
Peter Maydell24e60302015-01-20 15:19:32 +00001229 v = lduw_p(buf + i);
bellard9307c4c2004-04-04 12:57:25 +00001230 break;
1231 case 4:
Peter Maydell24e60302015-01-20 15:19:32 +00001232 v = (uint32_t)ldl_p(buf + i);
bellard9307c4c2004-04-04 12:57:25 +00001233 break;
1234 case 8:
Peter Maydell24e60302015-01-20 15:19:32 +00001235 v = ldq_p(buf + i);
bellard9307c4c2004-04-04 12:57:25 +00001236 break;
1237 }
aliguori376253e2009-03-05 23:01:23 +00001238 monitor_printf(mon, " ");
bellard9307c4c2004-04-04 12:57:25 +00001239 switch(format) {
1240 case 'o':
aliguori376253e2009-03-05 23:01:23 +00001241 monitor_printf(mon, "%#*" PRIo64, max_digits, v);
bellard9307c4c2004-04-04 12:57:25 +00001242 break;
1243 case 'x':
aliguori376253e2009-03-05 23:01:23 +00001244 monitor_printf(mon, "0x%0*" PRIx64, max_digits, v);
bellard9307c4c2004-04-04 12:57:25 +00001245 break;
1246 case 'u':
aliguori376253e2009-03-05 23:01:23 +00001247 monitor_printf(mon, "%*" PRIu64, max_digits, v);
bellard9307c4c2004-04-04 12:57:25 +00001248 break;
1249 case 'd':
aliguori376253e2009-03-05 23:01:23 +00001250 monitor_printf(mon, "%*" PRId64, max_digits, v);
bellard9307c4c2004-04-04 12:57:25 +00001251 break;
1252 case 'c':
aliguori376253e2009-03-05 23:01:23 +00001253 monitor_printc(mon, v);
bellard9307c4c2004-04-04 12:57:25 +00001254 break;
1255 }
1256 i += wsize;
1257 }
aliguori376253e2009-03-05 23:01:23 +00001258 monitor_printf(mon, "\n");
bellard9307c4c2004-04-04 12:57:25 +00001259 addr += l;
1260 len -= l;
1261 }
1262}
1263
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001264static void hmp_memory_dump(Monitor *mon, const QDict *qdict)
bellard9307c4c2004-04-04 12:57:25 +00001265{
Luiz Capitulino1bd14422009-08-28 15:27:17 -03001266 int count = qdict_get_int(qdict, "count");
1267 int format = qdict_get_int(qdict, "format");
1268 int size = qdict_get_int(qdict, "size");
1269 target_long addr = qdict_get_int(qdict, "addr");
1270
aliguori376253e2009-03-05 23:01:23 +00001271 memory_dump(mon, count, format, size, addr, 0);
bellard9307c4c2004-04-04 12:57:25 +00001272}
1273
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001274static void hmp_physical_memory_dump(Monitor *mon, const QDict *qdict)
bellard9307c4c2004-04-04 12:57:25 +00001275{
Luiz Capitulino1bd14422009-08-28 15:27:17 -03001276 int count = qdict_get_int(qdict, "count");
1277 int format = qdict_get_int(qdict, "format");
1278 int size = qdict_get_int(qdict, "size");
Avi Kivitya8170e52012-10-23 12:30:10 +02001279 hwaddr addr = qdict_get_int(qdict, "addr");
Luiz Capitulino1bd14422009-08-28 15:27:17 -03001280
aliguori376253e2009-03-05 23:01:23 +00001281 memory_dump(mon, count, format, size, addr, 1);
bellard9307c4c2004-04-04 12:57:25 +00001282}
1283
Luiz Capitulino1bd14422009-08-28 15:27:17 -03001284static void do_print(Monitor *mon, const QDict *qdict)
bellard9307c4c2004-04-04 12:57:25 +00001285{
Luiz Capitulino1bd14422009-08-28 15:27:17 -03001286 int format = qdict_get_int(qdict, "format");
Avi Kivitya8170e52012-10-23 12:30:10 +02001287 hwaddr val = qdict_get_int(qdict, "val");
Luiz Capitulino1bd14422009-08-28 15:27:17 -03001288
bellard9307c4c2004-04-04 12:57:25 +00001289 switch(format) {
1290 case 'o':
Avi Kivitya8170e52012-10-23 12:30:10 +02001291 monitor_printf(mon, "%#" HWADDR_PRIo, val);
bellard9307c4c2004-04-04 12:57:25 +00001292 break;
1293 case 'x':
Avi Kivitya8170e52012-10-23 12:30:10 +02001294 monitor_printf(mon, "%#" HWADDR_PRIx, val);
bellard9307c4c2004-04-04 12:57:25 +00001295 break;
1296 case 'u':
Avi Kivitya8170e52012-10-23 12:30:10 +02001297 monitor_printf(mon, "%" HWADDR_PRIu, val);
bellard9307c4c2004-04-04 12:57:25 +00001298 break;
1299 default:
1300 case 'd':
Avi Kivitya8170e52012-10-23 12:30:10 +02001301 monitor_printf(mon, "%" HWADDR_PRId, val);
bellard9307c4c2004-04-04 12:57:25 +00001302 break;
1303 case 'c':
aliguori376253e2009-03-05 23:01:23 +00001304 monitor_printc(mon, val);
bellard9307c4c2004-04-04 12:57:25 +00001305 break;
1306 }
aliguori376253e2009-03-05 23:01:23 +00001307 monitor_printf(mon, "\n");
bellard9307c4c2004-04-04 12:57:25 +00001308}
1309
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001310static void hmp_sum(Monitor *mon, const QDict *qdict)
bellarde4cf1ad2005-06-04 20:15:57 +00001311{
1312 uint32_t addr;
bellarde4cf1ad2005-06-04 20:15:57 +00001313 uint16_t sum;
Luiz Capitulinof18c16d2009-08-28 15:27:14 -03001314 uint32_t start = qdict_get_int(qdict, "start");
1315 uint32_t size = qdict_get_int(qdict, "size");
bellarde4cf1ad2005-06-04 20:15:57 +00001316
1317 sum = 0;
1318 for(addr = start; addr < (start + size); addr++) {
Peter Maydell42874d32015-04-26 16:49:24 +01001319 uint8_t val = address_space_ldub(&address_space_memory, addr,
1320 MEMTXATTRS_UNSPECIFIED, NULL);
bellarde4cf1ad2005-06-04 20:15:57 +00001321 /* BSD sum algorithm ('sum' Unix command) */
1322 sum = (sum >> 1) | (sum << 15);
Stefan Weil54f7b4a2011-04-10 18:23:39 +02001323 sum += val;
bellarde4cf1ad2005-06-04 20:15:57 +00001324 }
aliguori376253e2009-03-05 23:01:23 +00001325 monitor_printf(mon, "%05d\n", sum);
bellarde4cf1ad2005-06-04 20:15:57 +00001326}
1327
bellard13224a82006-07-14 22:03:35 +00001328static int mouse_button_state;
1329
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001330static void hmp_mouse_move(Monitor *mon, const QDict *qdict)
bellard13224a82006-07-14 22:03:35 +00001331{
Gerd Hoffmannc751a742013-12-04 15:02:28 +01001332 int dx, dy, dz, button;
Luiz Capitulino1d4daa92009-08-28 15:27:15 -03001333 const char *dx_str = qdict_get_str(qdict, "dx_str");
1334 const char *dy_str = qdict_get_str(qdict, "dy_str");
1335 const char *dz_str = qdict_get_try_str(qdict, "dz_str");
Gerd Hoffmannc751a742013-12-04 15:02:28 +01001336
bellard13224a82006-07-14 22:03:35 +00001337 dx = strtol(dx_str, NULL, 0);
1338 dy = strtol(dy_str, NULL, 0);
Gerd Hoffmannc751a742013-12-04 15:02:28 +01001339 qemu_input_queue_rel(NULL, INPUT_AXIS_X, dx);
1340 qemu_input_queue_rel(NULL, INPUT_AXIS_Y, dy);
1341
1342 if (dz_str) {
bellard13224a82006-07-14 22:03:35 +00001343 dz = strtol(dz_str, NULL, 0);
Gerd Hoffmannc751a742013-12-04 15:02:28 +01001344 if (dz != 0) {
1345 button = (dz > 0) ? INPUT_BUTTON_WHEEL_UP : INPUT_BUTTON_WHEEL_DOWN;
1346 qemu_input_queue_btn(NULL, button, true);
1347 qemu_input_event_sync();
1348 qemu_input_queue_btn(NULL, button, false);
1349 }
1350 }
1351 qemu_input_event_sync();
bellard13224a82006-07-14 22:03:35 +00001352}
1353
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001354static void hmp_mouse_button(Monitor *mon, const QDict *qdict)
bellard13224a82006-07-14 22:03:35 +00001355{
Gerd Hoffmannc751a742013-12-04 15:02:28 +01001356 static uint32_t bmap[INPUT_BUTTON_MAX] = {
1357 [INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON,
1358 [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON,
1359 [INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON,
1360 };
Luiz Capitulinod54908a2009-08-28 15:27:13 -03001361 int button_state = qdict_get_int(qdict, "button_state");
Gerd Hoffmannc751a742013-12-04 15:02:28 +01001362
1363 if (mouse_button_state == button_state) {
1364 return;
1365 }
1366 qemu_input_update_buttons(NULL, bmap, mouse_button_state, button_state);
1367 qemu_input_event_sync();
bellard13224a82006-07-14 22:03:35 +00001368 mouse_button_state = button_state;
bellard13224a82006-07-14 22:03:35 +00001369}
1370
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001371static void hmp_ioport_read(Monitor *mon, const QDict *qdict)
bellard34405572004-06-08 00:55:58 +00001372{
Luiz Capitulinoaa93e392009-08-28 15:27:18 -03001373 int size = qdict_get_int(qdict, "size");
1374 int addr = qdict_get_int(qdict, "addr");
1375 int has_index = qdict_haskey(qdict, "index");
bellard34405572004-06-08 00:55:58 +00001376 uint32_t val;
1377 int suffix;
1378
1379 if (has_index) {
Luiz Capitulinoaa93e392009-08-28 15:27:18 -03001380 int index = qdict_get_int(qdict, "index");
Blue Swirlafcea8c2009-09-20 16:05:47 +00001381 cpu_outb(addr & IOPORTS_MASK, index & 0xff);
bellard34405572004-06-08 00:55:58 +00001382 addr++;
1383 }
1384 addr &= 0xffff;
1385
1386 switch(size) {
1387 default:
1388 case 1:
Blue Swirlafcea8c2009-09-20 16:05:47 +00001389 val = cpu_inb(addr);
bellard34405572004-06-08 00:55:58 +00001390 suffix = 'b';
1391 break;
1392 case 2:
Blue Swirlafcea8c2009-09-20 16:05:47 +00001393 val = cpu_inw(addr);
bellard34405572004-06-08 00:55:58 +00001394 suffix = 'w';
1395 break;
1396 case 4:
Blue Swirlafcea8c2009-09-20 16:05:47 +00001397 val = cpu_inl(addr);
bellard34405572004-06-08 00:55:58 +00001398 suffix = 'l';
1399 break;
1400 }
aliguori376253e2009-03-05 23:01:23 +00001401 monitor_printf(mon, "port%c[0x%04x] = %#0*x\n",
1402 suffix, addr, size * 2, val);
bellard34405572004-06-08 00:55:58 +00001403}
bellarda3a91a32004-06-04 11:06:21 +00001404
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001405static void hmp_ioport_write(Monitor *mon, const QDict *qdict)
Jan Kiszkaf1147842009-07-14 10:20:11 +02001406{
Luiz Capitulino1bd14422009-08-28 15:27:17 -03001407 int size = qdict_get_int(qdict, "size");
1408 int addr = qdict_get_int(qdict, "addr");
1409 int val = qdict_get_int(qdict, "val");
1410
Jan Kiszkaf1147842009-07-14 10:20:11 +02001411 addr &= IOPORTS_MASK;
1412
1413 switch (size) {
1414 default:
1415 case 1:
Blue Swirlafcea8c2009-09-20 16:05:47 +00001416 cpu_outb(addr, val);
Jan Kiszkaf1147842009-07-14 10:20:11 +02001417 break;
1418 case 2:
Blue Swirlafcea8c2009-09-20 16:05:47 +00001419 cpu_outw(addr, val);
Jan Kiszkaf1147842009-07-14 10:20:11 +02001420 break;
1421 case 4:
Blue Swirlafcea8c2009-09-20 16:05:47 +00001422 cpu_outl(addr, val);
Jan Kiszkaf1147842009-07-14 10:20:11 +02001423 break;
1424 }
1425}
1426
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001427static void hmp_boot_set(Monitor *mon, const QDict *qdict)
aurel320ecdffb2008-05-04 20:11:34 +00001428{
Gongleif1839932014-12-03 18:20:58 +00001429 Error *local_err = NULL;
Luiz Capitulinod54908a2009-08-28 15:27:13 -03001430 const char *bootdevice = qdict_get_str(qdict, "bootdevice");
aurel320ecdffb2008-05-04 20:11:34 +00001431
Gongleif1839932014-12-03 18:20:58 +00001432 qemu_boot_set(bootdevice, &local_err);
1433 if (local_err) {
1434 monitor_printf(mon, "%s\n", error_get_pretty(local_err));
1435 error_free(local_err);
aurel320ecdffb2008-05-04 20:11:34 +00001436 } else {
Gongleif1839932014-12-03 18:20:58 +00001437 monitor_printf(mon, "boot device list now set to %s\n", bootdevice);
aurel320ecdffb2008-05-04 20:11:34 +00001438 }
1439}
1440
bellardb86bda52004-09-18 19:32:46 +00001441#if defined(TARGET_I386)
Avi Kivitya8170e52012-10-23 12:30:10 +02001442static void print_pte(Monitor *mon, hwaddr addr,
1443 hwaddr pte,
1444 hwaddr mask)
bellardb86bda52004-09-18 19:32:46 +00001445{
Blue Swirld65aaf32010-12-11 18:56:24 +00001446#ifdef TARGET_X86_64
1447 if (addr & (1ULL << 47)) {
1448 addr |= -1LL << 48;
1449 }
1450#endif
1451 monitor_printf(mon, TARGET_FMT_plx ": " TARGET_FMT_plx
1452 " %c%c%c%c%c%c%c%c%c\n",
aliguori376253e2009-03-05 23:01:23 +00001453 addr,
1454 pte & mask,
Blue Swirld65aaf32010-12-11 18:56:24 +00001455 pte & PG_NX_MASK ? 'X' : '-',
aliguori376253e2009-03-05 23:01:23 +00001456 pte & PG_GLOBAL_MASK ? 'G' : '-',
1457 pte & PG_PSE_MASK ? 'P' : '-',
1458 pte & PG_DIRTY_MASK ? 'D' : '-',
1459 pte & PG_ACCESSED_MASK ? 'A' : '-',
1460 pte & PG_PCD_MASK ? 'C' : '-',
1461 pte & PG_PWT_MASK ? 'T' : '-',
1462 pte & PG_USER_MASK ? 'U' : '-',
1463 pte & PG_RW_MASK ? 'W' : '-');
bellardb86bda52004-09-18 19:32:46 +00001464}
1465
Andreas Färber9349b4f2012-03-14 01:38:32 +01001466static void tlb_info_32(Monitor *mon, CPUArchState *env)
bellardb86bda52004-09-18 19:32:46 +00001467{
Austin Clements94ac5cd2011-08-21 14:49:45 -04001468 unsigned int l1, l2;
bellardb86bda52004-09-18 19:32:46 +00001469 uint32_t pgd, pde, pte;
1470
bellardb86bda52004-09-18 19:32:46 +00001471 pgd = env->cr[3] & ~0xfff;
1472 for(l1 = 0; l1 < 1024; l1++) {
Stefan Weilb8b79322011-03-26 21:11:05 +01001473 cpu_physical_memory_read(pgd + l1 * 4, &pde, 4);
bellardb86bda52004-09-18 19:32:46 +00001474 pde = le32_to_cpu(pde);
1475 if (pde & PG_PRESENT_MASK) {
1476 if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
Blue Swirld65aaf32010-12-11 18:56:24 +00001477 /* 4M pages */
1478 print_pte(mon, (l1 << 22), pde, ~((1 << 21) - 1));
bellardb86bda52004-09-18 19:32:46 +00001479 } else {
1480 for(l2 = 0; l2 < 1024; l2++) {
Stefan Weilb8b79322011-03-26 21:11:05 +01001481 cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, &pte, 4);
bellardb86bda52004-09-18 19:32:46 +00001482 pte = le32_to_cpu(pte);
1483 if (pte & PG_PRESENT_MASK) {
aliguori376253e2009-03-05 23:01:23 +00001484 print_pte(mon, (l1 << 22) + (l2 << 12),
ths5fafdf22007-09-16 21:08:06 +00001485 pte & ~PG_PSE_MASK,
bellardb86bda52004-09-18 19:32:46 +00001486 ~0xfff);
1487 }
1488 }
1489 }
1490 }
1491 }
1492}
1493
Andreas Färber9349b4f2012-03-14 01:38:32 +01001494static void tlb_info_pae32(Monitor *mon, CPUArchState *env)
Blue Swirld65aaf32010-12-11 18:56:24 +00001495{
Austin Clements94ac5cd2011-08-21 14:49:45 -04001496 unsigned int l1, l2, l3;
Blue Swirld65aaf32010-12-11 18:56:24 +00001497 uint64_t pdpe, pde, pte;
1498 uint64_t pdp_addr, pd_addr, pt_addr;
1499
1500 pdp_addr = env->cr[3] & ~0x1f;
1501 for (l1 = 0; l1 < 4; l1++) {
Stefan Weilb8b79322011-03-26 21:11:05 +01001502 cpu_physical_memory_read(pdp_addr + l1 * 8, &pdpe, 8);
Blue Swirld65aaf32010-12-11 18:56:24 +00001503 pdpe = le64_to_cpu(pdpe);
1504 if (pdpe & PG_PRESENT_MASK) {
1505 pd_addr = pdpe & 0x3fffffffff000ULL;
1506 for (l2 = 0; l2 < 512; l2++) {
Stefan Weilb8b79322011-03-26 21:11:05 +01001507 cpu_physical_memory_read(pd_addr + l2 * 8, &pde, 8);
Blue Swirld65aaf32010-12-11 18:56:24 +00001508 pde = le64_to_cpu(pde);
1509 if (pde & PG_PRESENT_MASK) {
1510 if (pde & PG_PSE_MASK) {
1511 /* 2M pages with PAE, CR4.PSE is ignored */
1512 print_pte(mon, (l1 << 30 ) + (l2 << 21), pde,
Avi Kivitya8170e52012-10-23 12:30:10 +02001513 ~((hwaddr)(1 << 20) - 1));
Blue Swirld65aaf32010-12-11 18:56:24 +00001514 } else {
1515 pt_addr = pde & 0x3fffffffff000ULL;
1516 for (l3 = 0; l3 < 512; l3++) {
Stefan Weilb8b79322011-03-26 21:11:05 +01001517 cpu_physical_memory_read(pt_addr + l3 * 8, &pte, 8);
Blue Swirld65aaf32010-12-11 18:56:24 +00001518 pte = le64_to_cpu(pte);
1519 if (pte & PG_PRESENT_MASK) {
1520 print_pte(mon, (l1 << 30 ) + (l2 << 21)
1521 + (l3 << 12),
1522 pte & ~PG_PSE_MASK,
Avi Kivitya8170e52012-10-23 12:30:10 +02001523 ~(hwaddr)0xfff);
Blue Swirld65aaf32010-12-11 18:56:24 +00001524 }
1525 }
1526 }
1527 }
1528 }
1529 }
1530 }
1531}
1532
1533#ifdef TARGET_X86_64
Andreas Färber9349b4f2012-03-14 01:38:32 +01001534static void tlb_info_64(Monitor *mon, CPUArchState *env)
Blue Swirld65aaf32010-12-11 18:56:24 +00001535{
1536 uint64_t l1, l2, l3, l4;
1537 uint64_t pml4e, pdpe, pde, pte;
1538 uint64_t pml4_addr, pdp_addr, pd_addr, pt_addr;
1539
1540 pml4_addr = env->cr[3] & 0x3fffffffff000ULL;
1541 for (l1 = 0; l1 < 512; l1++) {
Stefan Weilb8b79322011-03-26 21:11:05 +01001542 cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8);
Blue Swirld65aaf32010-12-11 18:56:24 +00001543 pml4e = le64_to_cpu(pml4e);
1544 if (pml4e & PG_PRESENT_MASK) {
1545 pdp_addr = pml4e & 0x3fffffffff000ULL;
1546 for (l2 = 0; l2 < 512; l2++) {
Stefan Weilb8b79322011-03-26 21:11:05 +01001547 cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8);
Blue Swirld65aaf32010-12-11 18:56:24 +00001548 pdpe = le64_to_cpu(pdpe);
1549 if (pdpe & PG_PRESENT_MASK) {
1550 if (pdpe & PG_PSE_MASK) {
1551 /* 1G pages, CR4.PSE is ignored */
1552 print_pte(mon, (l1 << 39) + (l2 << 30), pdpe,
1553 0x3ffffc0000000ULL);
1554 } else {
1555 pd_addr = pdpe & 0x3fffffffff000ULL;
1556 for (l3 = 0; l3 < 512; l3++) {
Stefan Weilb8b79322011-03-26 21:11:05 +01001557 cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8);
Blue Swirld65aaf32010-12-11 18:56:24 +00001558 pde = le64_to_cpu(pde);
1559 if (pde & PG_PRESENT_MASK) {
1560 if (pde & PG_PSE_MASK) {
1561 /* 2M pages, CR4.PSE is ignored */
1562 print_pte(mon, (l1 << 39) + (l2 << 30) +
1563 (l3 << 21), pde,
1564 0x3ffffffe00000ULL);
1565 } else {
1566 pt_addr = pde & 0x3fffffffff000ULL;
1567 for (l4 = 0; l4 < 512; l4++) {
1568 cpu_physical_memory_read(pt_addr
1569 + l4 * 8,
Stefan Weilb8b79322011-03-26 21:11:05 +01001570 &pte, 8);
Blue Swirld65aaf32010-12-11 18:56:24 +00001571 pte = le64_to_cpu(pte);
1572 if (pte & PG_PRESENT_MASK) {
1573 print_pte(mon, (l1 << 39) +
1574 (l2 << 30) +
1575 (l3 << 21) + (l4 << 12),
1576 pte & ~PG_PSE_MASK,
1577 0x3fffffffff000ULL);
1578 }
1579 }
1580 }
1581 }
1582 }
1583 }
1584 }
1585 }
1586 }
1587 }
1588}
1589#endif
1590
Markus Armbruster1ce6be22015-02-06 14:18:24 +01001591static void hmp_info_tlb(Monitor *mon, const QDict *qdict)
Blue Swirld65aaf32010-12-11 18:56:24 +00001592{
Andreas Färber9349b4f2012-03-14 01:38:32 +01001593 CPUArchState *env;
Blue Swirld65aaf32010-12-11 18:56:24 +00001594
1595 env = mon_get_cpu();
1596
1597 if (!(env->cr[0] & CR0_PG_MASK)) {
1598 monitor_printf(mon, "PG disabled\n");
1599 return;
1600 }
1601 if (env->cr[4] & CR4_PAE_MASK) {
1602#ifdef TARGET_X86_64
1603 if (env->hflags & HF_LMA_MASK) {
1604 tlb_info_64(mon, env);
1605 } else
1606#endif
1607 {
1608 tlb_info_pae32(mon, env);
1609 }
1610 } else {
1611 tlb_info_32(mon, env);
1612 }
1613}
1614
Avi Kivitya8170e52012-10-23 12:30:10 +02001615static void mem_print(Monitor *mon, hwaddr *pstart,
Blue Swirl1b3cba62010-12-11 18:56:27 +00001616 int *plast_prot,
Avi Kivitya8170e52012-10-23 12:30:10 +02001617 hwaddr end, int prot)
bellardb86bda52004-09-18 19:32:46 +00001618{
bellard9746b152004-11-11 18:30:24 +00001619 int prot1;
1620 prot1 = *plast_prot;
1621 if (prot != prot1) {
bellardb86bda52004-09-18 19:32:46 +00001622 if (*pstart != -1) {
Blue Swirl1b3cba62010-12-11 18:56:27 +00001623 monitor_printf(mon, TARGET_FMT_plx "-" TARGET_FMT_plx " "
1624 TARGET_FMT_plx " %c%c%c\n",
aliguori376253e2009-03-05 23:01:23 +00001625 *pstart, end, end - *pstart,
1626 prot1 & PG_USER_MASK ? 'u' : '-',
1627 'r',
1628 prot1 & PG_RW_MASK ? 'w' : '-');
bellardb86bda52004-09-18 19:32:46 +00001629 }
1630 if (prot != 0)
1631 *pstart = end;
1632 else
1633 *pstart = -1;
1634 *plast_prot = prot;
1635 }
1636}
1637
Andreas Färber9349b4f2012-03-14 01:38:32 +01001638static void mem_info_32(Monitor *mon, CPUArchState *env)
bellardb86bda52004-09-18 19:32:46 +00001639{
Austin Clementsb49ca722011-08-14 23:19:21 -04001640 unsigned int l1, l2;
1641 int prot, last_prot;
Blue Swirl1b3cba62010-12-11 18:56:27 +00001642 uint32_t pgd, pde, pte;
Avi Kivitya8170e52012-10-23 12:30:10 +02001643 hwaddr start, end;
bellardb86bda52004-09-18 19:32:46 +00001644
bellardb86bda52004-09-18 19:32:46 +00001645 pgd = env->cr[3] & ~0xfff;
1646 last_prot = 0;
1647 start = -1;
1648 for(l1 = 0; l1 < 1024; l1++) {
Stefan Weilb8b79322011-03-26 21:11:05 +01001649 cpu_physical_memory_read(pgd + l1 * 4, &pde, 4);
bellardb86bda52004-09-18 19:32:46 +00001650 pde = le32_to_cpu(pde);
1651 end = l1 << 22;
1652 if (pde & PG_PRESENT_MASK) {
1653 if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
1654 prot = pde & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK);
aliguori376253e2009-03-05 23:01:23 +00001655 mem_print(mon, &start, &last_prot, end, prot);
bellardb86bda52004-09-18 19:32:46 +00001656 } else {
1657 for(l2 = 0; l2 < 1024; l2++) {
Stefan Weilb8b79322011-03-26 21:11:05 +01001658 cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, &pte, 4);
bellardb86bda52004-09-18 19:32:46 +00001659 pte = le32_to_cpu(pte);
1660 end = (l1 << 22) + (l2 << 12);
1661 if (pte & PG_PRESENT_MASK) {
Austin Clementsc76c8412011-08-14 23:22:28 -04001662 prot = pte & pde &
1663 (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK);
bellardb86bda52004-09-18 19:32:46 +00001664 } else {
1665 prot = 0;
1666 }
aliguori376253e2009-03-05 23:01:23 +00001667 mem_print(mon, &start, &last_prot, end, prot);
bellardb86bda52004-09-18 19:32:46 +00001668 }
1669 }
1670 } else {
1671 prot = 0;
aliguori376253e2009-03-05 23:01:23 +00001672 mem_print(mon, &start, &last_prot, end, prot);
bellardb86bda52004-09-18 19:32:46 +00001673 }
1674 }
Austin Clements8a94b8ca2011-08-14 23:22:04 -04001675 /* Flush last range */
Avi Kivitya8170e52012-10-23 12:30:10 +02001676 mem_print(mon, &start, &last_prot, (hwaddr)1 << 32, 0);
bellardb86bda52004-09-18 19:32:46 +00001677}
Blue Swirl1b3cba62010-12-11 18:56:27 +00001678
Andreas Färber9349b4f2012-03-14 01:38:32 +01001679static void mem_info_pae32(Monitor *mon, CPUArchState *env)
Blue Swirl1b3cba62010-12-11 18:56:27 +00001680{
Austin Clementsb49ca722011-08-14 23:19:21 -04001681 unsigned int l1, l2, l3;
1682 int prot, last_prot;
Blue Swirl1b3cba62010-12-11 18:56:27 +00001683 uint64_t pdpe, pde, pte;
1684 uint64_t pdp_addr, pd_addr, pt_addr;
Avi Kivitya8170e52012-10-23 12:30:10 +02001685 hwaddr start, end;
Blue Swirl1b3cba62010-12-11 18:56:27 +00001686
1687 pdp_addr = env->cr[3] & ~0x1f;
1688 last_prot = 0;
1689 start = -1;
1690 for (l1 = 0; l1 < 4; l1++) {
Stefan Weilb8b79322011-03-26 21:11:05 +01001691 cpu_physical_memory_read(pdp_addr + l1 * 8, &pdpe, 8);
Blue Swirl1b3cba62010-12-11 18:56:27 +00001692 pdpe = le64_to_cpu(pdpe);
1693 end = l1 << 30;
1694 if (pdpe & PG_PRESENT_MASK) {
1695 pd_addr = pdpe & 0x3fffffffff000ULL;
1696 for (l2 = 0; l2 < 512; l2++) {
Stefan Weilb8b79322011-03-26 21:11:05 +01001697 cpu_physical_memory_read(pd_addr + l2 * 8, &pde, 8);
Blue Swirl1b3cba62010-12-11 18:56:27 +00001698 pde = le64_to_cpu(pde);
1699 end = (l1 << 30) + (l2 << 21);
1700 if (pde & PG_PRESENT_MASK) {
1701 if (pde & PG_PSE_MASK) {
1702 prot = pde & (PG_USER_MASK | PG_RW_MASK |
1703 PG_PRESENT_MASK);
1704 mem_print(mon, &start, &last_prot, end, prot);
1705 } else {
1706 pt_addr = pde & 0x3fffffffff000ULL;
1707 for (l3 = 0; l3 < 512; l3++) {
Stefan Weilb8b79322011-03-26 21:11:05 +01001708 cpu_physical_memory_read(pt_addr + l3 * 8, &pte, 8);
Blue Swirl1b3cba62010-12-11 18:56:27 +00001709 pte = le64_to_cpu(pte);
1710 end = (l1 << 30) + (l2 << 21) + (l3 << 12);
1711 if (pte & PG_PRESENT_MASK) {
Austin Clementsc76c8412011-08-14 23:22:28 -04001712 prot = pte & pde & (PG_USER_MASK | PG_RW_MASK |
1713 PG_PRESENT_MASK);
Blue Swirl1b3cba62010-12-11 18:56:27 +00001714 } else {
1715 prot = 0;
1716 }
1717 mem_print(mon, &start, &last_prot, end, prot);
1718 }
1719 }
1720 } else {
1721 prot = 0;
1722 mem_print(mon, &start, &last_prot, end, prot);
1723 }
1724 }
1725 } else {
1726 prot = 0;
1727 mem_print(mon, &start, &last_prot, end, prot);
1728 }
1729 }
Austin Clements8a94b8ca2011-08-14 23:22:04 -04001730 /* Flush last range */
Avi Kivitya8170e52012-10-23 12:30:10 +02001731 mem_print(mon, &start, &last_prot, (hwaddr)1 << 32, 0);
Blue Swirl1b3cba62010-12-11 18:56:27 +00001732}
1733
1734
1735#ifdef TARGET_X86_64
Andreas Färber9349b4f2012-03-14 01:38:32 +01001736static void mem_info_64(Monitor *mon, CPUArchState *env)
Blue Swirl1b3cba62010-12-11 18:56:27 +00001737{
1738 int prot, last_prot;
1739 uint64_t l1, l2, l3, l4;
1740 uint64_t pml4e, pdpe, pde, pte;
1741 uint64_t pml4_addr, pdp_addr, pd_addr, pt_addr, start, end;
1742
1743 pml4_addr = env->cr[3] & 0x3fffffffff000ULL;
1744 last_prot = 0;
1745 start = -1;
1746 for (l1 = 0; l1 < 512; l1++) {
Stefan Weilb8b79322011-03-26 21:11:05 +01001747 cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8);
Blue Swirl1b3cba62010-12-11 18:56:27 +00001748 pml4e = le64_to_cpu(pml4e);
1749 end = l1 << 39;
1750 if (pml4e & PG_PRESENT_MASK) {
1751 pdp_addr = pml4e & 0x3fffffffff000ULL;
1752 for (l2 = 0; l2 < 512; l2++) {
Stefan Weilb8b79322011-03-26 21:11:05 +01001753 cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8);
Blue Swirl1b3cba62010-12-11 18:56:27 +00001754 pdpe = le64_to_cpu(pdpe);
1755 end = (l1 << 39) + (l2 << 30);
1756 if (pdpe & PG_PRESENT_MASK) {
1757 if (pdpe & PG_PSE_MASK) {
Blue Swirl2d5b5072011-01-15 08:31:00 +00001758 prot = pdpe & (PG_USER_MASK | PG_RW_MASK |
1759 PG_PRESENT_MASK);
Austin Clementsc76c8412011-08-14 23:22:28 -04001760 prot &= pml4e;
Blue Swirl1b3cba62010-12-11 18:56:27 +00001761 mem_print(mon, &start, &last_prot, end, prot);
1762 } else {
1763 pd_addr = pdpe & 0x3fffffffff000ULL;
1764 for (l3 = 0; l3 < 512; l3++) {
Stefan Weilb8b79322011-03-26 21:11:05 +01001765 cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8);
Blue Swirl1b3cba62010-12-11 18:56:27 +00001766 pde = le64_to_cpu(pde);
1767 end = (l1 << 39) + (l2 << 30) + (l3 << 21);
1768 if (pde & PG_PRESENT_MASK) {
1769 if (pde & PG_PSE_MASK) {
1770 prot = pde & (PG_USER_MASK | PG_RW_MASK |
1771 PG_PRESENT_MASK);
Austin Clementsc76c8412011-08-14 23:22:28 -04001772 prot &= pml4e & pdpe;
Blue Swirl1b3cba62010-12-11 18:56:27 +00001773 mem_print(mon, &start, &last_prot, end, prot);
1774 } else {
1775 pt_addr = pde & 0x3fffffffff000ULL;
1776 for (l4 = 0; l4 < 512; l4++) {
1777 cpu_physical_memory_read(pt_addr
1778 + l4 * 8,
Stefan Weilb8b79322011-03-26 21:11:05 +01001779 &pte, 8);
Blue Swirl1b3cba62010-12-11 18:56:27 +00001780 pte = le64_to_cpu(pte);
1781 end = (l1 << 39) + (l2 << 30) +
1782 (l3 << 21) + (l4 << 12);
1783 if (pte & PG_PRESENT_MASK) {
1784 prot = pte & (PG_USER_MASK | PG_RW_MASK |
1785 PG_PRESENT_MASK);
Austin Clementsc76c8412011-08-14 23:22:28 -04001786 prot &= pml4e & pdpe & pde;
Blue Swirl1b3cba62010-12-11 18:56:27 +00001787 } else {
1788 prot = 0;
1789 }
1790 mem_print(mon, &start, &last_prot, end, prot);
1791 }
1792 }
1793 } else {
1794 prot = 0;
1795 mem_print(mon, &start, &last_prot, end, prot);
1796 }
1797 }
1798 }
1799 } else {
1800 prot = 0;
1801 mem_print(mon, &start, &last_prot, end, prot);
1802 }
1803 }
1804 } else {
1805 prot = 0;
1806 mem_print(mon, &start, &last_prot, end, prot);
1807 }
1808 }
Austin Clements8a94b8ca2011-08-14 23:22:04 -04001809 /* Flush last range */
Avi Kivitya8170e52012-10-23 12:30:10 +02001810 mem_print(mon, &start, &last_prot, (hwaddr)1 << 48, 0);
Blue Swirl1b3cba62010-12-11 18:56:27 +00001811}
1812#endif
1813
Markus Armbruster1ce6be22015-02-06 14:18:24 +01001814static void hmp_info_mem(Monitor *mon, const QDict *qdict)
Blue Swirl1b3cba62010-12-11 18:56:27 +00001815{
Andreas Färber9349b4f2012-03-14 01:38:32 +01001816 CPUArchState *env;
Blue Swirl1b3cba62010-12-11 18:56:27 +00001817
1818 env = mon_get_cpu();
1819
1820 if (!(env->cr[0] & CR0_PG_MASK)) {
1821 monitor_printf(mon, "PG disabled\n");
1822 return;
1823 }
1824 if (env->cr[4] & CR4_PAE_MASK) {
1825#ifdef TARGET_X86_64
1826 if (env->hflags & HF_LMA_MASK) {
1827 mem_info_64(mon, env);
1828 } else
1829#endif
1830 {
1831 mem_info_pae32(mon, env);
1832 }
1833 } else {
1834 mem_info_32(mon, env);
1835 }
1836}
bellardb86bda52004-09-18 19:32:46 +00001837#endif
1838
aurel327c664e22009-03-03 06:12:22 +00001839#if defined(TARGET_SH4)
1840
aliguori376253e2009-03-05 23:01:23 +00001841static void print_tlb(Monitor *mon, int idx, tlb_t *tlb)
aurel327c664e22009-03-03 06:12:22 +00001842{
aliguori376253e2009-03-05 23:01:23 +00001843 monitor_printf(mon, " tlb%i:\t"
1844 "asid=%hhu vpn=%x\tppn=%x\tsz=%hhu size=%u\t"
1845 "v=%hhu shared=%hhu cached=%hhu prot=%hhu "
1846 "dirty=%hhu writethrough=%hhu\n",
1847 idx,
1848 tlb->asid, tlb->vpn, tlb->ppn, tlb->sz, tlb->size,
1849 tlb->v, tlb->sh, tlb->c, tlb->pr,
1850 tlb->d, tlb->wt);
aurel327c664e22009-03-03 06:12:22 +00001851}
1852
Markus Armbruster1ce6be22015-02-06 14:18:24 +01001853static void hmp_info_tlb(Monitor *mon, const QDict *qdict)
aurel327c664e22009-03-03 06:12:22 +00001854{
Andreas Färber9349b4f2012-03-14 01:38:32 +01001855 CPUArchState *env = mon_get_cpu();
aurel327c664e22009-03-03 06:12:22 +00001856 int i;
1857
aliguori376253e2009-03-05 23:01:23 +00001858 monitor_printf (mon, "ITLB:\n");
aurel327c664e22009-03-03 06:12:22 +00001859 for (i = 0 ; i < ITLB_SIZE ; i++)
aliguori376253e2009-03-05 23:01:23 +00001860 print_tlb (mon, i, &env->itlb[i]);
1861 monitor_printf (mon, "UTLB:\n");
aurel327c664e22009-03-03 06:12:22 +00001862 for (i = 0 ; i < UTLB_SIZE ; i++)
aliguori376253e2009-03-05 23:01:23 +00001863 print_tlb (mon, i, &env->utlb[i]);
aurel327c664e22009-03-03 06:12:22 +00001864}
1865
1866#endif
1867
Max Filippov692f7372012-01-07 20:02:40 +04001868#if defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_XTENSA)
Markus Armbruster1ce6be22015-02-06 14:18:24 +01001869static void hmp_info_tlb(Monitor *mon, const QDict *qdict)
Blue Swirld41160a2010-12-19 13:42:56 +00001870{
Andreas Färber9349b4f2012-03-14 01:38:32 +01001871 CPUArchState *env1 = mon_get_cpu();
Blue Swirld41160a2010-12-19 13:42:56 +00001872
1873 dump_mmu((FILE*)mon, (fprintf_function)monitor_printf, env1);
1874}
1875#endif
1876
Markus Armbruster1ce6be22015-02-06 14:18:24 +01001877static void hmp_info_mtree(Monitor *mon, const QDict *qdict)
Blue Swirl314e2982011-09-11 20:22:05 +00001878{
1879 mtree_info((fprintf_function)monitor_printf, mon);
1880}
1881
Markus Armbruster1ce6be22015-02-06 14:18:24 +01001882static void hmp_info_numa(Monitor *mon, const QDict *qdict)
aliguori030ea372009-04-21 22:30:47 +00001883{
aliguorib28b6232009-04-22 20:20:29 +00001884 int i;
Andreas Färber1b1ed8d2012-12-17 04:22:03 +01001885 CPUState *cpu;
zhanghailiang5b009e42014-11-04 19:49:30 +08001886 uint64_t *node_mem;
aliguori030ea372009-04-21 22:30:47 +00001887
zhanghailiang5b009e42014-11-04 19:49:30 +08001888 node_mem = g_new0(uint64_t, nb_numa_nodes);
1889 query_numa_node_mem(node_mem);
aliguori030ea372009-04-21 22:30:47 +00001890 monitor_printf(mon, "%d nodes\n", nb_numa_nodes);
1891 for (i = 0; i < nb_numa_nodes; i++) {
1892 monitor_printf(mon, "node %d cpus:", i);
Andreas Färberbdc44642013-06-24 23:50:24 +02001893 CPU_FOREACH(cpu) {
Andreas Färber1b1ed8d2012-12-17 04:22:03 +01001894 if (cpu->numa_node == i) {
Andreas Färber55e5c282012-12-17 06:18:02 +01001895 monitor_printf(mon, " %d", cpu->cpu_index);
aliguori030ea372009-04-21 22:30:47 +00001896 }
1897 }
1898 monitor_printf(mon, "\n");
1899 monitor_printf(mon, "node %d size: %" PRId64 " MB\n", i,
zhanghailiang5b009e42014-11-04 19:49:30 +08001900 node_mem[i] >> 20);
aliguori030ea372009-04-21 22:30:47 +00001901 }
zhanghailiang5b009e42014-11-04 19:49:30 +08001902 g_free(node_mem);
aliguori030ea372009-04-21 22:30:47 +00001903}
1904
bellard5f1ce942006-02-08 22:40:15 +00001905#ifdef CONFIG_PROFILER
1906
Alexey Kardashevskiy89d5cbd2015-03-16 14:57:38 +11001907int64_t tcg_time;
Aurelien Jarnoe9a66252009-09-30 14:09:52 +02001908int64_t dev_time;
1909
Markus Armbruster1ce6be22015-02-06 14:18:24 +01001910static void hmp_info_profile(Monitor *mon, const QDict *qdict)
bellard5f1ce942006-02-08 22:40:15 +00001911{
aliguori376253e2009-03-05 23:01:23 +00001912 monitor_printf(mon, "async time %" PRId64 " (%0.3f)\n",
Juan Quintela6ee093c2009-09-10 03:04:26 +02001913 dev_time, dev_time / (double)get_ticks_per_sec());
aliguori376253e2009-03-05 23:01:23 +00001914 monitor_printf(mon, "qemu time %" PRId64 " (%0.3f)\n",
Alexey Kardashevskiy89d5cbd2015-03-16 14:57:38 +11001915 tcg_time, tcg_time / (double)get_ticks_per_sec());
1916 tcg_time = 0;
bellard5f1ce942006-02-08 22:40:15 +00001917 dev_time = 0;
bellard5f1ce942006-02-08 22:40:15 +00001918}
1919#else
Markus Armbruster1ce6be22015-02-06 14:18:24 +01001920static void hmp_info_profile(Monitor *mon, const QDict *qdict)
bellard5f1ce942006-02-08 22:40:15 +00001921{
aliguori376253e2009-03-05 23:01:23 +00001922 monitor_printf(mon, "Internal profiler not compiled\n");
bellard5f1ce942006-02-08 22:40:15 +00001923}
1924#endif
1925
bellardec36b692006-07-16 18:57:03 +00001926/* Capture support */
Blue Swirl72cf2d42009-09-12 07:36:22 +00001927static QLIST_HEAD (capture_list_head, CaptureState) capture_head;
bellardec36b692006-07-16 18:57:03 +00001928
Markus Armbruster1ce6be22015-02-06 14:18:24 +01001929static void hmp_info_capture(Monitor *mon, const QDict *qdict)
bellardec36b692006-07-16 18:57:03 +00001930{
1931 int i;
1932 CaptureState *s;
1933
1934 for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) {
aliguori376253e2009-03-05 23:01:23 +00001935 monitor_printf(mon, "[%d]: ", i);
bellardec36b692006-07-16 18:57:03 +00001936 s->ops.info (s->opaque);
1937 }
1938}
1939
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001940static void hmp_stopcapture(Monitor *mon, const QDict *qdict)
bellardec36b692006-07-16 18:57:03 +00001941{
1942 int i;
Luiz Capitulinod54908a2009-08-28 15:27:13 -03001943 int n = qdict_get_int(qdict, "n");
bellardec36b692006-07-16 18:57:03 +00001944 CaptureState *s;
1945
1946 for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) {
1947 if (i == n) {
1948 s->ops.destroy (s->opaque);
Blue Swirl72cf2d42009-09-12 07:36:22 +00001949 QLIST_REMOVE (s, entries);
Anthony Liguori7267c092011-08-20 22:09:37 -05001950 g_free (s);
bellardec36b692006-07-16 18:57:03 +00001951 return;
1952 }
1953 }
1954}
1955
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001956static void hmp_wavcapture(Monitor *mon, const QDict *qdict)
bellardec36b692006-07-16 18:57:03 +00001957{
Luiz Capitulinoc1925482009-08-28 15:27:19 -03001958 const char *path = qdict_get_str(qdict, "path");
1959 int has_freq = qdict_haskey(qdict, "freq");
1960 int freq = qdict_get_try_int(qdict, "freq", -1);
1961 int has_bits = qdict_haskey(qdict, "bits");
1962 int bits = qdict_get_try_int(qdict, "bits", -1);
1963 int has_channels = qdict_haskey(qdict, "nchannels");
1964 int nchannels = qdict_get_try_int(qdict, "nchannels", -1);
bellardec36b692006-07-16 18:57:03 +00001965 CaptureState *s;
1966
Anthony Liguori7267c092011-08-20 22:09:37 -05001967 s = g_malloc0 (sizeof (*s));
bellardec36b692006-07-16 18:57:03 +00001968
1969 freq = has_freq ? freq : 44100;
1970 bits = has_bits ? bits : 16;
1971 nchannels = has_channels ? nchannels : 2;
1972
1973 if (wav_start_capture (s, path, freq, bits, nchannels)) {
Isaku Yamahatad00b2612011-01-21 19:53:55 +09001974 monitor_printf(mon, "Failed to add wave capture\n");
Anthony Liguori7267c092011-08-20 22:09:37 -05001975 g_free (s);
Isaku Yamahatad00b2612011-01-21 19:53:55 +09001976 return;
bellardec36b692006-07-16 18:57:03 +00001977 }
Blue Swirl72cf2d42009-09-12 07:36:22 +00001978 QLIST_INSERT_HEAD (&capture_head, s, entries);
bellardec36b692006-07-16 18:57:03 +00001979}
bellardec36b692006-07-16 18:57:03 +00001980
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001981static qemu_acl *find_acl(Monitor *mon, const char *name)
aliguori76655d62009-03-06 20:27:37 +00001982{
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001983 qemu_acl *acl = qemu_acl_find(name);
aliguori76655d62009-03-06 20:27:37 +00001984
aliguori76655d62009-03-06 20:27:37 +00001985 if (!acl) {
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001986 monitor_printf(mon, "acl: unknown list '%s'\n", name);
aliguori76655d62009-03-06 20:27:37 +00001987 }
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001988 return acl;
1989}
aliguori76655d62009-03-06 20:27:37 +00001990
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01001991static void hmp_acl_show(Monitor *mon, const QDict *qdict)
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001992{
Luiz Capitulinod54908a2009-08-28 15:27:13 -03001993 const char *aclname = qdict_get_str(qdict, "aclname");
Jan Kiszka15dfcd42009-06-25 08:22:08 +02001994 qemu_acl *acl = find_acl(mon, aclname);
1995 qemu_acl_entry *entry;
1996 int i = 0;
1997
1998 if (acl) {
aliguori28a76be2009-03-06 20:27:40 +00001999 monitor_printf(mon, "policy: %s\n",
aliguori76655d62009-03-06 20:27:37 +00002000 acl->defaultDeny ? "deny" : "allow");
Blue Swirl72cf2d42009-09-12 07:36:22 +00002001 QTAILQ_FOREACH(entry, &acl->entries, next) {
aliguori28a76be2009-03-06 20:27:40 +00002002 i++;
2003 monitor_printf(mon, "%d: %s %s\n", i,
Jan Kiszka15dfcd42009-06-25 08:22:08 +02002004 entry->deny ? "deny" : "allow", entry->match);
aliguori28a76be2009-03-06 20:27:40 +00002005 }
Jan Kiszka15dfcd42009-06-25 08:22:08 +02002006 }
2007}
2008
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01002009static void hmp_acl_reset(Monitor *mon, const QDict *qdict)
Jan Kiszka15dfcd42009-06-25 08:22:08 +02002010{
Luiz Capitulinod54908a2009-08-28 15:27:13 -03002011 const char *aclname = qdict_get_str(qdict, "aclname");
Jan Kiszka15dfcd42009-06-25 08:22:08 +02002012 qemu_acl *acl = find_acl(mon, aclname);
2013
2014 if (acl) {
aliguori28a76be2009-03-06 20:27:40 +00002015 qemu_acl_reset(acl);
2016 monitor_printf(mon, "acl: removed all rules\n");
Jan Kiszka15dfcd42009-06-25 08:22:08 +02002017 }
2018}
aliguori76655d62009-03-06 20:27:37 +00002019
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01002020static void hmp_acl_policy(Monitor *mon, const QDict *qdict)
Jan Kiszka15dfcd42009-06-25 08:22:08 +02002021{
Luiz Capitulinof18c16d2009-08-28 15:27:14 -03002022 const char *aclname = qdict_get_str(qdict, "aclname");
2023 const char *policy = qdict_get_str(qdict, "policy");
Jan Kiszka15dfcd42009-06-25 08:22:08 +02002024 qemu_acl *acl = find_acl(mon, aclname);
2025
2026 if (acl) {
2027 if (strcmp(policy, "allow") == 0) {
aliguori28a76be2009-03-06 20:27:40 +00002028 acl->defaultDeny = 0;
2029 monitor_printf(mon, "acl: policy set to 'allow'\n");
Jan Kiszka15dfcd42009-06-25 08:22:08 +02002030 } else if (strcmp(policy, "deny") == 0) {
aliguori28a76be2009-03-06 20:27:40 +00002031 acl->defaultDeny = 1;
2032 monitor_printf(mon, "acl: policy set to 'deny'\n");
2033 } else {
Jan Kiszka15dfcd42009-06-25 08:22:08 +02002034 monitor_printf(mon, "acl: unknown policy '%s', "
2035 "expected 'deny' or 'allow'\n", policy);
aliguori28a76be2009-03-06 20:27:40 +00002036 }
Jan Kiszka15dfcd42009-06-25 08:22:08 +02002037 }
2038}
aliguori76655d62009-03-06 20:27:37 +00002039
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01002040static void hmp_acl_add(Monitor *mon, const QDict *qdict)
Jan Kiszka15dfcd42009-06-25 08:22:08 +02002041{
Luiz Capitulino1bd14422009-08-28 15:27:17 -03002042 const char *aclname = qdict_get_str(qdict, "aclname");
2043 const char *match = qdict_get_str(qdict, "match");
2044 const char *policy = qdict_get_str(qdict, "policy");
2045 int has_index = qdict_haskey(qdict, "index");
2046 int index = qdict_get_try_int(qdict, "index", -1);
Jan Kiszka15dfcd42009-06-25 08:22:08 +02002047 qemu_acl *acl = find_acl(mon, aclname);
2048 int deny, ret;
2049
2050 if (acl) {
2051 if (strcmp(policy, "allow") == 0) {
2052 deny = 0;
2053 } else if (strcmp(policy, "deny") == 0) {
2054 deny = 1;
2055 } else {
2056 monitor_printf(mon, "acl: unknown policy '%s', "
2057 "expected 'deny' or 'allow'\n", policy);
aliguori28a76be2009-03-06 20:27:40 +00002058 return;
2059 }
aliguori28a76be2009-03-06 20:27:40 +00002060 if (has_index)
2061 ret = qemu_acl_insert(acl, deny, match, index);
2062 else
2063 ret = qemu_acl_append(acl, deny, match);
2064 if (ret < 0)
2065 monitor_printf(mon, "acl: unable to add acl entry\n");
2066 else
2067 monitor_printf(mon, "acl: added rule at position %d\n", ret);
Jan Kiszka15dfcd42009-06-25 08:22:08 +02002068 }
2069}
aliguori76655d62009-03-06 20:27:37 +00002070
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01002071static void hmp_acl_remove(Monitor *mon, const QDict *qdict)
Jan Kiszka15dfcd42009-06-25 08:22:08 +02002072{
Luiz Capitulinof18c16d2009-08-28 15:27:14 -03002073 const char *aclname = qdict_get_str(qdict, "aclname");
2074 const char *match = qdict_get_str(qdict, "match");
Jan Kiszka15dfcd42009-06-25 08:22:08 +02002075 qemu_acl *acl = find_acl(mon, aclname);
2076 int ret;
aliguori76655d62009-03-06 20:27:37 +00002077
Jan Kiszka15dfcd42009-06-25 08:22:08 +02002078 if (acl) {
aliguori28a76be2009-03-06 20:27:40 +00002079 ret = qemu_acl_remove(acl, match);
2080 if (ret < 0)
2081 monitor_printf(mon, "acl: no matching acl entry\n");
2082 else
2083 monitor_printf(mon, "acl: removed rule at position %d\n", ret);
aliguori76655d62009-03-06 20:27:37 +00002084 }
2085}
2086
Huang Ying79c4f6b2009-06-23 10:05:14 +08002087#if defined(TARGET_I386)
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01002088static void hmp_mce(Monitor *mon, const QDict *qdict)
Huang Ying79c4f6b2009-06-23 10:05:14 +08002089{
Andreas Färber8c5cf3b2012-05-03 15:22:54 +02002090 X86CPU *cpu;
Andreas Färber55e5c282012-12-17 06:18:02 +01002091 CPUState *cs;
Luiz Capitulino37b7ad42009-08-28 15:27:21 -03002092 int cpu_index = qdict_get_int(qdict, "cpu_index");
2093 int bank = qdict_get_int(qdict, "bank");
2094 uint64_t status = qdict_get_int(qdict, "status");
2095 uint64_t mcg_status = qdict_get_int(qdict, "mcg_status");
2096 uint64_t addr = qdict_get_int(qdict, "addr");
2097 uint64_t misc = qdict_get_int(qdict, "misc");
Jan Kiszka747461c2011-03-02 08:56:10 +01002098 int flags = MCE_INJECT_UNCOND_AO;
Huang Ying79c4f6b2009-06-23 10:05:14 +08002099
Jan Kiszka747461c2011-03-02 08:56:10 +01002100 if (qdict_get_try_bool(qdict, "broadcast", 0)) {
2101 flags |= MCE_INJECT_BROADCAST;
2102 }
Andreas Färberc51a9442013-05-17 16:57:52 +02002103 cs = qemu_get_cpu(cpu_index);
2104 if (cs != NULL) {
2105 cpu = X86_CPU(cs);
2106 cpu_x86_inject_mce(mon, cpu, bank, status, mcg_status, addr, misc,
2107 flags);
Jin Dongming31ce5e02010-12-10 17:21:02 +09002108 }
Huang Ying79c4f6b2009-06-23 10:05:14 +08002109}
2110#endif
2111
Corey Bryant208c9d12012-06-22 14:36:09 -04002112void qmp_getfd(const char *fdname, Error **errp)
Mark McLoughlinf07918f2009-07-22 09:11:40 +01002113{
Anthony Liguoric227f092009-10-01 16:12:16 -05002114 mon_fd_t *monfd;
Mark McLoughlinf07918f2009-07-22 09:11:40 +01002115 int fd;
2116
Corey Bryant208c9d12012-06-22 14:36:09 -04002117 fd = qemu_chr_fe_get_msgfd(cur_mon->chr);
Mark McLoughlinf07918f2009-07-22 09:11:40 +01002118 if (fd == -1) {
Corey Bryant208c9d12012-06-22 14:36:09 -04002119 error_set(errp, QERR_FD_NOT_SUPPLIED);
2120 return;
Mark McLoughlinf07918f2009-07-22 09:11:40 +01002121 }
2122
2123 if (qemu_isdigit(fdname[0])) {
Stefan Hajnoczi0b9f0e22014-04-24 13:58:18 +02002124 close(fd);
Corey Bryant208c9d12012-06-22 14:36:09 -04002125 error_set(errp, QERR_INVALID_PARAMETER_VALUE, "fdname",
2126 "a name not starting with a digit");
2127 return;
Mark McLoughlinf07918f2009-07-22 09:11:40 +01002128 }
2129
Corey Bryant208c9d12012-06-22 14:36:09 -04002130 QLIST_FOREACH(monfd, &cur_mon->fds, next) {
Mark McLoughlinf07918f2009-07-22 09:11:40 +01002131 if (strcmp(monfd->name, fdname) != 0) {
2132 continue;
2133 }
2134
2135 close(monfd->fd);
2136 monfd->fd = fd;
Corey Bryant208c9d12012-06-22 14:36:09 -04002137 return;
Mark McLoughlinf07918f2009-07-22 09:11:40 +01002138 }
2139
Anthony Liguori7267c092011-08-20 22:09:37 -05002140 monfd = g_malloc0(sizeof(mon_fd_t));
2141 monfd->name = g_strdup(fdname);
Mark McLoughlinf07918f2009-07-22 09:11:40 +01002142 monfd->fd = fd;
2143
Corey Bryant208c9d12012-06-22 14:36:09 -04002144 QLIST_INSERT_HEAD(&cur_mon->fds, monfd, next);
Mark McLoughlinf07918f2009-07-22 09:11:40 +01002145}
2146
Corey Bryant208c9d12012-06-22 14:36:09 -04002147void qmp_closefd(const char *fdname, Error **errp)
Mark McLoughlinf07918f2009-07-22 09:11:40 +01002148{
Anthony Liguoric227f092009-10-01 16:12:16 -05002149 mon_fd_t *monfd;
Mark McLoughlinf07918f2009-07-22 09:11:40 +01002150
Corey Bryant208c9d12012-06-22 14:36:09 -04002151 QLIST_FOREACH(monfd, &cur_mon->fds, next) {
Mark McLoughlinf07918f2009-07-22 09:11:40 +01002152 if (strcmp(monfd->name, fdname) != 0) {
2153 continue;
2154 }
2155
Blue Swirl72cf2d42009-09-12 07:36:22 +00002156 QLIST_REMOVE(monfd, next);
Mark McLoughlinf07918f2009-07-22 09:11:40 +01002157 close(monfd->fd);
Anthony Liguori7267c092011-08-20 22:09:37 -05002158 g_free(monfd->name);
2159 g_free(monfd);
Corey Bryant208c9d12012-06-22 14:36:09 -04002160 return;
Mark McLoughlinf07918f2009-07-22 09:11:40 +01002161 }
2162
Corey Bryant208c9d12012-06-22 14:36:09 -04002163 error_set(errp, QERR_FD_NOT_FOUND, fdname);
Mark McLoughlinf07918f2009-07-22 09:11:40 +01002164}
2165
Markus Armbruster3e5a50d2015-02-06 13:55:43 +01002166static void hmp_loadvm(Monitor *mon, const QDict *qdict)
Juan Quintelac8d41b22009-08-20 19:42:21 +02002167{
Luiz Capitulino13548692011-07-29 15:36:43 -03002168 int saved_vm_running = runstate_is_running();
Luiz Capitulinod54908a2009-08-28 15:27:13 -03002169 const char *name = qdict_get_str(qdict, "name");
Juan Quintelac8d41b22009-08-20 19:42:21 +02002170
Luiz Capitulino0461d5a2011-09-30 14:45:27 -03002171 vm_stop(RUN_STATE_RESTORE_VM);
Juan Quintelac8d41b22009-08-20 19:42:21 +02002172
Miguel Di Ciurcio Filhof0aa7a82010-07-19 15:25:01 -03002173 if (load_vmstate(name) == 0 && saved_vm_running) {
Juan Quintelac8d41b22009-08-20 19:42:21 +02002174 vm_start();
Miguel Di Ciurcio Filhof0aa7a82010-07-19 15:25:01 -03002175 }
Juan Quintelac8d41b22009-08-20 19:42:21 +02002176}
2177
Paolo Bonzinia9940fc2012-09-20 16:50:32 +02002178int monitor_get_fd(Monitor *mon, const char *fdname, Error **errp)
Mark McLoughlin7768e042009-07-22 09:11:41 +01002179{
Anthony Liguoric227f092009-10-01 16:12:16 -05002180 mon_fd_t *monfd;
Mark McLoughlin7768e042009-07-22 09:11:41 +01002181
Blue Swirl72cf2d42009-09-12 07:36:22 +00002182 QLIST_FOREACH(monfd, &mon->fds, next) {
Mark McLoughlin7768e042009-07-22 09:11:41 +01002183 int fd;
2184
2185 if (strcmp(monfd->name, fdname) != 0) {
2186 continue;
2187 }
2188
2189 fd = monfd->fd;
2190
2191 /* caller takes ownership of fd */
Blue Swirl72cf2d42009-09-12 07:36:22 +00002192 QLIST_REMOVE(monfd, next);
Anthony Liguori7267c092011-08-20 22:09:37 -05002193 g_free(monfd->name);
2194 g_free(monfd);
Mark McLoughlin7768e042009-07-22 09:11:41 +01002195
2196 return fd;
2197 }
2198
Paolo Bonzinia9940fc2012-09-20 16:50:32 +02002199 error_setg(errp, "File descriptor named '%s' has not been found", fdname);
Mark McLoughlin7768e042009-07-22 09:11:41 +01002200 return -1;
2201}
2202
Corey Bryantba1c0482012-08-14 16:43:43 -04002203static void monitor_fdset_cleanup(MonFdset *mon_fdset)
2204{
2205 MonFdsetFd *mon_fdset_fd;
2206 MonFdsetFd *mon_fdset_fd_next;
2207
2208 QLIST_FOREACH_SAFE(mon_fdset_fd, &mon_fdset->fds, next, mon_fdset_fd_next) {
Corey Bryantebe52b52012-10-18 15:19:33 -04002209 if ((mon_fdset_fd->removed ||
2210 (QLIST_EMPTY(&mon_fdset->dup_fds) && mon_refcount == 0)) &&
2211 runstate_is_running()) {
Corey Bryantba1c0482012-08-14 16:43:43 -04002212 close(mon_fdset_fd->fd);
2213 g_free(mon_fdset_fd->opaque);
2214 QLIST_REMOVE(mon_fdset_fd, next);
2215 g_free(mon_fdset_fd);
2216 }
2217 }
2218
Corey Bryantadb696f2012-08-14 16:43:47 -04002219 if (QLIST_EMPTY(&mon_fdset->fds) && QLIST_EMPTY(&mon_fdset->dup_fds)) {
Corey Bryantba1c0482012-08-14 16:43:43 -04002220 QLIST_REMOVE(mon_fdset, next);
2221 g_free(mon_fdset);
2222 }
2223}
2224
Corey Bryantefb87c12012-08-14 16:43:48 -04002225static void monitor_fdsets_cleanup(void)
2226{
2227 MonFdset *mon_fdset;
2228 MonFdset *mon_fdset_next;
2229
2230 QLIST_FOREACH_SAFE(mon_fdset, &mon_fdsets, next, mon_fdset_next) {
2231 monitor_fdset_cleanup(mon_fdset);
2232 }
2233}
2234
Corey Bryantba1c0482012-08-14 16:43:43 -04002235AddfdInfo *qmp_add_fd(bool has_fdset_id, int64_t fdset_id, bool has_opaque,
2236 const char *opaque, Error **errp)
2237{
2238 int fd;
2239 Monitor *mon = cur_mon;
Corey Bryantba1c0482012-08-14 16:43:43 -04002240 AddfdInfo *fdinfo;
2241
2242 fd = qemu_chr_fe_get_msgfd(mon->chr);
2243 if (fd == -1) {
2244 error_set(errp, QERR_FD_NOT_SUPPLIED);
2245 goto error;
2246 }
2247
Corey Bryante446f702012-10-18 15:19:32 -04002248 fdinfo = monitor_fdset_add_fd(fd, has_fdset_id, fdset_id,
2249 has_opaque, opaque, errp);
2250 if (fdinfo) {
2251 return fdinfo;
Corey Bryant9ac54af2012-10-18 15:19:31 -04002252 }
2253
Corey Bryantba1c0482012-08-14 16:43:43 -04002254error:
2255 if (fd != -1) {
2256 close(fd);
2257 }
2258 return NULL;
2259}
2260
2261void qmp_remove_fd(int64_t fdset_id, bool has_fd, int64_t fd, Error **errp)
2262{
2263 MonFdset *mon_fdset;
2264 MonFdsetFd *mon_fdset_fd;
2265 char fd_str[60];
2266
2267 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
2268 if (mon_fdset->id != fdset_id) {
2269 continue;
2270 }
2271 QLIST_FOREACH(mon_fdset_fd, &mon_fdset->fds, next) {
2272 if (has_fd) {
2273 if (mon_fdset_fd->fd != fd) {
2274 continue;
2275 }
2276 mon_fdset_fd->removed = true;
2277 break;
2278 } else {
2279 mon_fdset_fd->removed = true;
2280 }
2281 }
2282 if (has_fd && !mon_fdset_fd) {
2283 goto error;
2284 }
2285 monitor_fdset_cleanup(mon_fdset);
2286 return;
2287 }
2288
2289error:
2290 if (has_fd) {
2291 snprintf(fd_str, sizeof(fd_str), "fdset-id:%" PRId64 ", fd:%" PRId64,
2292 fdset_id, fd);
2293 } else {
2294 snprintf(fd_str, sizeof(fd_str), "fdset-id:%" PRId64, fdset_id);
2295 }
2296 error_set(errp, QERR_FD_NOT_FOUND, fd_str);
2297}
2298
2299FdsetInfoList *qmp_query_fdsets(Error **errp)
2300{
2301 MonFdset *mon_fdset;
2302 MonFdsetFd *mon_fdset_fd;
2303 FdsetInfoList *fdset_list = NULL;
2304
2305 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
2306 FdsetInfoList *fdset_info = g_malloc0(sizeof(*fdset_info));
2307 FdsetFdInfoList *fdsetfd_list = NULL;
2308
2309 fdset_info->value = g_malloc0(sizeof(*fdset_info->value));
2310 fdset_info->value->fdset_id = mon_fdset->id;
2311
2312 QLIST_FOREACH(mon_fdset_fd, &mon_fdset->fds, next) {
2313 FdsetFdInfoList *fdsetfd_info;
2314
2315 fdsetfd_info = g_malloc0(sizeof(*fdsetfd_info));
2316 fdsetfd_info->value = g_malloc0(sizeof(*fdsetfd_info->value));
2317 fdsetfd_info->value->fd = mon_fdset_fd->fd;
2318 if (mon_fdset_fd->opaque) {
2319 fdsetfd_info->value->has_opaque = true;
2320 fdsetfd_info->value->opaque = g_strdup(mon_fdset_fd->opaque);
2321 } else {
2322 fdsetfd_info->value->has_opaque = false;
2323 }
2324
2325 fdsetfd_info->next = fdsetfd_list;
2326 fdsetfd_list = fdsetfd_info;
2327 }
2328
2329 fdset_info->value->fds = fdsetfd_list;
2330
2331 fdset_info->next = fdset_list;
2332 fdset_list = fdset_info;
2333 }
2334
2335 return fdset_list;
2336}
2337
Corey Bryante446f702012-10-18 15:19:32 -04002338AddfdInfo *monitor_fdset_add_fd(int fd, bool has_fdset_id, int64_t fdset_id,
2339 bool has_opaque, const char *opaque,
2340 Error **errp)
2341{
2342 MonFdset *mon_fdset = NULL;
2343 MonFdsetFd *mon_fdset_fd;
2344 AddfdInfo *fdinfo;
2345
2346 if (has_fdset_id) {
2347 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
2348 /* Break if match found or match impossible due to ordering by ID */
2349 if (fdset_id <= mon_fdset->id) {
2350 if (fdset_id < mon_fdset->id) {
2351 mon_fdset = NULL;
2352 }
2353 break;
2354 }
2355 }
2356 }
2357
2358 if (mon_fdset == NULL) {
2359 int64_t fdset_id_prev = -1;
2360 MonFdset *mon_fdset_cur = QLIST_FIRST(&mon_fdsets);
2361
2362 if (has_fdset_id) {
2363 if (fdset_id < 0) {
2364 error_set(errp, QERR_INVALID_PARAMETER_VALUE, "fdset-id",
2365 "a non-negative value");
2366 return NULL;
2367 }
2368 /* Use specified fdset ID */
2369 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
2370 mon_fdset_cur = mon_fdset;
2371 if (fdset_id < mon_fdset_cur->id) {
2372 break;
2373 }
2374 }
2375 } else {
2376 /* Use first available fdset ID */
2377 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
2378 mon_fdset_cur = mon_fdset;
2379 if (fdset_id_prev == mon_fdset_cur->id - 1) {
2380 fdset_id_prev = mon_fdset_cur->id;
2381 continue;
2382 }
2383 break;
2384 }
2385 }
2386
2387 mon_fdset = g_malloc0(sizeof(*mon_fdset));
2388 if (has_fdset_id) {
2389 mon_fdset->id = fdset_id;
2390 } else {
2391 mon_fdset->id = fdset_id_prev + 1;
2392 }
2393
2394 /* The fdset list is ordered by fdset ID */
2395 if (!mon_fdset_cur) {
2396 QLIST_INSERT_HEAD(&mon_fdsets, mon_fdset, next);
2397 } else if (mon_fdset->id < mon_fdset_cur->id) {
2398 QLIST_INSERT_BEFORE(mon_fdset_cur, mon_fdset, next);
2399 } else {
2400 QLIST_INSERT_AFTER(mon_fdset_cur, mon_fdset, next);
2401 }
2402 }
2403
2404 mon_fdset_fd = g_malloc0(sizeof(*mon_fdset_fd));
2405 mon_fdset_fd->fd = fd;
2406 mon_fdset_fd->removed = false;
2407 if (has_opaque) {
2408 mon_fdset_fd->opaque = g_strdup(opaque);
2409 }
2410 QLIST_INSERT_HEAD(&mon_fdset->fds, mon_fdset_fd, next);
2411
2412 fdinfo = g_malloc0(sizeof(*fdinfo));
2413 fdinfo->fdset_id = mon_fdset->id;
2414 fdinfo->fd = mon_fdset_fd->fd;
2415
2416 return fdinfo;
2417}
2418
Corey Bryantadb696f2012-08-14 16:43:47 -04002419int monitor_fdset_get_fd(int64_t fdset_id, int flags)
2420{
Blue Swirlb2dc64c2012-08-18 20:14:54 +00002421#ifndef _WIN32
Corey Bryantadb696f2012-08-14 16:43:47 -04002422 MonFdset *mon_fdset;
2423 MonFdsetFd *mon_fdset_fd;
2424 int mon_fd_flags;
2425
Corey Bryantadb696f2012-08-14 16:43:47 -04002426 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
2427 if (mon_fdset->id != fdset_id) {
2428 continue;
2429 }
2430 QLIST_FOREACH(mon_fdset_fd, &mon_fdset->fds, next) {
2431 mon_fd_flags = fcntl(mon_fdset_fd->fd, F_GETFL);
2432 if (mon_fd_flags == -1) {
2433 return -1;
2434 }
2435
2436 if ((flags & O_ACCMODE) == (mon_fd_flags & O_ACCMODE)) {
2437 return mon_fdset_fd->fd;
2438 }
2439 }
2440 errno = EACCES;
2441 return -1;
2442 }
2443#endif
2444
2445 errno = ENOENT;
2446 return -1;
2447}
2448
2449int monitor_fdset_dup_fd_add(int64_t fdset_id, int dup_fd)
2450{
2451 MonFdset *mon_fdset;
2452 MonFdsetFd *mon_fdset_fd_dup;
2453
2454 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
2455 if (mon_fdset->id != fdset_id) {
2456 continue;
2457 }
2458 QLIST_FOREACH(mon_fdset_fd_dup, &mon_fdset->dup_fds, next) {
2459 if (mon_fdset_fd_dup->fd == dup_fd) {
2460 return -1;
2461 }
2462 }
2463 mon_fdset_fd_dup = g_malloc0(sizeof(*mon_fdset_fd_dup));
2464 mon_fdset_fd_dup->fd = dup_fd;
2465 QLIST_INSERT_HEAD(&mon_fdset->dup_fds, mon_fdset_fd_dup, next);
2466 return 0;
2467 }
2468 return -1;
2469}
2470
2471static int monitor_fdset_dup_fd_find_remove(int dup_fd, bool remove)
2472{
2473 MonFdset *mon_fdset;
2474 MonFdsetFd *mon_fdset_fd_dup;
2475
2476 QLIST_FOREACH(mon_fdset, &mon_fdsets, next) {
2477 QLIST_FOREACH(mon_fdset_fd_dup, &mon_fdset->dup_fds, next) {
2478 if (mon_fdset_fd_dup->fd == dup_fd) {
2479 if (remove) {
2480 QLIST_REMOVE(mon_fdset_fd_dup, next);
2481 if (QLIST_EMPTY(&mon_fdset->dup_fds)) {
2482 monitor_fdset_cleanup(mon_fdset);
2483 }
Michael S. Tsirkinb3dd1b82014-08-17 11:45:17 +02002484 return -1;
2485 } else {
2486 return mon_fdset->id;
Corey Bryantadb696f2012-08-14 16:43:47 -04002487 }
Corey Bryantadb696f2012-08-14 16:43:47 -04002488 }
2489 }
2490 }
2491 return -1;
2492}
2493
2494int monitor_fdset_dup_fd_find(int dup_fd)
2495{
2496 return monitor_fdset_dup_fd_find_remove(dup_fd, false);
2497}
2498
Michael S. Tsirkinb3dd1b82014-08-17 11:45:17 +02002499void monitor_fdset_dup_fd_remove(int dup_fd)
Corey Bryantadb696f2012-08-14 16:43:47 -04002500{
Michael S. Tsirkinb3dd1b82014-08-17 11:45:17 +02002501 monitor_fdset_dup_fd_find_remove(dup_fd, true);
Corey Bryantadb696f2012-08-14 16:43:47 -04002502}
2503
Markus Armbruster1677f4c2015-02-09 14:03:19 +01002504int monitor_fd_param(Monitor *mon, const char *fdname, Error **errp)
Laszlo Ersek59063662014-04-10 10:24:31 +02002505{
2506 int fd;
2507 Error *local_err = NULL;
2508
2509 if (!qemu_isdigit(fdname[0]) && mon) {
Paolo Bonzinia9940fc2012-09-20 16:50:32 +02002510 fd = monitor_get_fd(mon, fdname, &local_err);
Nicholas Bellingera96ed022012-08-21 20:52:07 +00002511 } else {
2512 fd = qemu_parse_fd(fdname);
Laszlo Ersek59063662014-04-10 10:24:31 +02002513 if (fd == -1) {
2514 error_setg(&local_err, "Invalid file descriptor number '%s'",
2515 fdname);
2516 }
2517 }
2518 if (local_err) {
2519 error_propagate(errp, local_err);
2520 assert(fd == -1);
2521 } else {
2522 assert(fd != -1);
Nicholas Bellingera96ed022012-08-21 20:52:07 +00002523 }
2524
2525 return fd;
2526}
2527
Luiz Capitulinoacd0a092010-09-30 16:00:22 -03002528/* Please update hmp-commands.hx when adding or changing commands */
Wayne Xia816f8922011-10-12 11:32:41 +08002529static mon_cmd_t info_cmds[] = {
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002530 {
2531 .name = "version",
2532 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002533 .params = "",
2534 .help = "show the version of QEMU",
Wenchao Xia5f11cb02013-01-14 14:06:26 +08002535 .mhandler.cmd = hmp_info_version,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002536 },
2537 {
2538 .name = "network",
2539 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002540 .params = "",
2541 .help = "show the network state",
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002542 .mhandler.cmd = hmp_info_network,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002543 },
2544 {
2545 .name = "chardev",
2546 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002547 .params = "",
2548 .help = "show the character devices",
Wenchao Xia5f11cb02013-01-14 14:06:26 +08002549 .mhandler.cmd = hmp_info_chardev,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002550 },
2551 {
2552 .name = "block",
Kevin Wolfe6bb31e2014-09-15 12:19:14 +02002553 .args_type = "nodes:-n,verbose:-v,device:B?",
2554 .params = "[-n] [-v] [device]",
Wenchao Xiae73fe2b2013-06-06 12:28:01 +08002555 .help = "show info of one block device or all block devices "
Kevin Wolfe6bb31e2014-09-15 12:19:14 +02002556 "(-n: show named nodes; -v: show details)",
Wenchao Xia5f11cb02013-01-14 14:06:26 +08002557 .mhandler.cmd = hmp_info_block,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002558 },
2559 {
2560 .name = "blockstats",
2561 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002562 .params = "",
2563 .help = "show block device statistics",
Wenchao Xia5f11cb02013-01-14 14:06:26 +08002564 .mhandler.cmd = hmp_info_blockstats,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002565 },
2566 {
Stefan Hajnoczifb5458c2012-01-18 14:40:49 +00002567 .name = "block-jobs",
2568 .args_type = "",
2569 .params = "",
2570 .help = "show progress of ongoing block device operations",
Wenchao Xia5f11cb02013-01-14 14:06:26 +08002571 .mhandler.cmd = hmp_info_block_jobs,
Stefan Hajnoczifb5458c2012-01-18 14:40:49 +00002572 },
2573 {
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002574 .name = "registers",
2575 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002576 .params = "",
2577 .help = "show the cpu registers",
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002578 .mhandler.cmd = hmp_info_registers,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002579 },
2580 {
2581 .name = "cpus",
2582 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002583 .params = "",
2584 .help = "show infos for each CPU",
Wenchao Xia5f11cb02013-01-14 14:06:26 +08002585 .mhandler.cmd = hmp_info_cpus,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002586 },
2587 {
2588 .name = "history",
2589 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002590 .params = "",
2591 .help = "show the command line history",
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002592 .mhandler.cmd = hmp_info_history,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002593 },
Jan Kiszka661f1922011-10-16 11:53:13 +02002594#if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_MIPS) || \
2595 defined(TARGET_LM32) || (defined(TARGET_SPARC) && !defined(TARGET_SPARC64))
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002596 {
2597 .name = "irq",
2598 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002599 .params = "",
2600 .help = "show the interrupts statistics (if available)",
Jan Kiszka661f1922011-10-16 11:53:13 +02002601#ifdef TARGET_SPARC
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002602 .mhandler.cmd = sun4m_hmp_info_irq,
Jan Kiszka661f1922011-10-16 11:53:13 +02002603#elif defined(TARGET_LM32)
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002604 .mhandler.cmd = lm32_hmp_info_irq,
Jan Kiszka661f1922011-10-16 11:53:13 +02002605#else
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002606 .mhandler.cmd = hmp_info_irq,
Jan Kiszka661f1922011-10-16 11:53:13 +02002607#endif
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002608 },
2609 {
2610 .name = "pic",
2611 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002612 .params = "",
2613 .help = "show i8259 (PIC) state",
Jan Kiszka661f1922011-10-16 11:53:13 +02002614#ifdef TARGET_SPARC
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002615 .mhandler.cmd = sun4m_hmp_info_pic,
Jan Kiszka661f1922011-10-16 11:53:13 +02002616#elif defined(TARGET_LM32)
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002617 .mhandler.cmd = lm32_hmp_info_pic,
Jan Kiszka661f1922011-10-16 11:53:13 +02002618#else
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002619 .mhandler.cmd = hmp_info_pic,
Jan Kiszka661f1922011-10-16 11:53:13 +02002620#endif
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002621 },
Jan Kiszka661f1922011-10-16 11:53:13 +02002622#endif
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002623 {
2624 .name = "pci",
2625 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002626 .params = "",
2627 .help = "show PCI info",
Wenchao Xia5f11cb02013-01-14 14:06:26 +08002628 .mhandler.cmd = hmp_info_pci,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002629 },
Scott Woodbebabbc2011-08-18 10:38:42 +00002630#if defined(TARGET_I386) || defined(TARGET_SH4) || defined(TARGET_SPARC) || \
Max Filippov692f7372012-01-07 20:02:40 +04002631 defined(TARGET_PPC) || defined(TARGET_XTENSA)
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002632 {
2633 .name = "tlb",
2634 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002635 .params = "",
2636 .help = "show virtual to physical memory mappings",
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002637 .mhandler.cmd = hmp_info_tlb,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002638 },
aurel327c664e22009-03-03 06:12:22 +00002639#endif
2640#if defined(TARGET_I386)
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002641 {
2642 .name = "mem",
2643 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002644 .params = "",
2645 .help = "show the active virtual memory mappings",
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002646 .mhandler.cmd = hmp_info_mem,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002647 },
bellardb86bda52004-09-18 19:32:46 +00002648#endif
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002649 {
Blue Swirl314e2982011-09-11 20:22:05 +00002650 .name = "mtree",
2651 .args_type = "",
2652 .params = "",
2653 .help = "show memory tree",
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002654 .mhandler.cmd = hmp_info_mtree,
Blue Swirl314e2982011-09-11 20:22:05 +00002655 },
2656 {
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002657 .name = "jit",
2658 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002659 .params = "",
2660 .help = "show dynamic compiler info",
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002661 .mhandler.cmd = hmp_info_jit,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002662 },
2663 {
Max Filippov246ae242014-11-02 11:04:18 +03002664 .name = "opcount",
2665 .args_type = "",
2666 .params = "",
2667 .help = "show dynamic compiler opcode counters",
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002668 .mhandler.cmd = hmp_info_opcount,
Max Filippov246ae242014-11-02 11:04:18 +03002669 },
2670 {
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002671 .name = "kvm",
2672 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002673 .params = "",
2674 .help = "show KVM information",
Wenchao Xia5f11cb02013-01-14 14:06:26 +08002675 .mhandler.cmd = hmp_info_kvm,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002676 },
2677 {
2678 .name = "numa",
2679 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002680 .params = "",
2681 .help = "show NUMA information",
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002682 .mhandler.cmd = hmp_info_numa,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002683 },
2684 {
2685 .name = "usb",
2686 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002687 .params = "",
2688 .help = "show guest USB devices",
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002689 .mhandler.cmd = hmp_info_usb,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002690 },
2691 {
2692 .name = "usbhost",
2693 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002694 .params = "",
2695 .help = "show host USB devices",
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002696 .mhandler.cmd = hmp_info_usbhost,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002697 },
2698 {
2699 .name = "profile",
2700 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002701 .params = "",
2702 .help = "show profiling information",
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002703 .mhandler.cmd = hmp_info_profile,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002704 },
2705 {
2706 .name = "capture",
2707 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002708 .params = "",
2709 .help = "show capture information",
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002710 .mhandler.cmd = hmp_info_capture,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002711 },
2712 {
2713 .name = "snapshots",
2714 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002715 .params = "",
2716 .help = "show the currently saved VM snapshots",
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002717 .mhandler.cmd = hmp_info_snapshots,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002718 },
2719 {
2720 .name = "status",
2721 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002722 .params = "",
2723 .help = "show the current VM status (running|paused)",
Wenchao Xia5f11cb02013-01-14 14:06:26 +08002724 .mhandler.cmd = hmp_info_status,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002725 },
2726 {
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002727 .name = "mice",
2728 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002729 .params = "",
2730 .help = "show which guest mouse is receiving events",
Wenchao Xia5f11cb02013-01-14 14:06:26 +08002731 .mhandler.cmd = hmp_info_mice,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002732 },
2733 {
2734 .name = "vnc",
2735 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002736 .params = "",
2737 .help = "show the vnc server status",
Wenchao Xia5f11cb02013-01-14 14:06:26 +08002738 .mhandler.cmd = hmp_info_vnc,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002739 },
Gerd Hoffmanncb42a872010-11-30 11:02:51 +01002740#if defined(CONFIG_SPICE)
2741 {
2742 .name = "spice",
2743 .args_type = "",
2744 .params = "",
2745 .help = "show the spice server status",
Wenchao Xia5f11cb02013-01-14 14:06:26 +08002746 .mhandler.cmd = hmp_info_spice,
Gerd Hoffmanncb42a872010-11-30 11:02:51 +01002747 },
2748#endif
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002749 {
2750 .name = "name",
2751 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002752 .params = "",
2753 .help = "show the current VM name",
Wenchao Xia5f11cb02013-01-14 14:06:26 +08002754 .mhandler.cmd = hmp_info_name,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002755 },
2756 {
2757 .name = "uuid",
2758 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002759 .params = "",
2760 .help = "show the current VM UUID",
Wenchao Xia5f11cb02013-01-14 14:06:26 +08002761 .mhandler.cmd = hmp_info_uuid,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002762 },
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002763 {
2764 .name = "cpustats",
2765 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002766 .params = "",
2767 .help = "show CPU statistics",
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002768 .mhandler.cmd = hmp_info_cpustats,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002769 },
blueswir131a60e22007-10-26 18:42:59 +00002770#if defined(CONFIG_SLIRP)
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002771 {
2772 .name = "usernet",
2773 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002774 .params = "",
2775 .help = "show user network stack connection states",
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002776 .mhandler.cmd = hmp_info_usernet,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002777 },
blueswir131a60e22007-10-26 18:42:59 +00002778#endif
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002779 {
2780 .name = "migrate",
2781 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002782 .params = "",
2783 .help = "show migration status",
Wenchao Xia5f11cb02013-01-14 14:06:26 +08002784 .mhandler.cmd = hmp_info_migrate,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002785 },
2786 {
Orit Wassermanbbf6da32012-08-06 21:42:47 +03002787 .name = "migrate_capabilities",
2788 .args_type = "",
2789 .params = "",
2790 .help = "show current migration capabilities",
Wenchao Xia5f11cb02013-01-14 14:06:26 +08002791 .mhandler.cmd = hmp_info_migrate_capabilities,
Orit Wassermanbbf6da32012-08-06 21:42:47 +03002792 },
2793 {
Liang Li50e9a622015-03-23 16:32:29 +08002794 .name = "migrate_parameters",
2795 .args_type = "",
2796 .params = "",
2797 .help = "show current migration parameters",
2798 .mhandler.cmd = hmp_info_migrate_parameters,
2799 },
2800 {
Orit Wasserman9e1ba4c2012-08-06 21:42:54 +03002801 .name = "migrate_cache_size",
2802 .args_type = "",
2803 .params = "",
2804 .help = "show current migration xbzrle cache size",
Wenchao Xia5f11cb02013-01-14 14:06:26 +08002805 .mhandler.cmd = hmp_info_migrate_cache_size,
Orit Wasserman9e1ba4c2012-08-06 21:42:54 +03002806 },
2807 {
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002808 .name = "balloon",
2809 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002810 .params = "",
2811 .help = "show balloon information",
Wenchao Xia5f11cb02013-01-14 14:06:26 +08002812 .mhandler.cmd = hmp_info_balloon,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002813 },
2814 {
2815 .name = "qtree",
2816 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002817 .params = "",
2818 .help = "show device tree",
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002819 .mhandler.cmd = hmp_info_qtree,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002820 },
2821 {
2822 .name = "qdm",
2823 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002824 .params = "",
2825 .help = "show qdev device model list",
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002826 .mhandler.cmd = hmp_info_qdm,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002827 },
2828 {
Andreas Färbera01ff752014-05-07 17:03:18 +02002829 .name = "qom-tree",
2830 .args_type = "path:s?",
2831 .params = "[path]",
2832 .help = "show QOM composition tree",
2833 .mhandler.cmd = hmp_info_qom_tree,
2834 },
2835 {
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002836 .name = "roms",
2837 .args_type = "",
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002838 .params = "",
2839 .help = "show roms",
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002840 .mhandler.cmd = hmp_info_roms,
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002841 },
Prerna Saxena22890ab2010-06-24 17:04:53 +05302842 {
2843 .name = "trace-events",
2844 .args_type = "",
2845 .params = "",
2846 .help = "show available trace-events & their state",
Markus Armbruster1ce6be22015-02-06 14:18:24 +01002847 .mhandler.cmd = hmp_info_trace_events,
Prerna Saxena22890ab2010-06-24 17:04:53 +05302848 },
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002849 {
Stefan Bergerd1a0cf72013-02-27 12:47:49 -05002850 .name = "tpm",
2851 .args_type = "",
2852 .params = "",
2853 .help = "show the TPM device",
2854 .mhandler.cmd = hmp_info_tpm,
2855 },
2856 {
Hu Taoeb1539b2014-05-14 17:43:35 +08002857 .name = "memdev",
2858 .args_type = "",
2859 .params = "",
Igor Mammedov8f4e5ac2014-06-19 16:14:43 +02002860 .help = "show memory backends",
Hu Taoeb1539b2014-05-14 17:43:35 +08002861 .mhandler.cmd = hmp_info_memdev,
2862 },
2863 {
Zhu Guihuaa6318922014-09-23 13:35:19 +08002864 .name = "memory-devices",
2865 .args_type = "",
2866 .params = "",
2867 .help = "show memory devices",
2868 .mhandler.cmd = hmp_info_memory_devices,
2869 },
2870 {
Luiz Capitulinod7f9b682009-10-07 13:41:50 -03002871 .name = NULL,
2872 },
bellard9dc39cb2004-03-14 21:38:27 +00002873};
2874
Wenchao Xiaa13ced52013-01-14 14:06:28 +08002875/* mon_cmds and info_cmds would be sorted at runtime */
2876static mon_cmd_t mon_cmds[] = {
2877#include "hmp-commands.h"
2878 { NULL, NULL, },
2879};
2880
Luiz Capitulinof36b4af2010-09-15 17:17:45 -03002881static const mon_cmd_t qmp_cmds[] = {
Anthony Liguorie3193602011-09-02 12:34:47 -05002882#include "qmp-commands-old.h"
Luiz Capitulinof36b4af2010-09-15 17:17:45 -03002883 { /* NULL */ },
2884};
2885
bellard9307c4c2004-04-04 12:57:25 +00002886/*******************************************************************/
2887
2888static const char *pch;
Peter Maydell6ab7e542013-02-20 15:21:09 +00002889static sigjmp_buf expr_env;
bellard9307c4c2004-04-04 12:57:25 +00002890
bellard92a31b12005-02-10 22:00:52 +00002891#define MD_TLONG 0
2892#define MD_I32 1
2893
bellard9307c4c2004-04-04 12:57:25 +00002894typedef struct MonitorDef {
2895 const char *name;
2896 int offset;
blueswir18662d652008-10-02 18:32:44 +00002897 target_long (*get_value)(const struct MonitorDef *md, int val);
bellard92a31b12005-02-10 22:00:52 +00002898 int type;
bellard9307c4c2004-04-04 12:57:25 +00002899} MonitorDef;
2900
bellard57206fd2004-04-25 18:54:52 +00002901#if defined(TARGET_I386)
blueswir18662d652008-10-02 18:32:44 +00002902static target_long monitor_get_pc (const struct MonitorDef *md, int val)
bellard57206fd2004-04-25 18:54:52 +00002903{
Andreas Färber9349b4f2012-03-14 01:38:32 +01002904 CPUArchState *env = mon_get_cpu();
bellard6a00d602005-11-21 23:25:50 +00002905 return env->eip + env->segs[R_CS].base;
bellard57206fd2004-04-25 18:54:52 +00002906}
2907#endif
2908
bellarda541f292004-04-12 20:39:29 +00002909#if defined(TARGET_PPC)
blueswir18662d652008-10-02 18:32:44 +00002910static target_long monitor_get_ccr (const struct MonitorDef *md, int val)
bellarda541f292004-04-12 20:39:29 +00002911{
Andreas Färber9349b4f2012-03-14 01:38:32 +01002912 CPUArchState *env = mon_get_cpu();
bellarda541f292004-04-12 20:39:29 +00002913 unsigned int u;
2914 int i;
2915
2916 u = 0;
2917 for (i = 0; i < 8; i++)
Paolo Bonzinid2981182014-08-28 19:14:59 +02002918 u |= env->crf[i] << (32 - (4 * (i + 1)));
bellarda541f292004-04-12 20:39:29 +00002919
2920 return u;
2921}
2922
blueswir18662d652008-10-02 18:32:44 +00002923static target_long monitor_get_msr (const struct MonitorDef *md, int val)
bellarda541f292004-04-12 20:39:29 +00002924{
Andreas Färber9349b4f2012-03-14 01:38:32 +01002925 CPUArchState *env = mon_get_cpu();
j_mayer0411a972007-10-25 21:35:50 +00002926 return env->msr;
bellarda541f292004-04-12 20:39:29 +00002927}
2928
blueswir18662d652008-10-02 18:32:44 +00002929static target_long monitor_get_xer (const struct MonitorDef *md, int val)
bellarda541f292004-04-12 20:39:29 +00002930{
Andreas Färber9349b4f2012-03-14 01:38:32 +01002931 CPUArchState *env = mon_get_cpu();
aurel323d7b4172008-10-21 11:28:46 +00002932 return env->xer;
bellarda541f292004-04-12 20:39:29 +00002933}
bellard9fddaa02004-05-21 12:59:32 +00002934
blueswir18662d652008-10-02 18:32:44 +00002935static target_long monitor_get_decr (const struct MonitorDef *md, int val)
bellard9fddaa02004-05-21 12:59:32 +00002936{
Andreas Färber9349b4f2012-03-14 01:38:32 +01002937 CPUArchState *env = mon_get_cpu();
bellard6a00d602005-11-21 23:25:50 +00002938 return cpu_ppc_load_decr(env);
bellard9fddaa02004-05-21 12:59:32 +00002939}
2940
blueswir18662d652008-10-02 18:32:44 +00002941static target_long monitor_get_tbu (const struct MonitorDef *md, int val)
bellard9fddaa02004-05-21 12:59:32 +00002942{
Andreas Färber9349b4f2012-03-14 01:38:32 +01002943 CPUArchState *env = mon_get_cpu();
bellard6a00d602005-11-21 23:25:50 +00002944 return cpu_ppc_load_tbu(env);
bellard9fddaa02004-05-21 12:59:32 +00002945}
2946
blueswir18662d652008-10-02 18:32:44 +00002947static target_long monitor_get_tbl (const struct MonitorDef *md, int val)
bellard9fddaa02004-05-21 12:59:32 +00002948{
Andreas Färber9349b4f2012-03-14 01:38:32 +01002949 CPUArchState *env = mon_get_cpu();
bellard6a00d602005-11-21 23:25:50 +00002950 return cpu_ppc_load_tbl(env);
bellard9fddaa02004-05-21 12:59:32 +00002951}
bellarda541f292004-04-12 20:39:29 +00002952#endif
2953
bellarde95c8d52004-09-30 22:22:08 +00002954#if defined(TARGET_SPARC)
bellard7b936c02005-10-30 17:05:13 +00002955#ifndef TARGET_SPARC64
blueswir18662d652008-10-02 18:32:44 +00002956static target_long monitor_get_psr (const struct MonitorDef *md, int val)
bellarde95c8d52004-09-30 22:22:08 +00002957{
Andreas Färber9349b4f2012-03-14 01:38:32 +01002958 CPUArchState *env = mon_get_cpu();
Blue Swirl5a834bb2010-05-09 20:19:04 +00002959
2960 return cpu_get_psr(env);
bellarde95c8d52004-09-30 22:22:08 +00002961}
bellard7b936c02005-10-30 17:05:13 +00002962#endif
bellarde95c8d52004-09-30 22:22:08 +00002963
blueswir18662d652008-10-02 18:32:44 +00002964static target_long monitor_get_reg(const struct MonitorDef *md, int val)
bellarde95c8d52004-09-30 22:22:08 +00002965{
Andreas Färber9349b4f2012-03-14 01:38:32 +01002966 CPUArchState *env = mon_get_cpu();
bellard6a00d602005-11-21 23:25:50 +00002967 return env->regwptr[val];
bellarde95c8d52004-09-30 22:22:08 +00002968}
2969#endif
2970
blueswir18662d652008-10-02 18:32:44 +00002971static const MonitorDef monitor_defs[] = {
bellard9307c4c2004-04-04 12:57:25 +00002972#ifdef TARGET_I386
bellard57206fd2004-04-25 18:54:52 +00002973
2974#define SEG(name, seg) \
Andreas Färbere59d1672012-02-16 00:40:47 +01002975 { name, offsetof(CPUX86State, segs[seg].selector), NULL, MD_I32 },\
2976 { name ".base", offsetof(CPUX86State, segs[seg].base) },\
2977 { name ".limit", offsetof(CPUX86State, segs[seg].limit), NULL, MD_I32 },
bellard57206fd2004-04-25 18:54:52 +00002978
Andreas Färbere59d1672012-02-16 00:40:47 +01002979 { "eax", offsetof(CPUX86State, regs[0]) },
2980 { "ecx", offsetof(CPUX86State, regs[1]) },
2981 { "edx", offsetof(CPUX86State, regs[2]) },
2982 { "ebx", offsetof(CPUX86State, regs[3]) },
2983 { "esp|sp", offsetof(CPUX86State, regs[4]) },
2984 { "ebp|fp", offsetof(CPUX86State, regs[5]) },
2985 { "esi", offsetof(CPUX86State, regs[6]) },
2986 { "edi", offsetof(CPUX86State, regs[7]) },
bellard92a31b12005-02-10 22:00:52 +00002987#ifdef TARGET_X86_64
Andreas Färbere59d1672012-02-16 00:40:47 +01002988 { "r8", offsetof(CPUX86State, regs[8]) },
2989 { "r9", offsetof(CPUX86State, regs[9]) },
2990 { "r10", offsetof(CPUX86State, regs[10]) },
2991 { "r11", offsetof(CPUX86State, regs[11]) },
2992 { "r12", offsetof(CPUX86State, regs[12]) },
2993 { "r13", offsetof(CPUX86State, regs[13]) },
2994 { "r14", offsetof(CPUX86State, regs[14]) },
2995 { "r15", offsetof(CPUX86State, regs[15]) },
bellard92a31b12005-02-10 22:00:52 +00002996#endif
Andreas Färbere59d1672012-02-16 00:40:47 +01002997 { "eflags", offsetof(CPUX86State, eflags) },
2998 { "eip", offsetof(CPUX86State, eip) },
bellard57206fd2004-04-25 18:54:52 +00002999 SEG("cs", R_CS)
3000 SEG("ds", R_DS)
3001 SEG("es", R_ES)
bellard01038d22004-09-13 21:36:46 +00003002 SEG("ss", R_SS)
bellard57206fd2004-04-25 18:54:52 +00003003 SEG("fs", R_FS)
3004 SEG("gs", R_GS)
3005 { "pc", 0, monitor_get_pc, },
bellarda541f292004-04-12 20:39:29 +00003006#elif defined(TARGET_PPC)
j_mayerff937db2007-09-19 05:49:13 +00003007 /* General purpose registers */
Andreas Färbere59d1672012-02-16 00:40:47 +01003008 { "r0", offsetof(CPUPPCState, gpr[0]) },
3009 { "r1", offsetof(CPUPPCState, gpr[1]) },
3010 { "r2", offsetof(CPUPPCState, gpr[2]) },
3011 { "r3", offsetof(CPUPPCState, gpr[3]) },
3012 { "r4", offsetof(CPUPPCState, gpr[4]) },
3013 { "r5", offsetof(CPUPPCState, gpr[5]) },
3014 { "r6", offsetof(CPUPPCState, gpr[6]) },
3015 { "r7", offsetof(CPUPPCState, gpr[7]) },
3016 { "r8", offsetof(CPUPPCState, gpr[8]) },
3017 { "r9", offsetof(CPUPPCState, gpr[9]) },
3018 { "r10", offsetof(CPUPPCState, gpr[10]) },
3019 { "r11", offsetof(CPUPPCState, gpr[11]) },
3020 { "r12", offsetof(CPUPPCState, gpr[12]) },
3021 { "r13", offsetof(CPUPPCState, gpr[13]) },
3022 { "r14", offsetof(CPUPPCState, gpr[14]) },
3023 { "r15", offsetof(CPUPPCState, gpr[15]) },
3024 { "r16", offsetof(CPUPPCState, gpr[16]) },
3025 { "r17", offsetof(CPUPPCState, gpr[17]) },
3026 { "r18", offsetof(CPUPPCState, gpr[18]) },
3027 { "r19", offsetof(CPUPPCState, gpr[19]) },
3028 { "r20", offsetof(CPUPPCState, gpr[20]) },
3029 { "r21", offsetof(CPUPPCState, gpr[21]) },
3030 { "r22", offsetof(CPUPPCState, gpr[22]) },
3031 { "r23", offsetof(CPUPPCState, gpr[23]) },
3032 { "r24", offsetof(CPUPPCState, gpr[24]) },
3033 { "r25", offsetof(CPUPPCState, gpr[25]) },
3034 { "r26", offsetof(CPUPPCState, gpr[26]) },
3035 { "r27", offsetof(CPUPPCState, gpr[27]) },
3036 { "r28", offsetof(CPUPPCState, gpr[28]) },
3037 { "r29", offsetof(CPUPPCState, gpr[29]) },
3038 { "r30", offsetof(CPUPPCState, gpr[30]) },
3039 { "r31", offsetof(CPUPPCState, gpr[31]) },
j_mayerff937db2007-09-19 05:49:13 +00003040 /* Floating point registers */
Andreas Färbere59d1672012-02-16 00:40:47 +01003041 { "f0", offsetof(CPUPPCState, fpr[0]) },
3042 { "f1", offsetof(CPUPPCState, fpr[1]) },
3043 { "f2", offsetof(CPUPPCState, fpr[2]) },
3044 { "f3", offsetof(CPUPPCState, fpr[3]) },
3045 { "f4", offsetof(CPUPPCState, fpr[4]) },
3046 { "f5", offsetof(CPUPPCState, fpr[5]) },
3047 { "f6", offsetof(CPUPPCState, fpr[6]) },
3048 { "f7", offsetof(CPUPPCState, fpr[7]) },
3049 { "f8", offsetof(CPUPPCState, fpr[8]) },
3050 { "f9", offsetof(CPUPPCState, fpr[9]) },
3051 { "f10", offsetof(CPUPPCState, fpr[10]) },
3052 { "f11", offsetof(CPUPPCState, fpr[11]) },
3053 { "f12", offsetof(CPUPPCState, fpr[12]) },
3054 { "f13", offsetof(CPUPPCState, fpr[13]) },
3055 { "f14", offsetof(CPUPPCState, fpr[14]) },
3056 { "f15", offsetof(CPUPPCState, fpr[15]) },
3057 { "f16", offsetof(CPUPPCState, fpr[16]) },
3058 { "f17", offsetof(CPUPPCState, fpr[17]) },
3059 { "f18", offsetof(CPUPPCState, fpr[18]) },
3060 { "f19", offsetof(CPUPPCState, fpr[19]) },
3061 { "f20", offsetof(CPUPPCState, fpr[20]) },
3062 { "f21", offsetof(CPUPPCState, fpr[21]) },
3063 { "f22", offsetof(CPUPPCState, fpr[22]) },
3064 { "f23", offsetof(CPUPPCState, fpr[23]) },
3065 { "f24", offsetof(CPUPPCState, fpr[24]) },
3066 { "f25", offsetof(CPUPPCState, fpr[25]) },
3067 { "f26", offsetof(CPUPPCState, fpr[26]) },
3068 { "f27", offsetof(CPUPPCState, fpr[27]) },
3069 { "f28", offsetof(CPUPPCState, fpr[28]) },
3070 { "f29", offsetof(CPUPPCState, fpr[29]) },
3071 { "f30", offsetof(CPUPPCState, fpr[30]) },
3072 { "f31", offsetof(CPUPPCState, fpr[31]) },
3073 { "fpscr", offsetof(CPUPPCState, fpscr) },
j_mayerff937db2007-09-19 05:49:13 +00003074 /* Next instruction pointer */
Andreas Färbere59d1672012-02-16 00:40:47 +01003075 { "nip|pc", offsetof(CPUPPCState, nip) },
3076 { "lr", offsetof(CPUPPCState, lr) },
3077 { "ctr", offsetof(CPUPPCState, ctr) },
bellard9fddaa02004-05-21 12:59:32 +00003078 { "decr", 0, &monitor_get_decr, },
bellarda541f292004-04-12 20:39:29 +00003079 { "ccr", 0, &monitor_get_ccr, },
j_mayerff937db2007-09-19 05:49:13 +00003080 /* Machine state register */
bellarda541f292004-04-12 20:39:29 +00003081 { "msr", 0, &monitor_get_msr, },
3082 { "xer", 0, &monitor_get_xer, },
bellard9fddaa02004-05-21 12:59:32 +00003083 { "tbu", 0, &monitor_get_tbu, },
3084 { "tbl", 0, &monitor_get_tbl, },
j_mayerff937db2007-09-19 05:49:13 +00003085 /* Segment registers */
Andreas Färbere59d1672012-02-16 00:40:47 +01003086 { "sdr1", offsetof(CPUPPCState, spr[SPR_SDR1]) },
3087 { "sr0", offsetof(CPUPPCState, sr[0]) },
3088 { "sr1", offsetof(CPUPPCState, sr[1]) },
3089 { "sr2", offsetof(CPUPPCState, sr[2]) },
3090 { "sr3", offsetof(CPUPPCState, sr[3]) },
3091 { "sr4", offsetof(CPUPPCState, sr[4]) },
3092 { "sr5", offsetof(CPUPPCState, sr[5]) },
3093 { "sr6", offsetof(CPUPPCState, sr[6]) },
3094 { "sr7", offsetof(CPUPPCState, sr[7]) },
3095 { "sr8", offsetof(CPUPPCState, sr[8]) },
3096 { "sr9", offsetof(CPUPPCState, sr[9]) },
3097 { "sr10", offsetof(CPUPPCState, sr[10]) },
3098 { "sr11", offsetof(CPUPPCState, sr[11]) },
3099 { "sr12", offsetof(CPUPPCState, sr[12]) },
3100 { "sr13", offsetof(CPUPPCState, sr[13]) },
3101 { "sr14", offsetof(CPUPPCState, sr[14]) },
3102 { "sr15", offsetof(CPUPPCState, sr[15]) },
Scott Wood90dc8812011-04-29 17:10:23 -05003103 /* Too lazy to put BATs... */
Andreas Färbere59d1672012-02-16 00:40:47 +01003104 { "pvr", offsetof(CPUPPCState, spr[SPR_PVR]) },
Scott Wood90dc8812011-04-29 17:10:23 -05003105
Andreas Färbere59d1672012-02-16 00:40:47 +01003106 { "srr0", offsetof(CPUPPCState, spr[SPR_SRR0]) },
3107 { "srr1", offsetof(CPUPPCState, spr[SPR_SRR1]) },
Tom Musta04f1f782013-09-25 17:41:13 +10003108 { "dar", offsetof(CPUPPCState, spr[SPR_DAR]) },
3109 { "dsisr", offsetof(CPUPPCState, spr[SPR_DSISR]) },
3110 { "cfar", offsetof(CPUPPCState, spr[SPR_CFAR]) },
Andreas Färbere59d1672012-02-16 00:40:47 +01003111 { "sprg0", offsetof(CPUPPCState, spr[SPR_SPRG0]) },
3112 { "sprg1", offsetof(CPUPPCState, spr[SPR_SPRG1]) },
3113 { "sprg2", offsetof(CPUPPCState, spr[SPR_SPRG2]) },
3114 { "sprg3", offsetof(CPUPPCState, spr[SPR_SPRG3]) },
3115 { "sprg4", offsetof(CPUPPCState, spr[SPR_SPRG4]) },
3116 { "sprg5", offsetof(CPUPPCState, spr[SPR_SPRG5]) },
3117 { "sprg6", offsetof(CPUPPCState, spr[SPR_SPRG6]) },
3118 { "sprg7", offsetof(CPUPPCState, spr[SPR_SPRG7]) },
3119 { "pid", offsetof(CPUPPCState, spr[SPR_BOOKE_PID]) },
3120 { "csrr0", offsetof(CPUPPCState, spr[SPR_BOOKE_CSRR0]) },
3121 { "csrr1", offsetof(CPUPPCState, spr[SPR_BOOKE_CSRR1]) },
3122 { "esr", offsetof(CPUPPCState, spr[SPR_BOOKE_ESR]) },
3123 { "dear", offsetof(CPUPPCState, spr[SPR_BOOKE_DEAR]) },
3124 { "mcsr", offsetof(CPUPPCState, spr[SPR_BOOKE_MCSR]) },
3125 { "tsr", offsetof(CPUPPCState, spr[SPR_BOOKE_TSR]) },
3126 { "tcr", offsetof(CPUPPCState, spr[SPR_BOOKE_TCR]) },
3127 { "vrsave", offsetof(CPUPPCState, spr[SPR_VRSAVE]) },
3128 { "pir", offsetof(CPUPPCState, spr[SPR_BOOKE_PIR]) },
3129 { "mcsrr0", offsetof(CPUPPCState, spr[SPR_BOOKE_MCSRR0]) },
3130 { "mcsrr1", offsetof(CPUPPCState, spr[SPR_BOOKE_MCSRR1]) },
3131 { "decar", offsetof(CPUPPCState, spr[SPR_BOOKE_DECAR]) },
3132 { "ivpr", offsetof(CPUPPCState, spr[SPR_BOOKE_IVPR]) },
3133 { "epcr", offsetof(CPUPPCState, spr[SPR_BOOKE_EPCR]) },
3134 { "sprg8", offsetof(CPUPPCState, spr[SPR_BOOKE_SPRG8]) },
3135 { "ivor0", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR0]) },
3136 { "ivor1", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR1]) },
3137 { "ivor2", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR2]) },
3138 { "ivor3", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR3]) },
3139 { "ivor4", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR4]) },
3140 { "ivor5", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR5]) },
3141 { "ivor6", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR6]) },
3142 { "ivor7", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR7]) },
3143 { "ivor8", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR8]) },
3144 { "ivor9", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR9]) },
3145 { "ivor10", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR10]) },
3146 { "ivor11", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR11]) },
3147 { "ivor12", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR12]) },
3148 { "ivor13", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR13]) },
3149 { "ivor14", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR14]) },
3150 { "ivor15", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR15]) },
3151 { "ivor32", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR32]) },
3152 { "ivor33", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR33]) },
3153 { "ivor34", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR34]) },
3154 { "ivor35", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR35]) },
3155 { "ivor36", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR36]) },
3156 { "ivor37", offsetof(CPUPPCState, spr[SPR_BOOKE_IVOR37]) },
3157 { "mas0", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS0]) },
3158 { "mas1", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS1]) },
3159 { "mas2", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS2]) },
3160 { "mas3", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS3]) },
3161 { "mas4", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS4]) },
3162 { "mas6", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS6]) },
3163 { "mas7", offsetof(CPUPPCState, spr[SPR_BOOKE_MAS7]) },
3164 { "mmucfg", offsetof(CPUPPCState, spr[SPR_MMUCFG]) },
3165 { "tlb0cfg", offsetof(CPUPPCState, spr[SPR_BOOKE_TLB0CFG]) },
3166 { "tlb1cfg", offsetof(CPUPPCState, spr[SPR_BOOKE_TLB1CFG]) },
3167 { "epr", offsetof(CPUPPCState, spr[SPR_BOOKE_EPR]) },
3168 { "eplc", offsetof(CPUPPCState, spr[SPR_BOOKE_EPLC]) },
3169 { "epsc", offsetof(CPUPPCState, spr[SPR_BOOKE_EPSC]) },
3170 { "svr", offsetof(CPUPPCState, spr[SPR_E500_SVR]) },
3171 { "mcar", offsetof(CPUPPCState, spr[SPR_Exxx_MCAR]) },
3172 { "pid1", offsetof(CPUPPCState, spr[SPR_BOOKE_PID1]) },
3173 { "pid2", offsetof(CPUPPCState, spr[SPR_BOOKE_PID2]) },
3174 { "hid0", offsetof(CPUPPCState, spr[SPR_HID0]) },
Scott Wood90dc8812011-04-29 17:10:23 -05003175
bellarde95c8d52004-09-30 22:22:08 +00003176#elif defined(TARGET_SPARC)
Andreas Färbere59d1672012-02-16 00:40:47 +01003177 { "g0", offsetof(CPUSPARCState, gregs[0]) },
3178 { "g1", offsetof(CPUSPARCState, gregs[1]) },
3179 { "g2", offsetof(CPUSPARCState, gregs[2]) },
3180 { "g3", offsetof(CPUSPARCState, gregs[3]) },
3181 { "g4", offsetof(CPUSPARCState, gregs[4]) },
3182 { "g5", offsetof(CPUSPARCState, gregs[5]) },
3183 { "g6", offsetof(CPUSPARCState, gregs[6]) },
3184 { "g7", offsetof(CPUSPARCState, gregs[7]) },
bellarde95c8d52004-09-30 22:22:08 +00003185 { "o0", 0, monitor_get_reg },
3186 { "o1", 1, monitor_get_reg },
3187 { "o2", 2, monitor_get_reg },
3188 { "o3", 3, monitor_get_reg },
3189 { "o4", 4, monitor_get_reg },
3190 { "o5", 5, monitor_get_reg },
3191 { "o6", 6, monitor_get_reg },
3192 { "o7", 7, monitor_get_reg },
3193 { "l0", 8, monitor_get_reg },
3194 { "l1", 9, monitor_get_reg },
3195 { "l2", 10, monitor_get_reg },
3196 { "l3", 11, monitor_get_reg },
3197 { "l4", 12, monitor_get_reg },
3198 { "l5", 13, monitor_get_reg },
3199 { "l6", 14, monitor_get_reg },
3200 { "l7", 15, monitor_get_reg },
3201 { "i0", 16, monitor_get_reg },
3202 { "i1", 17, monitor_get_reg },
3203 { "i2", 18, monitor_get_reg },
3204 { "i3", 19, monitor_get_reg },
3205 { "i4", 20, monitor_get_reg },
3206 { "i5", 21, monitor_get_reg },
3207 { "i6", 22, monitor_get_reg },
3208 { "i7", 23, monitor_get_reg },
Andreas Färbere59d1672012-02-16 00:40:47 +01003209 { "pc", offsetof(CPUSPARCState, pc) },
3210 { "npc", offsetof(CPUSPARCState, npc) },
3211 { "y", offsetof(CPUSPARCState, y) },
bellard7b936c02005-10-30 17:05:13 +00003212#ifndef TARGET_SPARC64
bellarde95c8d52004-09-30 22:22:08 +00003213 { "psr", 0, &monitor_get_psr, },
Andreas Färbere59d1672012-02-16 00:40:47 +01003214 { "wim", offsetof(CPUSPARCState, wim) },
bellard7b936c02005-10-30 17:05:13 +00003215#endif
Andreas Färbere59d1672012-02-16 00:40:47 +01003216 { "tbr", offsetof(CPUSPARCState, tbr) },
3217 { "fsr", offsetof(CPUSPARCState, fsr) },
3218 { "f0", offsetof(CPUSPARCState, fpr[0].l.upper) },
3219 { "f1", offsetof(CPUSPARCState, fpr[0].l.lower) },
3220 { "f2", offsetof(CPUSPARCState, fpr[1].l.upper) },
3221 { "f3", offsetof(CPUSPARCState, fpr[1].l.lower) },
3222 { "f4", offsetof(CPUSPARCState, fpr[2].l.upper) },
3223 { "f5", offsetof(CPUSPARCState, fpr[2].l.lower) },
3224 { "f6", offsetof(CPUSPARCState, fpr[3].l.upper) },
3225 { "f7", offsetof(CPUSPARCState, fpr[3].l.lower) },
3226 { "f8", offsetof(CPUSPARCState, fpr[4].l.upper) },
3227 { "f9", offsetof(CPUSPARCState, fpr[4].l.lower) },
3228 { "f10", offsetof(CPUSPARCState, fpr[5].l.upper) },
3229 { "f11", offsetof(CPUSPARCState, fpr[5].l.lower) },
3230 { "f12", offsetof(CPUSPARCState, fpr[6].l.upper) },
3231 { "f13", offsetof(CPUSPARCState, fpr[6].l.lower) },
3232 { "f14", offsetof(CPUSPARCState, fpr[7].l.upper) },
3233 { "f15", offsetof(CPUSPARCState, fpr[7].l.lower) },
3234 { "f16", offsetof(CPUSPARCState, fpr[8].l.upper) },
3235 { "f17", offsetof(CPUSPARCState, fpr[8].l.lower) },
3236 { "f18", offsetof(CPUSPARCState, fpr[9].l.upper) },
3237 { "f19", offsetof(CPUSPARCState, fpr[9].l.lower) },
3238 { "f20", offsetof(CPUSPARCState, fpr[10].l.upper) },
3239 { "f21", offsetof(CPUSPARCState, fpr[10].l.lower) },
3240 { "f22", offsetof(CPUSPARCState, fpr[11].l.upper) },
3241 { "f23", offsetof(CPUSPARCState, fpr[11].l.lower) },
3242 { "f24", offsetof(CPUSPARCState, fpr[12].l.upper) },
3243 { "f25", offsetof(CPUSPARCState, fpr[12].l.lower) },
3244 { "f26", offsetof(CPUSPARCState, fpr[13].l.upper) },
3245 { "f27", offsetof(CPUSPARCState, fpr[13].l.lower) },
3246 { "f28", offsetof(CPUSPARCState, fpr[14].l.upper) },
3247 { "f29", offsetof(CPUSPARCState, fpr[14].l.lower) },
3248 { "f30", offsetof(CPUSPARCState, fpr[15].l.upper) },
3249 { "f31", offsetof(CPUSPARCState, fpr[15].l.lower) },
bellard7b936c02005-10-30 17:05:13 +00003250#ifdef TARGET_SPARC64
Andreas Färbere59d1672012-02-16 00:40:47 +01003251 { "f32", offsetof(CPUSPARCState, fpr[16]) },
3252 { "f34", offsetof(CPUSPARCState, fpr[17]) },
3253 { "f36", offsetof(CPUSPARCState, fpr[18]) },
3254 { "f38", offsetof(CPUSPARCState, fpr[19]) },
3255 { "f40", offsetof(CPUSPARCState, fpr[20]) },
3256 { "f42", offsetof(CPUSPARCState, fpr[21]) },
3257 { "f44", offsetof(CPUSPARCState, fpr[22]) },
3258 { "f46", offsetof(CPUSPARCState, fpr[23]) },
3259 { "f48", offsetof(CPUSPARCState, fpr[24]) },
3260 { "f50", offsetof(CPUSPARCState, fpr[25]) },
3261 { "f52", offsetof(CPUSPARCState, fpr[26]) },
3262 { "f54", offsetof(CPUSPARCState, fpr[27]) },
3263 { "f56", offsetof(CPUSPARCState, fpr[28]) },
3264 { "f58", offsetof(CPUSPARCState, fpr[29]) },
3265 { "f60", offsetof(CPUSPARCState, fpr[30]) },
3266 { "f62", offsetof(CPUSPARCState, fpr[31]) },
3267 { "asi", offsetof(CPUSPARCState, asi) },
3268 { "pstate", offsetof(CPUSPARCState, pstate) },
3269 { "cansave", offsetof(CPUSPARCState, cansave) },
3270 { "canrestore", offsetof(CPUSPARCState, canrestore) },
3271 { "otherwin", offsetof(CPUSPARCState, otherwin) },
3272 { "wstate", offsetof(CPUSPARCState, wstate) },
3273 { "cleanwin", offsetof(CPUSPARCState, cleanwin) },
3274 { "fprs", offsetof(CPUSPARCState, fprs) },
bellard7b936c02005-10-30 17:05:13 +00003275#endif
bellard9307c4c2004-04-04 12:57:25 +00003276#endif
3277 { NULL },
3278};
3279
Stefan Weil9c3175c2013-08-22 21:30:09 +02003280static void GCC_FMT_ATTR(2, 3) QEMU_NORETURN
3281expr_error(Monitor *mon, const char *fmt, ...)
bellard9dc39cb2004-03-14 21:38:27 +00003282{
Fam Zheng277acfe2013-08-20 10:58:21 +08003283 va_list ap;
3284 va_start(ap, fmt);
3285 monitor_vprintf(mon, fmt, ap);
3286 monitor_printf(mon, "\n");
3287 va_end(ap);
Peter Maydell6ab7e542013-02-20 15:21:09 +00003288 siglongjmp(expr_env, 1);
bellard9307c4c2004-04-04 12:57:25 +00003289}
3290
Markus Armbruster09b94182010-01-20 13:07:30 +01003291/* return 0 if OK, -1 if not found */
bellard92a31b12005-02-10 22:00:52 +00003292static int get_monitor_def(target_long *pval, const char *name)
bellard9307c4c2004-04-04 12:57:25 +00003293{
blueswir18662d652008-10-02 18:32:44 +00003294 const MonitorDef *md;
bellard92a31b12005-02-10 22:00:52 +00003295 void *ptr;
3296
bellard9307c4c2004-04-04 12:57:25 +00003297 for(md = monitor_defs; md->name != NULL; md++) {
3298 if (compare_cmd(name, md->name)) {
3299 if (md->get_value) {
bellarde95c8d52004-09-30 22:22:08 +00003300 *pval = md->get_value(md, md->offset);
bellard9307c4c2004-04-04 12:57:25 +00003301 } else {
Andreas Färber9349b4f2012-03-14 01:38:32 +01003302 CPUArchState *env = mon_get_cpu();
bellard6a00d602005-11-21 23:25:50 +00003303 ptr = (uint8_t *)env + md->offset;
bellard92a31b12005-02-10 22:00:52 +00003304 switch(md->type) {
3305 case MD_I32:
3306 *pval = *(int32_t *)ptr;
3307 break;
3308 case MD_TLONG:
3309 *pval = *(target_long *)ptr;
3310 break;
3311 default:
3312 *pval = 0;
3313 break;
3314 }
bellard9307c4c2004-04-04 12:57:25 +00003315 }
3316 return 0;
3317 }
3318 }
3319 return -1;
3320}
3321
3322static void next(void)
3323{
Blue Swirl660f11b2009-07-31 21:16:51 +00003324 if (*pch != '\0') {
bellard9307c4c2004-04-04 12:57:25 +00003325 pch++;
blueswir1cd390082008-11-16 13:53:32 +00003326 while (qemu_isspace(*pch))
bellard9307c4c2004-04-04 12:57:25 +00003327 pch++;
3328 }
3329}
3330
aliguori376253e2009-03-05 23:01:23 +00003331static int64_t expr_sum(Monitor *mon);
bellard9307c4c2004-04-04 12:57:25 +00003332
aliguori376253e2009-03-05 23:01:23 +00003333static int64_t expr_unary(Monitor *mon)
bellard9307c4c2004-04-04 12:57:25 +00003334{
blueswir1c2efc952007-09-25 17:28:42 +00003335 int64_t n;
bellard9307c4c2004-04-04 12:57:25 +00003336 char *p;
bellard6a00d602005-11-21 23:25:50 +00003337 int ret;
bellard9307c4c2004-04-04 12:57:25 +00003338
3339 switch(*pch) {
3340 case '+':
3341 next();
aliguori376253e2009-03-05 23:01:23 +00003342 n = expr_unary(mon);
bellard9307c4c2004-04-04 12:57:25 +00003343 break;
3344 case '-':
3345 next();
aliguori376253e2009-03-05 23:01:23 +00003346 n = -expr_unary(mon);
bellard9307c4c2004-04-04 12:57:25 +00003347 break;
3348 case '~':
3349 next();
aliguori376253e2009-03-05 23:01:23 +00003350 n = ~expr_unary(mon);
bellard9307c4c2004-04-04 12:57:25 +00003351 break;
3352 case '(':
3353 next();
aliguori376253e2009-03-05 23:01:23 +00003354 n = expr_sum(mon);
bellard9307c4c2004-04-04 12:57:25 +00003355 if (*pch != ')') {
aliguori376253e2009-03-05 23:01:23 +00003356 expr_error(mon, "')' expected");
bellard9307c4c2004-04-04 12:57:25 +00003357 }
3358 next();
3359 break;
bellard81d09122004-07-14 17:21:37 +00003360 case '\'':
3361 pch++;
3362 if (*pch == '\0')
aliguori376253e2009-03-05 23:01:23 +00003363 expr_error(mon, "character constant expected");
bellard81d09122004-07-14 17:21:37 +00003364 n = *pch;
3365 pch++;
3366 if (*pch != '\'')
aliguori376253e2009-03-05 23:01:23 +00003367 expr_error(mon, "missing terminating \' character");
bellard81d09122004-07-14 17:21:37 +00003368 next();
3369 break;
bellard9307c4c2004-04-04 12:57:25 +00003370 case '$':
3371 {
3372 char buf[128], *q;
ths69b34972007-12-17 03:15:52 +00003373 target_long reg=0;
ths3b46e622007-09-17 08:09:54 +00003374
bellard9307c4c2004-04-04 12:57:25 +00003375 pch++;
3376 q = buf;
3377 while ((*pch >= 'a' && *pch <= 'z') ||
3378 (*pch >= 'A' && *pch <= 'Z') ||
3379 (*pch >= '0' && *pch <= '9') ||
bellard57206fd2004-04-25 18:54:52 +00003380 *pch == '_' || *pch == '.') {
bellard9307c4c2004-04-04 12:57:25 +00003381 if ((q - buf) < sizeof(buf) - 1)
3382 *q++ = *pch;
3383 pch++;
3384 }
blueswir1cd390082008-11-16 13:53:32 +00003385 while (qemu_isspace(*pch))
bellard9307c4c2004-04-04 12:57:25 +00003386 pch++;
3387 *q = 0;
blueswir17743e582007-09-24 18:39:04 +00003388 ret = get_monitor_def(&reg, buf);
Markus Armbruster09b94182010-01-20 13:07:30 +01003389 if (ret < 0)
aliguori376253e2009-03-05 23:01:23 +00003390 expr_error(mon, "unknown register");
blueswir17743e582007-09-24 18:39:04 +00003391 n = reg;
bellard9307c4c2004-04-04 12:57:25 +00003392 }
3393 break;
3394 case '\0':
aliguori376253e2009-03-05 23:01:23 +00003395 expr_error(mon, "unexpected end of expression");
bellard9307c4c2004-04-04 12:57:25 +00003396 n = 0;
3397 break;
3398 default:
Luiz Capitulino6b0e33b2012-04-26 16:48:41 -03003399 errno = 0;
bellard4f4fbf72006-06-25 18:28:12 +00003400 n = strtoull(pch, &p, 0);
Luiz Capitulino6b0e33b2012-04-26 16:48:41 -03003401 if (errno == ERANGE) {
3402 expr_error(mon, "number too large");
3403 }
bellard9307c4c2004-04-04 12:57:25 +00003404 if (pch == p) {
Fam Zheng277acfe2013-08-20 10:58:21 +08003405 expr_error(mon, "invalid char '%c' in expression", *p);
bellard9307c4c2004-04-04 12:57:25 +00003406 }
3407 pch = p;
blueswir1cd390082008-11-16 13:53:32 +00003408 while (qemu_isspace(*pch))
bellard9307c4c2004-04-04 12:57:25 +00003409 pch++;
3410 break;
3411 }
3412 return n;
3413}
3414
3415
aliguori376253e2009-03-05 23:01:23 +00003416static int64_t expr_prod(Monitor *mon)
bellard9307c4c2004-04-04 12:57:25 +00003417{
blueswir1c2efc952007-09-25 17:28:42 +00003418 int64_t val, val2;
bellard92a31b12005-02-10 22:00:52 +00003419 int op;
ths3b46e622007-09-17 08:09:54 +00003420
aliguori376253e2009-03-05 23:01:23 +00003421 val = expr_unary(mon);
bellard9307c4c2004-04-04 12:57:25 +00003422 for(;;) {
3423 op = *pch;
3424 if (op != '*' && op != '/' && op != '%')
3425 break;
3426 next();
aliguori376253e2009-03-05 23:01:23 +00003427 val2 = expr_unary(mon);
bellard9307c4c2004-04-04 12:57:25 +00003428 switch(op) {
3429 default:
3430 case '*':
3431 val *= val2;
3432 break;
3433 case '/':
3434 case '%':
ths5fafdf22007-09-16 21:08:06 +00003435 if (val2 == 0)
aliguori376253e2009-03-05 23:01:23 +00003436 expr_error(mon, "division by zero");
bellard9307c4c2004-04-04 12:57:25 +00003437 if (op == '/')
3438 val /= val2;
3439 else
3440 val %= val2;
3441 break;
3442 }
3443 }
3444 return val;
3445}
3446
aliguori376253e2009-03-05 23:01:23 +00003447static int64_t expr_logic(Monitor *mon)
bellard9307c4c2004-04-04 12:57:25 +00003448{
blueswir1c2efc952007-09-25 17:28:42 +00003449 int64_t val, val2;
bellard92a31b12005-02-10 22:00:52 +00003450 int op;
bellard9307c4c2004-04-04 12:57:25 +00003451
aliguori376253e2009-03-05 23:01:23 +00003452 val = expr_prod(mon);
bellard9307c4c2004-04-04 12:57:25 +00003453 for(;;) {
3454 op = *pch;
3455 if (op != '&' && op != '|' && op != '^')
3456 break;
3457 next();
aliguori376253e2009-03-05 23:01:23 +00003458 val2 = expr_prod(mon);
bellard9307c4c2004-04-04 12:57:25 +00003459 switch(op) {
3460 default:
3461 case '&':
3462 val &= val2;
3463 break;
3464 case '|':
3465 val |= val2;
3466 break;
3467 case '^':
3468 val ^= val2;
3469 break;
3470 }
3471 }
3472 return val;
3473}
3474
aliguori376253e2009-03-05 23:01:23 +00003475static int64_t expr_sum(Monitor *mon)
bellard9307c4c2004-04-04 12:57:25 +00003476{
blueswir1c2efc952007-09-25 17:28:42 +00003477 int64_t val, val2;
bellard92a31b12005-02-10 22:00:52 +00003478 int op;
bellard9307c4c2004-04-04 12:57:25 +00003479
aliguori376253e2009-03-05 23:01:23 +00003480 val = expr_logic(mon);
bellard9307c4c2004-04-04 12:57:25 +00003481 for(;;) {
3482 op = *pch;
3483 if (op != '+' && op != '-')
3484 break;
3485 next();
aliguori376253e2009-03-05 23:01:23 +00003486 val2 = expr_logic(mon);
bellard9307c4c2004-04-04 12:57:25 +00003487 if (op == '+')
3488 val += val2;
3489 else
3490 val -= val2;
3491 }
3492 return val;
3493}
3494
aliguori376253e2009-03-05 23:01:23 +00003495static int get_expr(Monitor *mon, int64_t *pval, const char **pp)
bellard9307c4c2004-04-04 12:57:25 +00003496{
3497 pch = *pp;
Peter Maydell6ab7e542013-02-20 15:21:09 +00003498 if (sigsetjmp(expr_env, 0)) {
bellard9307c4c2004-04-04 12:57:25 +00003499 *pp = pch;
3500 return -1;
3501 }
blueswir1cd390082008-11-16 13:53:32 +00003502 while (qemu_isspace(*pch))
bellard9307c4c2004-04-04 12:57:25 +00003503 pch++;
aliguori376253e2009-03-05 23:01:23 +00003504 *pval = expr_sum(mon);
bellard9307c4c2004-04-04 12:57:25 +00003505 *pp = pch;
3506 return 0;
3507}
3508
Markus Armbruster3350a4d2010-01-25 14:23:03 +01003509static int get_double(Monitor *mon, double *pval, const char **pp)
3510{
3511 const char *p = *pp;
3512 char *tailp;
3513 double d;
3514
3515 d = strtod(p, &tailp);
3516 if (tailp == p) {
3517 monitor_printf(mon, "Number expected\n");
3518 return -1;
3519 }
3520 if (d != d || d - d != 0) {
3521 /* NaN or infinity */
3522 monitor_printf(mon, "Bad number\n");
3523 return -1;
3524 }
3525 *pval = d;
3526 *pp = tailp;
3527 return 0;
3528}
3529
Luiz Capitulino4590fd82009-06-09 18:21:30 -03003530/*
3531 * Store the command-name in cmdname, and return a pointer to
3532 * the remaining of the command string.
3533 */
3534static const char *get_command_name(const char *cmdline,
3535 char *cmdname, size_t nlen)
3536{
3537 size_t len;
3538 const char *p, *pstart;
3539
3540 p = cmdline;
3541 while (qemu_isspace(*p))
3542 p++;
3543 if (*p == '\0')
3544 return NULL;
3545 pstart = p;
3546 while (*p != '\0' && *p != '/' && !qemu_isspace(*p))
3547 p++;
3548 len = p - pstart;
3549 if (len > nlen - 1)
3550 len = nlen - 1;
3551 memcpy(cmdname, pstart, len);
3552 cmdname[len] = '\0';
3553 return p;
3554}
3555
Luiz Capitulino4d76d2b2009-08-28 15:27:09 -03003556/**
3557 * Read key of 'type' into 'key' and return the current
3558 * 'type' pointer.
3559 */
3560static char *key_get_info(const char *type, char **key)
3561{
3562 size_t len;
3563 char *p, *str;
3564
3565 if (*type == ',')
3566 type++;
3567
3568 p = strchr(type, ':');
3569 if (!p) {
3570 *key = NULL;
3571 return NULL;
3572 }
3573 len = p - type;
3574
Anthony Liguori7267c092011-08-20 22:09:37 -05003575 str = g_malloc(len + 1);
Luiz Capitulino4d76d2b2009-08-28 15:27:09 -03003576 memcpy(str, type, len);
3577 str[len] = '\0';
3578
3579 *key = str;
3580 return ++p;
3581}
3582
bellard9307c4c2004-04-04 12:57:25 +00003583static int default_fmt_format = 'x';
3584static int default_fmt_size = 4;
3585
lirans@il.ibm.comfbc3d962009-11-02 15:41:13 +02003586static int is_valid_option(const char *c, const char *typestr)
3587{
3588 char option[3];
3589
3590 option[0] = '-';
3591 option[1] = *c;
3592 option[2] = '\0';
3593
3594 typestr = strstr(typestr, option);
3595 return (typestr != NULL);
3596}
3597
Luiz Capitulino945c5ac2010-09-13 13:17:58 -03003598static const mon_cmd_t *search_dispatch_table(const mon_cmd_t *disp_table,
3599 const char *cmdname)
Luiz Capitulino7fd669a2009-11-26 22:58:54 -02003600{
3601 const mon_cmd_t *cmd;
3602
Luiz Capitulino945c5ac2010-09-13 13:17:58 -03003603 for (cmd = disp_table; cmd->name != NULL; cmd++) {
Luiz Capitulino7fd669a2009-11-26 22:58:54 -02003604 if (compare_cmd(cmdname, cmd->name)) {
3605 return cmd;
3606 }
3607 }
3608
3609 return NULL;
3610}
3611
Luiz Capitulinobead3ce2010-09-15 17:08:39 -03003612static const mon_cmd_t *qmp_find_cmd(const char *cmdname)
3613{
Luiz Capitulinof36b4af2010-09-15 17:17:45 -03003614 return search_dispatch_table(qmp_cmds, cmdname);
Luiz Capitulinobead3ce2010-09-15 17:08:39 -03003615}
3616
Wenchao Xia5f3d3352013-01-14 14:06:27 +08003617/*
3618 * Parse @cmdline according to command table @table.
3619 * If @cmdline is blank, return NULL.
3620 * If it can't be parsed, report to @mon, and return NULL.
3621 * Else, insert command arguments into @qdict, and return the command.
Peter Maydell085d8132013-03-18 17:20:07 +00003622 * If a sub-command table exists, and if @cmdline contains an additional string
3623 * for a sub-command, this function will try to search the sub-command table.
3624 * If no additional string for a sub-command is present, this function will
3625 * return the command found in @table.
Wenchao Xia5f3d3352013-01-14 14:06:27 +08003626 * Do not assume the returned command points into @table! It doesn't
3627 * when the command is a sub-command.
3628 */
Anthony Liguoric227f092009-10-01 16:12:16 -05003629static const mon_cmd_t *monitor_parse_command(Monitor *mon,
Luiz Capitulino55f81d92009-08-28 15:27:22 -03003630 const char *cmdline,
Wenchao Xia5f3d3352013-01-14 14:06:27 +08003631 int start,
3632 mon_cmd_t *table,
Luiz Capitulino55f81d92009-08-28 15:27:22 -03003633 QDict *qdict)
bellard9307c4c2004-04-04 12:57:25 +00003634{
Luiz Capitulino4590fd82009-06-09 18:21:30 -03003635 const char *p, *typestr;
Luiz Capitulino53773582009-08-28 15:27:25 -03003636 int c;
Anthony Liguoric227f092009-10-01 16:12:16 -05003637 const mon_cmd_t *cmd;
bellard9307c4c2004-04-04 12:57:25 +00003638 char cmdname[256];
3639 char buf[1024];
Luiz Capitulino4d76d2b2009-08-28 15:27:09 -03003640 char *key;
bellard9dc39cb2004-03-14 21:38:27 +00003641
3642#ifdef DEBUG
Wenchao Xia5f3d3352013-01-14 14:06:27 +08003643 monitor_printf(mon, "command='%s', start='%d'\n", cmdline, start);
bellard9dc39cb2004-03-14 21:38:27 +00003644#endif
ths3b46e622007-09-17 08:09:54 +00003645
bellard9307c4c2004-04-04 12:57:25 +00003646 /* extract the command name */
Wenchao Xia5f3d3352013-01-14 14:06:27 +08003647 p = get_command_name(cmdline + start, cmdname, sizeof(cmdname));
Luiz Capitulino4590fd82009-06-09 18:21:30 -03003648 if (!p)
Luiz Capitulino55f81d92009-08-28 15:27:22 -03003649 return NULL;
ths3b46e622007-09-17 08:09:54 +00003650
Wenchao Xia5f3d3352013-01-14 14:06:27 +08003651 cmd = search_dispatch_table(table, cmdname);
Luiz Capitulino7fd669a2009-11-26 22:58:54 -02003652 if (!cmd) {
Wenchao Xia5f3d3352013-01-14 14:06:27 +08003653 monitor_printf(mon, "unknown command: '%.*s'\n",
3654 (int)(p - cmdline), cmdline);
Luiz Capitulino55f81d92009-08-28 15:27:22 -03003655 return NULL;
Luiz Capitulinod91d9bf2009-06-09 18:21:54 -03003656 }
bellard9307c4c2004-04-04 12:57:25 +00003657
Wenchao Xia5f3d3352013-01-14 14:06:27 +08003658 /* filter out following useless space */
3659 while (qemu_isspace(*p)) {
3660 p++;
3661 }
3662 /* search sub command */
3663 if (cmd->sub_table != NULL) {
3664 /* check if user set additional command */
3665 if (*p == '\0') {
3666 return cmd;
3667 }
3668 return monitor_parse_command(mon, cmdline, p - cmdline,
3669 cmd->sub_table, qdict);
3670 }
3671
bellard9307c4c2004-04-04 12:57:25 +00003672 /* parse the parameters */
3673 typestr = cmd->args_type;
bellard9307c4c2004-04-04 12:57:25 +00003674 for(;;) {
Luiz Capitulino4d76d2b2009-08-28 15:27:09 -03003675 typestr = key_get_info(typestr, &key);
3676 if (!typestr)
bellard9307c4c2004-04-04 12:57:25 +00003677 break;
Luiz Capitulino4d76d2b2009-08-28 15:27:09 -03003678 c = *typestr;
bellard9307c4c2004-04-04 12:57:25 +00003679 typestr++;
3680 switch(c) {
3681 case 'F':
bellard81d09122004-07-14 17:21:37 +00003682 case 'B':
bellard9307c4c2004-04-04 12:57:25 +00003683 case 's':
3684 {
3685 int ret;
ths3b46e622007-09-17 08:09:54 +00003686
blueswir1cd390082008-11-16 13:53:32 +00003687 while (qemu_isspace(*p))
bellard9307c4c2004-04-04 12:57:25 +00003688 p++;
3689 if (*typestr == '?') {
3690 typestr++;
3691 if (*p == '\0') {
3692 /* no optional string: NULL argument */
Luiz Capitulino53773582009-08-28 15:27:25 -03003693 break;
bellard9307c4c2004-04-04 12:57:25 +00003694 }
3695 }
3696 ret = get_str(buf, sizeof(buf), &p);
3697 if (ret < 0) {
bellard81d09122004-07-14 17:21:37 +00003698 switch(c) {
3699 case 'F':
aliguori376253e2009-03-05 23:01:23 +00003700 monitor_printf(mon, "%s: filename expected\n",
3701 cmdname);
bellard81d09122004-07-14 17:21:37 +00003702 break;
3703 case 'B':
aliguori376253e2009-03-05 23:01:23 +00003704 monitor_printf(mon, "%s: block device name expected\n",
3705 cmdname);
bellard81d09122004-07-14 17:21:37 +00003706 break;
3707 default:
aliguori376253e2009-03-05 23:01:23 +00003708 monitor_printf(mon, "%s: string expected\n", cmdname);
bellard81d09122004-07-14 17:21:37 +00003709 break;
3710 }
bellard9307c4c2004-04-04 12:57:25 +00003711 goto fail;
3712 }
Luiz Capitulino53773582009-08-28 15:27:25 -03003713 qdict_put(qdict, key, qstring_from_str(buf));
bellard9307c4c2004-04-04 12:57:25 +00003714 }
3715 break;
Markus Armbruster361127d2010-02-10 20:24:35 +01003716 case 'O':
3717 {
3718 QemuOptsList *opts_list;
3719 QemuOpts *opts;
3720
3721 opts_list = qemu_find_opts(key);
3722 if (!opts_list || opts_list->desc->name) {
3723 goto bad_type;
3724 }
3725 while (qemu_isspace(*p)) {
3726 p++;
3727 }
3728 if (!*p)
3729 break;
3730 if (get_str(buf, sizeof(buf), &p) < 0) {
3731 goto fail;
3732 }
3733 opts = qemu_opts_parse(opts_list, buf, 1);
3734 if (!opts) {
3735 goto fail;
3736 }
3737 qemu_opts_to_qdict(opts, qdict);
3738 qemu_opts_del(opts);
3739 }
3740 break;
bellard9307c4c2004-04-04 12:57:25 +00003741 case '/':
3742 {
3743 int count, format, size;
ths3b46e622007-09-17 08:09:54 +00003744
blueswir1cd390082008-11-16 13:53:32 +00003745 while (qemu_isspace(*p))
bellard9307c4c2004-04-04 12:57:25 +00003746 p++;
3747 if (*p == '/') {
3748 /* format found */
3749 p++;
3750 count = 1;
blueswir1cd390082008-11-16 13:53:32 +00003751 if (qemu_isdigit(*p)) {
bellard9307c4c2004-04-04 12:57:25 +00003752 count = 0;
blueswir1cd390082008-11-16 13:53:32 +00003753 while (qemu_isdigit(*p)) {
bellard9307c4c2004-04-04 12:57:25 +00003754 count = count * 10 + (*p - '0');
3755 p++;
3756 }
3757 }
3758 size = -1;
3759 format = -1;
3760 for(;;) {
3761 switch(*p) {
3762 case 'o':
3763 case 'd':
3764 case 'u':
3765 case 'x':
3766 case 'i':
3767 case 'c':
3768 format = *p++;
3769 break;
3770 case 'b':
3771 size = 1;
3772 p++;
3773 break;
3774 case 'h':
3775 size = 2;
3776 p++;
3777 break;
3778 case 'w':
3779 size = 4;
3780 p++;
3781 break;
3782 case 'g':
3783 case 'L':
3784 size = 8;
3785 p++;
3786 break;
3787 default:
3788 goto next;
3789 }
3790 }
3791 next:
blueswir1cd390082008-11-16 13:53:32 +00003792 if (*p != '\0' && !qemu_isspace(*p)) {
aliguori376253e2009-03-05 23:01:23 +00003793 monitor_printf(mon, "invalid char in format: '%c'\n",
3794 *p);
bellard9307c4c2004-04-04 12:57:25 +00003795 goto fail;
3796 }
bellard9307c4c2004-04-04 12:57:25 +00003797 if (format < 0)
3798 format = default_fmt_format;
bellard4c27ba22004-04-25 18:05:08 +00003799 if (format != 'i') {
3800 /* for 'i', not specifying a size gives -1 as size */
3801 if (size < 0)
3802 size = default_fmt_size;
aurel32e90f0092008-10-01 21:45:51 +00003803 default_fmt_size = size;
bellard4c27ba22004-04-25 18:05:08 +00003804 }
bellard9307c4c2004-04-04 12:57:25 +00003805 default_fmt_format = format;
3806 } else {
3807 count = 1;
3808 format = default_fmt_format;
bellard4c27ba22004-04-25 18:05:08 +00003809 if (format != 'i') {
3810 size = default_fmt_size;
3811 } else {
3812 size = -1;
3813 }
bellard9307c4c2004-04-04 12:57:25 +00003814 }
Luiz Capitulinof7188bb2009-08-28 15:27:10 -03003815 qdict_put(qdict, "count", qint_from_int(count));
3816 qdict_put(qdict, "format", qint_from_int(format));
3817 qdict_put(qdict, "size", qint_from_int(size));
bellard9307c4c2004-04-04 12:57:25 +00003818 }
3819 break;
3820 case 'i':
bellard92a31b12005-02-10 22:00:52 +00003821 case 'l':
Luiz Capitulinob6e098d2009-12-18 13:25:04 -02003822 case 'M':
bellard9307c4c2004-04-04 12:57:25 +00003823 {
blueswir1c2efc952007-09-25 17:28:42 +00003824 int64_t val;
blueswir17743e582007-09-24 18:39:04 +00003825
blueswir1cd390082008-11-16 13:53:32 +00003826 while (qemu_isspace(*p))
bellard9307c4c2004-04-04 12:57:25 +00003827 p++;
bellard34405572004-06-08 00:55:58 +00003828 if (*typestr == '?' || *typestr == '.') {
bellard34405572004-06-08 00:55:58 +00003829 if (*typestr == '?') {
Luiz Capitulino53773582009-08-28 15:27:25 -03003830 if (*p == '\0') {
3831 typestr++;
3832 break;
3833 }
bellard34405572004-06-08 00:55:58 +00003834 } else {
3835 if (*p == '.') {
3836 p++;
blueswir1cd390082008-11-16 13:53:32 +00003837 while (qemu_isspace(*p))
bellard34405572004-06-08 00:55:58 +00003838 p++;
bellard34405572004-06-08 00:55:58 +00003839 } else {
Luiz Capitulino53773582009-08-28 15:27:25 -03003840 typestr++;
3841 break;
bellard34405572004-06-08 00:55:58 +00003842 }
3843 }
bellard13224a82006-07-14 22:03:35 +00003844 typestr++;
bellard9307c4c2004-04-04 12:57:25 +00003845 }
aliguori376253e2009-03-05 23:01:23 +00003846 if (get_expr(mon, &val, &p))
bellard9307c4c2004-04-04 12:57:25 +00003847 goto fail;
Luiz Capitulino675ebef2009-08-28 15:27:26 -03003848 /* Check if 'i' is greater than 32-bit */
3849 if ((c == 'i') && ((val >> 32) & 0xffffffff)) {
3850 monitor_printf(mon, "\'%s\' has failed: ", cmdname);
3851 monitor_printf(mon, "integer is for 32-bit values\n");
3852 goto fail;
Luiz Capitulinob6e098d2009-12-18 13:25:04 -02003853 } else if (c == 'M') {
Luiz Capitulino91162842012-04-26 17:34:30 -03003854 if (val < 0) {
3855 monitor_printf(mon, "enter a positive value\n");
3856 goto fail;
3857 }
Luiz Capitulinob6e098d2009-12-18 13:25:04 -02003858 val <<= 20;
Luiz Capitulino675ebef2009-08-28 15:27:26 -03003859 }
Luiz Capitulino53773582009-08-28 15:27:25 -03003860 qdict_put(qdict, key, qint_from_int(val));
bellard9307c4c2004-04-04 12:57:25 +00003861 }
3862 break;
Jes Sorensendbc0c672010-10-21 17:15:47 +02003863 case 'o':
3864 {
Jes Sorensen70b4f4b2011-01-05 11:41:02 +01003865 int64_t val;
Jes Sorensendbc0c672010-10-21 17:15:47 +02003866 char *end;
3867
3868 while (qemu_isspace(*p)) {
3869 p++;
3870 }
3871 if (*typestr == '?') {
3872 typestr++;
3873 if (*p == '\0') {
3874 break;
3875 }
3876 }
3877 val = strtosz(p, &end);
3878 if (val < 0) {
3879 monitor_printf(mon, "invalid size\n");
3880 goto fail;
3881 }
3882 qdict_put(qdict, key, qint_from_int(val));
3883 p = end;
3884 }
3885 break;
Markus Armbrusterfccfb11e2010-01-25 14:23:06 +01003886 case 'T':
Markus Armbruster3350a4d2010-01-25 14:23:03 +01003887 {
3888 double val;
3889
3890 while (qemu_isspace(*p))
3891 p++;
3892 if (*typestr == '?') {
3893 typestr++;
3894 if (*p == '\0') {
3895 break;
3896 }
3897 }
3898 if (get_double(mon, &val, &p) < 0) {
3899 goto fail;
3900 }
Jes Sorensen07de3e62010-10-21 17:15:49 +02003901 if (p[0] && p[1] == 's') {
Markus Armbrusterfccfb11e2010-01-25 14:23:06 +01003902 switch (*p) {
3903 case 'm':
3904 val /= 1e3; p += 2; break;
3905 case 'u':
3906 val /= 1e6; p += 2; break;
3907 case 'n':
3908 val /= 1e9; p += 2; break;
3909 }
3910 }
Markus Armbruster3350a4d2010-01-25 14:23:03 +01003911 if (*p && !qemu_isspace(*p)) {
3912 monitor_printf(mon, "Unknown unit suffix\n");
3913 goto fail;
3914 }
3915 qdict_put(qdict, key, qfloat_from_double(val));
3916 }
3917 break;
Markus Armbruster942cd1f2010-03-26 09:07:09 +01003918 case 'b':
3919 {
3920 const char *beg;
3921 int val;
3922
3923 while (qemu_isspace(*p)) {
3924 p++;
3925 }
3926 beg = p;
3927 while (qemu_isgraph(*p)) {
3928 p++;
3929 }
3930 if (p - beg == 2 && !memcmp(beg, "on", p - beg)) {
3931 val = 1;
3932 } else if (p - beg == 3 && !memcmp(beg, "off", p - beg)) {
3933 val = 0;
3934 } else {
3935 monitor_printf(mon, "Expected 'on' or 'off'\n");
3936 goto fail;
3937 }
3938 qdict_put(qdict, key, qbool_from_int(val));
3939 }
3940 break;
bellard9307c4c2004-04-04 12:57:25 +00003941 case '-':
3942 {
lirans@il.ibm.comfbc3d962009-11-02 15:41:13 +02003943 const char *tmp = p;
Luiz Capitulinoeb159d12010-05-28 15:25:24 -03003944 int skip_key = 0;
bellard9307c4c2004-04-04 12:57:25 +00003945 /* option */
ths3b46e622007-09-17 08:09:54 +00003946
bellard9307c4c2004-04-04 12:57:25 +00003947 c = *typestr++;
3948 if (c == '\0')
3949 goto bad_type;
blueswir1cd390082008-11-16 13:53:32 +00003950 while (qemu_isspace(*p))
bellard9307c4c2004-04-04 12:57:25 +00003951 p++;
bellard9307c4c2004-04-04 12:57:25 +00003952 if (*p == '-') {
3953 p++;
lirans@il.ibm.comfbc3d962009-11-02 15:41:13 +02003954 if(c != *p) {
3955 if(!is_valid_option(p, typestr)) {
3956
3957 monitor_printf(mon, "%s: unsupported option -%c\n",
3958 cmdname, *p);
3959 goto fail;
3960 } else {
3961 skip_key = 1;
3962 }
bellard9307c4c2004-04-04 12:57:25 +00003963 }
lirans@il.ibm.comfbc3d962009-11-02 15:41:13 +02003964 if(skip_key) {
3965 p = tmp;
3966 } else {
Luiz Capitulinoeb159d12010-05-28 15:25:24 -03003967 /* has option */
lirans@il.ibm.comfbc3d962009-11-02 15:41:13 +02003968 p++;
Luiz Capitulinoeb159d12010-05-28 15:25:24 -03003969 qdict_put(qdict, key, qbool_from_int(1));
lirans@il.ibm.comfbc3d962009-11-02 15:41:13 +02003970 }
bellard9307c4c2004-04-04 12:57:25 +00003971 }
bellard9307c4c2004-04-04 12:57:25 +00003972 }
3973 break;
Wenchao Xia129be002013-08-27 20:38:26 +08003974 case 'S':
3975 {
3976 /* package all remaining string */
3977 int len;
3978
3979 while (qemu_isspace(*p)) {
3980 p++;
3981 }
3982 if (*typestr == '?') {
3983 typestr++;
3984 if (*p == '\0') {
3985 /* no remaining string: NULL argument */
3986 break;
3987 }
3988 }
3989 len = strlen(p);
3990 if (len <= 0) {
3991 monitor_printf(mon, "%s: string expected\n",
3992 cmdname);
3993 break;
3994 }
3995 qdict_put(qdict, key, qstring_from_str(p));
3996 p += len;
3997 }
3998 break;
bellard9307c4c2004-04-04 12:57:25 +00003999 default:
4000 bad_type:
aliguori376253e2009-03-05 23:01:23 +00004001 monitor_printf(mon, "%s: unknown type '%c'\n", cmdname, c);
bellard9307c4c2004-04-04 12:57:25 +00004002 goto fail;
4003 }
Anthony Liguori7267c092011-08-20 22:09:37 -05004004 g_free(key);
Luiz Capitulino4d76d2b2009-08-28 15:27:09 -03004005 key = NULL;
bellard9307c4c2004-04-04 12:57:25 +00004006 }
4007 /* check that all arguments were parsed */
blueswir1cd390082008-11-16 13:53:32 +00004008 while (qemu_isspace(*p))
bellard9307c4c2004-04-04 12:57:25 +00004009 p++;
4010 if (*p != '\0') {
aliguori376253e2009-03-05 23:01:23 +00004011 monitor_printf(mon, "%s: extraneous characters at the end of line\n",
4012 cmdname);
bellard9307c4c2004-04-04 12:57:25 +00004013 goto fail;
4014 }
4015
Luiz Capitulino55f81d92009-08-28 15:27:22 -03004016 return cmd;
Gerd Hoffmannac7531e2009-08-14 10:36:06 +02004017
Luiz Capitulino55f81d92009-08-28 15:27:22 -03004018fail:
Anthony Liguori7267c092011-08-20 22:09:37 -05004019 g_free(key);
Luiz Capitulino55f81d92009-08-28 15:27:22 -03004020 return NULL;
4021}
4022
Markus Armbrusterd6f46832010-02-17 10:52:26 +01004023void monitor_set_error(Monitor *mon, QError *qerror)
4024{
4025 /* report only the first error */
4026 if (!mon->error) {
4027 mon->error = qerror;
4028 } else {
Markus Armbrusterd6f46832010-02-17 10:52:26 +01004029 QDECREF(qerror);
4030 }
4031}
4032
Luiz Capitulinof3c157c2009-11-26 22:58:55 -02004033static void handle_user_command(Monitor *mon, const char *cmdline)
Luiz Capitulino55f81d92009-08-28 15:27:22 -03004034{
Luiz Capitulino55f81d92009-08-28 15:27:22 -03004035 QDict *qdict;
Anthony Liguoric227f092009-10-01 16:12:16 -05004036 const mon_cmd_t *cmd;
Luiz Capitulino55f81d92009-08-28 15:27:22 -03004037
4038 qdict = qdict_new();
4039
Wenchao Xia77172392013-08-27 20:38:20 +08004040 cmd = monitor_parse_command(mon, cmdline, 0, mon->cmd_table, qdict);
Markus Armbruster8a4f5012015-03-05 18:50:05 +01004041 if (cmd) {
Luiz Capitulinoaf4ce882009-10-07 13:41:52 -03004042 cmd->mhandler.cmd(mon, qdict);
Luiz Capitulino55f81d92009-08-28 15:27:22 -03004043 }
4044
Luiz Capitulinof7188bb2009-08-28 15:27:10 -03004045 QDECREF(qdict);
bellard9dc39cb2004-03-14 21:38:27 +00004046}
4047
Wenchao Xiacd5c6bb2013-08-27 20:38:13 +08004048static void cmd_completion(Monitor *mon, const char *name, const char *list)
bellard81d09122004-07-14 17:21:37 +00004049{
4050 const char *p, *pstart;
4051 char cmd[128];
4052 int len;
4053
4054 p = list;
4055 for(;;) {
4056 pstart = p;
4057 p = strchr(p, '|');
4058 if (!p)
4059 p = pstart + strlen(pstart);
4060 len = p - pstart;
4061 if (len > sizeof(cmd) - 2)
4062 len = sizeof(cmd) - 2;
4063 memcpy(cmd, pstart, len);
4064 cmd[len] = '\0';
4065 if (name[0] == '\0' || !strncmp(name, cmd, strlen(name))) {
Wenchao Xiacd5c6bb2013-08-27 20:38:13 +08004066 readline_add_completion(mon->rs, cmd);
bellard81d09122004-07-14 17:21:37 +00004067 }
4068 if (*p == '\0')
4069 break;
4070 p++;
4071 }
4072}
4073
Wenchao Xiacb8f68b2013-08-27 20:38:14 +08004074static void file_completion(Monitor *mon, const char *input)
bellard81d09122004-07-14 17:21:37 +00004075{
4076 DIR *ffs;
4077 struct dirent *d;
4078 char path[1024];
4079 char file[1024], file_prefix[1024];
4080 int input_path_len;
4081 const char *p;
4082
ths5fafdf22007-09-16 21:08:06 +00004083 p = strrchr(input, '/');
bellard81d09122004-07-14 17:21:37 +00004084 if (!p) {
4085 input_path_len = 0;
4086 pstrcpy(file_prefix, sizeof(file_prefix), input);
blueswir1363a37d2008-08-21 17:58:08 +00004087 pstrcpy(path, sizeof(path), ".");
bellard81d09122004-07-14 17:21:37 +00004088 } else {
4089 input_path_len = p - input + 1;
4090 memcpy(path, input, input_path_len);
4091 if (input_path_len > sizeof(path) - 1)
4092 input_path_len = sizeof(path) - 1;
4093 path[input_path_len] = '\0';
4094 pstrcpy(file_prefix, sizeof(file_prefix), p + 1);
4095 }
4096#ifdef DEBUG_COMPLETION
Wenchao Xiacb8f68b2013-08-27 20:38:14 +08004097 monitor_printf(mon, "input='%s' path='%s' prefix='%s'\n",
aliguori376253e2009-03-05 23:01:23 +00004098 input, path, file_prefix);
bellard81d09122004-07-14 17:21:37 +00004099#endif
4100 ffs = opendir(path);
4101 if (!ffs)
4102 return;
4103 for(;;) {
4104 struct stat sb;
4105 d = readdir(ffs);
4106 if (!d)
4107 break;
Kusanagi Kouichi46c7fc12010-10-20 18:00:01 +09004108
4109 if (strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0) {
4110 continue;
4111 }
4112
bellard81d09122004-07-14 17:21:37 +00004113 if (strstart(d->d_name, file_prefix, NULL)) {
4114 memcpy(file, input, input_path_len);
blueswir1363a37d2008-08-21 17:58:08 +00004115 if (input_path_len < sizeof(file))
4116 pstrcpy(file + input_path_len, sizeof(file) - input_path_len,
4117 d->d_name);
bellard81d09122004-07-14 17:21:37 +00004118 /* stat the file to find out if it's a directory.
4119 * In that case add a slash to speed up typing long paths
4120 */
Markus Armbrusterc951d9a2011-11-16 15:43:47 +01004121 if (stat(file, &sb) == 0 && S_ISDIR(sb.st_mode)) {
blueswir1363a37d2008-08-21 17:58:08 +00004122 pstrcat(file, sizeof(file), "/");
Markus Armbrusterc951d9a2011-11-16 15:43:47 +01004123 }
Wenchao Xiacb8f68b2013-08-27 20:38:14 +08004124 readline_add_completion(mon->rs, file);
bellard81d09122004-07-14 17:21:37 +00004125 }
4126 }
4127 closedir(ffs);
4128}
4129
Luiz Capitulino4d76d2b2009-08-28 15:27:09 -03004130static const char *next_arg_type(const char *typestr)
4131{
4132 const char *p = strchr(typestr, ':');
4133 return (p != NULL ? ++p : typestr);
4134}
4135
Hani Benhabiles40d19392014-05-07 23:41:30 +01004136static void add_completion_option(ReadLineState *rs, const char *str,
4137 const char *option)
4138{
4139 if (!str || !option) {
4140 return;
4141 }
4142 if (!strncmp(option, str, strlen(str))) {
4143 readline_add_completion(rs, option);
4144 }
4145}
4146
Hani Benhabiles13e315d2014-05-07 23:41:29 +01004147void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str)
4148{
4149 size_t len;
4150 ChardevBackendInfoList *list, *start;
4151
4152 if (nb_args != 2) {
4153 return;
4154 }
4155 len = strlen(str);
4156 readline_set_completion_index(rs, len);
4157
4158 start = list = qmp_query_chardev_backends(NULL);
4159 while (list) {
4160 const char *chr_name = list->value->name;
4161
4162 if (!strncmp(chr_name, str, len)) {
4163 readline_add_completion(rs, chr_name);
4164 }
4165 list = list->next;
4166 }
4167 qapi_free_ChardevBackendInfoList(start);
4168}
4169
Hani Benhabilesb162b492014-05-07 23:41:31 +01004170void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str)
4171{
4172 size_t len;
4173 int i;
4174
4175 if (nb_args != 2) {
4176 return;
4177 }
4178 len = strlen(str);
4179 readline_set_completion_index(rs, len);
4180 for (i = 0; NetClientOptionsKind_lookup[i]; i++) {
4181 add_completion_option(rs, str, NetClientOptionsKind_lookup[i]);
4182 }
4183}
4184
Hani Benhabiles2da1b3a2014-04-13 16:25:07 +01004185void device_add_completion(ReadLineState *rs, int nb_args, const char *str)
Hani Benhabiles992d3e62014-02-06 23:30:11 +01004186{
4187 GSList *list, *elt;
4188 size_t len;
4189
Hani Benhabiles2da1b3a2014-04-13 16:25:07 +01004190 if (nb_args != 2) {
4191 return;
4192 }
4193
Hani Benhabiles992d3e62014-02-06 23:30:11 +01004194 len = strlen(str);
4195 readline_set_completion_index(rs, len);
4196 list = elt = object_class_get_list(TYPE_DEVICE, false);
4197 while (elt) {
4198 const char *name;
4199 DeviceClass *dc = OBJECT_CLASS_CHECK(DeviceClass, elt->data,
4200 TYPE_DEVICE);
4201 name = object_class_get_name(OBJECT_CLASS(dc));
Hani Benhabiles2da1b3a2014-04-13 16:25:07 +01004202
4203 if (!dc->cannot_instantiate_with_device_add_yet
4204 && !strncmp(name, str, len)) {
Hani Benhabiles992d3e62014-02-06 23:30:11 +01004205 readline_add_completion(rs, name);
4206 }
4207 elt = elt->next;
4208 }
4209 g_slist_free(list);
4210}
4211
Hani Benhabilesbfa40f72014-04-13 16:25:06 +01004212void object_add_completion(ReadLineState *rs, int nb_args, const char *str)
Hani Benhabiles1094fd32014-02-06 23:30:13 +01004213{
4214 GSList *list, *elt;
4215 size_t len;
4216
Hani Benhabilesbfa40f72014-04-13 16:25:06 +01004217 if (nb_args != 2) {
4218 return;
4219 }
4220
Hani Benhabiles1094fd32014-02-06 23:30:13 +01004221 len = strlen(str);
4222 readline_set_completion_index(rs, len);
4223 list = elt = object_class_get_list(TYPE_USER_CREATABLE, false);
4224 while (elt) {
4225 const char *name;
4226
4227 name = object_class_get_name(OBJECT_CLASS(elt->data));
4228 if (!strncmp(name, str, len) && strcmp(name, TYPE_USER_CREATABLE)) {
4229 readline_add_completion(rs, name);
4230 }
4231 elt = elt->next;
4232 }
4233 g_slist_free(list);
4234}
4235
Zhu Guihua6a1fa9f2014-10-21 19:46:05 +08004236static void peripheral_device_del_completion(ReadLineState *rs,
4237 const char *str, size_t len)
4238{
Marcel Apfelbaum4cae4d52014-11-26 13:50:01 +02004239 Object *peripheral = container_get(qdev_get_machine(), "/peripheral");
4240 GSList *list, *item;
Zhu Guihua6a1fa9f2014-10-21 19:46:05 +08004241
Marcel Apfelbaum4cae4d52014-11-26 13:50:01 +02004242 list = qdev_build_hotpluggable_device_list(peripheral);
4243 if (!list) {
Zhu Guihua6a1fa9f2014-10-21 19:46:05 +08004244 return;
4245 }
4246
Zhu Guihua6a1fa9f2014-10-21 19:46:05 +08004247 for (item = list; item; item = g_slist_next(item)) {
4248 DeviceState *dev = item->data;
4249
4250 if (dev->id && !strncmp(str, dev->id, len)) {
4251 readline_add_completion(rs, dev->id);
4252 }
4253 }
4254
4255 g_slist_free(list);
4256}
4257
Hani Benhabiles6297d9a2014-05-07 23:41:28 +01004258void chardev_remove_completion(ReadLineState *rs, int nb_args, const char *str)
4259{
4260 size_t len;
4261 ChardevInfoList *list, *start;
4262
4263 if (nb_args != 2) {
4264 return;
4265 }
4266 len = strlen(str);
4267 readline_set_completion_index(rs, len);
4268
4269 start = list = qmp_query_chardev(NULL);
4270 while (list) {
4271 ChardevInfo *chr = list->value;
4272
4273 if (!strncmp(chr->label, str, len)) {
4274 readline_add_completion(rs, chr->label);
4275 }
4276 list = list->next;
4277 }
4278 qapi_free_ChardevInfoList(start);
4279}
4280
Hani Benhabiles8e597772014-05-27 23:39:30 +01004281static void ringbuf_completion(ReadLineState *rs, const char *str)
4282{
4283 size_t len;
4284 ChardevInfoList *list, *start;
4285
4286 len = strlen(str);
4287 readline_set_completion_index(rs, len);
4288
4289 start = list = qmp_query_chardev(NULL);
4290 while (list) {
4291 ChardevInfo *chr_info = list->value;
4292
4293 if (!strncmp(chr_info->label, str, len)) {
4294 CharDriverState *chr = qemu_chr_find(chr_info->label);
4295 if (chr && chr_is_ringbuf(chr)) {
4296 readline_add_completion(rs, chr_info->label);
4297 }
4298 }
4299 list = list->next;
4300 }
4301 qapi_free_ChardevInfoList(start);
4302}
4303
Hani Benhabiles8e597772014-05-27 23:39:30 +01004304void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str)
4305{
4306 if (nb_args != 2) {
4307 return;
4308 }
4309 ringbuf_completion(rs, str);
4310}
4311
Hani Benhabiles2da1b3a2014-04-13 16:25:07 +01004312void device_del_completion(ReadLineState *rs, int nb_args, const char *str)
4313{
4314 size_t len;
4315
4316 if (nb_args != 2) {
4317 return;
4318 }
4319
4320 len = strlen(str);
4321 readline_set_completion_index(rs, len);
Zhu Guihua6a1fa9f2014-10-21 19:46:05 +08004322 peripheral_device_del_completion(rs, str, len);
Hani Benhabiles2da1b3a2014-04-13 16:25:07 +01004323}
4324
Hani Benhabilesbfa40f72014-04-13 16:25:06 +01004325void object_del_completion(ReadLineState *rs, int nb_args, const char *str)
Hani Benhabilesb48fa072014-02-06 23:30:12 +01004326{
4327 ObjectPropertyInfoList *list, *start;
4328 size_t len;
4329
Hani Benhabilesbfa40f72014-04-13 16:25:06 +01004330 if (nb_args != 2) {
4331 return;
4332 }
Hani Benhabilesb48fa072014-02-06 23:30:12 +01004333 len = strlen(str);
4334 readline_set_completion_index(rs, len);
4335
4336 start = list = qmp_qom_list("/objects", NULL);
4337 while (list) {
4338 ObjectPropertyInfo *info = list->value;
4339
4340 if (!strncmp(info->type, "child<", 5)
4341 && !strncmp(info->name, str, len)) {
4342 readline_add_completion(rs, info->name);
4343 }
4344 list = list->next;
4345 }
4346 qapi_free_ObjectPropertyInfoList(start);
4347}
4348
Hani Benhabiles29136cd2014-05-07 23:41:27 +01004349void sendkey_completion(ReadLineState *rs, int nb_args, const char *str)
4350{
4351 int i;
4352 char *sep;
4353 size_t len;
4354
4355 if (nb_args != 2) {
4356 return;
4357 }
4358 sep = strrchr(str, '-');
4359 if (sep) {
4360 str = sep + 1;
4361 }
4362 len = strlen(str);
4363 readline_set_completion_index(rs, len);
4364 for (i = 0; i < Q_KEY_CODE_MAX; i++) {
4365 if (!strncmp(str, QKeyCode_lookup[i], len)) {
4366 readline_add_completion(rs, QKeyCode_lookup[i]);
4367 }
4368 }
4369}
4370
Hani Benhabiles40d19392014-05-07 23:41:30 +01004371void set_link_completion(ReadLineState *rs, int nb_args, const char *str)
4372{
4373 size_t len;
4374
4375 len = strlen(str);
4376 readline_set_completion_index(rs, len);
4377 if (nb_args == 2) {
Jason Wangeaed4832015-04-23 14:21:38 +08004378 NetClientState *ncs[MAX_QUEUE_NUM];
Hani Benhabiles40d19392014-05-07 23:41:30 +01004379 int count, i;
4380 count = qemu_find_net_clients_except(NULL, ncs,
Jason Wangeaed4832015-04-23 14:21:38 +08004381 NET_CLIENT_OPTIONS_KIND_NONE,
4382 MAX_QUEUE_NUM);
Jason Wangbcfa4d62015-04-23 14:21:39 +08004383 for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
Hani Benhabiles40d19392014-05-07 23:41:30 +01004384 const char *name = ncs[i]->name;
4385 if (!strncmp(str, name, len)) {
4386 readline_add_completion(rs, name);
4387 }
4388 }
4389 } else if (nb_args == 3) {
4390 add_completion_option(rs, str, "on");
4391 add_completion_option(rs, str, "off");
4392 }
4393}
4394
Hani Benhabiles11b389f2014-05-07 23:41:32 +01004395void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str)
4396{
4397 int len, count, i;
Jason Wangeaed4832015-04-23 14:21:38 +08004398 NetClientState *ncs[MAX_QUEUE_NUM];
Hani Benhabiles11b389f2014-05-07 23:41:32 +01004399
4400 if (nb_args != 2) {
4401 return;
4402 }
4403
4404 len = strlen(str);
4405 readline_set_completion_index(rs, len);
4406 count = qemu_find_net_clients_except(NULL, ncs, NET_CLIENT_OPTIONS_KIND_NIC,
Jason Wangeaed4832015-04-23 14:21:38 +08004407 MAX_QUEUE_NUM);
Jason Wangbcfa4d62015-04-23 14:21:39 +08004408 for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
Hani Benhabiles11b389f2014-05-07 23:41:32 +01004409 QemuOpts *opts;
4410 const char *name = ncs[i]->name;
4411 if (strncmp(str, name, len)) {
4412 continue;
4413 }
4414 opts = qemu_opts_find(qemu_find_opts_err("netdev", NULL), name);
4415 if (opts) {
4416 readline_add_completion(rs, name);
4417 }
4418 }
4419}
4420
Hani Benhabilesd0ece342014-05-27 23:39:31 +01004421void watchdog_action_completion(ReadLineState *rs, int nb_args, const char *str)
4422{
Hani Benhabiles4bb08af2014-07-29 23:22:40 +01004423 int i;
4424
Hani Benhabilesd0ece342014-05-27 23:39:31 +01004425 if (nb_args != 2) {
4426 return;
4427 }
4428 readline_set_completion_index(rs, strlen(str));
Hani Benhabiles4bb08af2014-07-29 23:22:40 +01004429 for (i = 0; WatchdogExpirationAction_lookup[i]; i++) {
4430 add_completion_option(rs, str, WatchdogExpirationAction_lookup[i]);
4431 }
Hani Benhabilesd0ece342014-05-27 23:39:31 +01004432}
4433
Hani Benhabilesc68a0402014-05-27 23:39:32 +01004434void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
4435 const char *str)
4436{
4437 size_t len;
4438
4439 len = strlen(str);
4440 readline_set_completion_index(rs, len);
4441 if (nb_args == 2) {
4442 int i;
4443 for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
4444 const char *name = MigrationCapability_lookup[i];
4445 if (!strncmp(str, name, len)) {
4446 readline_add_completion(rs, name);
4447 }
4448 }
4449 } else if (nb_args == 3) {
4450 add_completion_option(rs, str, "on");
4451 add_completion_option(rs, str, "off");
4452 }
4453}
4454
Liang Li50e9a622015-03-23 16:32:29 +08004455void migrate_set_parameter_completion(ReadLineState *rs, int nb_args,
4456 const char *str)
4457{
4458 size_t len;
4459
4460 len = strlen(str);
4461 readline_set_completion_index(rs, len);
4462 if (nb_args == 2) {
4463 int i;
4464 for (i = 0; i < MIGRATION_PARAMETER_MAX; i++) {
4465 const char *name = MigrationParameter_lookup[i];
4466 if (!strncmp(str, name, len)) {
4467 readline_add_completion(rs, name);
4468 }
4469 }
4470 }
4471}
4472
Hani Benhabilese3bb5322014-05-27 23:39:34 +01004473void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str)
4474{
4475 int i;
4476 size_t len;
4477 if (nb_args != 2) {
4478 return;
4479 }
4480 len = strlen(str);
4481 readline_set_completion_index(rs, len);
4482 for (i = 0; host_net_devices[i]; i++) {
4483 if (!strncmp(host_net_devices[i], str, len)) {
4484 readline_add_completion(rs, host_net_devices[i]);
4485 }
4486 }
4487}
4488
Hani Benhabilesddd6b452014-05-27 23:39:36 +01004489void host_net_remove_completion(ReadLineState *rs, int nb_args, const char *str)
4490{
Jason Wangeaed4832015-04-23 14:21:38 +08004491 NetClientState *ncs[MAX_QUEUE_NUM];
Hani Benhabilesddd6b452014-05-27 23:39:36 +01004492 int count, i, len;
4493
4494 len = strlen(str);
4495 readline_set_completion_index(rs, len);
4496 if (nb_args == 2) {
4497 count = qemu_find_net_clients_except(NULL, ncs,
Jason Wangeaed4832015-04-23 14:21:38 +08004498 NET_CLIENT_OPTIONS_KIND_NONE,
4499 MAX_QUEUE_NUM);
Jason Wangbcfa4d62015-04-23 14:21:39 +08004500 for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
Hani Benhabilesddd6b452014-05-27 23:39:36 +01004501 int id;
4502 char name[16];
4503
4504 if (net_hub_id_for_client(ncs[i], &id)) {
4505 continue;
4506 }
4507 snprintf(name, sizeof(name), "%d", id);
4508 if (!strncmp(str, name, len)) {
4509 readline_add_completion(rs, name);
4510 }
4511 }
4512 return;
4513 } else if (nb_args == 3) {
4514 count = qemu_find_net_clients_except(NULL, ncs,
Jason Wangeaed4832015-04-23 14:21:38 +08004515 NET_CLIENT_OPTIONS_KIND_NIC,
4516 MAX_QUEUE_NUM);
Jason Wangbcfa4d62015-04-23 14:21:39 +08004517 for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
Jason Wang2c4681f2015-02-02 15:06:38 +08004518 int id;
Hani Benhabilesddd6b452014-05-27 23:39:36 +01004519 const char *name;
4520
Jason Wang2c4681f2015-02-02 15:06:38 +08004521 if (ncs[i]->info->type == NET_CLIENT_OPTIONS_KIND_HUBPORT ||
4522 net_hub_id_for_client(ncs[i], &id)) {
4523 continue;
4524 }
Hani Benhabilesddd6b452014-05-27 23:39:36 +01004525 name = ncs[i]->name;
4526 if (!strncmp(str, name, len)) {
4527 readline_add_completion(rs, name);
4528 }
4529 }
4530 return;
4531 }
4532}
4533
Hani Benhabilesb21631f2014-05-27 23:39:37 +01004534static void vm_completion(ReadLineState *rs, const char *str)
4535{
4536 size_t len;
4537 BlockDriverState *bs = NULL;
4538
4539 len = strlen(str);
4540 readline_set_completion_index(rs, len);
4541 while ((bs = bdrv_next(bs))) {
4542 SnapshotInfoList *snapshots, *snapshot;
4543
4544 if (!bdrv_can_snapshot(bs)) {
4545 continue;
4546 }
4547 if (bdrv_query_snapshot_info_list(bs, &snapshots, NULL)) {
4548 continue;
4549 }
4550 snapshot = snapshots;
4551 while (snapshot) {
4552 char *completion = snapshot->value->name;
4553 if (!strncmp(str, completion, len)) {
4554 readline_add_completion(rs, completion);
4555 }
4556 completion = snapshot->value->id;
4557 if (!strncmp(str, completion, len)) {
4558 readline_add_completion(rs, completion);
4559 }
4560 snapshot = snapshot->next;
4561 }
4562 qapi_free_SnapshotInfoList(snapshots);
4563 }
4564
4565}
4566
4567void delvm_completion(ReadLineState *rs, int nb_args, const char *str)
4568{
4569 if (nb_args == 2) {
4570 vm_completion(rs, str);
4571 }
4572}
4573
4574void loadvm_completion(ReadLineState *rs, int nb_args, const char *str)
4575{
4576 if (nb_args == 2) {
4577 vm_completion(rs, str);
4578 }
4579}
4580
Wenchao Xiac35b6402013-08-27 20:38:24 +08004581static void monitor_find_completion_by_table(Monitor *mon,
4582 const mon_cmd_t *cmd_table,
4583 char **args,
4584 int nb_args)
bellard81d09122004-07-14 17:21:37 +00004585{
4586 const char *cmdname;
Wenchao Xiac35b6402013-08-27 20:38:24 +08004587 int i;
Markus Armbrusterfea68bb2014-10-07 13:59:10 +02004588 const char *ptype, *str, *name;
Anthony Liguoric227f092009-10-01 16:12:16 -05004589 const mon_cmd_t *cmd;
Markus Armbrusterfea68bb2014-10-07 13:59:10 +02004590 BlockDriverState *bs;
bellard81d09122004-07-14 17:21:37 +00004591
bellard81d09122004-07-14 17:21:37 +00004592 if (nb_args <= 1) {
4593 /* command completion */
4594 if (nb_args == 0)
4595 cmdname = "";
4596 else
4597 cmdname = args[0];
Wenchao Xiad2674b22013-08-27 20:38:16 +08004598 readline_set_completion_index(mon->rs, strlen(cmdname));
Wenchao Xiac35b6402013-08-27 20:38:24 +08004599 for (cmd = cmd_table; cmd->name != NULL; cmd++) {
Wenchao Xiacd5c6bb2013-08-27 20:38:13 +08004600 cmd_completion(mon, cmdname, cmd->name);
bellard81d09122004-07-14 17:21:37 +00004601 }
4602 } else {
4603 /* find the command */
Wenchao Xiac35b6402013-08-27 20:38:24 +08004604 for (cmd = cmd_table; cmd->name != NULL; cmd++) {
Jan Kiszka03a63482010-06-16 00:38:33 +02004605 if (compare_cmd(args[0], cmd->name)) {
4606 break;
4607 }
bellard81d09122004-07-14 17:21:37 +00004608 }
Jan Kiszka03a63482010-06-16 00:38:33 +02004609 if (!cmd->name) {
Wenchao Xiac35b6402013-08-27 20:38:24 +08004610 return;
Jan Kiszka03a63482010-06-16 00:38:33 +02004611 }
4612
Wenchao Xiad903a772013-08-27 20:38:25 +08004613 if (cmd->sub_table) {
4614 /* do the job again */
Stefan Weile7ae7712015-03-08 19:30:01 +01004615 monitor_find_completion_by_table(mon, cmd->sub_table,
4616 &args[1], nb_args - 1);
4617 return;
Wenchao Xiad903a772013-08-27 20:38:25 +08004618 }
Hani Benhabilesbfa40f72014-04-13 16:25:06 +01004619 if (cmd->command_completion) {
Stefan Weile7ae7712015-03-08 19:30:01 +01004620 cmd->command_completion(mon->rs, nb_args, args[nb_args - 1]);
4621 return;
Hani Benhabilesbfa40f72014-04-13 16:25:06 +01004622 }
Wenchao Xiad903a772013-08-27 20:38:25 +08004623
Luiz Capitulino4d76d2b2009-08-28 15:27:09 -03004624 ptype = next_arg_type(cmd->args_type);
bellard81d09122004-07-14 17:21:37 +00004625 for(i = 0; i < nb_args - 2; i++) {
4626 if (*ptype != '\0') {
Luiz Capitulino4d76d2b2009-08-28 15:27:09 -03004627 ptype = next_arg_type(ptype);
bellard81d09122004-07-14 17:21:37 +00004628 while (*ptype == '?')
Luiz Capitulino4d76d2b2009-08-28 15:27:09 -03004629 ptype = next_arg_type(ptype);
bellard81d09122004-07-14 17:21:37 +00004630 }
4631 }
4632 str = args[nb_args - 1];
Kevin Wolf48fe86f2014-11-12 16:24:02 +01004633 while (*ptype == '-' && ptype[1] != '\0') {
Jan Kiszka3b6dbf22010-06-16 00:38:34 +02004634 ptype = next_arg_type(ptype);
Blue Swirl2a1704a2009-08-23 20:10:28 +00004635 }
bellard81d09122004-07-14 17:21:37 +00004636 switch(*ptype) {
4637 case 'F':
4638 /* file completion */
Wenchao Xiad2674b22013-08-27 20:38:16 +08004639 readline_set_completion_index(mon->rs, strlen(str));
Wenchao Xiacb8f68b2013-08-27 20:38:14 +08004640 file_completion(mon, str);
bellard81d09122004-07-14 17:21:37 +00004641 break;
4642 case 'B':
4643 /* block device name completion */
Wenchao Xia599a9262013-08-27 20:38:15 +08004644 readline_set_completion_index(mon->rs, strlen(str));
Markus Armbrusterfea68bb2014-10-07 13:59:10 +02004645 for (bs = bdrv_next(NULL); bs; bs = bdrv_next(bs)) {
4646 name = bdrv_get_device_name(bs);
4647 if (str[0] == '\0' ||
4648 !strncmp(name, str, strlen(str))) {
4649 readline_add_completion(mon->rs, name);
4650 }
4651 }
bellard81d09122004-07-14 17:21:37 +00004652 break;
bellard7fe48482004-10-09 18:08:01 +00004653 case 's':
Wenchao Xia129be002013-08-27 20:38:26 +08004654 case 'S':
Hani Benhabiles29136cd2014-05-07 23:41:27 +01004655 if (!strcmp(cmd->name, "help|?")) {
Wenchao Xia7ca0e062013-08-27 20:38:27 +08004656 monitor_find_completion_by_table(mon, cmd_table,
4657 &args[1], nb_args - 1);
bellard7fe48482004-10-09 18:08:01 +00004658 }
4659 break;
bellard81d09122004-07-14 17:21:37 +00004660 default:
4661 break;
4662 }
4663 }
Wenchao Xiac35b6402013-08-27 20:38:24 +08004664}
4665
Stefan Hajnoczic60bf332013-11-14 11:54:14 +01004666static void monitor_find_completion(void *opaque,
Wenchao Xiac35b6402013-08-27 20:38:24 +08004667 const char *cmdline)
4668{
Stefan Hajnoczic60bf332013-11-14 11:54:14 +01004669 Monitor *mon = opaque;
Wenchao Xiac35b6402013-08-27 20:38:24 +08004670 char *args[MAX_ARGS];
4671 int nb_args, len;
4672
4673 /* 1. parse the cmdline */
4674 if (parse_cmdline(cmdline, &nb_args, args) < 0) {
4675 return;
4676 }
4677#ifdef DEBUG_COMPLETION
Gonglei5fb9b5b2014-08-21 21:03:09 +08004678 {
4679 int i;
4680 for (i = 0; i < nb_args; i++) {
4681 monitor_printf(mon, "arg%d = '%s'\n", i, args[i]);
4682 }
Wenchao Xiac35b6402013-08-27 20:38:24 +08004683 }
4684#endif
4685
4686 /* if the line ends with a space, it means we want to complete the
4687 next arg */
4688 len = strlen(cmdline);
4689 if (len > 0 && qemu_isspace(cmdline[len - 1])) {
4690 if (nb_args >= MAX_ARGS) {
4691 goto cleanup;
4692 }
4693 args[nb_args++] = g_strdup("");
4694 }
4695
4696 /* 2. auto complete according to args */
4697 monitor_find_completion_by_table(mon, mon->cmd_table, args, nb_args);
Jan Kiszka03a63482010-06-16 00:38:33 +02004698
4699cleanup:
Wenchao Xiadcc70cd2013-08-27 20:38:22 +08004700 free_cmdline_args(args, nb_args);
bellard81d09122004-07-14 17:21:37 +00004701}
4702
aliguori731b0362009-03-05 23:01:42 +00004703static int monitor_can_read(void *opaque)
bellard9dc39cb2004-03-14 21:38:27 +00004704{
aliguori731b0362009-03-05 23:01:42 +00004705 Monitor *mon = opaque;
4706
Jan Kiszkac62313b2009-12-04 14:05:29 +01004707 return (mon->suspend_cnt == 0) ? 1 : 0;
bellard9dc39cb2004-03-14 21:38:27 +00004708}
4709
Markus Armbruster40861822015-05-29 10:27:16 +02004710static bool invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd,
4711 Error **errp)
Luiz Capitulino09069b12010-02-04 18:10:06 -02004712{
Eric Blake2d5a8342015-04-15 09:19:23 -06004713 bool is_cap = cmd->mhandler.cmd_new == do_qmp_capabilities;
4714 if (is_cap && qmp_cmd_mode(mon)) {
Markus Armbruster40861822015-05-29 10:27:16 +02004715 error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND,
4716 "Capabilities negotiation is already complete, command "
4717 "'%s' ignored", cmd->name);
Eric Blake2d5a8342015-04-15 09:19:23 -06004718 return true;
4719 }
4720 if (!is_cap && !qmp_cmd_mode(mon)) {
Markus Armbruster40861822015-05-29 10:27:16 +02004721 error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND,
4722 "Expecting capabilities negotiation with "
4723 "'qmp_capabilities' before command '%s'", cmd->name);
Eric Blake2d5a8342015-04-15 09:19:23 -06004724 return true;
4725 }
4726 return false;
Luiz Capitulino09069b12010-02-04 18:10:06 -02004727}
4728
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -03004729/*
Luiz Capitulino4af91932010-06-22 11:44:05 -03004730 * Argument validation rules:
4731 *
4732 * 1. The argument must exist in cmd_args qdict
4733 * 2. The argument type must be the expected one
4734 *
4735 * Special case: If the argument doesn't exist in cmd_args and
4736 * the QMP_ACCEPT_UNKNOWNS flag is set, then the
4737 * checking is skipped for it.
4738 */
Markus Armbruster326283a2015-03-02 18:39:09 +01004739static void check_client_args_type(const QDict *client_args,
4740 const QDict *cmd_args, int flags,
4741 Error **errp)
Luiz Capitulino4af91932010-06-22 11:44:05 -03004742{
4743 const QDictEntry *ent;
4744
4745 for (ent = qdict_first(client_args); ent;ent = qdict_next(client_args,ent)){
4746 QObject *obj;
4747 QString *arg_type;
4748 const QObject *client_arg = qdict_entry_value(ent);
4749 const char *client_arg_name = qdict_entry_key(ent);
4750
4751 obj = qdict_get(cmd_args, client_arg_name);
4752 if (!obj) {
4753 if (flags & QMP_ACCEPT_UNKNOWNS) {
4754 /* handler accepts unknowns */
4755 continue;
4756 }
4757 /* client arg doesn't exist */
Markus Armbruster326283a2015-03-02 18:39:09 +01004758 error_set(errp, QERR_INVALID_PARAMETER, client_arg_name);
4759 return;
Luiz Capitulino4af91932010-06-22 11:44:05 -03004760 }
4761
4762 arg_type = qobject_to_qstring(obj);
4763 assert(arg_type != NULL);
4764
4765 /* check if argument's type is correct */
4766 switch (qstring_get_str(arg_type)[0]) {
4767 case 'F':
4768 case 'B':
4769 case 's':
4770 if (qobject_type(client_arg) != QTYPE_QSTRING) {
Markus Armbruster326283a2015-03-02 18:39:09 +01004771 error_set(errp, QERR_INVALID_PARAMETER_TYPE,
4772 client_arg_name, "string");
4773 return;
Luiz Capitulino4af91932010-06-22 11:44:05 -03004774 }
4775 break;
4776 case 'i':
4777 case 'l':
4778 case 'M':
Jes Sorensendbc0c672010-10-21 17:15:47 +02004779 case 'o':
Luiz Capitulino4af91932010-06-22 11:44:05 -03004780 if (qobject_type(client_arg) != QTYPE_QINT) {
Markus Armbruster326283a2015-03-02 18:39:09 +01004781 error_set(errp, QERR_INVALID_PARAMETER_TYPE,
4782 client_arg_name, "int");
4783 return;
Luiz Capitulino4af91932010-06-22 11:44:05 -03004784 }
4785 break;
Luiz Capitulino4af91932010-06-22 11:44:05 -03004786 case 'T':
4787 if (qobject_type(client_arg) != QTYPE_QINT &&
4788 qobject_type(client_arg) != QTYPE_QFLOAT) {
Markus Armbruster326283a2015-03-02 18:39:09 +01004789 error_set(errp, QERR_INVALID_PARAMETER_TYPE,
4790 client_arg_name, "number");
4791 return;
Luiz Capitulino4af91932010-06-22 11:44:05 -03004792 }
4793 break;
4794 case 'b':
4795 case '-':
4796 if (qobject_type(client_arg) != QTYPE_QBOOL) {
Markus Armbruster326283a2015-03-02 18:39:09 +01004797 error_set(errp, QERR_INVALID_PARAMETER_TYPE,
4798 client_arg_name, "bool");
4799 return;
Luiz Capitulino4af91932010-06-22 11:44:05 -03004800 }
4801 break;
4802 case 'O':
4803 assert(flags & QMP_ACCEPT_UNKNOWNS);
4804 break;
Paolo Bonzinib9f89782012-03-22 12:51:11 +01004805 case 'q':
4806 /* Any QObject can be passed. */
4807 break;
Luiz Capitulino4af91932010-06-22 11:44:05 -03004808 case '/':
4809 case '.':
4810 /*
4811 * These types are not supported by QMP and thus are not
4812 * handled here. Fall through.
4813 */
4814 default:
4815 abort();
4816 }
4817 }
Luiz Capitulino4af91932010-06-22 11:44:05 -03004818}
4819
4820/*
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -03004821 * - Check if the client has passed all mandatory args
4822 * - Set special flags for argument validation
4823 */
Markus Armbruster326283a2015-03-02 18:39:09 +01004824static void check_mandatory_args(const QDict *cmd_args,
4825 const QDict *client_args, int *flags,
4826 Error **errp)
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -03004827{
4828 const QDictEntry *ent;
4829
4830 for (ent = qdict_first(cmd_args); ent; ent = qdict_next(cmd_args, ent)) {
4831 const char *cmd_arg_name = qdict_entry_key(ent);
4832 QString *type = qobject_to_qstring(qdict_entry_value(ent));
4833 assert(type != NULL);
4834
4835 if (qstring_get_str(type)[0] == 'O') {
4836 assert((*flags & QMP_ACCEPT_UNKNOWNS) == 0);
4837 *flags |= QMP_ACCEPT_UNKNOWNS;
4838 } else if (qstring_get_str(type)[0] != '-' &&
4839 qstring_get_str(type)[1] != '?' &&
4840 !qdict_haskey(client_args, cmd_arg_name)) {
Markus Armbruster326283a2015-03-02 18:39:09 +01004841 error_set(errp, QERR_MISSING_PARAMETER, cmd_arg_name);
4842 return;
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -03004843 }
4844 }
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -03004845}
4846
4847static QDict *qdict_from_args_type(const char *args_type)
4848{
4849 int i;
4850 QDict *qdict;
4851 QString *key, *type, *cur_qs;
4852
4853 assert(args_type != NULL);
4854
4855 qdict = qdict_new();
4856
4857 if (args_type == NULL || args_type[0] == '\0') {
4858 /* no args, empty qdict */
4859 goto out;
4860 }
4861
4862 key = qstring_new();
4863 type = qstring_new();
4864
4865 cur_qs = key;
4866
4867 for (i = 0;; i++) {
4868 switch (args_type[i]) {
4869 case ',':
4870 case '\0':
4871 qdict_put(qdict, qstring_get_str(key), type);
4872 QDECREF(key);
4873 if (args_type[i] == '\0') {
4874 goto out;
4875 }
4876 type = qstring_new(); /* qdict has ref */
4877 cur_qs = key = qstring_new();
4878 break;
4879 case ':':
4880 cur_qs = type;
4881 break;
4882 default:
4883 qstring_append_chr(cur_qs, args_type[i]);
4884 break;
4885 }
4886 }
4887
4888out:
4889 return qdict;
4890}
4891
4892/*
4893 * Client argument checking rules:
4894 *
4895 * 1. Client must provide all mandatory arguments
Luiz Capitulino4af91932010-06-22 11:44:05 -03004896 * 2. Each argument provided by the client must be expected
4897 * 3. Each argument provided by the client must have the type expected
4898 * by the command
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -03004899 */
Markus Armbruster326283a2015-03-02 18:39:09 +01004900static void qmp_check_client_args(const mon_cmd_t *cmd, QDict *client_args,
4901 Error **errp)
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -03004902{
Markus Armbruster326283a2015-03-02 18:39:09 +01004903 Error *err = NULL;
4904 int flags;
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -03004905 QDict *cmd_args;
4906
4907 cmd_args = qdict_from_args_type(cmd->args_type);
4908
4909 flags = 0;
Markus Armbruster326283a2015-03-02 18:39:09 +01004910 check_mandatory_args(cmd_args, client_args, &flags, &err);
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -03004911 if (err) {
4912 goto out;
4913 }
4914
Markus Armbruster326283a2015-03-02 18:39:09 +01004915 check_client_args_type(client_args, cmd_args, flags, &err);
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -03004916
4917out:
Markus Armbruster326283a2015-03-02 18:39:09 +01004918 error_propagate(errp, err);
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -03004919 QDECREF(cmd_args);
Luiz Capitulino2dbc8db2010-05-26 16:13:09 -03004920}
4921
Luiz Capitulinoc917c8f2010-05-31 17:28:01 -03004922/*
4923 * Input object checking rules
4924 *
4925 * 1. Input object must be a dict
4926 * 2. The "execute" key must exist
4927 * 3. The "execute" key must be a string
4928 * 4. If the "arguments" key exists, it must be a dict
4929 * 5. If the "id" key exists, it can be anything (ie. json-value)
4930 * 6. Any argument not listed above is considered invalid
4931 */
Markus Armbrusterba0510a2015-03-02 18:41:43 +01004932static QDict *qmp_check_input_obj(QObject *input_obj, Error **errp)
Luiz Capitulinoc917c8f2010-05-31 17:28:01 -03004933{
4934 const QDictEntry *ent;
4935 int has_exec_key = 0;
4936 QDict *input_dict;
4937
4938 if (qobject_type(input_obj) != QTYPE_QDICT) {
Markus Armbrusterba0510a2015-03-02 18:41:43 +01004939 error_set(errp, QERR_QMP_BAD_INPUT_OBJECT, "object");
Luiz Capitulinoc917c8f2010-05-31 17:28:01 -03004940 return NULL;
4941 }
4942
4943 input_dict = qobject_to_qdict(input_obj);
4944
4945 for (ent = qdict_first(input_dict); ent; ent = qdict_next(input_dict, ent)){
4946 const char *arg_name = qdict_entry_key(ent);
4947 const QObject *arg_obj = qdict_entry_value(ent);
4948
4949 if (!strcmp(arg_name, "execute")) {
4950 if (qobject_type(arg_obj) != QTYPE_QSTRING) {
Markus Armbrusterba0510a2015-03-02 18:41:43 +01004951 error_set(errp, QERR_QMP_BAD_INPUT_OBJECT_MEMBER,
4952 "execute", "string");
Luiz Capitulinoc917c8f2010-05-31 17:28:01 -03004953 return NULL;
4954 }
4955 has_exec_key = 1;
4956 } else if (!strcmp(arg_name, "arguments")) {
4957 if (qobject_type(arg_obj) != QTYPE_QDICT) {
Markus Armbrusterba0510a2015-03-02 18:41:43 +01004958 error_set(errp, QERR_QMP_BAD_INPUT_OBJECT_MEMBER,
4959 "arguments", "object");
Luiz Capitulinoc917c8f2010-05-31 17:28:01 -03004960 return NULL;
4961 }
Luiz Capitulinoc917c8f2010-05-31 17:28:01 -03004962 } else {
Markus Armbrusterba0510a2015-03-02 18:41:43 +01004963 error_set(errp, QERR_QMP_EXTRA_MEMBER, arg_name);
Luiz Capitulinoc917c8f2010-05-31 17:28:01 -03004964 return NULL;
4965 }
4966 }
4967
4968 if (!has_exec_key) {
Markus Armbrusterba0510a2015-03-02 18:41:43 +01004969 error_set(errp, QERR_QMP_BAD_INPUT_OBJECT, "execute");
Luiz Capitulinoc917c8f2010-05-31 17:28:01 -03004970 return NULL;
4971 }
4972
4973 return input_dict;
4974}
4975
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02004976static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
4977{
Markus Armbruster326283a2015-03-02 18:39:09 +01004978 Error *local_err = NULL;
Markus Armbruster84add862015-03-05 16:45:15 +01004979 QObject *obj, *data;
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02004980 QDict *input, *args;
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02004981 const mon_cmd_t *cmd;
Luiz Capitulino40e5a012011-10-21 16:15:31 -02004982 const char *cmd_name;
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02004983 Monitor *mon = cur_mon;
4984
Luiz Capitulinoe4940c62010-06-24 17:58:20 -03004985 args = input = NULL;
Markus Armbruster84add862015-03-05 16:45:15 +01004986 data = NULL;
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02004987
4988 obj = json_parser_parse(tokens, NULL);
4989 if (!obj) {
4990 // FIXME: should be triggered in json_parser_parse()
Markus Armbrusterab5b0272010-03-02 18:15:09 +01004991 qerror_report(QERR_JSON_PARSING);
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02004992 goto err_out;
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02004993 }
4994
Markus Armbrusterba0510a2015-03-02 18:41:43 +01004995 input = qmp_check_input_obj(obj, &local_err);
Luiz Capitulinoc917c8f2010-05-31 17:28:01 -03004996 if (!input) {
Markus Armbrusterba0510a2015-03-02 18:41:43 +01004997 qerror_report_err(local_err);
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02004998 qobject_decref(obj);
4999 goto err_out;
5000 }
5001
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02005002 mon->mc->id = qdict_get(input, "id");
5003 qobject_incref(mon->mc->id);
5004
Luiz Capitulino0bbab462010-05-31 17:32:50 -03005005 cmd_name = qdict_get_str(input, "execute");
Stefan Hajnoczi89bd8202011-09-23 08:23:06 +01005006 trace_handle_qmp_command(mon, cmd_name);
Anthony Liguorie3193602011-09-02 12:34:47 -05005007 cmd = qmp_find_cmd(cmd_name);
Eric Blake2d5a8342015-04-15 09:19:23 -06005008 if (!cmd) {
Markus Armbrustera6c90cb2015-01-13 16:16:35 +01005009 qerror_report(ERROR_CLASS_COMMAND_NOT_FOUND,
5010 "The command %s has not been found", cmd_name);
Luiz Capitulinoe4940c62010-06-24 17:58:20 -03005011 goto err_out;
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02005012 }
Markus Armbruster40861822015-05-29 10:27:16 +02005013 if (invalid_qmp_mode(mon, cmd, &local_err)) {
5014 qerror_report_err(local_err);
Eric Blake2d5a8342015-04-15 09:19:23 -06005015 goto err_out;
5016 }
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02005017
5018 obj = qdict_get(input, "arguments");
5019 if (!obj) {
5020 args = qdict_new();
5021 } else {
5022 args = qobject_to_qdict(obj);
5023 QINCREF(args);
5024 }
5025
Markus Armbruster326283a2015-03-02 18:39:09 +01005026 qmp_check_client_args(cmd, args, &local_err);
5027 if (local_err) {
5028 qerror_report_err(local_err);
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02005029 goto err_out;
5030 }
5031
Markus Armbruster84add862015-03-05 16:45:15 +01005032 if (cmd->mhandler.cmd_new(mon, args, &data)) {
5033 /* Command failed... */
5034 if (!monitor_has_error(mon)) {
5035 /* ... without setting an error, so make one up */
5036 qerror_report(QERR_UNDEFINED_ERROR);
5037 }
5038 }
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02005039
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02005040err_out:
Markus Armbruster70ea0c52015-03-06 10:47:08 +01005041 monitor_protocol_emitter(mon, data, mon->error);
Markus Armbruster84add862015-03-05 16:45:15 +01005042 qobject_decref(data);
Markus Armbruster70ea0c52015-03-06 10:47:08 +01005043 QDECREF(mon->error);
5044 mon->error = NULL;
Luiz Capitulinoe4940c62010-06-24 17:58:20 -03005045 QDECREF(input);
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02005046 QDECREF(args);
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02005047}
5048
Luiz Capitulino9b57c022009-11-26 22:58:58 -02005049/**
5050 * monitor_control_read(): Read and handle QMP input
5051 */
5052static void monitor_control_read(void *opaque, const uint8_t *buf, int size)
5053{
5054 Monitor *old_mon = cur_mon;
5055
5056 cur_mon = opaque;
5057
Luiz Capitulino5fa737a2009-11-26 22:59:01 -02005058 json_message_parser_feed(&cur_mon->mc->parser, (const char *) buf, size);
Luiz Capitulino9b57c022009-11-26 22:58:58 -02005059
5060 cur_mon = old_mon;
5061}
5062
aliguori731b0362009-03-05 23:01:42 +00005063static void monitor_read(void *opaque, const uint8_t *buf, int size)
bellard9dc39cb2004-03-14 21:38:27 +00005064{
aliguori731b0362009-03-05 23:01:42 +00005065 Monitor *old_mon = cur_mon;
bellard9dc39cb2004-03-14 21:38:27 +00005066 int i;
aliguori376253e2009-03-05 23:01:23 +00005067
aliguori731b0362009-03-05 23:01:42 +00005068 cur_mon = opaque;
bellard7e2515e2004-08-01 21:52:19 +00005069
aliguoricde76ee2009-03-05 23:01:51 +00005070 if (cur_mon->rs) {
5071 for (i = 0; i < size; i++)
5072 readline_handle_byte(cur_mon->rs, buf[i]);
5073 } else {
5074 if (size == 0 || buf[size - 1] != 0)
5075 monitor_printf(cur_mon, "corrupted command\n");
5076 else
Luiz Capitulinof3c157c2009-11-26 22:58:55 -02005077 handle_user_command(cur_mon, (char *)buf);
aliguoricde76ee2009-03-05 23:01:51 +00005078 }
aliguori731b0362009-03-05 23:01:42 +00005079
5080 cur_mon = old_mon;
5081}
aliguorid8f44602008-10-06 13:52:44 +00005082
Stefan Hajnoczic60bf332013-11-14 11:54:14 +01005083static void monitor_command_cb(void *opaque, const char *cmdline,
5084 void *readline_opaque)
bellard7e2515e2004-08-01 21:52:19 +00005085{
Stefan Hajnoczic60bf332013-11-14 11:54:14 +01005086 Monitor *mon = opaque;
5087
aliguori731b0362009-03-05 23:01:42 +00005088 monitor_suspend(mon);
Luiz Capitulinof3c157c2009-11-26 22:58:55 -02005089 handle_user_command(mon, cmdline);
aliguori731b0362009-03-05 23:01:42 +00005090 monitor_resume(mon);
aliguorid8f44602008-10-06 13:52:44 +00005091}
5092
aliguoricde76ee2009-03-05 23:01:51 +00005093int monitor_suspend(Monitor *mon)
aliguorid8f44602008-10-06 13:52:44 +00005094{
aliguoricde76ee2009-03-05 23:01:51 +00005095 if (!mon->rs)
5096 return -ENOTTY;
aliguori731b0362009-03-05 23:01:42 +00005097 mon->suspend_cnt++;
aliguoricde76ee2009-03-05 23:01:51 +00005098 return 0;
aliguorid8f44602008-10-06 13:52:44 +00005099}
5100
aliguori376253e2009-03-05 23:01:23 +00005101void monitor_resume(Monitor *mon)
aliguorid8f44602008-10-06 13:52:44 +00005102{
aliguoricde76ee2009-03-05 23:01:51 +00005103 if (!mon->rs)
5104 return;
aliguori731b0362009-03-05 23:01:42 +00005105 if (--mon->suspend_cnt == 0)
5106 readline_show_prompt(mon->rs);
bellard7e2515e2004-08-01 21:52:19 +00005107}
5108
Luiz Capitulinoca9567e2010-02-04 18:10:04 -02005109static QObject *get_qmp_greeting(void)
5110{
Luiz Capitulinob9c15f12011-08-26 17:38:13 -03005111 QObject *ver = NULL;
Luiz Capitulinoca9567e2010-02-04 18:10:04 -02005112
Luiz Capitulinob9c15f12011-08-26 17:38:13 -03005113 qmp_marshal_input_query_version(NULL, NULL, &ver);
Luiz Capitulinoca9567e2010-02-04 18:10:04 -02005114 return qobject_from_jsonf("{'QMP':{'version': %p,'capabilities': []}}",ver);
5115}
5116
Luiz Capitulino9b57c022009-11-26 22:58:58 -02005117/**
5118 * monitor_control_event(): Print QMP gretting
5119 */
5120static void monitor_control_event(void *opaque, int event)
5121{
Luiz Capitulino47116d12010-02-08 17:01:30 -02005122 QObject *data;
5123 Monitor *mon = opaque;
Luiz Capitulino9b57c022009-11-26 22:58:58 -02005124
Luiz Capitulino47116d12010-02-08 17:01:30 -02005125 switch (event) {
5126 case CHR_EVENT_OPENED:
Luiz Capitulino4a7e1192010-02-04 18:10:05 -02005127 mon->mc->command_mode = 0;
Luiz Capitulinoca9567e2010-02-04 18:10:04 -02005128 data = get_qmp_greeting();
Luiz Capitulino9b57c022009-11-26 22:58:58 -02005129 monitor_json_emitter(mon, data);
5130 qobject_decref(data);
Corey Bryantefb87c12012-08-14 16:43:48 -04005131 mon_refcount++;
Luiz Capitulino47116d12010-02-08 17:01:30 -02005132 break;
5133 case CHR_EVENT_CLOSED:
5134 json_message_parser_destroy(&mon->mc->parser);
Anthony Liguori58617a72012-08-23 08:03:21 -05005135 json_message_parser_init(&mon->mc->parser, handle_qmp_command);
Corey Bryantefb87c12012-08-14 16:43:48 -04005136 mon_refcount--;
5137 monitor_fdsets_cleanup();
Luiz Capitulino47116d12010-02-08 17:01:30 -02005138 break;
Luiz Capitulino9b57c022009-11-26 22:58:58 -02005139 }
5140}
5141
aliguori731b0362009-03-05 23:01:42 +00005142static void monitor_event(void *opaque, int event)
ths86e94de2007-01-05 22:01:59 +00005143{
aliguori376253e2009-03-05 23:01:23 +00005144 Monitor *mon = opaque;
5145
aliguori2724b182009-03-05 23:01:47 +00005146 switch (event) {
5147 case CHR_EVENT_MUX_IN:
Paolo Bonzini6cff3e82014-06-18 08:43:59 +02005148 qemu_mutex_lock(&mon->out_lock);
Gerd Hoffmanna7aec5d2009-09-10 10:58:54 +02005149 mon->mux_out = 0;
Paolo Bonzini6cff3e82014-06-18 08:43:59 +02005150 qemu_mutex_unlock(&mon->out_lock);
Gerd Hoffmanna7aec5d2009-09-10 10:58:54 +02005151 if (mon->reset_seen) {
5152 readline_restart(mon->rs);
5153 monitor_resume(mon);
5154 monitor_flush(mon);
5155 } else {
5156 mon->suspend_cnt = 0;
5157 }
aliguori2724b182009-03-05 23:01:47 +00005158 break;
ths86e94de2007-01-05 22:01:59 +00005159
aliguori2724b182009-03-05 23:01:47 +00005160 case CHR_EVENT_MUX_OUT:
Gerd Hoffmanna7aec5d2009-09-10 10:58:54 +02005161 if (mon->reset_seen) {
5162 if (mon->suspend_cnt == 0) {
5163 monitor_printf(mon, "\n");
5164 }
5165 monitor_flush(mon);
5166 monitor_suspend(mon);
5167 } else {
5168 mon->suspend_cnt++;
5169 }
Paolo Bonzini6cff3e82014-06-18 08:43:59 +02005170 qemu_mutex_lock(&mon->out_lock);
Gerd Hoffmanna7aec5d2009-09-10 10:58:54 +02005171 mon->mux_out = 1;
Paolo Bonzini6cff3e82014-06-18 08:43:59 +02005172 qemu_mutex_unlock(&mon->out_lock);
aliguori2724b182009-03-05 23:01:47 +00005173 break;
5174
Amit Shahb6b8df52009-10-07 18:31:16 +05305175 case CHR_EVENT_OPENED:
aliguori2724b182009-03-05 23:01:47 +00005176 monitor_printf(mon, "QEMU %s monitor - type 'help' for more "
5177 "information\n", QEMU_VERSION);
Gerd Hoffmanna7aec5d2009-09-10 10:58:54 +02005178 if (!mon->mux_out) {
Stratos Psomadakise5554e22014-09-15 15:34:57 +03005179 readline_restart(mon->rs);
aliguori2724b182009-03-05 23:01:47 +00005180 readline_show_prompt(mon->rs);
Gerd Hoffmanna7aec5d2009-09-10 10:58:54 +02005181 }
5182 mon->reset_seen = 1;
Corey Bryantefb87c12012-08-14 16:43:48 -04005183 mon_refcount++;
5184 break;
5185
5186 case CHR_EVENT_CLOSED:
5187 mon_refcount--;
5188 monitor_fdsets_cleanup();
aliguori2724b182009-03-05 23:01:47 +00005189 break;
5190 }
ths86e94de2007-01-05 22:01:59 +00005191}
5192
Wayne Xia816f8922011-10-12 11:32:41 +08005193static int
5194compare_mon_cmd(const void *a, const void *b)
5195{
5196 return strcmp(((const mon_cmd_t *)a)->name,
5197 ((const mon_cmd_t *)b)->name);
5198}
5199
5200static void sortcmdlist(void)
5201{
5202 int array_num;
5203 int elem_size = sizeof(mon_cmd_t);
5204
5205 array_num = sizeof(mon_cmds)/elem_size-1;
5206 qsort((void *)mon_cmds, array_num, elem_size, compare_mon_cmd);
5207
5208 array_num = sizeof(info_cmds)/elem_size-1;
5209 qsort((void *)info_cmds, array_num, elem_size, compare_mon_cmd);
5210}
5211
aliguori76655d62009-03-06 20:27:37 +00005212
5213/*
5214 * Local variables:
5215 * c-indent-level: 4
5216 * c-basic-offset: 4
5217 * tab-width: 8
5218 * End:
5219 */
5220
Stefan Hajnoczic60bf332013-11-14 11:54:14 +01005221/* These functions just adapt the readline interface in a typesafe way. We
5222 * could cast function pointers but that discards compiler checks.
5223 */
Stefan Weild5d15072014-01-25 18:18:23 +01005224static void GCC_FMT_ATTR(2, 3) monitor_readline_printf(void *opaque,
5225 const char *fmt, ...)
Stefan Hajnoczic60bf332013-11-14 11:54:14 +01005226{
5227 va_list ap;
5228 va_start(ap, fmt);
5229 monitor_vprintf(opaque, fmt, ap);
5230 va_end(ap);
5231}
5232
5233static void monitor_readline_flush(void *opaque)
5234{
5235 monitor_flush(opaque);
5236}
5237
Paolo Bonzinid622cb52014-06-18 08:44:00 +02005238static void __attribute__((constructor)) monitor_lock_init(void)
5239{
5240 qemu_mutex_init(&monitor_lock);
5241}
5242
aliguori731b0362009-03-05 23:01:42 +00005243void monitor_init(CharDriverState *chr, int flags)
bellard9dc39cb2004-03-14 21:38:27 +00005244{
aliguori731b0362009-03-05 23:01:42 +00005245 static int is_first_init = 1;
aliguori87127162009-03-05 23:01:29 +00005246 Monitor *mon;
ths20d8a3e2007-02-18 17:04:49 +00005247
5248 if (is_first_init) {
Wenchao Xia43a14cf2014-06-18 08:43:31 +02005249 monitor_qapi_event_init();
Wenchao Xiad0383172013-08-27 20:38:18 +08005250 sortcmdlist();
ths20d8a3e2007-02-18 17:04:49 +00005251 is_first_init = 0;
5252 }
aliguori87127162009-03-05 23:01:29 +00005253
Wenchao Xiab01fe892013-08-27 20:38:19 +08005254 mon = g_malloc(sizeof(*mon));
5255 monitor_data_init(mon);
ths20d8a3e2007-02-18 17:04:49 +00005256
aliguori87127162009-03-05 23:01:29 +00005257 mon->chr = chr;
aliguori731b0362009-03-05 23:01:42 +00005258 mon->flags = flags;
aliguoricde76ee2009-03-05 23:01:51 +00005259 if (flags & MONITOR_USE_READLINE) {
Stefan Hajnoczic60bf332013-11-14 11:54:14 +01005260 mon->rs = readline_init(monitor_readline_printf,
5261 monitor_readline_flush,
5262 mon,
5263 monitor_find_completion);
aliguoricde76ee2009-03-05 23:01:51 +00005264 monitor_read_command(mon, 0);
5265 }
aliguori87127162009-03-05 23:01:29 +00005266
Luiz Capitulino9b57c022009-11-26 22:58:58 -02005267 if (monitor_ctrl_mode(mon)) {
Anthony Liguori7267c092011-08-20 22:09:37 -05005268 mon->mc = g_malloc0(sizeof(MonitorControl));
Luiz Capitulino9b57c022009-11-26 22:58:58 -02005269 /* Control mode requires special handlers */
5270 qemu_chr_add_handlers(chr, monitor_can_read, monitor_control_read,
5271 monitor_control_event, mon);
Anthony Liguori15f31512011-08-15 11:17:35 -05005272 qemu_chr_fe_set_echo(chr, true);
Anthony Liguori26efaca2012-08-23 13:49:02 -05005273
5274 json_message_parser_init(&mon->mc->parser, handle_qmp_command);
Luiz Capitulino9b57c022009-11-26 22:58:58 -02005275 } else {
5276 qemu_chr_add_handlers(chr, monitor_can_read, monitor_read,
5277 monitor_event, mon);
5278 }
aliguori87127162009-03-05 23:01:29 +00005279
Paolo Bonzinid622cb52014-06-18 08:44:00 +02005280 qemu_mutex_lock(&monitor_lock);
Blue Swirl72cf2d42009-09-12 07:36:22 +00005281 QLIST_INSERT_HEAD(&mon_list, mon, entry);
Paolo Bonzinid622cb52014-06-18 08:44:00 +02005282 qemu_mutex_unlock(&monitor_lock);
5283
Markus Armbruster8631b602010-02-18 11:41:55 +01005284 if (!default_mon || (flags & MONITOR_IS_DEFAULT))
5285 default_mon = mon;
bellard7e2515e2004-08-01 21:52:19 +00005286}
5287
Stefan Hajnoczic60bf332013-11-14 11:54:14 +01005288static void bdrv_password_cb(void *opaque, const char *password,
5289 void *readline_opaque)
bellard7e2515e2004-08-01 21:52:19 +00005290{
Stefan Hajnoczic60bf332013-11-14 11:54:14 +01005291 Monitor *mon = opaque;
5292 BlockDriverState *bs = readline_opaque;
aliguoribb5fc202009-03-05 23:01:15 +00005293 int ret = 0;
Markus Armbruster4d2855a2015-01-29 10:37:00 +01005294 Error *local_err = NULL;
bellard7e2515e2004-08-01 21:52:19 +00005295
Markus Armbruster4d2855a2015-01-29 10:37:00 +01005296 bdrv_add_key(bs, password, &local_err);
5297 if (local_err) {
5298 monitor_printf(mon, "%s\n", error_get_pretty(local_err));
5299 error_free(local_err);
aliguoribb5fc202009-03-05 23:01:15 +00005300 ret = -EPERM;
bellard7e2515e2004-08-01 21:52:19 +00005301 }
aliguori731b0362009-03-05 23:01:42 +00005302 if (mon->password_completion_cb)
5303 mon->password_completion_cb(mon->password_opaque, ret);
aliguoribb5fc202009-03-05 23:01:15 +00005304
aliguori731b0362009-03-05 23:01:42 +00005305 monitor_read_command(mon, 1);
bellard9dc39cb2004-03-14 21:38:27 +00005306}
aliguoric0f4ce72009-03-05 23:01:01 +00005307
Luiz Capitulino0bbc47b2010-02-10 23:50:01 -02005308int monitor_read_bdrv_key_start(Monitor *mon, BlockDriverState *bs,
Markus Armbruster097310b2014-10-07 13:59:15 +02005309 BlockCompletionFunc *completion_cb,
Luiz Capitulino0bbc47b2010-02-10 23:50:01 -02005310 void *opaque)
aliguoric0f4ce72009-03-05 23:01:01 +00005311{
aliguoricde76ee2009-03-05 23:01:51 +00005312 int err;
5313
aliguori376253e2009-03-05 23:01:23 +00005314 monitor_printf(mon, "%s (%s) is encrypted.\n", bdrv_get_device_name(bs),
5315 bdrv_get_encrypted_filename(bs));
aliguoribb5fc202009-03-05 23:01:15 +00005316
aliguori731b0362009-03-05 23:01:42 +00005317 mon->password_completion_cb = completion_cb;
5318 mon->password_opaque = opaque;
aliguoribb5fc202009-03-05 23:01:15 +00005319
aliguoricde76ee2009-03-05 23:01:51 +00005320 err = monitor_read_password(mon, bdrv_password_cb, bs);
5321
5322 if (err && completion_cb)
5323 completion_cb(opaque, err);
Luiz Capitulino0bbc47b2010-02-10 23:50:01 -02005324
5325 return err;
aliguoric0f4ce72009-03-05 23:01:01 +00005326}
Luiz Capitulinoe42e8182011-11-22 17:58:31 -02005327
5328int monitor_read_block_device_key(Monitor *mon, const char *device,
Markus Armbruster097310b2014-10-07 13:59:15 +02005329 BlockCompletionFunc *completion_cb,
Luiz Capitulinoe42e8182011-11-22 17:58:31 -02005330 void *opaque)
5331{
Markus Armbruster9b14e0e2015-03-12 17:26:48 +01005332 Error *err = NULL;
Fam Zheng55606252015-03-02 19:36:46 +08005333 BlockBackend *blk;
Luiz Capitulinoe42e8182011-11-22 17:58:31 -02005334
Fam Zheng55606252015-03-02 19:36:46 +08005335 blk = blk_by_name(device);
5336 if (!blk) {
Luiz Capitulinoe42e8182011-11-22 17:58:31 -02005337 monitor_printf(mon, "Device not found %s\n", device);
5338 return -1;
5339 }
5340
Markus Armbruster9b14e0e2015-03-12 17:26:48 +01005341 bdrv_add_key(blk_bs(blk), NULL, &err);
5342 if (err) {
5343 error_free(err);
5344 return monitor_read_bdrv_key_start(mon, blk_bs(blk), completion_cb, opaque);
5345 }
5346
5347 if (completion_cb) {
5348 completion_cb(opaque, 0);
5349 }
5350 return 0;
Luiz Capitulinoe42e8182011-11-22 17:58:31 -02005351}
Paolo Bonzini4d454572012-11-26 16:03:42 +01005352
5353QemuOptsList qemu_mon_opts = {
5354 .name = "mon",
5355 .implied_opt_name = "chardev",
5356 .head = QTAILQ_HEAD_INITIALIZER(qemu_mon_opts.head),
5357 .desc = {
5358 {
5359 .name = "mode",
5360 .type = QEMU_OPT_STRING,
5361 },{
5362 .name = "chardev",
5363 .type = QEMU_OPT_STRING,
5364 },{
5365 .name = "default",
5366 .type = QEMU_OPT_BOOL,
5367 },{
5368 .name = "pretty",
5369 .type = QEMU_OPT_BOOL,
5370 },
5371 { /* end of list */ }
5372 },
5373};
Marcelo Tosattif2ae8ab2014-06-24 18:55:11 -03005374
5375#ifndef TARGET_I386
5376void qmp_rtc_reset_reinjection(Error **errp)
5377{
5378 error_set(errp, QERR_FEATURE_DISABLED, "rtc-reset-reinjection");
5379}
5380#endif