]> git.proxmox.com Git - mirror_qemu.git/blame - system/qtest.c
target/i386: Rename tcg_cpu_FOO() to include 'x86'
[mirror_qemu.git] / system / qtest.c
CommitLineData
c7f0f3b1
AL
1/*
2 * Test Server
3 *
4 * Copyright IBM, Corp. 2011
5 *
6 * Authors:
7 * Anthony Liguori <aliguori@us.ibm.com>
8 *
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
11 *
12 */
13
d38ea87a 14#include "qemu/osdep.h"
da34e65c 15#include "qapi/error.h"
9c17d615 16#include "sysemu/qtest.h"
54d31236 17#include "sysemu/runstate.h"
4d43a603 18#include "chardev/char-fe.h"
022c62cb
PB
19#include "exec/ioport.h"
20#include "exec/memory.h"
09637edb 21#include "exec/tswap.h"
496bde82 22#include "hw/qdev-core.h"
c7f0f3b1 23#include "hw/irq.h"
65eac5bd 24#include "hw/core/cpu.h"
940e43aa 25#include "qemu/accel.h"
740b1759 26#include "sysemu/cpu-timers.h"
1ad9580b
ST
27#include "qemu/config-file.h"
28#include "qemu/option.h"
29#include "qemu/error-report.h"
0b8fa32f 30#include "qemu/module.h"
aa15f497 31#include "qemu/cutils.h"
6ba7ada3 32#include "qom/object_interfaces.h"
c7f0f3b1
AL
33
34#define MAX_IRQ 256
35
6ba7ada3
PB
36#define TYPE_QTEST "qtest"
37
38OBJECT_DECLARE_SIMPLE_TYPE(QTest, QTEST)
39
40struct QTest {
41 Object parent;
42
43 bool has_machine_link;
44 char *chr_name;
45 Chardev *chr;
46 CharBackend qtest_chr;
47 char *log;
48};
49
d5286af5 50bool qtest_allowed;
c7f0f3b1 51
20288345 52static DeviceState *irq_intercept_dev;
c7f0f3b1 53static FILE *qtest_log_fp;
6ba7ada3 54static QTest *qtest;
c7f0f3b1
AL
55static GString *inbuf;
56static int irq_levels[MAX_IRQ];
20e4ae11 57static GTimer *timer;
c7f0f3b1 58static bool qtest_opened;
e731d083
AB
59static void (*qtest_server_send)(void*, const char*);
60static void *qtest_server_send_opaque;
c7f0f3b1 61
20e4ae11 62#define FMT_timeval "%.06f"
c7f0f3b1
AL
63
64/**
f59c6de7 65 * DOC: QTest Protocol
c7f0f3b1
AL
66 *
67 * Line based protocol, request/response based. Server can send async messages
68 * so clients should always handle many async messages before the response
69 * comes in.
70 *
71 * Valid requests
f59c6de7 72 * ^^^^^^^^^^^^^^
c7f0f3b1 73 *
8156be56 74 * Clock management:
f59c6de7 75 * """""""""""""""""
8156be56 76 *
bc72ad67 77 * The qtest client is completely in charge of the QEMU_CLOCK_VIRTUAL. qtest commands
8156be56
PB
78 * let you adjust the value of the clock (monotonically). All the commands
79 * return the current value of the clock in nanoseconds.
80 *
f59c6de7
EH
81 * .. code-block:: none
82 *
8156be56
PB
83 * > clock_step
84 * < OK VALUE
85 *
f59c6de7
EH
86 * Advance the clock to the next deadline. Useful when waiting for
87 * asynchronous events.
88 *
89 * .. code-block:: none
8156be56
PB
90 *
91 * > clock_step NS
92 * < OK VALUE
93 *
f59c6de7
EH
94 * Advance the clock by NS nanoseconds.
95 *
96 * .. code-block:: none
8156be56
PB
97 *
98 * > clock_set NS
99 * < OK VALUE
100 *
f59c6de7 101 * Advance the clock to NS nanoseconds (do nothing if it's already past).
8156be56
PB
102 *
103 * PIO and memory access:
f59c6de7
EH
104 * """"""""""""""""""""""
105 *
106 * .. code-block:: none
8156be56 107 *
c7f0f3b1
AL
108 * > outb ADDR VALUE
109 * < OK
110 *
f59c6de7
EH
111 * .. code-block:: none
112 *
c7f0f3b1
AL
113 * > outw ADDR VALUE
114 * < OK
115 *
f59c6de7
EH
116 * .. code-block:: none
117 *
c7f0f3b1
AL
118 * > outl ADDR VALUE
119 * < OK
120 *
f59c6de7
EH
121 * .. code-block:: none
122 *
c7f0f3b1
AL
123 * > inb ADDR
124 * < OK VALUE
125 *
f59c6de7
EH
126 * .. code-block:: none
127 *
c7f0f3b1
AL
128 * > inw ADDR
129 * < OK VALUE
130 *
f59c6de7
EH
131 * .. code-block:: none
132 *
c7f0f3b1
AL
133 * > inl ADDR
134 * < OK VALUE
135 *
f59c6de7
EH
136 * .. code-block:: none
137 *
872536bf
AF
138 * > writeb ADDR VALUE
139 * < OK
140 *
f59c6de7
EH
141 * .. code-block:: none
142 *
872536bf
AF
143 * > writew ADDR VALUE
144 * < OK
145 *
f59c6de7
EH
146 * .. code-block:: none
147 *
872536bf
AF
148 * > writel ADDR VALUE
149 * < OK
150 *
f59c6de7
EH
151 * .. code-block:: none
152 *
872536bf
AF
153 * > writeq ADDR VALUE
154 * < OK
155 *
f59c6de7
EH
156 * .. code-block:: none
157 *
872536bf
AF
158 * > readb ADDR
159 * < OK VALUE
160 *
f59c6de7
EH
161 * .. code-block:: none
162 *
872536bf
AF
163 * > readw ADDR
164 * < OK VALUE
165 *
f59c6de7
EH
166 * .. code-block:: none
167 *
872536bf
AF
168 * > readl ADDR
169 * < OK VALUE
170 *
f59c6de7
EH
171 * .. code-block:: none
172 *
872536bf
AF
173 * > readq ADDR
174 * < OK VALUE
175 *
f59c6de7
EH
176 * .. code-block:: none
177 *
c7f0f3b1
AL
178 * > read ADDR SIZE
179 * < OK DATA
180 *
f59c6de7
EH
181 * .. code-block:: none
182 *
c7f0f3b1
AL
183 * > write ADDR SIZE DATA
184 * < OK
185 *
f59c6de7
EH
186 * .. code-block:: none
187 *
7a6a740d
JS
188 * > b64read ADDR SIZE
189 * < OK B64_DATA
190 *
f59c6de7
EH
191 * .. code-block:: none
192 *
7a6a740d
JS
193 * > b64write ADDR SIZE B64_DATA
194 * < OK
195 *
f59c6de7
EH
196 * .. code-block:: none
197 *
4d007963
JS
198 * > memset ADDR SIZE VALUE
199 * < OK
200 *
c7f0f3b1 201 * ADDR, SIZE, VALUE are all integers parsed with strtoul() with a base of 0.
5f31bbf1 202 * For 'memset' a zero size is permitted and does nothing.
c7f0f3b1
AL
203 *
204 * DATA is an arbitrarily long hex number prefixed with '0x'. If it's smaller
205 * than the expected size, the value will be zero filled at the end of the data
206 * sequence.
207 *
7a6a740d
JS
208 * B64_DATA is an arbitrarily long base64 encoded string.
209 * If the sizes do not match, the data will be truncated.
210 *
20288345 211 * IRQ management:
f59c6de7
EH
212 * """""""""""""""
213 *
214 * .. code-block:: none
20288345
PB
215 *
216 * > irq_intercept_in QOM-PATH
217 * < OK
218 *
f59c6de7
EH
219 * .. code-block:: none
220 *
20288345
PB
221 * > irq_intercept_out QOM-PATH
222 * < OK
223 *
224 * Attach to the gpio-in (resp. gpio-out) pins exported by the device at
225 * QOM-PATH. When the pin is triggered, one of the following async messages
f59c6de7 226 * will be printed to the qtest stream::
20288345
PB
227 *
228 * IRQ raise NUM
229 * IRQ lower NUM
230 *
231 * where NUM is an IRQ number. For the PC, interrupts can be intercepted
232 * simply with "irq_intercept_in ioapic" (note that IRQ0 comes out with
233 * NUM=0 even though it is remapped to GSI 2).
9813dc6a
SG
234 *
235 * Setting interrupt level:
f59c6de7
EH
236 * """"""""""""""""""""""""
237 *
238 * .. code-block:: none
9813dc6a
SG
239 *
240 * > set_irq_in QOM-PATH NAME NUM LEVEL
241 * < OK
242 *
f59c6de7
EH
243 * where NAME is the name of the irq/gpio list, NUM is an IRQ number and
244 * LEVEL is an signed integer IRQ level.
9813dc6a
SG
245 *
246 * Forcibly set the given interrupt pin to the given level.
247 *
c7f0f3b1
AL
248 */
249
250static int hex2nib(char ch)
251{
252 if (ch >= '0' && ch <= '9') {
253 return ch - '0';
254 } else if (ch >= 'a' && ch <= 'f') {
255 return 10 + (ch - 'a');
256 } else if (ch >= 'A' && ch <= 'F') {
2a802aaf 257 return 10 + (ch - 'A');
c7f0f3b1
AL
258 } else {
259 return -1;
260 }
261}
262
c7a6bf5d 263void qtest_send_prefix(CharBackend *chr)
c7f0f3b1 264{
c7f0f3b1
AL
265 if (!qtest_log_fp || !qtest_opened) {
266 return;
267 }
268
20e4ae11 269 fprintf(qtest_log_fp, "[S +" FMT_timeval "] ", g_timer_elapsed(timer, NULL));
c7f0f3b1
AL
270}
271
9edc6313 272static void G_GNUC_PRINTF(1, 2) qtest_log_send(const char *fmt, ...)
7a6a740d
JS
273{
274 va_list ap;
275
276 if (!qtest_log_fp || !qtest_opened) {
277 return;
278 }
279
280 qtest_send_prefix(NULL);
281
282 va_start(ap, fmt);
283 vfprintf(qtest_log_fp, fmt, ap);
284 va_end(ap);
285}
286
e731d083 287static void qtest_server_char_be_send(void *opaque, const char *str)
332cc7e9 288{
e731d083
AB
289 size_t len = strlen(str);
290 CharBackend* chr = (CharBackend *)opaque;
332cc7e9
JS
291 qemu_chr_fe_write_all(chr, (uint8_t *)str, len);
292 if (qtest_log_fp && qtest_opened) {
293 fprintf(qtest_log_fp, "%s", str);
294 }
295}
296
5345fdb4 297static void qtest_send(CharBackend *chr, const char *str)
332cc7e9 298{
e731d083 299 qtest_server_send(qtest_server_send_opaque, str);
332cc7e9
JS
300}
301
c7a6bf5d 302void qtest_sendf(CharBackend *chr, const char *fmt, ...)
c7f0f3b1
AL
303{
304 va_list ap;
332cc7e9 305 gchar *buffer;
c7f0f3b1
AL
306
307 va_start(ap, fmt);
332cc7e9
JS
308 buffer = g_strdup_vprintf(fmt, ap);
309 qtest_send(chr, buffer);
fc34059f 310 g_free(buffer);
c7f0f3b1 311 va_end(ap);
c7f0f3b1
AL
312}
313
20288345
PB
314static void qtest_irq_handler(void *opaque, int n, int level)
315{
60a79016
PC
316 qemu_irq old_irq = *(qemu_irq *)opaque;
317 qemu_set_irq(old_irq, level);
20288345
PB
318
319 if (irq_levels[n] != level) {
6ba7ada3 320 CharBackend *chr = &qtest->qtest_chr;
20288345
PB
321 irq_levels[n] = level;
322 qtest_send_prefix(chr);
332cc7e9
JS
323 qtest_sendf(chr, "IRQ %s %d\n",
324 level ? "raise" : "lower", n);
20288345
PB
325 }
326}
327
740b1759
CF
328static int64_t qtest_clock_counter;
329
330int64_t qtest_get_virtual_clock(void)
331{
332 return qatomic_read_i64(&qtest_clock_counter);
333}
334
335static void qtest_set_virtual_clock(int64_t count)
336{
337 qatomic_set_i64(&qtest_clock_counter, count);
338}
339
340static void qtest_clock_warp(int64_t dest)
341{
342 int64_t clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
343 AioContext *aio_context;
344 assert(qtest_enabled());
345 aio_context = qemu_get_aio_context();
346 while (clock < dest) {
347 int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
348 QEMU_TIMER_ATTR_ALL);
349 int64_t warp = qemu_soonest_timeout(dest - clock, deadline);
350
351 qtest_set_virtual_clock(qtest_get_virtual_clock() + warp);
352
353 qemu_clock_run_timers(QEMU_CLOCK_VIRTUAL);
354 timerlist_run_timers(aio_context->tlg.tl[QEMU_CLOCK_VIRTUAL]);
355 clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
356 }
357 qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
358}
359
c7a6bf5d
TH
360static bool (*process_command_cb)(CharBackend *chr, gchar **words);
361
362void qtest_set_command_cb(bool (*pc_cb)(CharBackend *chr, gchar **words))
363{
364 assert(!process_command_cb); /* Switch to a list if we need more than one */
365
366 process_command_cb = pc_cb;
367}
368
7458dcf4
CL
369static void qtest_install_gpio_out_intercept(DeviceState *dev, const char *name, int n)
370{
371 qemu_irq *disconnected = g_new0(qemu_irq, 1);
372 qemu_irq icpt = qemu_allocate_irq(qtest_irq_handler,
373 disconnected, n);
374
375 *disconnected = qdev_intercept_gpio_out(dev, icpt, name, n);
376}
377
5345fdb4 378static void qtest_process_command(CharBackend *chr, gchar **words)
c7f0f3b1
AL
379{
380 const gchar *command;
381
382 g_assert(words);
383
384 command = words[0];
385
386 if (qtest_log_fp) {
c7f0f3b1
AL
387 int i;
388
20e4ae11 389 fprintf(qtest_log_fp, "[R +" FMT_timeval "]", g_timer_elapsed(timer, NULL));
c7f0f3b1
AL
390 for (i = 0; words[i]; i++) {
391 fprintf(qtest_log_fp, " %s", words[i]);
392 }
393 fprintf(qtest_log_fp, "\n");
394 }
395
396 g_assert(command);
20288345
PB
397 if (strcmp(words[0], "irq_intercept_out") == 0
398 || strcmp(words[0], "irq_intercept_in") == 0) {
a5f54290
PC
399 DeviceState *dev;
400 NamedGPIOList *ngl;
fe692f7c 401 bool is_named;
a8610f8b 402 bool is_outbound;
c7bb6fa6 403 bool interception_succeeded = false;
20288345
PB
404
405 g_assert(words[1]);
fe692f7c 406 is_named = words[2] != NULL;
a8610f8b 407 is_outbound = words[0][14] == 'o';
20288345
PB
408 dev = DEVICE(object_resolve_path(words[1], NULL));
409 if (!dev) {
410 qtest_send_prefix(chr);
411 qtest_send(chr, "FAIL Unknown device\n");
7d37435b 412 return;
20288345
PB
413 }
414
fe692f7c
CL
415 if (is_named && !is_outbound) {
416 qtest_send_prefix(chr);
417 qtest_send(chr, "FAIL Interception of named in-GPIOs not yet supported\n");
418 return;
419 }
420
20288345
PB
421 if (irq_intercept_dev) {
422 qtest_send_prefix(chr);
423 if (irq_intercept_dev != dev) {
424 qtest_send(chr, "FAIL IRQ intercept already enabled\n");
425 } else {
426 qtest_send(chr, "OK\n");
427 }
7d37435b 428 return;
20288345
PB
429 }
430
a5f54290 431 QLIST_FOREACH(ngl, &dev->gpios, node) {
a8610f8b
CL
432 /* We don't support inbound interception of named GPIOs yet */
433 if (is_outbound) {
434 /* NULL is valid and matchable, for "unnamed GPIO" */
435 if (g_strcmp0(ngl->name, words[2]) == 0) {
436 int i;
437 for (i = 0; i < ngl->num_out; ++i) {
438 qtest_install_gpio_out_intercept(dev, ngl->name, i);
439 }
c7bb6fa6 440 interception_succeeded = true;
60a79016 441 }
a5f54290
PC
442 } else {
443 qemu_irq_intercept_in(ngl->in, qtest_irq_handler,
444 ngl->num_in);
c7bb6fa6 445 interception_succeeded = true;
a5f54290 446 }
20288345 447 }
c7bb6fa6 448
20288345 449 qtest_send_prefix(chr);
c7bb6fa6
CL
450 if (interception_succeeded) {
451 irq_intercept_dev = dev;
452 qtest_send(chr, "OK\n");
453 } else {
454 qtest_send(chr, "FAIL No intercepts installed\n");
455 }
9813dc6a
SG
456 } else if (strcmp(words[0], "set_irq_in") == 0) {
457 DeviceState *dev;
458 qemu_irq irq;
459 char *name;
460 int ret;
461 int num;
462 int level;
463
464 g_assert(words[1] && words[2] && words[3] && words[4]);
20288345 465
9813dc6a
SG
466 dev = DEVICE(object_resolve_path(words[1], NULL));
467 if (!dev) {
468 qtest_send_prefix(chr);
469 qtest_send(chr, "FAIL Unknown device\n");
470 return;
471 }
472
473 if (strcmp(words[2], "unnamed-gpio-in") == 0) {
474 name = NULL;
475 } else {
476 name = words[2];
477 }
478
479 ret = qemu_strtoi(words[3], NULL, 0, &num);
480 g_assert(!ret);
481 ret = qemu_strtoi(words[4], NULL, 0, &level);
482 g_assert(!ret);
483
484 irq = qdev_get_gpio_in_named(dev, name, num);
485
486 qemu_set_irq(irq, level);
487 qtest_send_prefix(chr);
488 qtest_send(chr, "OK\n");
20288345
PB
489 } else if (strcmp(words[0], "outb") == 0 ||
490 strcmp(words[0], "outw") == 0 ||
491 strcmp(words[0], "outl") == 0) {
aa15f497
LV
492 unsigned long addr;
493 unsigned long value;
14773125 494 int ret;
c7f0f3b1
AL
495
496 g_assert(words[1] && words[2]);
14773125
EB
497 ret = qemu_strtoul(words[1], NULL, 0, &addr);
498 g_assert(ret == 0);
499 ret = qemu_strtoul(words[2], NULL, 0, &value);
500 g_assert(ret == 0);
aa15f497 501 g_assert(addr <= 0xffff);
c7f0f3b1
AL
502
503 if (words[0][3] == 'b') {
504 cpu_outb(addr, value);
505 } else if (words[0][3] == 'w') {
506 cpu_outw(addr, value);
507 } else if (words[0][3] == 'l') {
508 cpu_outl(addr, value);
509 }
510 qtest_send_prefix(chr);
511 qtest_send(chr, "OK\n");
512 } else if (strcmp(words[0], "inb") == 0 ||
513 strcmp(words[0], "inw") == 0 ||
514 strcmp(words[0], "inl") == 0) {
aa15f497 515 unsigned long addr;
c7f0f3b1 516 uint32_t value = -1U;
14773125 517 int ret;
c7f0f3b1
AL
518
519 g_assert(words[1]);
14773125
EB
520 ret = qemu_strtoul(words[1], NULL, 0, &addr);
521 g_assert(ret == 0);
aa15f497 522 g_assert(addr <= 0xffff);
c7f0f3b1
AL
523
524 if (words[0][2] == 'b') {
525 value = cpu_inb(addr);
526 } else if (words[0][2] == 'w') {
527 value = cpu_inw(addr);
528 } else if (words[0][2] == 'l') {
529 value = cpu_inl(addr);
530 }
531 qtest_send_prefix(chr);
332cc7e9 532 qtest_sendf(chr, "OK 0x%04x\n", value);
872536bf
AF
533 } else if (strcmp(words[0], "writeb") == 0 ||
534 strcmp(words[0], "writew") == 0 ||
535 strcmp(words[0], "writel") == 0 ||
536 strcmp(words[0], "writeq") == 0) {
537 uint64_t addr;
538 uint64_t value;
14773125 539 int ret;
872536bf
AF
540
541 g_assert(words[1] && words[2]);
14773125
EB
542 ret = qemu_strtou64(words[1], NULL, 0, &addr);
543 g_assert(ret == 0);
544 ret = qemu_strtou64(words[2], NULL, 0, &value);
545 g_assert(ret == 0);
872536bf
AF
546
547 if (words[0][5] == 'b') {
548 uint8_t data = value;
19f70347
PM
549 address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
550 &data, 1);
872536bf
AF
551 } else if (words[0][5] == 'w') {
552 uint16_t data = value;
553 tswap16s(&data);
19f70347
PM
554 address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
555 &data, 2);
872536bf
AF
556 } else if (words[0][5] == 'l') {
557 uint32_t data = value;
558 tswap32s(&data);
19f70347
PM
559 address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
560 &data, 4);
872536bf
AF
561 } else if (words[0][5] == 'q') {
562 uint64_t data = value;
563 tswap64s(&data);
19f70347
PM
564 address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
565 &data, 8);
872536bf
AF
566 }
567 qtest_send_prefix(chr);
568 qtest_send(chr, "OK\n");
569 } else if (strcmp(words[0], "readb") == 0 ||
570 strcmp(words[0], "readw") == 0 ||
571 strcmp(words[0], "readl") == 0 ||
572 strcmp(words[0], "readq") == 0) {
573 uint64_t addr;
574 uint64_t value = UINT64_C(-1);
14773125 575 int ret;
872536bf
AF
576
577 g_assert(words[1]);
14773125
EB
578 ret = qemu_strtou64(words[1], NULL, 0, &addr);
579 g_assert(ret == 0);
872536bf
AF
580
581 if (words[0][4] == 'b') {
582 uint8_t data;
19f70347
PM
583 address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
584 &data, 1);
872536bf
AF
585 value = data;
586 } else if (words[0][4] == 'w') {
587 uint16_t data;
19f70347
PM
588 address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
589 &data, 2);
872536bf
AF
590 value = tswap16(data);
591 } else if (words[0][4] == 'l') {
592 uint32_t data;
19f70347
PM
593 address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
594 &data, 4);
872536bf
AF
595 value = tswap32(data);
596 } else if (words[0][4] == 'q') {
19f70347
PM
597 address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
598 &value, 8);
872536bf
AF
599 tswap64s(&value);
600 }
601 qtest_send_prefix(chr);
332cc7e9 602 qtest_sendf(chr, "OK 0x%016" PRIx64 "\n", value);
c7f0f3b1
AL
603 } else if (strcmp(words[0], "read") == 0) {
604 uint64_t addr, len, i;
605 uint8_t *data;
5560b85a 606 char *enc;
14773125 607 int ret;
c7f0f3b1
AL
608
609 g_assert(words[1] && words[2]);
14773125
EB
610 ret = qemu_strtou64(words[1], NULL, 0, &addr);
611 g_assert(ret == 0);
612 ret = qemu_strtou64(words[2], NULL, 0, &len);
613 g_assert(ret == 0);
204febd1
GK
614 /* We'd send garbage to libqtest if len is 0 */
615 g_assert(len);
c7f0f3b1
AL
616
617 data = g_malloc(len);
19f70347
PM
618 address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, data,
619 len);
c7f0f3b1 620
5560b85a 621 enc = g_malloc(2 * len + 1);
c7f0f3b1 622 for (i = 0; i < len; i++) {
5560b85a 623 sprintf(&enc[i * 2], "%02x", data[i]);
c7f0f3b1 624 }
5560b85a
JS
625
626 qtest_send_prefix(chr);
627 qtest_sendf(chr, "OK 0x%s\n", enc);
c7f0f3b1
AL
628
629 g_free(data);
5560b85a 630 g_free(enc);
7a6a740d
JS
631 } else if (strcmp(words[0], "b64read") == 0) {
632 uint64_t addr, len;
633 uint8_t *data;
634 gchar *b64_data;
14773125 635 int ret;
7a6a740d
JS
636
637 g_assert(words[1] && words[2]);
14773125
EB
638 ret = qemu_strtou64(words[1], NULL, 0, &addr);
639 g_assert(ret == 0);
640 ret = qemu_strtou64(words[2], NULL, 0, &len);
641 g_assert(ret == 0);
7a6a740d
JS
642
643 data = g_malloc(len);
19f70347
PM
644 address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, data,
645 len);
7a6a740d
JS
646 b64_data = g_base64_encode(data, len);
647 qtest_send_prefix(chr);
648 qtest_sendf(chr, "OK %s\n", b64_data);
649
650 g_free(data);
651 g_free(b64_data);
c7f0f3b1
AL
652 } else if (strcmp(words[0], "write") == 0) {
653 uint64_t addr, len, i;
654 uint8_t *data;
655 size_t data_len;
14773125 656 int ret;
c7f0f3b1
AL
657
658 g_assert(words[1] && words[2] && words[3]);
14773125
EB
659 ret = qemu_strtou64(words[1], NULL, 0, &addr);
660 g_assert(ret == 0);
661 ret = qemu_strtou64(words[2], NULL, 0, &len);
662 g_assert(ret == 0);
c7f0f3b1
AL
663
664 data_len = strlen(words[3]);
665 if (data_len < 3) {
666 qtest_send(chr, "ERR invalid argument size\n");
667 return;
668 }
669
670 data = g_malloc(len);
671 for (i = 0; i < len; i++) {
672 if ((i * 2 + 4) <= data_len) {
673 data[i] = hex2nib(words[3][i * 2 + 2]) << 4;
674 data[i] |= hex2nib(words[3][i * 2 + 3]);
675 } else {
676 data[i] = 0;
677 }
678 }
19f70347
PM
679 address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, data,
680 len);
c7f0f3b1
AL
681 g_free(data);
682
4d007963
JS
683 qtest_send_prefix(chr);
684 qtest_send(chr, "OK\n");
685 } else if (strcmp(words[0], "memset") == 0) {
686 uint64_t addr, len;
687 uint8_t *data;
aa15f497 688 unsigned long pattern;
14773125 689 int ret;
4d007963
JS
690
691 g_assert(words[1] && words[2] && words[3]);
14773125
EB
692 ret = qemu_strtou64(words[1], NULL, 0, &addr);
693 g_assert(ret == 0);
694 ret = qemu_strtou64(words[2], NULL, 0, &len);
695 g_assert(ret == 0);
696 ret = qemu_strtoul(words[3], NULL, 0, &pattern);
697 g_assert(ret == 0);
4d007963 698
5f31bbf1
PM
699 if (len) {
700 data = g_malloc(len);
701 memset(data, pattern, len);
19f70347
PM
702 address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
703 data, len);
5f31bbf1
PM
704 g_free(data);
705 }
4d007963 706
7a6a740d
JS
707 qtest_send_prefix(chr);
708 qtest_send(chr, "OK\n");
709 } else if (strcmp(words[0], "b64write") == 0) {
710 uint64_t addr, len;
711 uint8_t *data;
712 size_t data_len;
713 gsize out_len;
14773125 714 int ret;
7a6a740d
JS
715
716 g_assert(words[1] && words[2] && words[3]);
14773125
EB
717 ret = qemu_strtou64(words[1], NULL, 0, &addr);
718 g_assert(ret == 0);
719 ret = qemu_strtou64(words[2], NULL, 0, &len);
720 g_assert(ret == 0);
7a6a740d
JS
721
722 data_len = strlen(words[3]);
723 if (data_len < 3) {
724 qtest_send(chr, "ERR invalid argument size\n");
725 return;
726 }
727
728 data = g_base64_decode_inplace(words[3], &out_len);
729 if (out_len != len) {
730 qtest_log_send("b64write: data length mismatch (told %"PRIu64", "
731 "found %zu)\n",
732 len, out_len);
733 out_len = MIN(out_len, len);
734 }
735
19f70347
PM
736 address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, data,
737 len);
7a6a740d 738
c7f0f3b1
AL
739 qtest_send_prefix(chr);
740 qtest_send(chr, "OK\n");
54ce6f22
LV
741 } else if (strcmp(words[0], "endianness") == 0) {
742 qtest_send_prefix(chr);
09637edb
TH
743 if (target_words_bigendian()) {
744 qtest_sendf(chr, "OK big\n");
745 } else {
746 qtest_sendf(chr, "OK little\n");
747 }
d4fce24f 748 } else if (qtest_enabled() && strcmp(words[0], "clock_step") == 0) {
8156be56
PB
749 int64_t ns;
750
751 if (words[1]) {
14773125
EB
752 int ret = qemu_strtoi64(words[1], NULL, 0, &ns);
753 g_assert(ret == 0);
8156be56 754 } else {
dcb15780
PD
755 ns = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
756 QEMU_TIMER_ATTR_ALL);
8156be56 757 }
bc72ad67 758 qtest_clock_warp(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns);
8156be56 759 qtest_send_prefix(chr);
332cc7e9
JS
760 qtest_sendf(chr, "OK %"PRIi64"\n",
761 (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
eb062cfa 762 } else if (strcmp(words[0], "module_load") == 0) {
c551fb0b
CF
763 Error *local_err = NULL;
764 int rv;
eb062cfa
MAL
765 g_assert(words[1] && words[2]);
766
767 qtest_send_prefix(chr);
c551fb0b
CF
768 rv = module_load(words[1], words[2], &local_err);
769 if (rv > 0) {
eb062cfa
MAL
770 qtest_sendf(chr, "OK\n");
771 } else {
c551fb0b
CF
772 if (rv < 0) {
773 error_report_err(local_err);
774 }
eb062cfa
MAL
775 qtest_sendf(chr, "FAIL\n");
776 }
d4fce24f 777 } else if (qtest_enabled() && strcmp(words[0], "clock_set") == 0) {
8156be56 778 int64_t ns;
14773125 779 int ret;
8156be56
PB
780
781 g_assert(words[1]);
14773125
EB
782 ret = qemu_strtoi64(words[1], NULL, 0, &ns);
783 g_assert(ret == 0);
8156be56
PB
784 qtest_clock_warp(ns);
785 qtest_send_prefix(chr);
332cc7e9
JS
786 qtest_sendf(chr, "OK %"PRIi64"\n",
787 (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
c7a6bf5d
TH
788 } else if (process_command_cb && process_command_cb(chr, words)) {
789 /* Command got consumed by the callback handler */
c7f0f3b1
AL
790 } else {
791 qtest_send_prefix(chr);
332cc7e9 792 qtest_sendf(chr, "FAIL Unknown command '%s'\n", words[0]);
c7f0f3b1
AL
793 }
794}
795
5345fdb4 796static void qtest_process_inbuf(CharBackend *chr, GString *inbuf)
c7f0f3b1
AL
797{
798 char *end;
799
800 while ((end = strchr(inbuf->str, '\n')) != NULL) {
801 size_t offset;
802 GString *cmd;
803 gchar **words;
804
805 offset = end - inbuf->str;
806
807 cmd = g_string_new_len(inbuf->str, offset);
808 g_string_erase(inbuf, 0, offset + 1);
809
810 words = g_strsplit(cmd->str, " ", 0);
811 qtest_process_command(chr, words);
812 g_strfreev(words);
813
814 g_string_free(cmd, TRUE);
815 }
816}
817
818static void qtest_read(void *opaque, const uint8_t *buf, int size)
819{
5345fdb4 820 CharBackend *chr = opaque;
c7f0f3b1
AL
821
822 g_string_append_len(inbuf, (const gchar *)buf, size);
823 qtest_process_inbuf(chr, inbuf);
824}
825
826static int qtest_can_read(void *opaque)
827{
828 return 1024;
829}
830
083b266f 831static void qtest_event(void *opaque, QEMUChrEvent event)
c7f0f3b1
AL
832{
833 int i;
834
835 switch (event) {
836 case CHR_EVENT_OPENED:
ba646ff6
MA
837 /*
838 * We used to call qemu_system_reset() here, hoping we could
839 * use the same process for multiple tests that way. Never
840 * used. Injects an extra reset even when it's not used, and
841 * that can mess up tests, e.g. -boot once.
842 */
c7f0f3b1
AL
843 for (i = 0; i < ARRAY_SIZE(irq_levels); i++) {
844 irq_levels[i] = 0;
845 }
20e4ae11
MAL
846
847 g_clear_pointer(&timer, g_timer_destroy);
848 timer = g_timer_new();
c7f0f3b1
AL
849 qtest_opened = true;
850 if (qtest_log_fp) {
20e4ae11 851 fprintf(qtest_log_fp, "[I " FMT_timeval "] OPENED\n", g_timer_elapsed(timer, NULL));
c7f0f3b1
AL
852 }
853 break;
854 case CHR_EVENT_CLOSED:
855 qtest_opened = false;
856 if (qtest_log_fp) {
20e4ae11 857 fprintf(qtest_log_fp, "[I +" FMT_timeval "] CLOSED\n", g_timer_elapsed(timer, NULL));
c7f0f3b1 858 }
20e4ae11 859 g_clear_pointer(&timer, g_timer_destroy);
c7f0f3b1
AL
860 break;
861 default:
862 break;
863 }
864}
6ba7ada3 865
2b8985f1 866void qtest_server_init(const char *qtest_chrdev, const char *qtest_log, Error **errp)
d4fce24f 867{
6ba7ada3 868 ERRP_GUARD();
0ec7b3e7 869 Chardev *chr;
63ba5e13 870 Object *qobj;
c7f0f3b1 871
4ad6f6cb 872 chr = qemu_chr_new("qtest", qtest_chrdev, NULL);
23802b4f
FZ
873 if (chr == NULL) {
874 error_setg(errp, "Failed to initialize device for qtest: \"%s\"",
875 qtest_chrdev);
876 return;
877 }
878
63ba5e13
PMD
879 qobj = object_new(TYPE_QTEST);
880 object_property_set_str(qobj, "chardev", chr->label, &error_abort);
6ba7ada3 881 if (qtest_log) {
63ba5e13 882 object_property_set_str(qobj, "log", qtest_log, &error_abort);
6ba7ada3 883 }
63ba5e13
PMD
884 object_property_add_child(qdev_get_machine(), "qtest", qobj);
885 user_creatable_complete(USER_CREATABLE(qobj), errp);
6ba7ada3 886 if (*errp) {
63ba5e13 887 object_unparent(qobj);
6ba7ada3
PB
888 }
889 object_unref(OBJECT(chr));
63ba5e13 890 object_unref(qobj);
6ba7ada3
PB
891}
892
893static bool qtest_server_start(QTest *q, Error **errp)
894{
895 Chardev *chr = q->chr;
896 const char *qtest_log = q->log;
897
c7f0f3b1
AL
898 if (qtest_log) {
899 if (strcmp(qtest_log, "none") != 0) {
900 qtest_log_fp = fopen(qtest_log, "w+");
901 }
902 } else {
903 qtest_log_fp = stderr;
904 }
905
6ba7ada3
PB
906 if (!qemu_chr_fe_init(&q->qtest_chr, chr, errp)) {
907 return false;
908 }
909 qemu_chr_fe_set_handlers(&q->qtest_chr, qtest_can_read, qtest_read,
910 qtest_event, NULL, &q->qtest_chr, NULL, true);
911 qemu_chr_fe_set_echo(&q->qtest_chr, true);
107684c0
LL
912
913 inbuf = g_string_new("");
e731d083
AB
914
915 if (!qtest_server_send) {
6ba7ada3 916 qtest_server_set_send_handler(qtest_server_char_be_send, &q->qtest_chr);
e731d083 917 }
6ba7ada3
PB
918 qtest = q;
919 return true;
e731d083
AB
920}
921
3fc92f87
AB
922void qtest_server_set_send_handler(void (*send)(void*, const char*),
923 void *opaque)
e731d083
AB
924{
925 qtest_server_send = send;
926 qtest_server_send_opaque = opaque;
c7f0f3b1 927}
b3be57c3
MT
928
929bool qtest_driver(void)
930{
6ba7ada3 931 return qtest && qtest->qtest_chr.chr != NULL;
b3be57c3 932}
0bd9aef8
AB
933
934void qtest_server_inproc_recv(void *dummy, const char *buf)
935{
936 static GString *gstr;
937 if (!gstr) {
938 gstr = g_string_new(NULL);
939 }
940 g_string_append(gstr, buf);
941 if (gstr->str[gstr->len - 1] == '\n') {
942 qtest_process_inbuf(NULL, gstr);
943 g_string_truncate(gstr, 0);
944 }
945}
6ba7ada3
PB
946
947static void qtest_complete(UserCreatable *uc, Error **errp)
948{
949 QTest *q = QTEST(uc);
950 if (qtest) {
951 error_setg(errp, "Only one instance of qtest can be created");
952 return;
953 }
954 if (!q->chr_name) {
955 error_setg(errp, "No backend specified");
956 return;
957 }
958
959 if (OBJECT(uc)->parent != qdev_get_machine()) {
960 q->has_machine_link = true;
961 object_property_add_const_link(qdev_get_machine(), "qtest", OBJECT(uc));
962 } else {
963 /* -qtest was used. */
964 }
965
966 qtest_server_start(q, errp);
967}
968
969static void qtest_unparent(Object *obj)
970{
971 QTest *q = QTEST(obj);
972
973 if (qtest == q) {
974 qemu_chr_fe_disconnect(&q->qtest_chr);
975 assert(!qtest_opened);
976 qemu_chr_fe_deinit(&q->qtest_chr, false);
977 if (qtest_log_fp) {
978 fclose(qtest_log_fp);
979 qtest_log_fp = NULL;
980 }
981 qtest = NULL;
982 }
983
984 if (q->has_machine_link) {
985 object_property_del(qdev_get_machine(), "qtest");
986 q->has_machine_link = false;
987 }
988}
989
990static void qtest_set_log(Object *obj, const char *value, Error **errp)
991{
992 QTest *q = QTEST(obj);
993
994 if (qtest == q) {
8d095933 995 error_setg(errp, "Property 'log' can not be set now");
6ba7ada3
PB
996 } else {
997 g_free(q->log);
998 q->log = g_strdup(value);
999 }
1000}
1001
1002static char *qtest_get_log(Object *obj, Error **errp)
1003{
1004 QTest *q = QTEST(obj);
1005
1006 return g_strdup(q->log);
1007}
1008
1009static void qtest_set_chardev(Object *obj, const char *value, Error **errp)
1010{
1011 QTest *q = QTEST(obj);
1012 Chardev *chr;
1013
1014 if (qtest == q) {
8d095933 1015 error_setg(errp, "Property 'chardev' can not be set now");
6ba7ada3
PB
1016 return;
1017 }
1018
1019 chr = qemu_chr_find(value);
1020 if (!chr) {
1021 error_setg(errp, "Cannot find character device '%s'", value);
1022 return;
1023 }
1024
1025 g_free(q->chr_name);
1026 q->chr_name = g_strdup(value);
1027
1028 if (q->chr) {
1029 object_unref(q->chr);
1030 }
1031 q->chr = chr;
1032 object_ref(chr);
1033}
1034
1035static char *qtest_get_chardev(Object *obj, Error **errp)
1036{
1037 QTest *q = QTEST(obj);
1038
1039 return g_strdup(q->chr_name);
1040}
1041
1042static void qtest_class_init(ObjectClass *oc, void *data)
1043{
1044 UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
1045
1046 oc->unparent = qtest_unparent;
1047 ucc->complete = qtest_complete;
1048
1049 object_class_property_add_str(oc, "chardev",
1050 qtest_get_chardev, qtest_set_chardev);
1051 object_class_property_add_str(oc, "log",
1052 qtest_get_log, qtest_set_log);
1053}
1054
1055static const TypeInfo qtest_info = {
1056 .name = TYPE_QTEST,
1057 .parent = TYPE_OBJECT,
1058 .class_init = qtest_class_init,
1059 .instance_size = sizeof(QTest),
1060 .interfaces = (InterfaceInfo[]) {
1061 { TYPE_USER_CREATABLE },
1062 { }
1063 }
1064};
1065
1066static void register_types(void)
1067{
1068 type_register_static(&qtest_info);
1069}
1070
1071type_init(register_types);