From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
To: Frank Chang <frank.chang@sifive.com>
Cc: qemu-devel@nongnu.org, 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
Subject: Re: [PATCH v2 04/15] hw/riscv: add riscv-iommu-pci device
Date: Thu, 2 May 2024 06:37:47 -0300 [thread overview]
Message-ID: <471027a0-20e0-4d42-b5ed-2f6fb4da7b8a@ventanamicro.com> (raw)
In-Reply-To: <CANzO1D3gOh23xhPhjcrGqSanf=aX_o-V+mBQY7yW6P+0hOR6Nw@mail.gmail.com>
On 4/29/24 04:21, Frank Chang wrote:
> Daniel Henrique Barboza <dbarboza@ventanamicro.com <mailto:dbarboza@ventanamicro.com>> 於 2024年3月8日 週五 上午12:04寫道:
> >
> > From: Tomasz Jeznach <tjeznach@rivosinc.com <mailto:tjeznach@rivosinc.com>>
> >
> > The RISC-V IOMMU can be modelled as a PCIe device following the
> > guidelines of the RISC-V IOMMU spec, chapter 7.1, "Integrating an IOMMU
> > as a PCIe device".
> >
> > Signed-off-by: Tomasz Jeznach <tjeznach@rivosinc.com <mailto:tjeznach@rivosinc.com>>
> > Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com <mailto:dbarboza@ventanamicro.com>>
> > ---
> > hw/riscv/meson.build | 2 +-
> > hw/riscv/riscv-iommu-pci.c | 173 +++++++++++++++++++++++++++++++++++++
> > 2 files changed, 174 insertions(+), 1 deletion(-)
> > create mode 100644 hw/riscv/riscv-iommu-pci.c
> >
> > diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build
> > index ba9eebd605..4674cec6c4 100644
> > --- a/hw/riscv/meson.build
> > +++ b/hw/riscv/meson.build
> > @@ -10,6 +10,6 @@ riscv_ss.add(when: 'CONFIG_SIFIVE_U', if_true: files('sifive_u.c'))
> > riscv_ss.add(when: 'CONFIG_SPIKE', if_true: files('spike.c'))
> > riscv_ss.add(when: 'CONFIG_MICROCHIP_PFSOC', if_true: files('microchip_pfsoc.c'))
> > riscv_ss.add(when: 'CONFIG_ACPI', if_true: files('virt-acpi-build.c'))
> > -riscv_ss.add(when: 'CONFIG_RISCV_IOMMU', if_true: files('riscv-iommu.c'))
> > +riscv_ss.add(when: 'CONFIG_RISCV_IOMMU', if_true: files('riscv-iommu.c', 'riscv-iommu-pci.c'))
> >
> > hw_arch += {'riscv': riscv_ss}
> > diff --git a/hw/riscv/riscv-iommu-pci.c b/hw/riscv/riscv-iommu-pci.c
> > new file mode 100644
> > index 0000000000..4eb1057210
> > --- /dev/null
> > +++ b/hw/riscv/riscv-iommu-pci.c
> > @@ -0,0 +1,173 @@
> > +/*
> > + * QEMU emulation of an RISC-V IOMMU (Ziommu)
> > + *
> > + * Copyright (C) 2022-2023 Rivos Inc.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License as published by
> > + * the Free Software Foundation; either version 2 of the License.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> > + * GNU General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU General Public License along
> > + * with this program; if not, see <http://www.gnu.org/licenses/ <http://www.gnu.org/licenses/>>.
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "hw/pci/msi.h"
> > +#include "hw/pci/msix.h"
> > +#include "hw/pci/pci_bus.h"
> > +#include "hw/qdev-properties.h"
> > +#include "hw/riscv/riscv_hart.h"
> > +#include "migration/vmstate.h"
> > +#include "qapi/error.h"
> > +#include "qemu/error-report.h"
> > +#include "qemu/host-utils.h"
> > +#include "qom/object.h"
> > +
> > +#include "cpu_bits.h"
> > +#include "riscv-iommu.h"
> > +#include "riscv-iommu-bits.h"
> > +
> > +#ifndef PCI_VENDOR_ID_RIVOS
> > +#define PCI_VENDOR_ID_RIVOS 0x1efd
> > +#endif
> > +
> > +#ifndef PCI_DEVICE_ID_RIVOS_IOMMU
> > +#define PCI_DEVICE_ID_RIVOS_IOMMU 0xedf1
> > +#endif
> > +
> > +/* RISC-V IOMMU PCI Device Emulation */
> > +
> > +typedef struct RISCVIOMMUStatePci {
> > + PCIDevice pci; /* Parent PCIe device state */
> > + MemoryRegion bar0; /* PCI BAR (including MSI-x config) */
> > + RISCVIOMMUState iommu; /* common IOMMU state */
> > +} RISCVIOMMUStatePci;
> > +
> > +/* interrupt delivery callback */
> > +static void riscv_iommu_pci_notify(RISCVIOMMUState *iommu, unsigned vector)
> > +{
> > + RISCVIOMMUStatePci *s = container_of(iommu, RISCVIOMMUStatePci, iommu);
> > +
> > + if (msix_enabled(&(s->pci))) {
> > + msix_notify(&(s->pci), vector);
> > + }
> > +}
> > +
> > +static void riscv_iommu_pci_realize(PCIDevice *dev, Error **errp)
> > +{
> > + RISCVIOMMUStatePci *s = DO_UPCAST(RISCVIOMMUStatePci, pci, dev);
> > + RISCVIOMMUState *iommu = &s->iommu;
> > + Error *err = NULL;
> > +
> > + /* Set device id for trace / debug */
> > + DEVICE(iommu)->id = g_strdup_printf("%02x:%02x.%01x",
> > + pci_dev_bus_num(dev), PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
>
> pci_dev_bus_num() calls pci_bus_num(),
> and pci_bus_num() is assigned to pcibus_num(),
> which returns bus->parent_dev->config[PCI_SECONDARY_BUS]
> However, PCI bus number is not initialized by SW when IOMMU is initialized.
> So pci_bus_num() will always return 0, IIRC.
> Same issue as pci_bus_num() above.
>
> > + qdev_realize(DEVICE(iommu), NULL, errp);
> > +
> > + memory_region_init(&s->bar0, OBJECT(s), "riscv-iommu-bar0",
> > + QEMU_ALIGN_UP(memory_region_size(&iommu->regs_mr), TARGET_PAGE_SIZE));
> > + memory_region_add_subregion(&s->bar0, 0, &iommu->regs_mr);
> > +
> > + pcie_endpoint_cap_init(dev, 0);
> > +
> > + pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY |
> > + PCI_BASE_ADDRESS_MEM_TYPE_64, &s->bar0);
> > +
> > + int ret = msix_init(dev, RISCV_IOMMU_INTR_COUNT,
> > + &s->bar0, 0, RISCV_IOMMU_REG_MSI_CONFIG,
> > + &s->bar0, 0, RISCV_IOMMU_REG_MSI_CONFIG + 256, 0, &err);
> > +
> > + if (ret == -ENOTSUP) {
> > + /*
> > + * MSI-x is not supported by the platform.
> > + * Driver should use timer/polling based notification handlers.
> > + */
> > + warn_report_err(err);
> > + } else if (ret < 0) {
> > + error_propagate(errp, err);
> > + return;
> > + } else {
> > + /* mark all allocated MSIx vectors as used. */
> > + msix_vector_use(dev, RISCV_IOMMU_INTR_CQ);
> > + msix_vector_use(dev, RISCV_IOMMU_INTR_FQ);
> > + msix_vector_use(dev, RISCV_IOMMU_INTR_PM);
> > + msix_vector_use(dev, RISCV_IOMMU_INTR_PQ);
> > + iommu->notify = riscv_iommu_pci_notify;
> > + }
> > +
> > + PCIBus *bus = pci_device_root_bus(dev);
> > + if (!bus) {
> > + error_setg(errp, "can't find PCIe root port for %02x:%02x.%x",
> > + pci_bus_num(pci_get_bus(dev)), PCI_SLOT(dev->devfn),
>
> Same issue to pci_dev_bus_num() above.
>
> > + PCI_FUNC(dev->devfn));
> > + return;
> > + }
> > +
> > + riscv_iommu_pci_setup_iommu(iommu, bus, errp);
> > +}
> > +
> > +static void riscv_iommu_pci_exit(PCIDevice *pci_dev)
> > +{
> > + pci_setup_iommu(pci_device_root_bus(pci_dev), NULL, NULL);
> > +}
> > +
> > +static const VMStateDescription riscv_iommu_vmstate = {
> > + .name = "riscv-iommu",
> > + .unmigratable = 1
> > +};
> > +
> > +static void riscv_iommu_pci_init(Object *obj)
> > +{
> > + RISCVIOMMUStatePci *s = RISCV_IOMMU_PCI(obj);
> > + RISCVIOMMUState *iommu = &s->iommu;
> > +
> > + object_initialize_child(obj, "iommu", iommu, TYPE_RISCV_IOMMU);
> > + qdev_alias_all_properties(DEVICE(iommu), obj);
> > +}
> > +
> > +static Property riscv_iommu_pci_properties[] = {
> > + DEFINE_PROP_END_OF_LIST(),
> > +};
>
> Do we need to assign the empty properties?
>
> > +
> > +static void riscv_iommu_pci_class_init(ObjectClass *klass, void *data)
> > +{
> > + DeviceClass *dc = DEVICE_CLASS(klass);
> > + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
> > +
> > + k->realize = riscv_iommu_pci_realize;
> > + k->exit = riscv_iommu_pci_exit;
> > + k->vendor_id = PCI_VENDOR_ID_RIVOS;
> > + k->device_id = PCI_DEVICE_ID_RIVOS_IOMMU;
>
> I know RIVOS originally modeled this IOMMU,
> but we (SiFive) also have our IOMMU based on RISC-V IOMMU:
> https://open-src-soc.org/2022-05/media/slides/RISC-V-International-Day-2022-05-05-14h10-Perinne-Peresse.pdf <https://open-src-soc.org/2022-05/media/slides/RISC-V-International-Day-2022-05-05-14h10-Perinne-Peresse.pdf>
> Do we have the guidelines on how to extend the vendor IOMMU?
We'll use a generic PCI ID for the QEMU IOMMU model. Drew is giving a
hand looking into it. We'll either send a separated patch to add
the new PCI ID or fold the patch into this series.
As for extend the generic IOMMU, you can use this base implementation
(that doesn't have anything specific to Rivos, it's a generic spec
implementation) to implement the Si-Five device if you want. It
woud a device like:
> > +static const TypeInfo riscv_sifive_iommu_pci = {
> > + .name = TYPE_RISCV_SIFIVE_IOMMU_PCI,
> > + .parent = TYPE_RISCV_IOMMU_PCI,
Same thing with the base emulation code. You can use it as a base and then
add the logic that is exclusive to Si-Five on top of it.
Thanks,
Daniel
>
> > + k->revision = 0;
> > + k->class_id = 0x0806;
>
> We should add
> #define PCI_CLASS_SYSTEM_IOMMU 0x0806
> instead of the hard-coded value.
>
> P.S. AMD's IOMMU also uses hard-coded value 0x0806 in: hw/i386/amd_iommu.c.
>
> > + dc->desc = "RISCV-IOMMU DMA Remapping device";
> > + dc->vmsd = &riscv_iommu_vmstate;
> > + dc->hotpluggable = false;
> > + dc->user_creatable = true;
> > + set_bit(DEVICE_CATEGORY_MISC, dc->categories);
> > + device_class_set_props(dc, riscv_iommu_pci_properties);
> > +}
> > +
> > +static const TypeInfo riscv_iommu_pci = {
> > + .name = TYPE_RISCV_IOMMU_PCI,
> > + .parent = TYPE_PCI_DEVICE,
> > + .class_init = riscv_iommu_pci_class_init,
> > + .instance_init = riscv_iommu_pci_init,
> > + .instance_size = sizeof(RISCVIOMMUStatePci),
> > + .interfaces = (InterfaceInfo[]) {
> > + { INTERFACE_PCIE_DEVICE },
> > + { },
> > + },
> > +};
> > +
> > +static void riscv_iommu_register_pci_types(void)
> > +{
> > + type_register_static(&riscv_iommu_pci);
> > +}
> > +
> > +type_init(riscv_iommu_register_pci_types);
> > --
> > 2.43.2
> >
> >
next prev parent reply other threads:[~2024-05-02 9:38 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-07 16:03 [PATCH v2 00/15] riscv: QEMU RISC-V IOMMU Support Daniel Henrique Barboza
2024-03-07 16:03 ` [PATCH v2 01/15] exec/memtxattr: add process identifier to the transaction attributes Daniel Henrique Barboza
2024-04-23 16:33 ` Frank Chang
2024-03-07 16:03 ` [PATCH v2 02/15] hw/riscv: add riscv-iommu-bits.h Daniel Henrique Barboza
2024-05-10 11:01 ` Frank Chang
2024-05-15 10:02 ` Eric Cheng
2024-05-15 14:28 ` Daniel Henrique Barboza
2024-03-07 16:03 ` [PATCH v2 03/15] hw/riscv: add RISC-V IOMMU base emulation Daniel Henrique Barboza
2024-05-01 11:57 ` Jason Chien
2024-05-14 20:06 ` Daniel Henrique Barboza
2024-05-02 11:37 ` Frank Chang
2024-05-08 11:15 ` Daniel Henrique Barboza
2024-05-10 10:58 ` Frank Chang
2024-05-13 12:41 ` Daniel Henrique Barboza
2024-05-13 12:37 ` Daniel Henrique Barboza
2024-05-16 7:13 ` Frank Chang
2024-05-20 16:17 ` Daniel Henrique Barboza
2024-05-21 10:52 ` Frank Chang
2024-05-21 12:28 ` Daniel Henrique Barboza
2024-03-07 16:03 ` [PATCH v2 04/15] hw/riscv: add riscv-iommu-pci device Daniel Henrique Barboza
2024-04-29 7:21 ` Frank Chang
2024-05-02 9:37 ` Daniel Henrique Barboza [this message]
2024-03-07 16:03 ` [PATCH v2 05/15] hw/riscv: add riscv-iommu-sys platform device Daniel Henrique Barboza
2024-04-30 1:35 ` Frank Chang
2024-03-07 16:03 ` [PATCH v2 06/15] hw/riscv/virt.c: support for RISC-V IOMMU PCIDevice hotplug Daniel Henrique Barboza
2024-04-30 2:17 ` Frank Chang
2024-05-15 6:25 ` Eric Cheng
2024-05-15 7:16 ` Andrew Jones
2024-03-07 16:03 ` [PATCH v2 07/15] test/qtest: add riscv-iommu-pci tests Daniel Henrique Barboza
2024-04-30 3:33 ` Frank Chang
2024-03-07 16:03 ` [PATCH v2 08/15] hw/riscv/riscv-iommu: add Address Translation Cache (IOATC) Daniel Henrique Barboza
2024-05-08 7:26 ` Frank Chang
2024-05-16 21:45 ` Daniel Henrique Barboza
2024-03-07 16:03 ` [PATCH v2 09/15] hw/riscv/riscv-iommu: add s-stage and g-stage support Daniel Henrique Barboza
2024-05-10 10:36 ` Frank Chang
2024-05-10 11:14 ` Andrew Jones
2024-05-16 19:41 ` Daniel Henrique Barboza
2024-03-07 16:03 ` [PATCH v2 10/15] hw/riscv/riscv-iommu: add ATS support Daniel Henrique Barboza
2024-05-08 2:57 ` Frank Chang
2024-05-17 9:29 ` Daniel Henrique Barboza
2024-03-07 16:03 ` [PATCH v2 11/15] hw/riscv/riscv-iommu: add DBG support Daniel Henrique Barboza
2024-05-06 4:09 ` Frank Chang
2024-05-06 13:05 ` Daniel Henrique Barboza
2024-05-10 10:59 ` Frank Chang
2024-03-07 16:03 ` [PATCH v2 12/15] hw/riscv/riscv-iommu: Add another irq for mrif notifications Daniel Henrique Barboza
2024-05-06 6:12 ` Frank Chang
2024-03-07 16:03 ` [PATCH v2 13/15] qtest/riscv-iommu-test: add init queues test Daniel Henrique Barboza
2024-05-07 8:01 ` Frank Chang
2024-03-07 16:03 ` [PATCH v2 14/15] hw/misc: EDU: added PASID support Daniel Henrique Barboza
2024-05-07 9:06 ` Frank Chang
2024-03-07 16:03 ` [PATCH v2 15/15] hw/misc: EDU: add ATS/PRI capability Daniel Henrique Barboza
2024-05-07 15:32 ` Frank Chang
2024-05-16 13:59 ` Daniel Henrique Barboza
2024-05-10 11:14 ` [PATCH v2 00/15] riscv: QEMU RISC-V IOMMU Support Frank Chang
2024-05-20 16:26 ` 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=471027a0-20e0-4d42-b5ed-2f6fb4da7b8a@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=liwei1518@gmail.com \
--cc=palmer@rivosinc.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-riscv@nongnu.org \
--cc=tjeznach@rivosinc.com \
--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.