X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=qtest.c;h=584c70762a6c1c2ccd576602644041dac235d2c7;hb=7af31519e220efc0572cacec5ac65dc54e73985d;hp=b7a3821ca7342d2371bb4e49049fe1db2f6bcc49;hpb=d5286af5ef27bfe25aa0472eb4d695964ae16b23;p=qemu.git diff --git a/qtest.c b/qtest.c index b7a3821ca..584c70762 100644 --- a/qtest.c +++ b/qtest.c @@ -13,7 +13,7 @@ #include "sysemu/qtest.h" #include "hw/qdev.h" -#include "char/char.h" +#include "sysemu/char.h" #include "exec/ioport.h" #include "exec/memory.h" #include "hw/irq.h" @@ -47,7 +47,7 @@ static bool qtest_opened; * * Clock management: * - * The qtest client is completely in charge of the vm_clock. qtest commands + * The qtest client is completely in charge of the QEMU_CLOCK_VIRTUAL. qtest commands * let you adjust the value of the clock (monotonically). All the commands * return the current value of the clock in nanoseconds. * @@ -87,6 +87,30 @@ static bool qtest_opened; * > inl ADDR * < OK VALUE * + * > writeb ADDR VALUE + * < OK + * + * > writew ADDR VALUE + * < OK + * + * > writel ADDR VALUE + * < OK + * + * > writeq ADDR VALUE + * < OK + * + * > readb ADDR + * < OK VALUE + * + * > readw ADDR + * < OK VALUE + * + * > readl ADDR + * < OK VALUE + * + * > readq ADDR + * < OK VALUE + * * > read ADDR SIZE * < OK DATA * @@ -153,7 +177,7 @@ static void qtest_send_prefix(CharDriverState *chr) qtest_get_time(&tv); fprintf(qtest_log_fp, "[S +" FMT_timeval "] ", - tv.tv_sec, (long) tv.tv_usec); + (long) tv.tv_sec, (long) tv.tv_usec); } static void GCC_FMT_ATTR(2, 3) qtest_send(CharDriverState *chr, @@ -167,7 +191,7 @@ static void GCC_FMT_ATTR(2, 3) qtest_send(CharDriverState *chr, len = vsnprintf(buffer, sizeof(buffer), fmt, ap); va_end(ap); - qemu_chr_fe_write(chr, (uint8_t *)buffer, len); + qemu_chr_fe_write_all(chr, (uint8_t *)buffer, len); if (qtest_log_fp && qtest_opened) { fprintf(qtest_log_fp, "%s", buffer); } @@ -201,7 +225,7 @@ static void qtest_process_command(CharDriverState *chr, gchar **words) qtest_get_time(&tv); fprintf(qtest_log_fp, "[R +" FMT_timeval "]", - tv.tv_sec, (long) tv.tv_usec); + (long) tv.tv_sec, (long) tv.tv_usec); for (i = 0; words[i]; i++) { fprintf(qtest_log_fp, " %s", words[i]); } @@ -247,8 +271,8 @@ static void qtest_process_command(CharDriverState *chr, gchar **words) uint32_t value; g_assert(words[1] && words[2]); - addr = strtol(words[1], NULL, 0); - value = strtol(words[2], NULL, 0); + addr = strtoul(words[1], NULL, 0); + value = strtoul(words[2], NULL, 0); if (words[0][3] == 'b') { cpu_outb(addr, value); @@ -266,7 +290,7 @@ static void qtest_process_command(CharDriverState *chr, gchar **words) uint32_t value = -1U; g_assert(words[1]); - addr = strtol(words[1], NULL, 0); + addr = strtoul(words[1], NULL, 0); if (words[0][2] == 'b') { value = cpu_inb(addr); @@ -277,13 +301,70 @@ static void qtest_process_command(CharDriverState *chr, gchar **words) } qtest_send_prefix(chr); qtest_send(chr, "OK 0x%04x\n", value); + } else if (strcmp(words[0], "writeb") == 0 || + strcmp(words[0], "writew") == 0 || + strcmp(words[0], "writel") == 0 || + strcmp(words[0], "writeq") == 0) { + uint64_t addr; + uint64_t value; + + g_assert(words[1] && words[2]); + addr = strtoull(words[1], NULL, 0); + value = strtoull(words[2], NULL, 0); + + if (words[0][5] == 'b') { + uint8_t data = value; + cpu_physical_memory_write(addr, &data, 1); + } else if (words[0][5] == 'w') { + uint16_t data = value; + tswap16s(&data); + cpu_physical_memory_write(addr, &data, 2); + } else if (words[0][5] == 'l') { + uint32_t data = value; + tswap32s(&data); + cpu_physical_memory_write(addr, &data, 4); + } else if (words[0][5] == 'q') { + uint64_t data = value; + tswap64s(&data); + cpu_physical_memory_write(addr, &data, 8); + } + qtest_send_prefix(chr); + qtest_send(chr, "OK\n"); + } else if (strcmp(words[0], "readb") == 0 || + strcmp(words[0], "readw") == 0 || + strcmp(words[0], "readl") == 0 || + strcmp(words[0], "readq") == 0) { + uint64_t addr; + uint64_t value = UINT64_C(-1); + + g_assert(words[1]); + addr = strtoull(words[1], NULL, 0); + + if (words[0][4] == 'b') { + uint8_t data; + cpu_physical_memory_read(addr, &data, 1); + value = data; + } else if (words[0][4] == 'w') { + uint16_t data; + cpu_physical_memory_read(addr, &data, 2); + value = tswap16(data); + } else if (words[0][4] == 'l') { + uint32_t data; + cpu_physical_memory_read(addr, &data, 4); + value = tswap32(data); + } else if (words[0][4] == 'q') { + cpu_physical_memory_read(addr, &value, 8); + tswap64s(&value); + } + qtest_send_prefix(chr); + qtest_send(chr, "OK 0x%016" PRIx64 "\n", value); } else if (strcmp(words[0], "read") == 0) { uint64_t addr, len, i; uint8_t *data; g_assert(words[1] && words[2]); - addr = strtoul(words[1], NULL, 0); - len = strtoul(words[2], NULL, 0); + addr = strtoull(words[1], NULL, 0); + len = strtoull(words[2], NULL, 0); data = g_malloc(len); cpu_physical_memory_read(addr, data, len); @@ -302,8 +383,8 @@ static void qtest_process_command(CharDriverState *chr, gchar **words) size_t data_len; g_assert(words[1] && words[2] && words[3]); - addr = strtoul(words[1], NULL, 0); - len = strtoul(words[2], NULL, 0); + addr = strtoull(words[1], NULL, 0); + len = strtoull(words[2], NULL, 0); data_len = strlen(words[3]); if (data_len < 3) { @@ -331,11 +412,11 @@ static void qtest_process_command(CharDriverState *chr, gchar **words) if (words[1]) { ns = strtoll(words[1], NULL, 0); } else { - ns = qemu_clock_deadline(vm_clock); + ns = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL); } - qtest_clock_warp(qemu_get_clock_ns(vm_clock) + ns); + qtest_clock_warp(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns); qtest_send_prefix(chr); - qtest_send(chr, "OK %"PRIi64"\n", (int64_t)qemu_get_clock_ns(vm_clock)); + qtest_send(chr, "OK %"PRIi64"\n", (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); } else if (strcmp(words[0], "clock_set") == 0) { int64_t ns; @@ -343,7 +424,7 @@ static void qtest_process_command(CharDriverState *chr, gchar **words) ns = strtoll(words[1], NULL, 0); qtest_clock_warp(ns); qtest_send_prefix(chr); - qtest_send(chr, "OK %"PRIi64"\n", (int64_t)qemu_get_clock_ns(vm_clock)); + qtest_send(chr, "OK %"PRIi64"\n", (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); } else { qtest_send_prefix(chr); qtest_send(chr, "FAIL Unknown command `%s'\n", words[0]); @@ -391,7 +472,12 @@ static void qtest_event(void *opaque, int event) switch (event) { case CHR_EVENT_OPENED: - qemu_system_reset(false); + /* + * We used to call qemu_system_reset() here, hoping we could + * use the same process for multiple tests that way. Never + * used. Injects an extra reset even when it's not used, and + * that can mess up tests, e.g. -boot once. + */ for (i = 0; i < ARRAY_SIZE(irq_levels); i++) { irq_levels[i] = 0; } @@ -399,7 +485,7 @@ static void qtest_event(void *opaque, int event) qtest_opened = true; if (qtest_log_fp) { fprintf(qtest_log_fp, "[I " FMT_timeval "] OPENED\n", - start_time.tv_sec, (long) start_time.tv_usec); + (long) start_time.tv_sec, (long) start_time.tv_usec); } break; case CHR_EVENT_CLOSED: @@ -408,7 +494,7 @@ static void qtest_event(void *opaque, int event) qemu_timeval tv; qtest_get_time(&tv); fprintf(qtest_log_fp, "[I +" FMT_timeval "] CLOSED\n", - tv.tv_sec, (long) tv.tv_usec); + (long) tv.tv_sec, (long) tv.tv_usec); } break; default: