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