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