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 "sysemu/accel.h"
24#include "sysemu/cpus.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 "config-devices.h"
31#ifdef CONFIG_PSERIES
32#include "hw/ppc/spapr_rtas.h"
33#endif
34
35#define MAX_IRQ 256
36
37bool qtest_allowed;
38
39static DeviceState *irq_intercept_dev;
40static FILE *qtest_log_fp;
41static CharBackend qtest_chr;
42static GString *inbuf;
43static int irq_levels[MAX_IRQ];
44static qemu_timeval start_time;
45static bool qtest_opened;
46static void (*qtest_server_send)(void*, const char*);
47static void *qtest_server_send_opaque;
48
49#define FMT_timeval "%ld.%06ld"
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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
182static int hex2nib(char ch)
183{
184 if (ch >= '0' && ch <= '9') {
185 return ch - '0';
186 } else if (ch >= 'a' && ch <= 'f') {
187 return 10 + (ch - 'a');
188 } else if (ch >= 'A' && ch <= 'F') {
189 return 10 + (ch - 'A');
190 } else {
191 return -1;
192 }
193}
194
195static void qtest_get_time(qemu_timeval *tv)
196{
197 qemu_gettimeofday(tv);
198 tv->tv_sec -= start_time.tv_sec;
199 tv->tv_usec -= start_time.tv_usec;
200 if (tv->tv_usec < 0) {
201 tv->tv_usec += 1000000;
202 tv->tv_sec -= 1;
203 }
204}
205
206static void qtest_send_prefix(CharBackend *chr)
207{
208 qemu_timeval tv;
209
210 if (!qtest_log_fp || !qtest_opened) {
211 return;
212 }
213
214 qtest_get_time(&tv);
215 fprintf(qtest_log_fp, "[S +" FMT_timeval "] ",
216 (long) tv.tv_sec, (long) tv.tv_usec);
217}
218
219static void GCC_FMT_ATTR(1, 2) qtest_log_send(const char *fmt, ...)
220{
221 va_list ap;
222
223 if (!qtest_log_fp || !qtest_opened) {
224 return;
225 }
226
227 qtest_send_prefix(NULL);
228
229 va_start(ap, fmt);
230 vfprintf(qtest_log_fp, fmt, ap);
231 va_end(ap);
232}
233
234static void qtest_server_char_be_send(void *opaque, const char *str)
235{
236 size_t len = strlen(str);
237 CharBackend* chr = (CharBackend *)opaque;
238 qemu_chr_fe_write_all(chr, (uint8_t *)str, len);
239 if (qtest_log_fp && qtest_opened) {
240 fprintf(qtest_log_fp, "%s", str);
241 }
242}
243
244static void qtest_send(CharBackend *chr, const char *str)
245{
246 qtest_server_send(qtest_server_send_opaque, str);
247}
248
249static void GCC_FMT_ATTR(2, 3) qtest_sendf(CharBackend *chr,
250 const char *fmt, ...)
251{
252 va_list ap;
253 gchar *buffer;
254
255 va_start(ap, fmt);
256 buffer = g_strdup_vprintf(fmt, ap);
257 qtest_send(chr, buffer);
258 g_free(buffer);
259 va_end(ap);
260}
261
262static void qtest_irq_handler(void *opaque, int n, int level)
263{
264 qemu_irq old_irq = *(qemu_irq *)opaque;
265 qemu_set_irq(old_irq, level);
266
267 if (irq_levels[n] != level) {
268 CharBackend *chr = &qtest_chr;
269 irq_levels[n] = level;
270 qtest_send_prefix(chr);
271 qtest_sendf(chr, "IRQ %s %d\n",
272 level ? "raise" : "lower", n);
273 }
274}
275
276static void qtest_process_command(CharBackend *chr, gchar **words)
277{
278 const gchar *command;
279
280 g_assert(words);
281
282 command = words[0];
283
284 if (qtest_log_fp) {
285 qemu_timeval tv;
286 int i;
287
288 qtest_get_time(&tv);
289 fprintf(qtest_log_fp, "[R +" FMT_timeval "]",
290 (long) tv.tv_sec, (long) tv.tv_usec);
291 for (i = 0; words[i]; i++) {
292 fprintf(qtest_log_fp, " %s", words[i]);
293 }
294 fprintf(qtest_log_fp, "\n");
295 }
296
297 g_assert(command);
298 if (strcmp(words[0], "irq_intercept_out") == 0
299 || strcmp(words[0], "irq_intercept_in") == 0) {
300 DeviceState *dev;
301 NamedGPIOList *ngl;
302
303 g_assert(words[1]);
304 dev = DEVICE(object_resolve_path(words[1], NULL));
305 if (!dev) {
306 qtest_send_prefix(chr);
307 qtest_send(chr, "FAIL Unknown device\n");
308 return;
309 }
310
311 if (irq_intercept_dev) {
312 qtest_send_prefix(chr);
313 if (irq_intercept_dev != dev) {
314 qtest_send(chr, "FAIL IRQ intercept already enabled\n");
315 } else {
316 qtest_send(chr, "OK\n");
317 }
318 return;
319 }
320
321 QLIST_FOREACH(ngl, &dev->gpios, node) {
322
323 if (ngl->name) {
324 continue;
325 }
326 if (words[0][14] == 'o') {
327 int i;
328 for (i = 0; i < ngl->num_out; ++i) {
329 qemu_irq *disconnected = g_new0(qemu_irq, 1);
330 qemu_irq icpt = qemu_allocate_irq(qtest_irq_handler,
331 disconnected, i);
332
333 *disconnected = qdev_intercept_gpio_out(dev, icpt,
334 ngl->name, i);
335 }
336 } else {
337 qemu_irq_intercept_in(ngl->in, qtest_irq_handler,
338 ngl->num_in);
339 }
340 }
341 irq_intercept_dev = dev;
342 qtest_send_prefix(chr);
343 qtest_send(chr, "OK\n");
344 } else if (strcmp(words[0], "set_irq_in") == 0) {
345 DeviceState *dev;
346 qemu_irq irq;
347 char *name;
348 int ret;
349 int num;
350 int level;
351
352 g_assert(words[1] && words[2] && words[3] && words[4]);
353
354 dev = DEVICE(object_resolve_path(words[1], NULL));
355 if (!dev) {
356 qtest_send_prefix(chr);
357 qtest_send(chr, "FAIL Unknown device\n");
358 return;
359 }
360
361 if (strcmp(words[2], "unnamed-gpio-in") == 0) {
362 name = NULL;
363 } else {
364 name = words[2];
365 }
366
367 ret = qemu_strtoi(words[3], NULL, 0, &num);
368 g_assert(!ret);
369 ret = qemu_strtoi(words[4], NULL, 0, &level);
370 g_assert(!ret);
371
372 irq = qdev_get_gpio_in_named(dev, name, num);
373
374 qemu_set_irq(irq, level);
375 qtest_send_prefix(chr);
376 qtest_send(chr, "OK\n");
377 } else if (strcmp(words[0], "outb") == 0 ||
378 strcmp(words[0], "outw") == 0 ||
379 strcmp(words[0], "outl") == 0) {
380 unsigned long addr;
381 unsigned long value;
382 int ret;
383
384 g_assert(words[1] && words[2]);
385 ret = qemu_strtoul(words[1], NULL, 0, &addr);
386 g_assert(ret == 0);
387 ret = qemu_strtoul(words[2], NULL, 0, &value);
388 g_assert(ret == 0);
389 g_assert(addr <= 0xffff);
390
391 if (words[0][3] == 'b') {
392 cpu_outb(addr, value);
393 } else if (words[0][3] == 'w') {
394 cpu_outw(addr, value);
395 } else if (words[0][3] == 'l') {
396 cpu_outl(addr, value);
397 }
398 qtest_send_prefix(chr);
399 qtest_send(chr, "OK\n");
400 } else if (strcmp(words[0], "inb") == 0 ||
401 strcmp(words[0], "inw") == 0 ||
402 strcmp(words[0], "inl") == 0) {
403 unsigned long addr;
404 uint32_t value = -1U;
405 int ret;
406
407 g_assert(words[1]);
408 ret = qemu_strtoul(words[1], NULL, 0, &addr);
409 g_assert(ret == 0);
410 g_assert(addr <= 0xffff);
411
412 if (words[0][2] == 'b') {
413 value = cpu_inb(addr);
414 } else if (words[0][2] == 'w') {
415 value = cpu_inw(addr);
416 } else if (words[0][2] == 'l') {
417 value = cpu_inl(addr);
418 }
419 qtest_send_prefix(chr);
420 qtest_sendf(chr, "OK 0x%04x\n", value);
421 } else if (strcmp(words[0], "writeb") == 0 ||
422 strcmp(words[0], "writew") == 0 ||
423 strcmp(words[0], "writel") == 0 ||
424 strcmp(words[0], "writeq") == 0) {
425 uint64_t addr;
426 uint64_t value;
427 int ret;
428
429 g_assert(words[1] && words[2]);
430 ret = qemu_strtou64(words[1], NULL, 0, &addr);
431 g_assert(ret == 0);
432 ret = qemu_strtou64(words[2], NULL, 0, &value);
433 g_assert(ret == 0);
434
435 if (words[0][5] == 'b') {
436 uint8_t data = value;
437 address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
438 &data, 1);
439 } else if (words[0][5] == 'w') {
440 uint16_t data = value;
441 tswap16s(&data);
442 address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
443 &data, 2);
444 } else if (words[0][5] == 'l') {
445 uint32_t data = value;
446 tswap32s(&data);
447 address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
448 &data, 4);
449 } else if (words[0][5] == 'q') {
450 uint64_t data = value;
451 tswap64s(&data);
452 address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
453 &data, 8);
454 }
455 qtest_send_prefix(chr);
456 qtest_send(chr, "OK\n");
457 } else if (strcmp(words[0], "readb") == 0 ||
458 strcmp(words[0], "readw") == 0 ||
459 strcmp(words[0], "readl") == 0 ||
460 strcmp(words[0], "readq") == 0) {
461 uint64_t addr;
462 uint64_t value = UINT64_C(-1);
463 int ret;
464
465 g_assert(words[1]);
466 ret = qemu_strtou64(words[1], NULL, 0, &addr);
467 g_assert(ret == 0);
468
469 if (words[0][4] == 'b') {
470 uint8_t data;
471 address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
472 &data, 1);
473 value = data;
474 } else if (words[0][4] == 'w') {
475 uint16_t data;
476 address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
477 &data, 2);
478 value = tswap16(data);
479 } else if (words[0][4] == 'l') {
480 uint32_t data;
481 address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
482 &data, 4);
483 value = tswap32(data);
484 } else if (words[0][4] == 'q') {
485 address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
486 &value, 8);
487 tswap64s(&value);
488 }
489 qtest_send_prefix(chr);
490 qtest_sendf(chr, "OK 0x%016" PRIx64 "\n", value);
491 } else if (strcmp(words[0], "read") == 0) {
492 uint64_t addr, len, i;
493 uint8_t *data;
494 char *enc;
495 int ret;
496
497 g_assert(words[1] && words[2]);
498 ret = qemu_strtou64(words[1], NULL, 0, &addr);
499 g_assert(ret == 0);
500 ret = qemu_strtou64(words[2], NULL, 0, &len);
501 g_assert(ret == 0);
502
503 g_assert(len);
504
505 data = g_malloc(len);
506 address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, data,
507 len);
508
509 enc = g_malloc(2 * len + 1);
510 for (i = 0; i < len; i++) {
511 sprintf(&enc[i * 2], "%02x", data[i]);
512 }
513
514 qtest_send_prefix(chr);
515 qtest_sendf(chr, "OK 0x%s\n", enc);
516
517 g_free(data);
518 g_free(enc);
519 } else if (strcmp(words[0], "b64read") == 0) {
520 uint64_t addr, len;
521 uint8_t *data;
522 gchar *b64_data;
523 int ret;
524
525 g_assert(words[1] && words[2]);
526 ret = qemu_strtou64(words[1], NULL, 0, &addr);
527 g_assert(ret == 0);
528 ret = qemu_strtou64(words[2], NULL, 0, &len);
529 g_assert(ret == 0);
530
531 data = g_malloc(len);
532 address_space_read(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, data,
533 len);
534 b64_data = g_base64_encode(data, len);
535 qtest_send_prefix(chr);
536 qtest_sendf(chr, "OK %s\n", b64_data);
537
538 g_free(data);
539 g_free(b64_data);
540 } else if (strcmp(words[0], "write") == 0) {
541 uint64_t addr, len, i;
542 uint8_t *data;
543 size_t data_len;
544 int ret;
545
546 g_assert(words[1] && words[2] && words[3]);
547 ret = qemu_strtou64(words[1], NULL, 0, &addr);
548 g_assert(ret == 0);
549 ret = qemu_strtou64(words[2], NULL, 0, &len);
550 g_assert(ret == 0);
551
552 data_len = strlen(words[3]);
553 if (data_len < 3) {
554 qtest_send(chr, "ERR invalid argument size\n");
555 return;
556 }
557
558 data = g_malloc(len);
559 for (i = 0; i < len; i++) {
560 if ((i * 2 + 4) <= data_len) {
561 data[i] = hex2nib(words[3][i * 2 + 2]) << 4;
562 data[i] |= hex2nib(words[3][i * 2 + 3]);
563 } else {
564 data[i] = 0;
565 }
566 }
567 address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, data,
568 len);
569 g_free(data);
570
571 qtest_send_prefix(chr);
572 qtest_send(chr, "OK\n");
573 } else if (strcmp(words[0], "memset") == 0) {
574 uint64_t addr, len;
575 uint8_t *data;
576 unsigned long pattern;
577 int ret;
578
579 g_assert(words[1] && words[2] && words[3]);
580 ret = qemu_strtou64(words[1], NULL, 0, &addr);
581 g_assert(ret == 0);
582 ret = qemu_strtou64(words[2], NULL, 0, &len);
583 g_assert(ret == 0);
584 ret = qemu_strtoul(words[3], NULL, 0, &pattern);
585 g_assert(ret == 0);
586
587 if (len) {
588 data = g_malloc(len);
589 memset(data, pattern, len);
590 address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED,
591 data, len);
592 g_free(data);
593 }
594
595 qtest_send_prefix(chr);
596 qtest_send(chr, "OK\n");
597 } else if (strcmp(words[0], "b64write") == 0) {
598 uint64_t addr, len;
599 uint8_t *data;
600 size_t data_len;
601 gsize out_len;
602 int ret;
603
604 g_assert(words[1] && words[2] && words[3]);
605 ret = qemu_strtou64(words[1], NULL, 0, &addr);
606 g_assert(ret == 0);
607 ret = qemu_strtou64(words[2], NULL, 0, &len);
608 g_assert(ret == 0);
609
610 data_len = strlen(words[3]);
611 if (data_len < 3) {
612 qtest_send(chr, "ERR invalid argument size\n");
613 return;
614 }
615
616 data = g_base64_decode_inplace(words[3], &out_len);
617 if (out_len != len) {
618 qtest_log_send("b64write: data length mismatch (told %"PRIu64", "
619 "found %zu)\n",
620 len, out_len);
621 out_len = MIN(out_len, len);
622 }
623
624 address_space_write(first_cpu->as, addr, MEMTXATTRS_UNSPECIFIED, data,
625 len);
626
627 qtest_send_prefix(chr);
628 qtest_send(chr, "OK\n");
629 } else if (strcmp(words[0], "endianness") == 0) {
630 qtest_send_prefix(chr);
631#if defined(TARGET_WORDS_BIGENDIAN)
632 qtest_sendf(chr, "OK big\n");
633#else
634 qtest_sendf(chr, "OK little\n");
635#endif
636#ifdef CONFIG_PSERIES
637 } else if (strcmp(words[0], "rtas") == 0) {
638 uint64_t res, args, ret;
639 unsigned long nargs, nret;
640 int rc;
641
642 rc = qemu_strtoul(words[2], NULL, 0, &nargs);
643 g_assert(rc == 0);
644 rc = qemu_strtou64(words[3], NULL, 0, &args);
645 g_assert(rc == 0);
646 rc = qemu_strtoul(words[4], NULL, 0, &nret);
647 g_assert(rc == 0);
648 rc = qemu_strtou64(words[5], NULL, 0, &ret);
649 g_assert(rc == 0);
650 res = qtest_rtas_call(words[1], nargs, args, nret, ret);
651
652 qtest_send_prefix(chr);
653 qtest_sendf(chr, "OK %"PRIu64"\n", res);
654#endif
655 } else if (qtest_enabled() && strcmp(words[0], "clock_step") == 0) {
656 int64_t ns;
657
658 if (words[1]) {
659 int ret = qemu_strtoi64(words[1], NULL, 0, &ns);
660 g_assert(ret == 0);
661 } else {
662 ns = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
663 QEMU_TIMER_ATTR_ALL);
664 }
665 qtest_clock_warp(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns);
666 qtest_send_prefix(chr);
667 qtest_sendf(chr, "OK %"PRIi64"\n",
668 (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
669 } else if (strcmp(words[0], "module_load") == 0) {
670 g_assert(words[1] && words[2]);
671
672 qtest_send_prefix(chr);
673 if (module_load_one(words[1], words[2])) {
674 qtest_sendf(chr, "OK\n");
675 } else {
676 qtest_sendf(chr, "FAIL\n");
677 }
678 } else if (qtest_enabled() && strcmp(words[0], "clock_set") == 0) {
679 int64_t ns;
680 int ret;
681
682 g_assert(words[1]);
683 ret = qemu_strtoi64(words[1], NULL, 0, &ns);
684 g_assert(ret == 0);
685 qtest_clock_warp(ns);
686 qtest_send_prefix(chr);
687 qtest_sendf(chr, "OK %"PRIi64"\n",
688 (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
689 } else {
690 qtest_send_prefix(chr);
691 qtest_sendf(chr, "FAIL Unknown command '%s'\n", words[0]);
692 }
693}
694
695static void qtest_process_inbuf(CharBackend *chr, GString *inbuf)
696{
697 char *end;
698
699 while ((end = strchr(inbuf->str, '\n')) != NULL) {
700 size_t offset;
701 GString *cmd;
702 gchar **words;
703
704 offset = end - inbuf->str;
705
706 cmd = g_string_new_len(inbuf->str, offset);
707 g_string_erase(inbuf, 0, offset + 1);
708
709 words = g_strsplit(cmd->str, " ", 0);
710 qtest_process_command(chr, words);
711 g_strfreev(words);
712
713 g_string_free(cmd, TRUE);
714 }
715}
716
717static void qtest_read(void *opaque, const uint8_t *buf, int size)
718{
719 CharBackend *chr = opaque;
720
721 g_string_append_len(inbuf, (const gchar *)buf, size);
722 qtest_process_inbuf(chr, inbuf);
723}
724
725static int qtest_can_read(void *opaque)
726{
727 return 1024;
728}
729
730static void qtest_event(void *opaque, QEMUChrEvent event)
731{
732 int i;
733
734 switch (event) {
735 case CHR_EVENT_OPENED:
736
737
738
739
740
741
742 for (i = 0; i < ARRAY_SIZE(irq_levels); i++) {
743 irq_levels[i] = 0;
744 }
745 qemu_gettimeofday(&start_time);
746 qtest_opened = true;
747 if (qtest_log_fp) {
748 fprintf(qtest_log_fp, "[I " FMT_timeval "] OPENED\n",
749 (long) start_time.tv_sec, (long) start_time.tv_usec);
750 }
751 break;
752 case CHR_EVENT_CLOSED:
753 qtest_opened = false;
754 if (qtest_log_fp) {
755 qemu_timeval tv;
756 qtest_get_time(&tv);
757 fprintf(qtest_log_fp, "[I +" FMT_timeval "] CLOSED\n",
758 (long) tv.tv_sec, (long) tv.tv_usec);
759 }
760 break;
761 default:
762 break;
763 }
764}
765void qtest_server_init(const char *qtest_chrdev, const char *qtest_log, Error **errp)
766{
767 Chardev *chr;
768
769 chr = qemu_chr_new("qtest", qtest_chrdev, NULL);
770
771 if (chr == NULL) {
772 error_setg(errp, "Failed to initialize device for qtest: \"%s\"",
773 qtest_chrdev);
774 return;
775 }
776
777 if (qtest_log) {
778 if (strcmp(qtest_log, "none") != 0) {
779 qtest_log_fp = fopen(qtest_log, "w+");
780 }
781 } else {
782 qtest_log_fp = stderr;
783 }
784
785 qemu_chr_fe_init(&qtest_chr, chr, errp);
786 qemu_chr_fe_set_handlers(&qtest_chr, qtest_can_read, qtest_read,
787 qtest_event, NULL, &qtest_chr, NULL, true);
788 qemu_chr_fe_set_echo(&qtest_chr, true);
789
790 inbuf = g_string_new("");
791
792 if (!qtest_server_send) {
793 qtest_server_set_send_handler(qtest_server_char_be_send, &qtest_chr);
794 }
795}
796
797void qtest_server_set_send_handler(void (*send)(void*, const char*),
798 void *opaque)
799{
800 qtest_server_send = send;
801 qtest_server_send_opaque = opaque;
802}
803
804bool qtest_driver(void)
805{
806 return qtest_chr.chr != NULL;
807}
808
809void qtest_server_inproc_recv(void *dummy, const char *buf)
810{
811 static GString *gstr;
812 if (!gstr) {
813 gstr = g_string_new(NULL);
814 }
815 g_string_append(gstr, buf);
816 if (gstr->str[gstr->len - 1] == '\n') {
817 qtest_process_inbuf(NULL, gstr);
818 g_string_truncate(gstr, 0);
819 }
820}
821