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