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