From nobody Mon Nov 25 01:34:36 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1719260422; cv=none; d=zohomail.com; s=zohoarc; b=ChhEvxg1rP092TURBw7aYQvK7Q8LTxRPl5DpisVAzWkpRoGk8yxN1gvKfDJOh861h3EJXEm5WjmoddKA4ihiMhMpyGeaKe05zRTJFbZHVbvYV0SispCLbSh9FMreJWvgH1VCyTas/C1zGBgG3U1vJBYiG8VCQGq2vE2rRFNZpmg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1719260422; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=NG4P/lJ6x4PJhHgoddItxpf5RxnWl1cFbNKez3j30KI=; b=gP7w3KZy4eoF3pVmILAGulinZSou84q4bIskbJ9BKA61ZlXRj4y8rvRkRws+KGekzJ3U7hDd1+7N0xLN+ck9eVQrTCQfSSsUo3TlKUf3t8qTfuYuHKu/5v+tJgYy9gCoMUBqfF7g5mVLdDMjWsrdKW4WtB9MjW6T2PttKwqp15A= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1719260422739380.576902126342; Mon, 24 Jun 2024 13:20:22 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sLq9m-0004JJ-7g; Mon, 24 Jun 2024 16:19:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sLq9l-0004Iv-9t for qemu-devel@nongnu.org; Mon, 24 Jun 2024 16:19:17 -0400 Received: from mail-pf1-x431.google.com ([2607:f8b0:4864:20::431]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sLq9i-0003g1-8j for qemu-devel@nongnu.org; Mon, 24 Jun 2024 16:19:16 -0400 Received: by mail-pf1-x431.google.com with SMTP id d2e1a72fcca58-7066c9741b7so1463455b3a.1 for ; Mon, 24 Jun 2024 13:19:13 -0700 (PDT) Received: from grind.dc1.ventanamicro.com ([2804:7f0:bcc0:1aea:63a7:288e:eb77:fe54]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-70688f2d76bsm1927091b3a.41.2024.06.24.13.19.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Jun 2024 13:19:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1719260353; x=1719865153; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=NG4P/lJ6x4PJhHgoddItxpf5RxnWl1cFbNKez3j30KI=; b=UkZ+j1vM3ACCUEPZSun/L4jA9Zc4HLv4WlxuZ14tBzTcgjk9ZVmhEgTPwzgKnT40xS Bz76Cfoo+Q+XsElW+Ow493BuKC6RQ9as3k6Qw1v0GLb6pubyloPnNTRozlzTBqbH0WZk a13DjL2/MkC/5006ANjhudAxrsLI1jgS57CeCvAaC2mXjPdIgY70Tx0tSA+/qXidIKXw lr4j5URBN3ff9KUHXP4exjemVIVeO2CvnE7/F0nmsS1kMdrvbE5nNtYNkGqlxPrdC1tv btNcjCOG659NXafAoooItyfUApo6F2DKwZN+0+bCRGFfwOnkDtml/d5WkrQvl3GDJxBL gvrA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719260353; x=1719865153; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=NG4P/lJ6x4PJhHgoddItxpf5RxnWl1cFbNKez3j30KI=; b=CRdvWd8x6H3kljuPlf2Xs9BkamBYkBdwkARa/TSyOlqqgFQj05Xv8NrZxey71XMZGu 5sIhc44i5Nc8/Mx/CH3/LaSx9uHxPHhQ11Rdq92IoUZ+CsknSu3MS+h+DGT2A4M87sCz EzGyu2EEZ8iZwzxOXv9i7zIO0K0BV2jewea/xHQ8VzQFk+dyoOa/5Mlm1TQaS8HY2Tfw 3nAYhNrn47POt4RjLE++kchrVe5q88kBaJdNFqg0yPBXPfZ+Ci7ZUu4hx7Yd3TUnPDsH GOPVnfXuYHjI2hL4JJ/RfFVh6kiW0qi2exCy79uTjYKGENciG7bXWBfdIwfyhjjaeE0m mEug== X-Gm-Message-State: AOJu0YxbHGEY/r/zHMavOzu70LSN6OOoBD8SbdueiSosucMwekpH6bEU gfkJDG/q1iEHYouuV79Tz4HXiJJ3nd01aVKlumE+8xE/k8wOJ2Oc9j0OrfOZqQDIwprE5PI+JHK p X-Google-Smtp-Source: AGHT+IGIB37SCt+KyIyqsGcUIFBcGTsooLspHY1Z2rajX8Nw4mSaWjv/aC8dMTT5qFO/lCDqo9w4cA== X-Received: by 2002:aa7:9e5c:0:b0:705:d822:31ed with SMTP id d2e1a72fcca58-706745a3a9dmr5436103b3a.15.1719260352619; Mon, 24 Jun 2024 13:19:12 -0700 (PDT) From: Daniel Henrique Barboza 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, ajones@ventanamicro.com, tjeznach@rivosinc.com, frank.chang@sifive.com, jason.chien@sifive.com, Daniel Henrique Barboza Subject: [PATCH v4 07/14] test/qtest: add riscv-iommu-pci tests Date: Mon, 24 Jun 2024 17:18:17 -0300 Message-ID: <20240624201825.1054980-8-dbarboza@ventanamicro.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240624201825.1054980-1-dbarboza@ventanamicro.com> References: <20240624201825.1054980-1-dbarboza@ventanamicro.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::431; envelope-from=dbarboza@ventanamicro.com; helo=mail-pf1-x431.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @ventanamicro.com) X-ZM-MESSAGEID: 1719260424109100003 Content-Type: text/plain; charset="utf-8" To test the RISC-V IOMMU emulation we'll use its PCI representation. Create a new 'riscv-iommu-pci' libqos device that will be present with CONFIG_RISCV_IOMMU. This config is only available for RISC-V, so this device will only be consumed by the RISC-V libqos machine. Start with basic tests: a PCI sanity check and a reset state register test. The reset test was taken from the RISC-V IOMMU spec chapter 5.2, "Reset behavior". More tests will be added later. Signed-off-by: Daniel Henrique Barboza Reviewed-by: Frank Chang Acked-by: Alistair Francis --- tests/qtest/libqos/meson.build | 4 ++ tests/qtest/libqos/riscv-iommu.c | 76 ++++++++++++++++++++++++++ tests/qtest/libqos/riscv-iommu.h | 71 ++++++++++++++++++++++++ tests/qtest/meson.build | 1 + tests/qtest/riscv-iommu-test.c | 93 ++++++++++++++++++++++++++++++++ 5 files changed, 245 insertions(+) create mode 100644 tests/qtest/libqos/riscv-iommu.c create mode 100644 tests/qtest/libqos/riscv-iommu.h create mode 100644 tests/qtest/riscv-iommu-test.c diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build index 558eb4c24b..03fd51b804 100644 --- a/tests/qtest/libqos/meson.build +++ b/tests/qtest/libqos/meson.build @@ -68,6 +68,10 @@ if have_virtfs libqos_srcs +=3D files('virtio-9p.c', 'virtio-9p-client.c') endif =20 +if config_all_devices.has_key('CONFIG_RISCV_IOMMU') + libqos_srcs +=3D files('riscv-iommu.c') +endif + libqos =3D static_library('qos', libqos_srcs + genh, name_suffix: 'fa', build_by_default: false) diff --git a/tests/qtest/libqos/riscv-iommu.c b/tests/qtest/libqos/riscv-io= mmu.c new file mode 100644 index 0000000000..01e3b31c0b --- /dev/null +++ b/tests/qtest/libqos/riscv-iommu.c @@ -0,0 +1,76 @@ +/* + * libqos driver riscv-iommu-pci framework + * + * Copyright (c) 2024 Ventana Micro Systems Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at = your + * option) any later version. See the COPYING file in the top-level direc= tory. + * + */ + +#include "qemu/osdep.h" +#include "../libqtest.h" +#include "qemu/module.h" +#include "qgraph.h" +#include "pci.h" +#include "riscv-iommu.h" + +static void *riscv_iommu_pci_get_driver(void *obj, const char *interface) +{ + QRISCVIOMMU *r_iommu_pci =3D obj; + + if (!g_strcmp0(interface, "pci-device")) { + return &r_iommu_pci->dev; + } + + fprintf(stderr, "%s not present in riscv_iommu_pci\n", interface); + g_assert_not_reached(); +} + +static void riscv_iommu_pci_start_hw(QOSGraphObject *obj) +{ + QRISCVIOMMU *pci =3D (QRISCVIOMMU *)obj; + qpci_device_enable(&pci->dev); +} + +static void riscv_iommu_pci_destructor(QOSGraphObject *obj) +{ + QRISCVIOMMU *pci =3D (QRISCVIOMMU *)obj; + qpci_iounmap(&pci->dev, pci->reg_bar); +} + +static void *riscv_iommu_pci_create(void *pci_bus, QGuestAllocator *alloc, + void *addr) +{ + QRISCVIOMMU *r_iommu_pci =3D g_new0(QRISCVIOMMU, 1); + QPCIBus *bus =3D pci_bus; + + qpci_device_init(&r_iommu_pci->dev, bus, addr); + r_iommu_pci->reg_bar =3D qpci_iomap(&r_iommu_pci->dev, 0, NULL); + + r_iommu_pci->obj.get_driver =3D riscv_iommu_pci_get_driver; + r_iommu_pci->obj.start_hw =3D riscv_iommu_pci_start_hw; + r_iommu_pci->obj.destructor =3D riscv_iommu_pci_destructor; + return &r_iommu_pci->obj; +} + +static void riscv_iommu_pci_register_nodes(void) +{ + QPCIAddress addr =3D { + .vendor_id =3D RISCV_IOMMU_PCI_VENDOR_ID, + .device_id =3D RISCV_IOMMU_PCI_DEVICE_ID, + .devfn =3D QPCI_DEVFN(1, 0), + }; + + QOSGraphEdgeOptions opts =3D { + .extra_device_opts =3D "addr=3D01.0", + }; + + add_qpci_address(&opts, &addr); + + qos_node_create_driver("riscv-iommu-pci", riscv_iommu_pci_create); + qos_node_produces("riscv-iommu-pci", "pci-device"); + qos_node_consumes("riscv-iommu-pci", "pci-bus", &opts); +} + +libqos_init(riscv_iommu_pci_register_nodes); diff --git a/tests/qtest/libqos/riscv-iommu.h b/tests/qtest/libqos/riscv-io= mmu.h new file mode 100644 index 0000000000..d123efb41f --- /dev/null +++ b/tests/qtest/libqos/riscv-iommu.h @@ -0,0 +1,71 @@ +/* + * libqos driver riscv-iommu-pci framework + * + * Copyright (c) 2024 Ventana Micro Systems Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at = your + * option) any later version. See the COPYING file in the top-level direc= tory. + * + */ + +#ifndef TESTS_LIBQOS_RISCV_IOMMU_H +#define TESTS_LIBQOS_RISCV_IOMMU_H + +#include "qgraph.h" +#include "pci.h" +#include "qemu/bitops.h" + +#ifndef GENMASK_ULL +#define GENMASK_ULL(h, l) (((~0ULL) >> (63 - (h) + (l))) << (l)) +#endif + +/* + * RISC-V IOMMU uses PCI_VENDOR_ID_REDHAT 0x1b36 and + * PCI_DEVICE_ID_REDHAT_RISCV_IOMMU 0x0014. + */ +#define RISCV_IOMMU_PCI_VENDOR_ID 0x1b36 +#define RISCV_IOMMU_PCI_DEVICE_ID 0x0014 +#define RISCV_IOMMU_PCI_DEVICE_CLASS 0x0806 + +/* Common field positions */ +#define RISCV_IOMMU_QUEUE_ENABLE BIT(0) +#define RISCV_IOMMU_QUEUE_INTR_ENABLE BIT(1) +#define RISCV_IOMMU_QUEUE_MEM_FAULT BIT(8) +#define RISCV_IOMMU_QUEUE_ACTIVE BIT(16) +#define RISCV_IOMMU_QUEUE_BUSY BIT(17) + +#define RISCV_IOMMU_REG_CAP 0x0000 +#define RISCV_IOMMU_CAP_VERSION GENMASK_ULL(7, 0) + +#define RISCV_IOMMU_REG_DDTP 0x0010 +#define RISCV_IOMMU_DDTP_BUSY BIT_ULL(4) +#define RISCV_IOMMU_DDTP_MODE GENMASK_ULL(3, 0) +#define RISCV_IOMMU_DDTP_MODE_OFF 0 + +#define RISCV_IOMMU_REG_CQCSR 0x0048 +#define RISCV_IOMMU_CQCSR_CQEN RISCV_IOMMU_QUEUE_ENABLE +#define RISCV_IOMMU_CQCSR_CIE RISCV_IOMMU_QUEUE_INTR_ENABLE +#define RISCV_IOMMU_CQCSR_CQON RISCV_IOMMU_QUEUE_ACTIVE +#define RISCV_IOMMU_CQCSR_BUSY RISCV_IOMMU_QUEUE_BUSY + +#define RISCV_IOMMU_REG_FQCSR 0x004C +#define RISCV_IOMMU_FQCSR_FQEN RISCV_IOMMU_QUEUE_ENABLE +#define RISCV_IOMMU_FQCSR_FIE RISCV_IOMMU_QUEUE_INTR_ENABLE +#define RISCV_IOMMU_FQCSR_FQON RISCV_IOMMU_QUEUE_ACTIVE +#define RISCV_IOMMU_FQCSR_BUSY RISCV_IOMMU_QUEUE_BUSY + +#define RISCV_IOMMU_REG_PQCSR 0x0050 +#define RISCV_IOMMU_PQCSR_PQEN RISCV_IOMMU_QUEUE_ENABLE +#define RISCV_IOMMU_PQCSR_PIE RISCV_IOMMU_QUEUE_INTR_ENABLE +#define RISCV_IOMMU_PQCSR_PQON RISCV_IOMMU_QUEUE_ACTIVE +#define RISCV_IOMMU_PQCSR_BUSY RISCV_IOMMU_QUEUE_BUSY + +#define RISCV_IOMMU_REG_IPSR 0x0054 + +typedef struct QRISCVIOMMU { + QOSGraphObject obj; + QPCIDevice dev; + QPCIBar reg_bar; +} QRISCVIOMMU; + +#endif diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index 12792948ff..a838450d2d 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -293,6 +293,7 @@ qos_test_ss.add( 'vmxnet3-test.c', 'igb-test.c', 'ufs-test.c', + 'riscv-iommu-test.c', ) =20 if config_all_devices.has_key('CONFIG_VIRTIO_SERIAL') diff --git a/tests/qtest/riscv-iommu-test.c b/tests/qtest/riscv-iommu-test.c new file mode 100644 index 0000000000..7f0dbd0211 --- /dev/null +++ b/tests/qtest/riscv-iommu-test.c @@ -0,0 +1,93 @@ +/* + * QTest testcase for RISC-V IOMMU + * + * Copyright (c) 2024 Ventana Micro Systems Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or (at = your + * option) any later version. See the COPYING file in the top-level direc= tory. + * + */ + +#include "qemu/osdep.h" +#include "libqtest-single.h" +#include "qemu/module.h" +#include "libqos/qgraph.h" +#include "libqos/riscv-iommu.h" +#include "hw/pci/pci_regs.h" + +static uint32_t riscv_iommu_read_reg32(QRISCVIOMMU *r_iommu, int reg_offse= t) +{ + uint32_t reg; + + qpci_memread(&r_iommu->dev, r_iommu->reg_bar, reg_offset, + ®, sizeof(reg)); + return reg; +} + +static uint64_t riscv_iommu_read_reg64(QRISCVIOMMU *r_iommu, int reg_offse= t) +{ + uint64_t reg; + + qpci_memread(&r_iommu->dev, r_iommu->reg_bar, reg_offset, + ®, sizeof(reg)); + return reg; +} + +static void test_pci_config(void *obj, void *data, QGuestAllocator *t_allo= c) +{ + QRISCVIOMMU *r_iommu =3D obj; + QPCIDevice *dev =3D &r_iommu->dev; + uint16_t vendorid, deviceid, classid; + + vendorid =3D qpci_config_readw(dev, PCI_VENDOR_ID); + deviceid =3D qpci_config_readw(dev, PCI_DEVICE_ID); + classid =3D qpci_config_readw(dev, PCI_CLASS_DEVICE); + + g_assert_cmpuint(vendorid, =3D=3D, RISCV_IOMMU_PCI_VENDOR_ID); + g_assert_cmpuint(deviceid, =3D=3D, RISCV_IOMMU_PCI_DEVICE_ID); + g_assert_cmpuint(classid, =3D=3D, RISCV_IOMMU_PCI_DEVICE_CLASS); +} + +static void test_reg_reset(void *obj, void *data, QGuestAllocator *t_alloc) +{ + QRISCVIOMMU *r_iommu =3D obj; + uint64_t cap; + uint32_t reg; + + cap =3D riscv_iommu_read_reg64(r_iommu, RISCV_IOMMU_REG_CAP); + g_assert_cmpuint(cap & RISCV_IOMMU_CAP_VERSION, =3D=3D, 0x10); + + reg =3D riscv_iommu_read_reg32(r_iommu, RISCV_IOMMU_REG_CQCSR); + g_assert_cmpuint(reg & RISCV_IOMMU_CQCSR_CQEN, =3D=3D, 0); + g_assert_cmpuint(reg & RISCV_IOMMU_CQCSR_CIE, =3D=3D, 0); + g_assert_cmpuint(reg & RISCV_IOMMU_CQCSR_CQON, =3D=3D, 0); + g_assert_cmpuint(reg & RISCV_IOMMU_CQCSR_BUSY, =3D=3D, 0); + + reg =3D riscv_iommu_read_reg32(r_iommu, RISCV_IOMMU_REG_FQCSR); + g_assert_cmpuint(reg & RISCV_IOMMU_FQCSR_FQEN, =3D=3D, 0); + g_assert_cmpuint(reg & RISCV_IOMMU_FQCSR_FIE, =3D=3D, 0); + g_assert_cmpuint(reg & RISCV_IOMMU_FQCSR_FQON, =3D=3D, 0); + g_assert_cmpuint(reg & RISCV_IOMMU_FQCSR_BUSY, =3D=3D, 0); + + reg =3D riscv_iommu_read_reg32(r_iommu, RISCV_IOMMU_REG_PQCSR); + g_assert_cmpuint(reg & RISCV_IOMMU_PQCSR_PQEN, =3D=3D, 0); + g_assert_cmpuint(reg & RISCV_IOMMU_PQCSR_PIE, =3D=3D, 0); + g_assert_cmpuint(reg & RISCV_IOMMU_PQCSR_PQON, =3D=3D, 0); + g_assert_cmpuint(reg & RISCV_IOMMU_PQCSR_BUSY, =3D=3D, 0); + + reg =3D riscv_iommu_read_reg32(r_iommu, RISCV_IOMMU_REG_DDTP); + g_assert_cmpuint(reg & RISCV_IOMMU_DDTP_BUSY, =3D=3D, 0); + g_assert_cmpuint(reg & RISCV_IOMMU_DDTP_MODE, =3D=3D, + RISCV_IOMMU_DDTP_MODE_OFF); + + reg =3D riscv_iommu_read_reg32(r_iommu, RISCV_IOMMU_REG_IPSR); + g_assert_cmpuint(reg, =3D=3D, 0); +} + +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); +} + +libqos_init(register_riscv_iommu_test); --=20 2.45.2