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