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