qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v5 1/5] qtest: add read/write accessors with a speci


From: Laurent Vivier
Subject: [Qemu-devel] [PATCH v5 1/5] qtest: add read/write accessors with a specific endianness
Date: Tue, 4 Oct 2016 18:44:42 +0200

From: Cédric Le Goater <address@hidden>

Some test scenarios require to access memory regions using a specific
endianness, such as a device region, but the current qtest memory
accessors are done in native endian, which means that the values are
byteswapped in qtest if the endianness of the guest and the host are
different.

To maintain the endianness of a value, we need a new set of memory
accessor. This can be done in two ways:

- first, convert the value to the required endianness in libqtest and
  then use the memread/write routines so that qtest accesses the guest
  memory without doing any supplementary byteswapping

- an alternative method would be to handle the byte swapping on the
  qtest side. For that, we would need to extend the read/write
  protocol with an ending word : "native|le|be" and modify the tswap
  calls accordingly under the qtest_process_command() routine.

The result is the same and the first method is simpler.

Signed-off-by: Cédric Le Goater <address@hidden>
Signed-off-by: Laurent Vivier <address@hidden>
---
 tests/libqtest.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/libqtest.h | 71 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 162 insertions(+)

diff --git a/tests/libqtest.c b/tests/libqtest.c
index 6f6bdf1..611f2c3 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -15,6 +15,7 @@
  *
  */
 #include "qemu/osdep.h"
+#include "qemu/bswap.h"
 #include "libqtest.h"
 
 #include <sys/socket.h>
@@ -688,6 +689,42 @@ void qtest_writeq(QTestState *s, uint64_t addr, uint64_t 
value)
     qtest_write(s, "writeq", addr, value);
 }
 
+void qtest_writew_be(QTestState *s, uint64_t addr, uint16_t value)
+{
+    value = cpu_to_be16(value);
+    qtest_memread(s, addr, &value, sizeof(value));
+}
+
+void qtest_writel_be(QTestState *s, uint64_t addr, uint32_t value)
+{
+    value = cpu_to_be32(value);
+    qtest_memread(s, addr, &value, sizeof(value));
+}
+
+void qtest_writeq_be(QTestState *s, uint64_t addr, uint64_t value)
+{
+    value = cpu_to_be64(value);
+    qtest_memread(s, addr, &value, sizeof(value));
+}
+
+void qtest_writew_le(QTestState *s, uint64_t addr, uint16_t value)
+{
+    value = cpu_to_le16(value);
+    qtest_memread(s, addr, &value, sizeof(value));
+}
+
+void qtest_writel_le(QTestState *s, uint64_t addr, uint32_t value)
+{
+    value = cpu_to_le32(value);
+    qtest_memread(s, addr, &value, sizeof(value));
+}
+
+void qtest_writeq_le(QTestState *s, uint64_t addr, uint64_t value)
+{
+    value = cpu_to_le64(value);
+    qtest_memread(s, addr, &value, sizeof(value));
+}
+
 static uint64_t qtest_read(QTestState *s, const char *cmd, uint64_t addr)
 {
     gchar **args;
@@ -721,6 +758,60 @@ uint64_t qtest_readq(QTestState *s, uint64_t addr)
     return qtest_read(s, "readq", addr);
 }
 
+uint16_t qtest_readw_be(QTestState *s, uint64_t addr)
+{
+    uint16_t value;
+
+    qtest_memread(s, addr, &value, sizeof(value));
+
+    return be16_to_cpu(value);
+}
+
+uint32_t qtest_readl_be(QTestState *s, uint64_t addr)
+{
+    uint32_t value;
+
+    qtest_memread(s, addr, &value, sizeof(value));
+
+    return be32_to_cpu(value);
+}
+
+uint64_t qtest_readq_be(QTestState *s, uint64_t addr)
+{
+    uint64_t value;
+
+    qtest_memread(s, addr, &value, sizeof(value));
+
+    return be64_to_cpu(value);
+}
+
+uint16_t qtest_readw_le(QTestState *s, uint64_t addr)
+{
+    uint16_t value;
+
+    qtest_memread(s, addr, &value, sizeof(value));
+
+    return le16_to_cpu(value);
+}
+
+uint32_t qtest_readl_le(QTestState *s, uint64_t addr)
+{
+    uint32_t value;
+
+    qtest_memread(s, addr, &value, sizeof(value));
+
+    return le32_to_cpu(value);
+}
+
+uint64_t qtest_readq_le(QTestState *s, uint64_t addr)
+{
+    uint64_t value;
+
+    qtest_memread(s, addr, &value, sizeof(value));
+
+    return le64_to_cpu(value);
+}
+
 static int hex2nib(char ch)
 {
     if (ch >= '0' && ch <= '9') {
diff --git a/tests/libqtest.h b/tests/libqtest.h
index f7402e0..d5c25a9 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -887,4 +887,75 @@ void qmp_fd_send(int fd, const char *fmt, ...);
 QDict *qmp_fdv(int fd, const char *fmt, va_list ap);
 QDict *qmp_fd(int fd, const char *fmt, ...);
 
+/*
+ * BE/LE read/write accessors
+ */
+uint16_t qtest_readw_be(QTestState *s, uint64_t addr);
+uint32_t qtest_readl_be(QTestState *s, uint64_t addr);
+uint64_t qtest_readq_be(QTestState *s, uint64_t addr);
+
+static inline uint16_t readw_be(uint64_t addr)
+{
+    return qtest_readw_be(global_qtest, addr);
+}
+static inline uint32_t readl_be(uint64_t addr)
+{
+    return qtest_readl_be(global_qtest, addr);
+}
+static inline uint64_t readq_be(uint64_t addr)
+{
+    return qtest_readq_be(global_qtest, addr);
+}
+
+void qtest_writew_be(QTestState *s, uint64_t addr, uint16_t value);
+void qtest_writel_be(QTestState *s, uint64_t addr, uint32_t value);
+void qtest_writeq_be(QTestState *s, uint64_t addr, uint64_t value);
+
+static inline void writew_be(uint64_t addr, uint16_t value)
+{
+    qtest_writew_be(global_qtest, addr, value);
+}
+static inline void writel_be(uint64_t addr, uint32_t value)
+{
+    qtest_writel_be(global_qtest, addr, value);
+}
+static inline void writeq_be(uint64_t addr, uint64_t value)
+{
+    qtest_writeq_be(global_qtest, addr, value);
+}
+
+uint16_t qtest_readw_le(QTestState *s, uint64_t addr);
+uint32_t qtest_readl_le(QTestState *s, uint64_t addr);
+uint64_t qtest_readq_le(QTestState *s, uint64_t addr);
+
+static inline uint16_t readw_le(uint64_t addr)
+{
+    return qtest_readw_le(global_qtest, addr);
+}
+static inline uint32_t readl_le(uint64_t addr)
+{
+    return qtest_readl_le(global_qtest, addr);
+}
+static inline uint64_t readq_le(uint64_t addr)
+{
+    return qtest_readq_le(global_qtest, addr);
+}
+
+void qtest_writew_le(QTestState *s, uint64_t addr, uint16_t value);
+void qtest_writel_le(QTestState *s, uint64_t addr, uint32_t value);
+void qtest_writeq_le(QTestState *s, uint64_t addr, uint64_t value);
+
+static inline void writew_le(uint64_t addr, uint16_t value)
+{
+    qtest_writew_le(global_qtest, addr, value);
+}
+static inline void writel_le(uint64_t addr, uint32_t value)
+{
+    qtest_writel_le(global_qtest, addr, value);
+}
+static inline void writeq_le(uint64_t addr, uint64_t value)
+{
+    qtest_writeq_le(global_qtest, addr, value);
+}
+
 #endif
-- 
2.7.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]