From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
To: qemu-devel@nongnu.org
Cc: qemu-riscv@nongnu.org, alistair.francis@wdc.com,
bmeng@tinylab.org, liwei1518@gmail.com,
zhiwei_liu@linux.alibaba.com, palmer@rivosinc.com,
jason.chien@sifive.com, frank.chang@sifive.com,
ajones@ventanamicro.com,
Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Subject: [PATCH for-9.2 v6 11/12] qtest/riscv-iommu-test: add init queues test
Date: Thu, 1 Aug 2024 12:43:32 -0300 [thread overview]
Message-ID: <20240801154334.1009852-12-dbarboza@ventanamicro.com> (raw)
In-Reply-To: <20240801154334.1009852-1-dbarboza@ventanamicro.com>
Add an additional test to further exercise the IOMMU where we attempt to
initialize the command, fault and page-request queues.
These steps are taken from chapter 6.2 of the RISC-V IOMMU spec,
"Guidelines for initialization". It emulates what we expect from the
software/OS when initializing the IOMMU.
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Frank Chang <frank.chang@sifive.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
---
tests/qtest/libqos/riscv-iommu.h | 29 +++++++
tests/qtest/riscv-iommu-test.c | 141 +++++++++++++++++++++++++++++++
2 files changed, 170 insertions(+)
diff --git a/tests/qtest/libqos/riscv-iommu.h b/tests/qtest/libqos/riscv-iommu.h
index d123efb41f..c62ddedbac 100644
--- a/tests/qtest/libqos/riscv-iommu.h
+++ b/tests/qtest/libqos/riscv-iommu.h
@@ -62,6 +62,35 @@
#define RISCV_IOMMU_REG_IPSR 0x0054
+#define RISCV_IOMMU_REG_IVEC 0x02F8
+#define RISCV_IOMMU_REG_IVEC_CIV GENMASK_ULL(3, 0)
+#define RISCV_IOMMU_REG_IVEC_FIV GENMASK_ULL(7, 4)
+#define RISCV_IOMMU_REG_IVEC_PIV GENMASK_ULL(15, 12)
+
+#define RISCV_IOMMU_REG_CQB 0x0018
+#define RISCV_IOMMU_CQB_PPN_START 10
+#define RISCV_IOMMU_CQB_PPN_LEN 44
+#define RISCV_IOMMU_CQB_LOG2SZ_START 0
+#define RISCV_IOMMU_CQB_LOG2SZ_LEN 5
+
+#define RISCV_IOMMU_REG_CQT 0x0024
+
+#define RISCV_IOMMU_REG_FQB 0x0028
+#define RISCV_IOMMU_FQB_PPN_START 10
+#define RISCV_IOMMU_FQB_PPN_LEN 44
+#define RISCV_IOMMU_FQB_LOG2SZ_START 0
+#define RISCV_IOMMU_FQB_LOG2SZ_LEN 5
+
+#define RISCV_IOMMU_REG_FQT 0x0034
+
+#define RISCV_IOMMU_REG_PQB 0x0038
+#define RISCV_IOMMU_PQB_PPN_START 10
+#define RISCV_IOMMU_PQB_PPN_LEN 44
+#define RISCV_IOMMU_PQB_LOG2SZ_START 0
+#define RISCV_IOMMU_PQB_LOG2SZ_LEN 5
+
+#define RISCV_IOMMU_REG_PQT 0x0044
+
typedef struct QRISCVIOMMU {
QOSGraphObject obj;
QPCIDevice dev;
diff --git a/tests/qtest/riscv-iommu-test.c b/tests/qtest/riscv-iommu-test.c
index 7f0dbd0211..9e2afcb4b9 100644
--- a/tests/qtest/riscv-iommu-test.c
+++ b/tests/qtest/riscv-iommu-test.c
@@ -33,6 +33,20 @@ static uint64_t riscv_iommu_read_reg64(QRISCVIOMMU *r_iommu, int reg_offset)
return reg;
}
+static void riscv_iommu_write_reg32(QRISCVIOMMU *r_iommu, int reg_offset,
+ uint32_t val)
+{
+ qpci_memwrite(&r_iommu->dev, r_iommu->reg_bar, reg_offset,
+ &val, sizeof(val));
+}
+
+static void riscv_iommu_write_reg64(QRISCVIOMMU *r_iommu, int reg_offset,
+ uint64_t val)
+{
+ qpci_memwrite(&r_iommu->dev, r_iommu->reg_bar, reg_offset,
+ &val, sizeof(val));
+}
+
static void test_pci_config(void *obj, void *data, QGuestAllocator *t_alloc)
{
QRISCVIOMMU *r_iommu = obj;
@@ -84,10 +98,137 @@ static void test_reg_reset(void *obj, void *data, QGuestAllocator *t_alloc)
g_assert_cmpuint(reg, ==, 0);
}
+/*
+ * Common timeout-based poll for CQCSR, FQCSR and PQCSR. All
+ * their ON bits are mapped as RISCV_IOMMU_QUEUE_ACTIVE (16),
+ */
+static void qtest_wait_for_queue_active(QRISCVIOMMU *r_iommu,
+ uint32_t queue_csr)
+{
+ QTestState *qts = global_qtest;
+ guint64 timeout_us = 2 * 1000 * 1000;
+ gint64 start_time = g_get_monotonic_time();
+ uint32_t reg;
+
+ for (;;) {
+ qtest_clock_step(qts, 100);
+
+ reg = riscv_iommu_read_reg32(r_iommu, queue_csr);
+ if (reg & RISCV_IOMMU_QUEUE_ACTIVE) {
+ break;
+ }
+ g_assert(g_get_monotonic_time() - start_time <= timeout_us);
+ }
+}
+
+/*
+ * Goes through the queue activation procedures of chapter 6.2,
+ * "Guidelines for initialization", of the RISCV-IOMMU spec.
+ */
+static void test_iommu_init_queues(void *obj, void *data,
+ QGuestAllocator *t_alloc)
+{
+ QRISCVIOMMU *r_iommu = obj;
+ uint64_t reg64, q_addr;
+ uint32_t reg;
+ int k;
+
+ reg64 = riscv_iommu_read_reg64(r_iommu, RISCV_IOMMU_REG_CAP);
+ g_assert_cmpuint(reg64 & RISCV_IOMMU_CAP_VERSION, ==, 0x10);
+
+ /*
+ * Program the command queue. Write 0xF to civ, assert that
+ * we have 4 writable bits (k = 4). The amount of entries N in the
+ * command queue is 2^4 = 16. We need to alloc a N*16 bytes
+ * buffer and use it to set cqb.
+ */
+ riscv_iommu_write_reg32(r_iommu, RISCV_IOMMU_REG_IVEC,
+ 0xFFFF & RISCV_IOMMU_REG_IVEC_CIV);
+ reg = riscv_iommu_read_reg32(r_iommu, RISCV_IOMMU_REG_IVEC);
+ g_assert_cmpuint(reg & RISCV_IOMMU_REG_IVEC_CIV, ==, 0xF);
+
+ q_addr = guest_alloc(t_alloc, 16 * 16);
+ reg64 = 0;
+ k = 4;
+ deposit64(reg64, RISCV_IOMMU_CQB_PPN_START,
+ RISCV_IOMMU_CQB_PPN_LEN, q_addr);
+ deposit64(reg64, RISCV_IOMMU_CQB_LOG2SZ_START,
+ RISCV_IOMMU_CQB_LOG2SZ_LEN, k - 1);
+ riscv_iommu_write_reg64(r_iommu, RISCV_IOMMU_REG_CQB, reg64);
+
+ /* cqt = 0, cqcsr.cqen = 1, poll cqcsr.cqon until it reads 1 */
+ riscv_iommu_write_reg32(r_iommu, RISCV_IOMMU_REG_CQT, 0);
+
+ reg = riscv_iommu_read_reg32(r_iommu, RISCV_IOMMU_REG_CQCSR);
+ reg |= RISCV_IOMMU_CQCSR_CQEN;
+ riscv_iommu_write_reg32(r_iommu, RISCV_IOMMU_REG_CQCSR, reg);
+
+ qtest_wait_for_queue_active(r_iommu, RISCV_IOMMU_REG_CQCSR);
+
+ /*
+ * Program the fault queue. Similar to the above:
+ * - Write 0xF to fiv, assert that we have 4 writable bits (k = 4)
+ * - Alloc a 16*32 bytes (instead of 16*16) buffer and use it to set
+ * fqb
+ */
+ riscv_iommu_write_reg32(r_iommu, RISCV_IOMMU_REG_IVEC,
+ 0xFFFF & RISCV_IOMMU_REG_IVEC_FIV);
+ reg = riscv_iommu_read_reg32(r_iommu, RISCV_IOMMU_REG_IVEC);
+ g_assert_cmpuint(reg & RISCV_IOMMU_REG_IVEC_FIV, ==, 0xF0);
+
+ q_addr = guest_alloc(t_alloc, 16 * 32);
+ reg64 = 0;
+ k = 4;
+ deposit64(reg64, RISCV_IOMMU_FQB_PPN_START,
+ RISCV_IOMMU_FQB_PPN_LEN, q_addr);
+ deposit64(reg64, RISCV_IOMMU_FQB_LOG2SZ_START,
+ RISCV_IOMMU_FQB_LOG2SZ_LEN, k - 1);
+ riscv_iommu_write_reg64(r_iommu, RISCV_IOMMU_REG_FQB, reg64);
+
+ /* fqt = 0, fqcsr.fqen = 1, poll fqcsr.fqon until it reads 1 */
+ riscv_iommu_write_reg32(r_iommu, RISCV_IOMMU_REG_FQT, 0);
+
+ reg = riscv_iommu_read_reg32(r_iommu, RISCV_IOMMU_REG_FQCSR);
+ reg |= RISCV_IOMMU_FQCSR_FQEN;
+ riscv_iommu_write_reg32(r_iommu, RISCV_IOMMU_REG_FQCSR, reg);
+
+ qtest_wait_for_queue_active(r_iommu, RISCV_IOMMU_REG_FQCSR);
+
+ /*
+ * Program the page-request queue:
+ - Write 0xF to piv, assert that we have 4 writable bits (k = 4)
+ - Alloc a 16*16 bytes buffer and use it to set pqb.
+ */
+ riscv_iommu_write_reg32(r_iommu, RISCV_IOMMU_REG_IVEC,
+ 0xFFFF & RISCV_IOMMU_REG_IVEC_PIV);
+ reg = riscv_iommu_read_reg32(r_iommu, RISCV_IOMMU_REG_IVEC);
+ g_assert_cmpuint(reg & RISCV_IOMMU_REG_IVEC_PIV, ==, 0xF000);
+
+ q_addr = guest_alloc(t_alloc, 16 * 16);
+ reg64 = 0;
+ k = 4;
+ deposit64(reg64, RISCV_IOMMU_PQB_PPN_START,
+ RISCV_IOMMU_PQB_PPN_LEN, q_addr);
+ deposit64(reg64, RISCV_IOMMU_PQB_LOG2SZ_START,
+ RISCV_IOMMU_PQB_LOG2SZ_LEN, k - 1);
+ riscv_iommu_write_reg64(r_iommu, RISCV_IOMMU_REG_PQB, reg64);
+
+ /* pqt = 0, pqcsr.pqen = 1, poll pqcsr.pqon until it reads 1 */
+ riscv_iommu_write_reg32(r_iommu, RISCV_IOMMU_REG_PQT, 0);
+
+ reg = riscv_iommu_read_reg32(r_iommu, RISCV_IOMMU_REG_PQCSR);
+ reg |= RISCV_IOMMU_PQCSR_PQEN;
+ riscv_iommu_write_reg32(r_iommu, RISCV_IOMMU_REG_PQCSR, reg);
+
+ qtest_wait_for_queue_active(r_iommu, RISCV_IOMMU_REG_PQCSR);
+}
+
static void register_riscv_iommu_test(void)
{
qos_add_test("pci_config", "riscv-iommu-pci", test_pci_config, NULL);
qos_add_test("reg_reset", "riscv-iommu-pci", test_reg_reset, NULL);
+ qos_add_test("iommu_init_queues", "riscv-iommu-pci",
+ test_iommu_init_queues, NULL);
}
libqos_init(register_riscv_iommu_test);
--
2.45.2
next prev parent reply other threads:[~2024-08-01 15:46 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-01 15:43 [PATCH for-9.2 v6 00/12] riscv: QEMU RISC-V IOMMU Support Daniel Henrique Barboza
2024-08-01 15:43 ` [PATCH for-9.2 v6 01/12] exec/memtxattr: add process identifier to the transaction attributes Daniel Henrique Barboza
2024-08-01 15:43 ` [PATCH for-9.2 v6 02/12] hw/riscv: add riscv-iommu-bits.h Daniel Henrique Barboza
2024-08-04 23:04 ` Alistair Francis
2024-08-05 18:25 ` Daniel Henrique Barboza
2024-08-05 23:46 ` Alistair Francis
2024-08-07 8:37 ` Jason Chien
2024-08-01 15:43 ` [PATCH for-9.2 v6 03/12] hw/riscv: add RISC-V IOMMU base emulation Daniel Henrique Barboza
2024-08-04 23:23 ` Alistair Francis
2024-08-17 11:34 ` Andrew Jones
2024-08-18 18:20 ` Daniel Henrique Barboza
2024-08-20 15:16 ` Jason Chien
2024-08-23 12:42 ` Daniel Henrique Barboza
2024-08-27 2:18 ` Tomasz Jeznach
2024-09-03 11:46 ` Daniel Henrique Barboza
2024-10-01 23:28 ` Tomasz Jeznach
2024-10-02 0:05 ` Daniel Henrique Barboza
2024-10-03 8:42 ` Andrew Jones
2024-08-01 15:43 ` [PATCH for-9.2 v6 04/12] pci-ids.rst: add Red Hat pci-id for RISC-V IOMMU device Daniel Henrique Barboza
2024-08-21 11:34 ` Gerd Hoffmann
2024-08-01 15:43 ` [PATCH for-9.2 v6 05/12] hw/riscv: add riscv-iommu-pci reference device Daniel Henrique Barboza
2024-08-01 15:43 ` [PATCH for-9.2 v6 06/12] hw/riscv/virt.c: support for RISC-V IOMMU PCIDevice hotplug Daniel Henrique Barboza
2024-08-01 15:43 ` [PATCH for-9.2 v6 07/12] test/qtest: add riscv-iommu-pci tests Daniel Henrique Barboza
2024-08-01 15:43 ` [PATCH for-9.2 v6 08/12] hw/riscv/riscv-iommu: add Address Translation Cache (IOATC) Daniel Henrique Barboza
2024-08-20 15:27 ` Jason Chien
2024-08-23 17:18 ` Daniel Henrique Barboza
2024-08-27 2:44 ` Tomasz Jeznach
2024-08-27 11:56 ` Daniel Henrique Barboza
2024-08-01 15:43 ` [PATCH for-9.2 v6 09/12] hw/riscv/riscv-iommu: add ATS support Daniel Henrique Barboza
2024-08-01 15:43 ` [PATCH for-9.2 v6 10/12] hw/riscv/riscv-iommu: add DBG support Daniel Henrique Barboza
2024-08-04 23:35 ` Alistair Francis
2024-08-01 15:43 ` Daniel Henrique Barboza [this message]
2024-08-01 15:43 ` [PATCH for-9.2 v6 12/12] docs/specs: add riscv-iommu Daniel Henrique Barboza
2024-08-04 23:39 ` Alistair Francis
2024-09-03 12:56 ` Daniel Henrique Barboza
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240801154334.1009852-12-dbarboza@ventanamicro.com \
--to=dbarboza@ventanamicro.com \
--cc=ajones@ventanamicro.com \
--cc=alistair.francis@wdc.com \
--cc=bmeng@tinylab.org \
--cc=frank.chang@sifive.com \
--cc=jason.chien@sifive.com \
--cc=liwei1518@gmail.com \
--cc=palmer@rivosinc.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-riscv@nongnu.org \
--cc=zhiwei_liu@linux.alibaba.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.