]>
Commit | Line | Data |
---|---|---|
9dc39cba | 1 | /* |
864a3fa4 | 2 | * QEMU monitor, target-dependent part |
5fafdf24 | 3 | * |
9dc39cba | 4 | * Copyright (c) 2003-2004 Fabrice Bellard |
5fafdf24 | 5 | * |
9dc39cba FB |
6 | * 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 | */ | |
e688df6b | 24 | |
d38ea87a | 25 | #include "qemu/osdep.h" |
5bce308a | 26 | #include "monitor-internal.h" |
b4a42f81 | 27 | #include "monitor/qdev.h" |
68ac40d2 | 28 | #include "net/slirp.h" |
bf353ad5 | 29 | #include "sysemu/device_tree.h" |
bf957284 | 30 | #include "monitor/hmp-target.h" |
275307aa | 31 | #include "monitor/hmp.h" |
a2dde2f2 | 32 | #include "block/block-hmp-cmds.h" |
fa4dcf57 | 33 | #include "qapi/qapi-commands-control.h" |
00ca24ff | 34 | #include "qapi/qapi-commands-misc.h" |
dd98234c | 35 | #include "qapi/qapi-commands-machine.h" |
e688df6b | 36 | #include "qapi/error.h" |
f348b6d1 | 37 | #include "qemu/cutils.h" |
6a5bd307 | 38 | |
a4538a5c JH |
39 | #if defined(TARGET_S390X) |
40 | #include "hw/s390x/storage-keys.h" | |
f860d497 | 41 | #include "hw/s390x/storage-attributes.h" |
a4538a5c JH |
42 | #endif |
43 | ||
c9f8004b MOA |
44 | /* Make devices configuration available for use in hmp-commands*.hx templates */ |
45 | #include CONFIG_DEVICES | |
46 | ||
a0cd5e1c | 47 | static HMPCommand hmp_info_cmds[]; |
9dc39cba | 48 | |
ed7bda5d KW |
49 | /** |
50 | * Is @name in the '|' separated list of names @list? | |
51 | */ | |
52 | int hmp_compare_cmd(const char *name, const char *list) | |
9dc39cba FB |
53 | { |
54 | const char *p, *pstart; | |
55 | int len; | |
56 | len = strlen(name); | |
57 | p = list; | |
ed7bda5d | 58 | for (;;) { |
9dc39cba | 59 | pstart = p; |
5c99fa37 | 60 | p = qemu_strchrnul(p, '|'); |
ed7bda5d | 61 | if ((p - pstart) == len && !memcmp(pstart, name, len)) { |
9dc39cba | 62 | return 1; |
f5438c05 WX |
63 | } |
64 | if (*p == '\0') { | |
65 | break; | |
66 | } | |
ed7bda5d | 67 | p++; |
f5438c05 | 68 | } |
dcc70cdf | 69 | return 0; |
9dc39cba FB |
70 | } |
71 | ||
acd0a093 | 72 | /* Please update hmp-commands.hx when adding or changing commands */ |
a0cd5e1c | 73 | static HMPCommand hmp_info_cmds[] = { |
da76ee76 PB |
74 | #include "hmp-commands-info.h" |
75 | { NULL, NULL, }, | |
9dc39cba FB |
76 | }; |
77 | ||
a0cd5e1c | 78 | /* hmp_cmds and hmp_info_cmds would be sorted at runtime */ |
ed7bda5d | 79 | HMPCommand hmp_cmds[] = { |
a13ced59 WX |
80 | #include "hmp-commands.h" |
81 | { NULL, NULL, }, | |
82 | }; | |
83 | ||
ed7bda5d KW |
84 | /* |
85 | * Set @pval to the value in the register identified by @name. | |
86 | * return 0 if OK, -1 if not found | |
87 | */ | |
2fc5d01b | 88 | int get_monitor_def(Monitor *mon, int64_t *pval, const char *name) |
9307c4c1 | 89 | { |
bf957284 | 90 | const MonitorDef *md = target_monitor_defs(); |
2fc5d01b | 91 | CPUState *cs = mon_get_cpu(mon); |
92a31b1f | 92 | void *ptr; |
0a9516c2 AK |
93 | uint64_t tmp = 0; |
94 | int ret; | |
92a31b1f | 95 | |
854e67fe | 96 | if (cs == NULL || md == NULL) { |
bf957284 PB |
97 | return -1; |
98 | } | |
99 | ||
100 | for(; md->name != NULL; md++) { | |
ed7bda5d | 101 | if (hmp_compare_cmd(name, md->name)) { |
9307c4c1 | 102 | if (md->get_value) { |
43cf067f | 103 | *pval = md->get_value(mon, md, md->offset); |
9307c4c1 | 104 | } else { |
e7cff9c6 | 105 | CPUArchState *env = mon_get_cpu_env(mon); |
6a00d601 | 106 | ptr = (uint8_t *)env + md->offset; |
92a31b1f FB |
107 | switch(md->type) { |
108 | case MD_I32: | |
109 | *pval = *(int32_t *)ptr; | |
110 | break; | |
111 | case MD_TLONG: | |
112 | *pval = *(target_long *)ptr; | |
113 | break; | |
114 | default: | |
115 | *pval = 0; | |
116 | break; | |
117 | } | |
9307c4c1 FB |
118 | } |
119 | return 0; | |
120 | } | |
121 | } | |
0a9516c2 | 122 | |
854e67fe | 123 | ret = target_get_monitor_def(cs, name, &tmp); |
0a9516c2 AK |
124 | if (!ret) { |
125 | *pval = (target_long) tmp; | |
126 | } | |
127 | ||
128 | return ret; | |
9307c4c1 FB |
129 | } |
130 | ||
816f8925 WX |
131 | static int |
132 | compare_mon_cmd(const void *a, const void *b) | |
133 | { | |
a0cd5e1c KW |
134 | return strcmp(((const HMPCommand *)a)->name, |
135 | ((const HMPCommand *)b)->name); | |
816f8925 WX |
136 | } |
137 | ||
9d2b5f2c | 138 | static void __attribute__((__constructor__)) sortcmdlist(void) |
816f8925 | 139 | { |
a0cd5e1c KW |
140 | qsort(hmp_cmds, ARRAY_SIZE(hmp_cmds) - 1, |
141 | sizeof(*hmp_cmds), | |
142 | compare_mon_cmd); | |
143 | qsort(hmp_info_cmds, ARRAY_SIZE(hmp_info_cmds) - 1, | |
144 | sizeof(*hmp_info_cmds), | |
145 | compare_mon_cmd); | |
816f8925 WX |
146 | } |
147 | ||
f0e48cbd GH |
148 | void monitor_register_hmp(const char *name, bool info, |
149 | void (*cmd)(Monitor *mon, const QDict *qdict)) | |
150 | { | |
151 | HMPCommand *table = info ? hmp_info_cmds : hmp_cmds; | |
152 | ||
153 | while (table->name != NULL) { | |
154 | if (strcmp(table->name, name) == 0) { | |
f9429c67 | 155 | g_assert(table->cmd == NULL && table->cmd_info_hrt == NULL); |
f0e48cbd GH |
156 | table->cmd = cmd; |
157 | return; | |
158 | } | |
159 | table++; | |
160 | } | |
161 | g_assert_not_reached(); | |
162 | } | |
163 | ||
f9429c67 DB |
164 | void monitor_register_hmp_info_hrt(const char *name, |
165 | HumanReadableText *(*handler)(Error **errp)) | |
166 | { | |
167 | HMPCommand *table = hmp_info_cmds; | |
168 | ||
169 | while (table->name != NULL) { | |
170 | if (strcmp(table->name, name) == 0) { | |
171 | g_assert(table->cmd == NULL && table->cmd_info_hrt == NULL); | |
172 | table->cmd_info_hrt = handler; | |
173 | return; | |
174 | } | |
175 | table++; | |
176 | } | |
177 | g_assert_not_reached(); | |
178 | } |