linux-user: Fix qemu brk() to not zero bytes on current page
[qemu/armbru.git] / softmmu / qtest.c
blobf8d764b7190f9eff2beec102a500d0827addf250
1 /*
2 * Test Server
4 * Copyright IBM, Corp. 2011
6 * Authors:
7 * Anthony Liguori <aliguori@us.ibm.com>
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.
14 #include "qemu/osdep.h"
15 #include "qapi/error.h"
16 #include "sysemu/qtest.h"
17 #include "sysemu/runstate.h"
18 #include "chardev/char-fe.h"
19 #include "exec/ioport.h"
20 #include "exec/memory.h"
21 #include "exec/tswap.h"
22 #include "hw/qdev-core.h"
23 #include "hw/irq.h"
24 #include "qemu/accel.h"
25 #include "sysemu/cpu-timers.h"
26 #include "qemu/config-file.h"
27 #include "qemu/option.h"
28 #include "qemu/error-report.h"
29 #include "qemu/module.h"
30 #include "qemu/cutils.h"
31 #include "qom/object_interfaces.h"
33 #define MAX_IRQ 256
35 #define TYPE_QTEST "qtest"
37 OBJECT_DECLARE_SIMPLE_TYPE(QTest, QTEST)
39 struct QTest {
40 Object parent;
42 bool has_machine_link;
43 char *chr_name;
44 Chardev *chr;
45 CharBackend qtest_chr;
46 char *log;
49 bool qtest_allowed;
51 static DeviceState *irq_intercept_dev;
52 static FILE *qtest_log_fp;
53 static QTest *qtest;
54 static GString *inbuf;
55 static int irq_levels[MAX_IRQ];
56 static GTimer *timer;
57 static bool qtest_opened;
58 static void (*qtest_server_send)(void*, const char*);
59 static void *qtest_server_send_opaque;
61 #define FMT_timeval "%.06f"
63 /**
64 * DOC: QTest Protocol
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.
70 * Valid requests
71 * ^^^^^^^^^^^^^^
73 * Clock management:
74 * """""""""""""""""
76 * The qtest client is completely in charge of the QEMU_CLOCK_VIRTUAL. qtest commands
77 * let you adjust the value of the clock (monotonically). All the commands
78 * return the current value of the clock in nanoseconds.
80 * .. code-block:: none
82 * > clock_step
83 * < OK VALUE
85 * Advance the clock to the next deadline. Useful when waiting for
86 * asynchronous events.
88 * .. code-block:: none
90 * > clock_step NS
91 * < OK VALUE
93 * Advance the clock by NS nanoseconds.
95 * .. code-block:: none
97 * > clock_set NS
98 * < OK VALUE
100 * Advance the clock to NS nanoseconds (do nothing if it's already past).
102 * PIO and memory access:
103 * """"""""""""""""""""""
105 * .. code-block:: none
107 * > outb ADDR VALUE
108 * < OK
110 * .. code-block:: none
112 * > outw ADDR VALUE
113 * < OK
115 * .. code-block:: none
117 * > outl ADDR VALUE
118 * < OK
120 * .. code-block:: none
122 * > inb ADDR
123 * < OK VALUE
125 * .. code-block:: none
127 * > inw ADDR
128 * < OK VALUE
130 * .. code-block:: none
132 * > inl ADDR
133 * < OK VALUE
135 * .. code-block:: none
137 * > writeb ADDR VALUE
138 * < OK
140 * .. code-block:: none
142 * > writew ADDR VALUE
143 * < OK
145 * .. code-block:: none
147 * > writel ADDR VALUE
148 * < OK
150 * .. code-block:: none
152 * > writeq ADDR VALUE
153 * < OK
155 * .. code-block:: none
157 * > readb ADDR
158 * < OK VALUE
160 * .. code-block:: none
162 * > readw ADDR
163 * < OK VALUE
165 * .. code-block:: none
167 * > readl ADDR
168 * < OK VALUE
170 * .. code-block:: none
172 * > readq ADDR
173 * < OK VALUE
175 * .. code-block:: none
177 * > read ADDR SIZE
178 * < OK DATA
180 * .. code-block:: none
182 * > write ADDR SIZE DATA
183 * < OK
185 * .. code-block:: none
187 * > b64read ADDR SIZE
188 * < OK B64_DATA
190 * .. code-block:: none
192 * > b64write ADDR SIZE B64_DATA
193 * < OK
195 * .. code-block:: none
197 * > memset ADDR SIZE VALUE
198 * < OK
200 * ADDR, SIZE, VALUE are all integers parsed with strtoul() with a base of 0.
201 * For 'memset' a zero size is permitted and does nothing.
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.
207 * B64_DATA is an arbitrarily long base64 encoded string.
208 * If the sizes do not match, the data will be truncated.
210 * IRQ management:
211 * """""""""""""""
213 * .. code-block:: none
215 * > irq_intercept_in QOM-PATH
216 * < OK
218 * .. code-block:: none
220 * > irq_intercept_out QOM-PATH
221 * < OK
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
225 * will be printed to the qtest stream::
227 * IRQ raise NUM
228 * IRQ lower NUM
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).
234 * Setting interrupt level:
235 * """"""""""""""""""""""""
237 * .. code-block:: none
239 * > set_irq_in QOM-PATH NAME NUM LEVEL
240 * < OK
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.
245 * Forcibly set the given interrupt pin to the given level.
249 static int hex2nib(char ch)
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') {
256 return 10 + (ch - 'A');
257 } else {
258 return -1;
262 void qtest_send_prefix(CharBackend *chr)
264 if (!qtest_log_fp || !qtest_opened) {
265 return;
268 fprintf(qtest_log_fp, "[S +" FMT_timeval "] ", g_timer_elapsed(timer, NULL));
271 static void G_GNUC_PRINTF(1, 2) qtest_log_send(const char *fmt, ...)
273 va_list ap;
275 if (!qtest_log_fp || !qtest_opened) {
276 return;
279 qtest_send_prefix(NULL);
281 va_start(ap, fmt);
282 vfprintf(qtest_log_fp, fmt, ap);
283 va_end(ap);
286 static void qtest_server_char_be_send(void *opaque, const char *str)
288 size_t len = strlen(str);
289 CharBackend* chr = (CharBackend *)opaque;
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);
296 static void qtest_send(CharBackend *chr, const char *str)
298 qtest_server_send(qtest_server_send_opaque, str);
301 void qtest_sendf(CharBackend *chr, const char *fmt, ...)
303 va_list ap;
304 gchar *buffer;
306 va_start(ap, fmt);
307 buffer = g_strdup_vprintf(fmt, ap);
308 qtest_send(chr, buffer);
309 g_free(buffer);
310 va_end(ap);
313 static void qtest_irq_handler(void *opaque, int n, int level)
315 qemu_irq old_irq = *(qemu_irq *)opaque;
316 qemu_set_irq(old_irq, level);
318 if (irq_levels[n] != level) {
319 CharBackend *chr = &qtest->qtest_chr;
320 irq_levels[n] = level;
321 qtest_send_prefix(chr);
322 qtest_sendf(chr, "IRQ %s %d\n",
323 level ? "raise" : "lower", n);
327 static int64_t qtest_clock_counter;
329 int64_t qtest_get_virtual_clock(void)
331 return qatomic_read_i64(&qtest_clock_counter);
334 static void qtest_set_virtual_clock(int64_t count)
336 qatomic_set_i64(&qtest_clock_counter, count);
339 static void qtest_clock_warp(int64_t dest)
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);
350 qtest_set_virtual_clock(qtest_get_virtual_clock() + warp);
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);
356 qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
359 static bool (*process_command_cb)(CharBackend *chr, gchar **words);
361 void qtest_set_command_cb(bool (*pc_cb)(CharBackend *chr, gchar **words))
363 assert(!process_command_cb); /* Switch to a list if we need more than one */
365 process_command_cb = pc_cb;
368 static void qtest_process_command(CharBackend *chr, gchar **words)
370 const gchar *command;
372 g_assert(words);
374 command = words[0];
376 if (qtest_log_fp) {
377 int i;
379 fprintf(qtest_log_fp, "[R +" FMT_timeval "]", g_timer_elapsed(timer, NULL));
380 for (i = 0; words[i]; i++) {
381 fprintf(qtest_log_fp, " %s", words[i]);
383 fprintf(qtest_log_fp, "\n");
386 g_assert(command);
387 if (strcmp(words[0], "irq_intercept_out") == 0
388 || strcmp(words[0], "irq_intercept_in") == 0) {
389 DeviceState *dev;
390 NamedGPIOList *ngl;
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");
397 return;
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");
407 return;
410 QLIST_FOREACH(ngl, &dev->gpios, node) {
411 /* We don't support intercept of named GPIOs yet */
412 if (ngl->name) {
413 continue;
415 if (words[0][14] == 'o') {
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);
422 *disconnected = qdev_intercept_gpio_out(dev, icpt,
423 ngl->name, i);
425 } else {
426 qemu_irq_intercept_in(ngl->in, qtest_irq_handler,
427 ngl->num_in);
430 irq_intercept_dev = dev;
431 qtest_send_prefix(chr);
432 qtest_send(chr, "OK\n");
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;
441 g_assert(words[1] && words[2] && words[3] && words[4]);
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;
450 if (strcmp(words[2], "unnamed-gpio-in") == 0) {
451 name = NULL;
452 } else {
453 name = words[2];
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);
461 irq = qdev_get_gpio_in_named(dev, name, num);
463 qemu_set_irq(irq, level);
464 qtest_send_prefix(chr);
465 qtest_send(chr, "OK\n");
466 } else if (strcmp(words[0], "outb") == 0 ||
467 strcmp(words[0], "outw") == 0 ||
468 strcmp(words[0], "outl") == 0) {
469 unsigned long addr;
470 unsigned long value;
471 int ret;
473 g_assert(words[1] && words[2]);
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);
478 g_assert(addr <= 0xffff);
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);
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) {
492 unsigned long addr;
493 uint32_t value = -1U;
494 int ret;
496 g_assert(words[1]);
497 ret = qemu_strtoul(words[1], NULL, 0, &addr);
498 g_assert(ret == 0);
499 g_assert(addr <= 0xffff);
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);
508 qtest_send_prefix(chr);
509 qtest_sendf(chr, "OK 0x%04x\n", value);
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;
516 int ret;
518 g_assert(words[1] && words[2]);
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);
524 if (words[0][5] == 'b') {
525 uint8_t data = value;
526 address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
527 &data, 1);
528 } else if (words[0][5] == 'w') {
529 uint16_t data = value;
530 tswap16s(&data);
531 address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
532 &data, 2);
533 } else if (words[0][5] == 'l') {
534 uint32_t data = value;
535 tswap32s(&data);
536 address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
537 &data, 4);
538 } else if (words[0][5] == 'q') {
539 uint64_t data = value;
540 tswap64s(&data);
541 address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
542 &data, 8);
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);
552 int ret;
554 g_assert(words[1]);
555 ret = qemu_strtou64(words[1], NULL, 0, &addr);
556 g_assert(ret == 0);
558 if (words[0][4] == 'b') {
559 uint8_t data;
560 address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
561 &data, 1);
562 value = data;
563 } else if (words[0][4] == 'w') {
564 uint16_t data;
565 address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
566 &data, 2);
567 value = tswap16(data);
568 } else if (words[0][4] == 'l') {
569 uint32_t data;
570 address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
571 &data, 4);
572 value = tswap32(data);
573 } else if (words[0][4] == 'q') {
574 address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
575 &value, 8);
576 tswap64s(&value);
578 qtest_send_prefix(chr);
579 qtest_sendf(chr, "OK 0x%016" PRIx64 "\n", value);
580 } else if (strcmp(words[0], "read") == 0) {
581 uint64_t addr, len, i;
582 uint8_t *data;
583 char *enc;
584 int ret;
586 g_assert(words[1] && words[2]);
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);
591 /* We'd send garbage to libqtest if len is 0 */
592 g_assert(len);
594 data = g_malloc(len);
595 address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, data,
596 len);
598 enc = g_malloc(2 * len + 1);
599 for (i = 0; i < len; i++) {
600 sprintf(&enc[i * 2], "%02x", data[i]);
603 qtest_send_prefix(chr);
604 qtest_sendf(chr, "OK 0x%s\n", enc);
606 g_free(data);
607 g_free(enc);
608 } else if (strcmp(words[0], "b64read") == 0) {
609 uint64_t addr, len;
610 uint8_t *data;
611 gchar *b64_data;
612 int ret;
614 g_assert(words[1] && words[2]);
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);
620 data = g_malloc(len);
621 address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, data,
622 len);
623 b64_data = g_base64_encode(data, len);
624 qtest_send_prefix(chr);
625 qtest_sendf(chr, "OK %s\n", b64_data);
627 g_free(data);
628 g_free(b64_data);
629 } else if (strcmp(words[0], "write") == 0) {
630 uint64_t addr, len, i;
631 uint8_t *data;
632 size_t data_len;
633 int ret;
635 g_assert(words[1] && words[2] && words[3]);
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);
641 data_len = strlen(words[3]);
642 if (data_len < 3) {
643 qtest_send(chr, "ERR invalid argument size\n");
644 return;
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;
656 address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, data,
657 len);
658 g_free(data);
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;
665 unsigned long pattern;
666 int ret;
668 g_assert(words[1] && words[2] && words[3]);
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);
676 if (len) {
677 data = g_malloc(len);
678 memset(data, pattern, len);
679 address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
680 data, len);
681 g_free(data);
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;
691 int ret;
693 g_assert(words[1] && words[2] && words[3]);
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);
699 data_len = strlen(words[3]);
700 if (data_len < 3) {
701 qtest_send(chr, "ERR invalid argument size\n");
702 return;
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);
713 address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, data,
714 len);
716 qtest_send_prefix(chr);
717 qtest_send(chr, "OK\n");
718 } else if (strcmp(words[0], "endianness") == 0) {
719 qtest_send_prefix(chr);
720 if (target_words_bigendian()) {
721 qtest_sendf(chr, "OK big\n");
722 } else {
723 qtest_sendf(chr, "OK little\n");
725 } else if (qtest_enabled() && strcmp(words[0], "clock_step") == 0) {
726 int64_t ns;
728 if (words[1]) {
729 int ret = qemu_strtoi64(words[1], NULL, 0, &ns);
730 g_assert(ret == 0);
731 } else {
732 ns = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
733 QEMU_TIMER_ATTR_ALL);
735 qtest_clock_warp(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns);
736 qtest_send_prefix(chr);
737 qtest_sendf(chr, "OK %"PRIi64"\n",
738 (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
739 } else if (strcmp(words[0], "module_load") == 0) {
740 Error *local_err = NULL;
741 int rv;
742 g_assert(words[1] && words[2]);
744 qtest_send_prefix(chr);
745 rv = module_load(words[1], words[2], &local_err);
746 if (rv > 0) {
747 qtest_sendf(chr, "OK\n");
748 } else {
749 if (rv < 0) {
750 error_report_err(local_err);
752 qtest_sendf(chr, "FAIL\n");
754 } else if (qtest_enabled() && strcmp(words[0], "clock_set") == 0) {
755 int64_t ns;
756 int ret;
758 g_assert(words[1]);
759 ret = qemu_strtoi64(words[1], NULL, 0, &ns);
760 g_assert(ret == 0);
761 qtest_clock_warp(ns);
762 qtest_send_prefix(chr);
763 qtest_sendf(chr, "OK %"PRIi64"\n",
764 (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
765 } else if (process_command_cb && process_command_cb(chr, words)) {
766 /* Command got consumed by the callback handler */
767 } else {
768 qtest_send_prefix(chr);
769 qtest_sendf(chr, "FAIL Unknown command '%s'\n", words[0]);
773 static void qtest_process_inbuf(CharBackend *chr, GString *inbuf)
775 char *end;
777 while ((end = strchr(inbuf->str, '\n')) != NULL) {
778 size_t offset;
779 GString *cmd;
780 gchar **words;
782 offset = end - inbuf->str;
784 cmd = g_string_new_len(inbuf->str, offset);
785 g_string_erase(inbuf, 0, offset + 1);
787 words = g_strsplit(cmd->str, " ", 0);
788 qtest_process_command(chr, words);
789 g_strfreev(words);
791 g_string_free(cmd, TRUE);
795 static void qtest_read(void *opaque, const uint8_t *buf, int size)
797 CharBackend *chr = opaque;
799 g_string_append_len(inbuf, (const gchar *)buf, size);
800 qtest_process_inbuf(chr, inbuf);
803 static int qtest_can_read(void *opaque)
805 return 1024;
808 static void qtest_event(void *opaque, QEMUChrEvent event)
810 int i;
812 switch (event) {
813 case CHR_EVENT_OPENED:
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.
820 for (i = 0; i < ARRAY_SIZE(irq_levels); i++) {
821 irq_levels[i] = 0;
824 g_clear_pointer(&timer, g_timer_destroy);
825 timer = g_timer_new();
826 qtest_opened = true;
827 if (qtest_log_fp) {
828 fprintf(qtest_log_fp, "[I " FMT_timeval "] OPENED\n", g_timer_elapsed(timer, NULL));
830 break;
831 case CHR_EVENT_CLOSED:
832 qtest_opened = false;
833 if (qtest_log_fp) {
834 fprintf(qtest_log_fp, "[I +" FMT_timeval "] CLOSED\n", g_timer_elapsed(timer, NULL));
836 g_clear_pointer(&timer, g_timer_destroy);
837 break;
838 default:
839 break;
843 void qtest_server_init(const char *qtest_chrdev, const char *qtest_log, Error **errp)
845 ERRP_GUARD();
846 Chardev *chr;
847 Object *qtest;
849 chr = qemu_chr_new("qtest", qtest_chrdev, NULL);
850 if (chr == NULL) {
851 error_setg(errp, "Failed to initialize device for qtest: \"%s\"",
852 qtest_chrdev);
853 return;
856 qtest = object_new(TYPE_QTEST);
857 object_property_set_str(qtest, "chardev", chr->label, &error_abort);
858 if (qtest_log) {
859 object_property_set_str(qtest, "log", qtest_log, &error_abort);
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);
866 object_unref(OBJECT(chr));
867 object_unref(qtest);
870 static bool qtest_server_start(QTest *q, Error **errp)
872 Chardev *chr = q->chr;
873 const char *qtest_log = q->log;
875 if (qtest_log) {
876 if (strcmp(qtest_log, "none") != 0) {
877 qtest_log_fp = fopen(qtest_log, "w+");
879 } else {
880 qtest_log_fp = stderr;
883 if (!qemu_chr_fe_init(&q->qtest_chr, chr, errp)) {
884 return false;
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);
890 inbuf = g_string_new("");
892 if (!qtest_server_send) {
893 qtest_server_set_send_handler(qtest_server_char_be_send, &q->qtest_chr);
895 qtest = q;
896 return true;
899 void qtest_server_set_send_handler(void (*send)(void*, const char*),
900 void *opaque)
902 qtest_server_send = send;
903 qtest_server_send_opaque = opaque;
906 bool qtest_driver(void)
908 return qtest && qtest->qtest_chr.chr != NULL;
911 void qtest_server_inproc_recv(void *dummy, const char *buf)
913 static GString *gstr;
914 if (!gstr) {
915 gstr = g_string_new(NULL);
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);
924 static void qtest_complete(UserCreatable *uc, Error **errp)
926 QTest *q = QTEST(uc);
927 if (qtest) {
928 error_setg(errp, "Only one instance of qtest can be created");
929 return;
931 if (!q->chr_name) {
932 error_setg(errp, "No backend specified");
933 return;
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. */
943 qtest_server_start(q, errp);
946 static void qtest_unparent(Object *obj)
948 QTest *q = QTEST(obj);
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;
958 qtest = NULL;
961 if (q->has_machine_link) {
962 object_property_del(qdev_get_machine(), "qtest");
963 q->has_machine_link = false;
967 static void qtest_set_log(Object *obj, const char *value, Error **errp)
969 QTest *q = QTEST(obj);
971 if (qtest == q) {
972 error_setg(errp, "Property 'log' can not be set now");
973 } else {
974 g_free(q->log);
975 q->log = g_strdup(value);
979 static char *qtest_get_log(Object *obj, Error **errp)
981 QTest *q = QTEST(obj);
983 return g_strdup(q->log);
986 static void qtest_set_chardev(Object *obj, const char *value, Error **errp)
988 QTest *q = QTEST(obj);
989 Chardev *chr;
991 if (qtest == q) {
992 error_setg(errp, "Property 'chardev' can not be set now");
993 return;
996 chr = qemu_chr_find(value);
997 if (!chr) {
998 error_setg(errp, "Cannot find character device '%s'", value);
999 return;
1002 g_free(q->chr_name);
1003 q->chr_name = g_strdup(value);
1005 if (q->chr) {
1006 object_unref(q->chr);
1008 q->chr = chr;
1009 object_ref(chr);
1012 static char *qtest_get_chardev(Object *obj, Error **errp)
1014 QTest *q = QTEST(obj);
1016 return g_strdup(q->chr_name);
1019 static void qtest_class_init(ObjectClass *oc, void *data)
1021 UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
1023 oc->unparent = qtest_unparent;
1024 ucc->complete = qtest_complete;
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);
1032 static 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 },
1043 static void register_types(void)
1045 type_register_static(&qtest_info);
1048 type_init(register_types);