qtest: Add base64 encoded read/write
[sdk/emulator/qemu.git] / qtest.c
1 /*
2  * Test Server
3  *
4  * Copyright IBM, Corp. 2011
5  *
6  * Authors:
7  *  Anthony Liguori   <aliguori@us.ibm.com>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2 or later.
10  * See the COPYING file in the top-level directory.
11  *
12  */
13
14 #include "sysemu/qtest.h"
15 #include "hw/qdev.h"
16 #include "sysemu/char.h"
17 #include "exec/ioport.h"
18 #include "exec/memory.h"
19 #include "hw/irq.h"
20 #include "sysemu/accel.h"
21 #include "sysemu/sysemu.h"
22 #include "sysemu/cpus.h"
23 #include "qemu/config-file.h"
24 #include "qemu/option.h"
25 #include "qemu/error-report.h"
26
27 #define MAX_IRQ 256
28
29 bool qtest_allowed;
30
31 static DeviceState *irq_intercept_dev;
32 static FILE *qtest_log_fp;
33 static CharDriverState *qtest_chr;
34 static GString *inbuf;
35 static int irq_levels[MAX_IRQ];
36 static qemu_timeval start_time;
37 static bool qtest_opened;
38
39 #define FMT_timeval "%ld.%06ld"
40
41 /**
42  * QTest Protocol
43  *
44  * Line based protocol, request/response based.  Server can send async messages
45  * so clients should always handle many async messages before the response
46  * comes in.
47  *
48  * Valid requests
49  *
50  * Clock management:
51  *
52  * The qtest client is completely in charge of the QEMU_CLOCK_VIRTUAL.  qtest commands
53  * let you adjust the value of the clock (monotonically).  All the commands
54  * return the current value of the clock in nanoseconds.
55  *
56  *  > clock_step
57  *  < OK VALUE
58  *
59  *     Advance the clock to the next deadline.  Useful when waiting for
60  *     asynchronous events.
61  *
62  *  > clock_step NS
63  *  < OK VALUE
64  *
65  *     Advance the clock by NS nanoseconds.
66  *
67  *  > clock_set NS
68  *  < OK VALUE
69  *
70  *     Advance the clock to NS nanoseconds (do nothing if it's already past).
71  *
72  * PIO and memory access:
73  *
74  *  > outb ADDR VALUE
75  *  < OK
76  *
77  *  > outw ADDR VALUE
78  *  < OK
79  *
80  *  > outl ADDR VALUE
81  *  < OK
82  *
83  *  > inb ADDR
84  *  < OK VALUE
85  *
86  *  > inw ADDR
87  *  < OK VALUE
88  *
89  *  > inl ADDR
90  *  < OK VALUE
91  *
92  *  > writeb ADDR VALUE
93  *  < OK
94  *
95  *  > writew ADDR VALUE
96  *  < OK
97  *
98  *  > writel ADDR VALUE
99  *  < OK
100  *
101  *  > writeq ADDR VALUE
102  *  < OK
103  *
104  *  > readb ADDR
105  *  < OK VALUE
106  *
107  *  > readw ADDR
108  *  < OK VALUE
109  *
110  *  > readl ADDR
111  *  < OK VALUE
112  *
113  *  > readq ADDR
114  *  < OK VALUE
115  *
116  *  > read ADDR SIZE
117  *  < OK DATA
118  *
119  *  > write ADDR SIZE DATA
120  *  < OK
121  *
122  *  > b64read ADDR SIZE
123  *  < OK B64_DATA
124  *
125  *  > b64write ADDR SIZE B64_DATA
126  *  < OK
127  *
128  * ADDR, SIZE, VALUE are all integers parsed with strtoul() with a base of 0.
129  *
130  * DATA is an arbitrarily long hex number prefixed with '0x'.  If it's smaller
131  * than the expected size, the value will be zero filled at the end of the data
132  * sequence.
133  *
134  * B64_DATA is an arbitrarily long base64 encoded string.
135  * If the sizes do not match, the data will be truncated.
136  *
137  * IRQ management:
138  *
139  *  > irq_intercept_in QOM-PATH
140  *  < OK
141  *
142  *  > irq_intercept_out QOM-PATH
143  *  < OK
144  *
145  * Attach to the gpio-in (resp. gpio-out) pins exported by the device at
146  * QOM-PATH.  When the pin is triggered, one of the following async messages
147  * will be printed to the qtest stream:
148  *
149  *  IRQ raise NUM
150  *  IRQ lower NUM
151  *
152  * where NUM is an IRQ number.  For the PC, interrupts can be intercepted
153  * simply with "irq_intercept_in ioapic" (note that IRQ0 comes out with
154  * NUM=0 even though it is remapped to GSI 2).
155  */
156
157 static int hex2nib(char ch)
158 {
159     if (ch >= '0' && ch <= '9') {
160         return ch - '0';
161     } else if (ch >= 'a' && ch <= 'f') {
162         return 10 + (ch - 'a');
163     } else if (ch >= 'A' && ch <= 'F') {
164         return 10 + (ch - 'A');
165     } else {
166         return -1;
167     }
168 }
169
170 static void qtest_get_time(qemu_timeval *tv)
171 {
172     qemu_gettimeofday(tv);
173     tv->tv_sec -= start_time.tv_sec;
174     tv->tv_usec -= start_time.tv_usec;
175     if (tv->tv_usec < 0) {
176         tv->tv_usec += 1000000;
177         tv->tv_sec -= 1;
178     }
179 }
180
181 static void qtest_send_prefix(CharDriverState *chr)
182 {
183     qemu_timeval tv;
184
185     if (!qtest_log_fp || !qtest_opened) {
186         return;
187     }
188
189     qtest_get_time(&tv);
190     fprintf(qtest_log_fp, "[S +" FMT_timeval "] ",
191             (long) tv.tv_sec, (long) tv.tv_usec);
192 }
193
194 static void GCC_FMT_ATTR(1, 2) qtest_log_send(const char *fmt, ...)
195 {
196     va_list ap;
197
198     if (!qtest_log_fp || !qtest_opened) {
199         return;
200     }
201
202     qtest_send_prefix(NULL);
203
204     va_start(ap, fmt);
205     vfprintf(qtest_log_fp, fmt, ap);
206     va_end(ap);
207 }
208
209 static void do_qtest_send(CharDriverState *chr, const char *str, size_t len)
210 {
211     qemu_chr_fe_write_all(chr, (uint8_t *)str, len);
212     if (qtest_log_fp && qtest_opened) {
213         fprintf(qtest_log_fp, "%s", str);
214     }
215 }
216
217 static void qtest_send(CharDriverState *chr, const char *str)
218 {
219     do_qtest_send(chr, str, strlen(str));
220 }
221
222 static void GCC_FMT_ATTR(2, 3) qtest_sendf(CharDriverState *chr,
223                                            const char *fmt, ...)
224 {
225     va_list ap;
226     gchar *buffer;
227
228     va_start(ap, fmt);
229     buffer = g_strdup_vprintf(fmt, ap);
230     qtest_send(chr, buffer);
231     va_end(ap);
232 }
233
234 static void qtest_irq_handler(void *opaque, int n, int level)
235 {
236     qemu_irq old_irq = *(qemu_irq *)opaque;
237     qemu_set_irq(old_irq, level);
238
239     if (irq_levels[n] != level) {
240         CharDriverState *chr = qtest_chr;
241         irq_levels[n] = level;
242         qtest_send_prefix(chr);
243         qtest_sendf(chr, "IRQ %s %d\n",
244                     level ? "raise" : "lower", n);
245     }
246 }
247
248 static void qtest_process_command(CharDriverState *chr, gchar **words)
249 {
250     const gchar *command;
251
252     g_assert(words);
253
254     command = words[0];
255
256     if (qtest_log_fp) {
257         qemu_timeval tv;
258         int i;
259
260         qtest_get_time(&tv);
261         fprintf(qtest_log_fp, "[R +" FMT_timeval "]",
262                 (long) tv.tv_sec, (long) tv.tv_usec);
263         for (i = 0; words[i]; i++) {
264             fprintf(qtest_log_fp, " %s", words[i]);
265         }
266         fprintf(qtest_log_fp, "\n");
267     }
268
269     g_assert(command);
270     if (strcmp(words[0], "irq_intercept_out") == 0
271         || strcmp(words[0], "irq_intercept_in") == 0) {
272         DeviceState *dev;
273         NamedGPIOList *ngl;
274
275         g_assert(words[1]);
276         dev = DEVICE(object_resolve_path(words[1], NULL));
277         if (!dev) {
278             qtest_send_prefix(chr);
279             qtest_send(chr, "FAIL Unknown device\n");
280             return;
281         }
282
283         if (irq_intercept_dev) {
284             qtest_send_prefix(chr);
285             if (irq_intercept_dev != dev) {
286                 qtest_send(chr, "FAIL IRQ intercept already enabled\n");
287             } else {
288                 qtest_send(chr, "OK\n");
289             }
290             return;
291         }
292
293         QLIST_FOREACH(ngl, &dev->gpios, node) {
294             /* We don't support intercept of named GPIOs yet */
295             if (ngl->name) {
296                 continue;
297             }
298             if (words[0][14] == 'o') {
299                 int i;
300                 for (i = 0; i < ngl->num_out; ++i) {
301                     qemu_irq *disconnected = g_new0(qemu_irq, 1);
302                     qemu_irq icpt = qemu_allocate_irq(qtest_irq_handler,
303                                                       disconnected, i);
304
305                     *disconnected = qdev_intercept_gpio_out(dev, icpt,
306                                                             ngl->name, i);
307                 }
308             } else {
309                 qemu_irq_intercept_in(ngl->in, qtest_irq_handler,
310                                       ngl->num_in);
311             }
312         }
313         irq_intercept_dev = dev;
314         qtest_send_prefix(chr);
315         qtest_send(chr, "OK\n");
316
317     } else if (strcmp(words[0], "outb") == 0 ||
318                strcmp(words[0], "outw") == 0 ||
319                strcmp(words[0], "outl") == 0) {
320         uint16_t addr;
321         uint32_t value;
322
323         g_assert(words[1] && words[2]);
324         addr = strtoul(words[1], NULL, 0);
325         value = strtoul(words[2], NULL, 0);
326
327         if (words[0][3] == 'b') {
328             cpu_outb(addr, value);
329         } else if (words[0][3] == 'w') {
330             cpu_outw(addr, value);
331         } else if (words[0][3] == 'l') {
332             cpu_outl(addr, value);
333         }
334         qtest_send_prefix(chr);
335         qtest_send(chr, "OK\n");
336     } else if (strcmp(words[0], "inb") == 0 ||
337         strcmp(words[0], "inw") == 0 ||
338         strcmp(words[0], "inl") == 0) {
339         uint16_t addr;
340         uint32_t value = -1U;
341
342         g_assert(words[1]);
343         addr = strtoul(words[1], NULL, 0);
344
345         if (words[0][2] == 'b') {
346             value = cpu_inb(addr);
347         } else if (words[0][2] == 'w') {
348             value = cpu_inw(addr);
349         } else if (words[0][2] == 'l') {
350             value = cpu_inl(addr);
351         }
352         qtest_send_prefix(chr);
353         qtest_sendf(chr, "OK 0x%04x\n", value);
354     } else if (strcmp(words[0], "writeb") == 0 ||
355                strcmp(words[0], "writew") == 0 ||
356                strcmp(words[0], "writel") == 0 ||
357                strcmp(words[0], "writeq") == 0) {
358         uint64_t addr;
359         uint64_t value;
360
361         g_assert(words[1] && words[2]);
362         addr = strtoull(words[1], NULL, 0);
363         value = strtoull(words[2], NULL, 0);
364
365         if (words[0][5] == 'b') {
366             uint8_t data = value;
367             cpu_physical_memory_write(addr, &data, 1);
368         } else if (words[0][5] == 'w') {
369             uint16_t data = value;
370             tswap16s(&data);
371             cpu_physical_memory_write(addr, &data, 2);
372         } else if (words[0][5] == 'l') {
373             uint32_t data = value;
374             tswap32s(&data);
375             cpu_physical_memory_write(addr, &data, 4);
376         } else if (words[0][5] == 'q') {
377             uint64_t data = value;
378             tswap64s(&data);
379             cpu_physical_memory_write(addr, &data, 8);
380         }
381         qtest_send_prefix(chr);
382         qtest_send(chr, "OK\n");
383     } else if (strcmp(words[0], "readb") == 0 ||
384                strcmp(words[0], "readw") == 0 ||
385                strcmp(words[0], "readl") == 0 ||
386                strcmp(words[0], "readq") == 0) {
387         uint64_t addr;
388         uint64_t value = UINT64_C(-1);
389
390         g_assert(words[1]);
391         addr = strtoull(words[1], NULL, 0);
392
393         if (words[0][4] == 'b') {
394             uint8_t data;
395             cpu_physical_memory_read(addr, &data, 1);
396             value = data;
397         } else if (words[0][4] == 'w') {
398             uint16_t data;
399             cpu_physical_memory_read(addr, &data, 2);
400             value = tswap16(data);
401         } else if (words[0][4] == 'l') {
402             uint32_t data;
403             cpu_physical_memory_read(addr, &data, 4);
404             value = tswap32(data);
405         } else if (words[0][4] == 'q') {
406             cpu_physical_memory_read(addr, &value, 8);
407             tswap64s(&value);
408         }
409         qtest_send_prefix(chr);
410         qtest_sendf(chr, "OK 0x%016" PRIx64 "\n", value);
411     } else if (strcmp(words[0], "read") == 0) {
412         uint64_t addr, len, i;
413         uint8_t *data;
414
415         g_assert(words[1] && words[2]);
416         addr = strtoull(words[1], NULL, 0);
417         len = strtoull(words[2], NULL, 0);
418
419         data = g_malloc(len);
420         cpu_physical_memory_read(addr, data, len);
421
422         qtest_send_prefix(chr);
423         qtest_send(chr, "OK 0x");
424         for (i = 0; i < len; i++) {
425             qtest_sendf(chr, "%02x", data[i]);
426         }
427         qtest_send(chr, "\n");
428
429         g_free(data);
430     } else if (strcmp(words[0], "b64read") == 0) {
431         uint64_t addr, len;
432         uint8_t *data;
433         gchar *b64_data;
434
435         g_assert(words[1] && words[2]);
436         addr = strtoull(words[1], NULL, 0);
437         len = strtoull(words[2], NULL, 0);
438
439         data = g_malloc(len);
440         cpu_physical_memory_read(addr, data, len);
441         b64_data = g_base64_encode(data, len);
442         qtest_send_prefix(chr);
443         qtest_sendf(chr, "OK %s\n", b64_data);
444
445         g_free(data);
446         g_free(b64_data);
447     } else if (strcmp(words[0], "write") == 0) {
448         uint64_t addr, len, i;
449         uint8_t *data;
450         size_t data_len;
451
452         g_assert(words[1] && words[2] && words[3]);
453         addr = strtoull(words[1], NULL, 0);
454         len = strtoull(words[2], NULL, 0);
455
456         data_len = strlen(words[3]);
457         if (data_len < 3) {
458             qtest_send(chr, "ERR invalid argument size\n");
459             return;
460         }
461
462         data = g_malloc(len);
463         for (i = 0; i < len; i++) {
464             if ((i * 2 + 4) <= data_len) {
465                 data[i] = hex2nib(words[3][i * 2 + 2]) << 4;
466                 data[i] |= hex2nib(words[3][i * 2 + 3]);
467             } else {
468                 data[i] = 0;
469             }
470         }
471         cpu_physical_memory_write(addr, data, len);
472         g_free(data);
473
474         qtest_send_prefix(chr);
475         qtest_send(chr, "OK\n");
476     }  else if (strcmp(words[0], "b64write") == 0) {
477         uint64_t addr, len;
478         uint8_t *data;
479         size_t data_len;
480         gsize out_len;
481
482         g_assert(words[1] && words[2] && words[3]);
483         addr = strtoull(words[1], NULL, 0);
484         len = strtoull(words[2], NULL, 0);
485
486         data_len = strlen(words[3]);
487         if (data_len < 3) {
488             qtest_send(chr, "ERR invalid argument size\n");
489             return;
490         }
491
492         data = g_base64_decode_inplace(words[3], &out_len);
493         if (out_len != len) {
494             qtest_log_send("b64write: data length mismatch (told %"PRIu64", "
495                            "found %zu)\n",
496                            len, out_len);
497             out_len = MIN(out_len, len);
498         }
499
500         cpu_physical_memory_write(addr, data, out_len);
501
502         qtest_send_prefix(chr);
503         qtest_send(chr, "OK\n");
504     } else if (qtest_enabled() && strcmp(words[0], "clock_step") == 0) {
505         int64_t ns;
506
507         if (words[1]) {
508             ns = strtoll(words[1], NULL, 0);
509         } else {
510             ns = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
511         }
512         qtest_clock_warp(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns);
513         qtest_send_prefix(chr);
514         qtest_sendf(chr, "OK %"PRIi64"\n",
515                     (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
516     } else if (qtest_enabled() && strcmp(words[0], "clock_set") == 0) {
517         int64_t ns;
518
519         g_assert(words[1]);
520         ns = strtoll(words[1], NULL, 0);
521         qtest_clock_warp(ns);
522         qtest_send_prefix(chr);
523         qtest_sendf(chr, "OK %"PRIi64"\n",
524                     (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
525     } else {
526         qtest_send_prefix(chr);
527         qtest_sendf(chr, "FAIL Unknown command '%s'\n", words[0]);
528     }
529 }
530
531 static void qtest_process_inbuf(CharDriverState *chr, GString *inbuf)
532 {
533     char *end;
534
535     while ((end = strchr(inbuf->str, '\n')) != NULL) {
536         size_t offset;
537         GString *cmd;
538         gchar **words;
539
540         offset = end - inbuf->str;
541
542         cmd = g_string_new_len(inbuf->str, offset);
543         g_string_erase(inbuf, 0, offset + 1);
544
545         words = g_strsplit(cmd->str, " ", 0);
546         qtest_process_command(chr, words);
547         g_strfreev(words);
548
549         g_string_free(cmd, TRUE);
550     }
551 }
552
553 static void qtest_read(void *opaque, const uint8_t *buf, int size)
554 {
555     CharDriverState *chr = opaque;
556
557     g_string_append_len(inbuf, (const gchar *)buf, size);
558     qtest_process_inbuf(chr, inbuf);
559 }
560
561 static int qtest_can_read(void *opaque)
562 {
563     return 1024;
564 }
565
566 static void qtest_event(void *opaque, int event)
567 {
568     int i;
569
570     switch (event) {
571     case CHR_EVENT_OPENED:
572         /*
573          * We used to call qemu_system_reset() here, hoping we could
574          * use the same process for multiple tests that way.  Never
575          * used.  Injects an extra reset even when it's not used, and
576          * that can mess up tests, e.g. -boot once.
577          */
578         for (i = 0; i < ARRAY_SIZE(irq_levels); i++) {
579             irq_levels[i] = 0;
580         }
581         qemu_gettimeofday(&start_time);
582         qtest_opened = true;
583         if (qtest_log_fp) {
584             fprintf(qtest_log_fp, "[I " FMT_timeval "] OPENED\n",
585                     (long) start_time.tv_sec, (long) start_time.tv_usec);
586         }
587         break;
588     case CHR_EVENT_CLOSED:
589         qtest_opened = false;
590         if (qtest_log_fp) {
591             qemu_timeval tv;
592             qtest_get_time(&tv);
593             fprintf(qtest_log_fp, "[I +" FMT_timeval "] CLOSED\n",
594                     (long) tv.tv_sec, (long) tv.tv_usec);
595         }
596         break;
597     default:
598         break;
599     }
600 }
601
602 static int qtest_init_accel(MachineState *ms)
603 {
604     QemuOpts *opts = qemu_opts_create(qemu_find_opts("icount"), NULL, 0,
605                                       &error_abort);
606     qemu_opt_set(opts, "shift", "0", &error_abort);
607     configure_icount(opts, &error_abort);
608     qemu_opts_del(opts);
609     return 0;
610 }
611
612 void qtest_init(const char *qtest_chrdev, const char *qtest_log, Error **errp)
613 {
614     CharDriverState *chr;
615
616     chr = qemu_chr_new("qtest", qtest_chrdev, NULL);
617
618     if (chr == NULL) {
619         error_setg(errp, "Failed to initialize device for qtest: \"%s\"",
620                    qtest_chrdev);
621         return;
622     }
623
624     if (qtest_log) {
625         if (strcmp(qtest_log, "none") != 0) {
626             qtest_log_fp = fopen(qtest_log, "w+");
627         }
628     } else {
629         qtest_log_fp = stderr;
630     }
631
632     qemu_chr_add_handlers(chr, qtest_can_read, qtest_read, qtest_event, chr);
633     qemu_chr_fe_set_echo(chr, true);
634
635     inbuf = g_string_new("");
636     qtest_chr = chr;
637 }
638
639 bool qtest_driver(void)
640 {
641     return qtest_chr;
642 }
643
644 static void qtest_accel_class_init(ObjectClass *oc, void *data)
645 {
646     AccelClass *ac = ACCEL_CLASS(oc);
647     ac->name = "QTest";
648     ac->available = qtest_available;
649     ac->init_machine = qtest_init_accel;
650     ac->allowed = &qtest_allowed;
651 }
652
653 #define TYPE_QTEST_ACCEL ACCEL_CLASS_NAME("qtest")
654
655 static const TypeInfo qtest_accel_type = {
656     .name = TYPE_QTEST_ACCEL,
657     .parent = TYPE_ACCEL,
658     .class_init = qtest_accel_class_init,
659 };
660
661 static void qtest_type_init(void)
662 {
663     type_register_static(&qtest_accel_type);
664 }
665
666 type_init(qtest_type_init);