xref: /qemu/monitor/hmp-target.c (revision 864a3fa4)
1*864a3fa4SMarkus Armbruster /*
2*864a3fa4SMarkus Armbruster  * QEMU monitor, target-dependent part
3*864a3fa4SMarkus Armbruster  *
4*864a3fa4SMarkus Armbruster  * Copyright (c) 2003-2004 Fabrice Bellard
5*864a3fa4SMarkus Armbruster  *
6*864a3fa4SMarkus Armbruster  * Permission is hereby granted, free of charge, to any person obtaining a copy
7*864a3fa4SMarkus Armbruster  * of this software and associated documentation files (the "Software"), to deal
8*864a3fa4SMarkus Armbruster  * in the Software without restriction, including without limitation the rights
9*864a3fa4SMarkus Armbruster  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10*864a3fa4SMarkus Armbruster  * copies of the Software, and to permit persons to whom the Software is
11*864a3fa4SMarkus Armbruster  * furnished to do so, subject to the following conditions:
12*864a3fa4SMarkus Armbruster  *
13*864a3fa4SMarkus Armbruster  * The above copyright notice and this permission notice shall be included in
14*864a3fa4SMarkus Armbruster  * all copies or substantial portions of the Software.
15*864a3fa4SMarkus Armbruster  *
16*864a3fa4SMarkus Armbruster  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*864a3fa4SMarkus Armbruster  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*864a3fa4SMarkus Armbruster  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19*864a3fa4SMarkus Armbruster  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*864a3fa4SMarkus Armbruster  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21*864a3fa4SMarkus Armbruster  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22*864a3fa4SMarkus Armbruster  * THE SOFTWARE.
23*864a3fa4SMarkus Armbruster  */
24*864a3fa4SMarkus Armbruster 
25*864a3fa4SMarkus Armbruster #include "qemu/osdep.h"
26*864a3fa4SMarkus Armbruster #include "monitor-internal.h"
27*864a3fa4SMarkus Armbruster #include "monitor/qdev.h"
28*864a3fa4SMarkus Armbruster #include "net/slirp.h"
29*864a3fa4SMarkus Armbruster #include "sysemu/device_tree.h"
30*864a3fa4SMarkus Armbruster #include "monitor/hmp-target.h"
31*864a3fa4SMarkus Armbruster #include "monitor/hmp.h"
32*864a3fa4SMarkus Armbruster #include "block/block-hmp-cmds.h"
33*864a3fa4SMarkus Armbruster #include "qapi/qapi-commands-control.h"
34*864a3fa4SMarkus Armbruster #include "qapi/qapi-commands-misc.h"
35*864a3fa4SMarkus Armbruster #include "qapi/qapi-commands-machine.h"
36*864a3fa4SMarkus Armbruster #include "qapi/error.h"
37*864a3fa4SMarkus Armbruster #include "qemu/cutils.h"
38*864a3fa4SMarkus Armbruster 
39*864a3fa4SMarkus Armbruster #if defined(TARGET_S390X)
40*864a3fa4SMarkus Armbruster #include "hw/s390x/storage-keys.h"
41*864a3fa4SMarkus Armbruster #include "hw/s390x/storage-attributes.h"
42*864a3fa4SMarkus Armbruster #endif
43*864a3fa4SMarkus Armbruster 
44*864a3fa4SMarkus Armbruster /* Make devices configuration available for use in hmp-commands*.hx templates */
45*864a3fa4SMarkus Armbruster #include CONFIG_DEVICES
46*864a3fa4SMarkus Armbruster 
47*864a3fa4SMarkus Armbruster static HMPCommand hmp_info_cmds[];
48*864a3fa4SMarkus Armbruster 
49*864a3fa4SMarkus Armbruster /**
50*864a3fa4SMarkus Armbruster  * Is @name in the '|' separated list of names @list?
51*864a3fa4SMarkus Armbruster  */
hmp_compare_cmd(const char * name,const char * list)52*864a3fa4SMarkus Armbruster int hmp_compare_cmd(const char *name, const char *list)
53*864a3fa4SMarkus Armbruster {
54*864a3fa4SMarkus Armbruster     const char *p, *pstart;
55*864a3fa4SMarkus Armbruster     int len;
56*864a3fa4SMarkus Armbruster     len = strlen(name);
57*864a3fa4SMarkus Armbruster     p = list;
58*864a3fa4SMarkus Armbruster     for (;;) {
59*864a3fa4SMarkus Armbruster         pstart = p;
60*864a3fa4SMarkus Armbruster         p = qemu_strchrnul(p, '|');
61*864a3fa4SMarkus Armbruster         if ((p - pstart) == len && !memcmp(pstart, name, len)) {
62*864a3fa4SMarkus Armbruster             return 1;
63*864a3fa4SMarkus Armbruster         }
64*864a3fa4SMarkus Armbruster         if (*p == '\0') {
65*864a3fa4SMarkus Armbruster             break;
66*864a3fa4SMarkus Armbruster         }
67*864a3fa4SMarkus Armbruster         p++;
68*864a3fa4SMarkus Armbruster     }
69*864a3fa4SMarkus Armbruster     return 0;
70*864a3fa4SMarkus Armbruster }
71*864a3fa4SMarkus Armbruster 
72*864a3fa4SMarkus Armbruster /* Please update hmp-commands.hx when adding or changing commands */
73*864a3fa4SMarkus Armbruster static HMPCommand hmp_info_cmds[] = {
74*864a3fa4SMarkus Armbruster #include "hmp-commands-info.h"
75*864a3fa4SMarkus Armbruster     { NULL, NULL, },
76*864a3fa4SMarkus Armbruster };
77*864a3fa4SMarkus Armbruster 
78*864a3fa4SMarkus Armbruster /* hmp_cmds and hmp_info_cmds would be sorted at runtime */
79*864a3fa4SMarkus Armbruster HMPCommand hmp_cmds[] = {
80*864a3fa4SMarkus Armbruster #include "hmp-commands.h"
81*864a3fa4SMarkus Armbruster     { NULL, NULL, },
82*864a3fa4SMarkus Armbruster };
83*864a3fa4SMarkus Armbruster 
84*864a3fa4SMarkus Armbruster /*
85*864a3fa4SMarkus Armbruster  * Set @pval to the value in the register identified by @name.
86*864a3fa4SMarkus Armbruster  * return 0 if OK, -1 if not found
87*864a3fa4SMarkus Armbruster  */
get_monitor_def(Monitor * mon,int64_t * pval,const char * name)88*864a3fa4SMarkus Armbruster int get_monitor_def(Monitor *mon, int64_t *pval, const char *name)
89*864a3fa4SMarkus Armbruster {
90*864a3fa4SMarkus Armbruster     const MonitorDef *md = target_monitor_defs();
91*864a3fa4SMarkus Armbruster     CPUState *cs = mon_get_cpu(mon);
92*864a3fa4SMarkus Armbruster     void *ptr;
93*864a3fa4SMarkus Armbruster     uint64_t tmp = 0;
94*864a3fa4SMarkus Armbruster     int ret;
95*864a3fa4SMarkus Armbruster 
96*864a3fa4SMarkus Armbruster     if (cs == NULL || md == NULL) {
97*864a3fa4SMarkus Armbruster         return -1;
98*864a3fa4SMarkus Armbruster     }
99*864a3fa4SMarkus Armbruster 
100*864a3fa4SMarkus Armbruster     for(; md->name != NULL; md++) {
101*864a3fa4SMarkus Armbruster         if (hmp_compare_cmd(name, md->name)) {
102*864a3fa4SMarkus Armbruster             if (md->get_value) {
103*864a3fa4SMarkus Armbruster                 *pval = md->get_value(mon, md, md->offset);
104*864a3fa4SMarkus Armbruster             } else {
105*864a3fa4SMarkus Armbruster                 CPUArchState *env = mon_get_cpu_env(mon);
106*864a3fa4SMarkus Armbruster                 ptr = (uint8_t *)env + md->offset;
107*864a3fa4SMarkus Armbruster                 switch(md->type) {
108*864a3fa4SMarkus Armbruster                 case MD_I32:
109*864a3fa4SMarkus Armbruster                     *pval = *(int32_t *)ptr;
110*864a3fa4SMarkus Armbruster                     break;
111*864a3fa4SMarkus Armbruster                 case MD_TLONG:
112*864a3fa4SMarkus Armbruster                     *pval = *(target_long *)ptr;
113*864a3fa4SMarkus Armbruster                     break;
114*864a3fa4SMarkus Armbruster                 default:
115*864a3fa4SMarkus Armbruster                     *pval = 0;
116*864a3fa4SMarkus Armbruster                     break;
117*864a3fa4SMarkus Armbruster                 }
118*864a3fa4SMarkus Armbruster             }
119*864a3fa4SMarkus Armbruster             return 0;
120*864a3fa4SMarkus Armbruster         }
121*864a3fa4SMarkus Armbruster     }
122*864a3fa4SMarkus Armbruster 
123*864a3fa4SMarkus Armbruster     ret = target_get_monitor_def(cs, name, &tmp);
124*864a3fa4SMarkus Armbruster     if (!ret) {
125*864a3fa4SMarkus Armbruster         *pval = (target_long) tmp;
126*864a3fa4SMarkus Armbruster     }
127*864a3fa4SMarkus Armbruster 
128*864a3fa4SMarkus Armbruster     return ret;
129*864a3fa4SMarkus Armbruster }
130*864a3fa4SMarkus Armbruster 
131*864a3fa4SMarkus Armbruster static int
compare_mon_cmd(const void * a,const void * b)132*864a3fa4SMarkus Armbruster compare_mon_cmd(const void *a, const void *b)
133*864a3fa4SMarkus Armbruster {
134*864a3fa4SMarkus Armbruster     return strcmp(((const HMPCommand *)a)->name,
135*864a3fa4SMarkus Armbruster             ((const HMPCommand *)b)->name);
136*864a3fa4SMarkus Armbruster }
137*864a3fa4SMarkus Armbruster 
sortcmdlist(void)138*864a3fa4SMarkus Armbruster static void __attribute__((__constructor__)) sortcmdlist(void)
139*864a3fa4SMarkus Armbruster {
140*864a3fa4SMarkus Armbruster     qsort(hmp_cmds, ARRAY_SIZE(hmp_cmds) - 1,
141*864a3fa4SMarkus Armbruster           sizeof(*hmp_cmds),
142*864a3fa4SMarkus Armbruster           compare_mon_cmd);
143*864a3fa4SMarkus Armbruster     qsort(hmp_info_cmds, ARRAY_SIZE(hmp_info_cmds) - 1,
144*864a3fa4SMarkus Armbruster           sizeof(*hmp_info_cmds),
145*864a3fa4SMarkus Armbruster           compare_mon_cmd);
146*864a3fa4SMarkus Armbruster }
147*864a3fa4SMarkus Armbruster 
monitor_register_hmp(const char * name,bool info,void (* cmd)(Monitor * mon,const QDict * qdict))148*864a3fa4SMarkus Armbruster void monitor_register_hmp(const char *name, bool info,
149*864a3fa4SMarkus Armbruster                           void (*cmd)(Monitor *mon, const QDict *qdict))
150*864a3fa4SMarkus Armbruster {
151*864a3fa4SMarkus Armbruster     HMPCommand *table = info ? hmp_info_cmds : hmp_cmds;
152*864a3fa4SMarkus Armbruster 
153*864a3fa4SMarkus Armbruster     while (table->name != NULL) {
154*864a3fa4SMarkus Armbruster         if (strcmp(table->name, name) == 0) {
155*864a3fa4SMarkus Armbruster             g_assert(table->cmd == NULL && table->cmd_info_hrt == NULL);
156*864a3fa4SMarkus Armbruster             table->cmd = cmd;
157*864a3fa4SMarkus Armbruster             return;
158*864a3fa4SMarkus Armbruster         }
159*864a3fa4SMarkus Armbruster         table++;
160*864a3fa4SMarkus Armbruster     }
161*864a3fa4SMarkus Armbruster     g_assert_not_reached();
162*864a3fa4SMarkus Armbruster }
163*864a3fa4SMarkus Armbruster 
monitor_register_hmp_info_hrt(const char * name,HumanReadableText * (* handler)(Error ** errp))164*864a3fa4SMarkus Armbruster void monitor_register_hmp_info_hrt(const char *name,
165*864a3fa4SMarkus Armbruster                                    HumanReadableText *(*handler)(Error **errp))
166*864a3fa4SMarkus Armbruster {
167*864a3fa4SMarkus Armbruster     HMPCommand *table = hmp_info_cmds;
168*864a3fa4SMarkus Armbruster 
169*864a3fa4SMarkus Armbruster     while (table->name != NULL) {
170*864a3fa4SMarkus Armbruster         if (strcmp(table->name, name) == 0) {
171*864a3fa4SMarkus Armbruster             g_assert(table->cmd == NULL && table->cmd_info_hrt == NULL);
172*864a3fa4SMarkus Armbruster             table->cmd_info_hrt = handler;
173*864a3fa4SMarkus Armbruster             return;
174*864a3fa4SMarkus Armbruster         }
175*864a3fa4SMarkus Armbruster         table++;
176*864a3fa4SMarkus Armbruster     }
177*864a3fa4SMarkus Armbruster     g_assert_not_reached();
178*864a3fa4SMarkus Armbruster }
179