]> git.proxmox.com Git - qemu.git/blobdiff - qtest.c
Open 2.0 development tree
[qemu.git] / qtest.c
diff --git a/qtest.c b/qtest.c
index c9b58ceb8b1b9c506c91692d9a2740c2a98fa008..584c70762a6c1c2ccd576602644041dac235d2c7 100644 (file)
--- 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"
@@ -24,7 +24,7 @@
 
 const char *qtest_chrdev;
 const char *qtest_log;
-int qtest_allowed = 0;
+bool qtest_allowed;
 
 static DeviceState *irq_intercept_dev;
 static FILE *qtest_log_fp;
@@ -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: