From patchwork Tue Oct 4 16:44:42 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 678169 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3spPv35gfrz9t0t for ; Wed, 5 Oct 2016 03:46:23 +1100 (AEDT) Received: from localhost ([::1]:44259 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1brSrF-0004XG-9J for incoming@patchwork.ozlabs.org; Tue, 04 Oct 2016 12:46:21 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45391) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1brSpt-0003Ra-JG for qemu-devel@nongnu.org; Tue, 04 Oct 2016 12:44:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1brSpq-0001m0-KM for qemu-devel@nongnu.org; Tue, 04 Oct 2016 12:44:56 -0400 Received: from mx1.redhat.com ([209.132.183.28]:36868) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1brSpq-0001lr-Bp; Tue, 04 Oct 2016 12:44:54 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id CDE3D9E620; Tue, 4 Oct 2016 16:44:53 +0000 (UTC) Received: from thinkpad.redhat.com (ovpn-112-35.ams2.redhat.com [10.36.112.35]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u94GilW6023538; Tue, 4 Oct 2016 12:44:51 -0400 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Tue, 4 Oct 2016 18:44:42 +0200 Message-Id: <1475599486-30446-2-git-send-email-lvivier@redhat.com> In-Reply-To: <1475599486-30446-1-git-send-email-lvivier@redhat.com> References: <1475599486-30446-1-git-send-email-lvivier@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Tue, 04 Oct 2016 16:44:53 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v5 1/5] qtest: add read/write accessors with a specific endianness X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Laurent Vivier , thuth@redhat.com, Greg Kurz , qemu-ppc@nongnu.org, =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= , dgibson@redhat.com, Gerd Hoffmann Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Cédric Le Goater 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 Signed-off-by: Laurent Vivier --- 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 @@ -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