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