Re: [PATCH v4 03/14] hw/riscv: add RISC-V IOMMU base emulation

2024-08-27 Thread Tomasz Jeznach
On Thu, Jul 4, 2024 at 7:20 AM Jason Chien  wrote:
>
> Hi Danial,
>
> On 2024/6/25 上午 04:18, Daniel Henrique Barboza wrote:
> > From: Tomasz Jeznach 
> >
> > The RISC-V IOMMU specification is now ratified as-per the RISC-V
> > international process. The latest frozen specifcation can be found at:
> >
> > https://github.com/riscv-non-isa/riscv-iommu/releases/download/v1.0/riscv-iommu.pdf
> >
> > Add the foundation of the device emulation for RISC-V IOMMU, which
> > includes an IOMMU that has no capabilities but MSI interrupt support and
> > fault queue interfaces. We'll add more features incrementally in the
> > next patches.
> >
> > Co-developed-by: Sebastien Boeuf 
> > Signed-off-by: Sebastien Boeuf 
> > Signed-off-by: Tomasz Jeznach 
> > Signed-off-by: Daniel Henrique Barboza 
> > ---
> >   hw/riscv/Kconfig|4 +
> >   hw/riscv/meson.build|1 +
> >   hw/riscv/riscv-iommu-bits.h |2 +
> >   hw/riscv/riscv-iommu.c  | 1641 +++
> >   hw/riscv/riscv-iommu.h  |  142 +++
> >   hw/riscv/trace-events   |   11 +
> >   hw/riscv/trace.h|1 +
> >   include/hw/riscv/iommu.h|   36 +
> >   meson.build |1 +
> >   9 files changed, 1839 insertions(+)
> >   create mode 100644 hw/riscv/riscv-iommu.c
> >   create mode 100644 hw/riscv/riscv-iommu.h
> >   create mode 100644 hw/riscv/trace-events
> >   create mode 100644 hw/riscv/trace.h
> >   create mode 100644 include/hw/riscv/iommu.h
> >
> > diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
> > index a2030e3a6f..f69d6e3c8e 100644
> > --- a/hw/riscv/Kconfig
> > +++ b/hw/riscv/Kconfig
> > @@ -1,3 +1,6 @@
> > +config RISCV_IOMMU
> > +bool
> > +
> >   config RISCV_NUMA
> >   bool
> >
> > @@ -47,6 +50,7 @@ config RISCV_VIRT
> >   select SERIAL
> >   select RISCV_ACLINT
> >   select RISCV_APLIC
> > +select RISCV_IOMMU
> >   select RISCV_IMSIC
> >   select SIFIVE_PLIC
> >   select SIFIVE_TEST
> > diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build
> > index f872674093..cbc99c6e8e 100644
> > --- a/hw/riscv/meson.build
> > +++ b/hw/riscv/meson.build
> > @@ -10,5 +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'))
> >
> >   hw_arch += {'riscv': riscv_ss}
> > diff --git a/hw/riscv/riscv-iommu-bits.h b/hw/riscv/riscv-iommu-bits.h
> > index f29b916acb..8a1af73685 100644
> > --- a/hw/riscv/riscv-iommu-bits.h
> > +++ b/hw/riscv/riscv-iommu-bits.h
> > @@ -82,6 +82,7 @@ struct riscv_iommu_pq_record {
> >
> >   /* 5.4 Features control register (32bits) */
> >   #define RISCV_IOMMU_REG_FCTL0x0008
> > +#define RISCV_IOMMU_FCTL_BE BIT(0)
> >   #define RISCV_IOMMU_FCTL_WSIBIT(1)
> >
> >   /* 5.5 Device-directory-table pointer (64bits) */
> > @@ -311,6 +312,7 @@ enum riscv_iommu_fq_causes {
> >
> >   /* Translation attributes fields */
> >   #define RISCV_IOMMU_PC_TA_V BIT_ULL(0)
> > +#define RISCV_IOMMU_PC_TA_RESERVED  GENMASK_ULL(63, 32)
> >
> >   /* First stage context fields */
> >   #define RISCV_IOMMU_PC_FSC_PPN  GENMASK_ULL(43, 0)
> > diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
> > new file mode 100644
> > index 00..37d7d1e657
> > --- /dev/null
> > +++ b/hw/riscv/riscv-iommu.c
> > @@ -0,0 +1,1641 @@
> > +/*
> > + * QEMU emulation of an RISC-V IOMMU
> > + *
> > + * Copyright (C) 2021-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 .
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "qom/object.h"
> > +#include "hw/pci/pci_bus.h"
> > +#include "hw/pci/pci_device.h"
> > +#include "hw/qdev-properties.h"
> > +#include "hw/riscv/riscv_hart.h"
> > +#include "migration/vmstate.h"
> > +#include "qapi/error.h"
> > +#include "qemu/timer.h"
> > +
> > +#include "cpu_bits.h"
> > +#include "riscv-iommu.h"
> > +#include "riscv-iommu-bits.h"
> > +#include "trace.h"
> > +
> > +#define LIMIT_CACHE_CTX   (1U << 7)
> > +#define LIMIT_CACHE_IOT   (1U << 20)
> > +
> > +/* Physical page numb

Re: [PATCH v4 03/14] hw/riscv: add RISC-V IOMMU base emulation

2024-07-05 Thread Daniel Henrique Barboza

Hi,

On 7/4/24 11:20 AM, Jason Chien wrote:

Hi Danial,

On 2024/6/25 上午 04:18, Daniel Henrique Barboza wrote:

From: Tomasz Jeznach 

The RISC-V IOMMU specification is now ratified as-per the RISC-V
international process. The latest frozen specifcation can be found at:

https://github.com/riscv-non-isa/riscv-iommu/releases/download/v1.0/riscv-iommu.pdf

Add the foundation of the device emulation for RISC-V IOMMU, which
includes an IOMMU that has no capabilities but MSI interrupt support and
fault queue interfaces. We'll add more features incrementally in the
next patches.

Co-developed-by: Sebastien Boeuf 
Signed-off-by: Sebastien Boeuf 
Signed-off-by: Tomasz Jeznach 
Signed-off-by: Daniel Henrique Barboza 
---
  hw/riscv/Kconfig    |    4 +
  hw/riscv/meson.build    |    1 +
  hw/riscv/riscv-iommu-bits.h |    2 +
  hw/riscv/riscv-iommu.c  | 1641 +++
  hw/riscv/riscv-iommu.h  |  142 +++
  hw/riscv/trace-events   |   11 +
  hw/riscv/trace.h    |    1 +
  include/hw/riscv/iommu.h    |   36 +
  meson.build |    1 +
  9 files changed, 1839 insertions(+)
  create mode 100644 hw/riscv/riscv-iommu.c
  create mode 100644 hw/riscv/riscv-iommu.h
  create mode 100644 hw/riscv/trace-events
  create mode 100644 hw/riscv/trace.h
  create mode 100644 include/hw/riscv/iommu.h

diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index a2030e3a6f..f69d6e3c8e 100644


(...)



+/* IOMMU index for transactions without process_id specified. */
+#define RISCV_IOMMU_NOPROCID 0
+
+static void riscv_iommu_notify(RISCVIOMMUState *s, int vec)
+{
+    const uint32_t fctl = riscv_iommu_reg_get32(s, RISCV_IOMMU_REG_FCTL);
+    uint32_t ipsr, ivec;
+
+    if (fctl & RISCV_IOMMU_FCTL_WSI || !s->notify) {

For WSI, we can assert INTx by invoking pci_set_irq().


For now we're not advertising WSI support because we don't have a way to test it
(riscv-iommu-pci only supports MSI). In fact riscv_iommu_notify() isn't called
for any WSI capable device, at least for now.

I'm finishing some patches where we'll re-introduce riscv-iommu-sys in the 
'virt'
machine with WSI. At that point we'll pay more attention with the WSI bits that
we're ignoring for now.


+    return;
+    }
+
+    ipsr = riscv_iommu_reg_mod32(s, RISCV_IOMMU_REG_IPSR, (1 << vec), 0);
+    ivec = riscv_iommu_reg_get32(s, RISCV_IOMMU_REG_IVEC);
+
+    if (!(ipsr & (1 << vec))) {
+    s->notify(s, (ivec >> (vec * 4)) & 0x0F);
+    }
+}
+


(...)


+
+/* Check if GPA matches MSI/MRIF pattern. */
+static bool riscv_iommu_msi_check(RISCVIOMMUState *s, RISCVIOMMUContext *ctx,
+    dma_addr_t gpa)
+{


If IOMMU does not support MSI, that is, s->enable_msi is false, we can return 
false.



Done.


+    if (get_field(ctx->msiptp, RISCV_IOMMU_DC_MSIPTP_MODE) !=
+    RISCV_IOMMU_DC_MSIPTP_MODE_FLAT) {
+    return false; /* Invalid MSI/MRIF mode */
+    }
+
+    if ((PPN_DOWN(gpa) ^ ctx->msi_addr_pattern) & ~ctx->msi_addr_mask) {
+    return false; /* GPA not in MSI range defined by AIA IMSIC rules. */
+    }
+
+    return true;
+}
+
+/* RISCV IOMMU Address Translation Lookup - Page Table Walk */
+static int riscv_iommu_spa_fetch(RISCVIOMMUState *s, RISCVIOMMUContext *ctx,
+    IOMMUTLBEntry *iotlb)
+{
+    /* Early check for MSI address match when IOVA == GPA */
+    if (iotlb->perm & IOMMU_WO &&
+    riscv_iommu_msi_check(s, ctx, iotlb->iova)) {
+    iotlb->target_as = &s->trap_as;
+    iotlb->translated_addr = iotlb->iova;
+    iotlb->addr_mask = ~TARGET_PAGE_MASK;
+    return 0;
+    }

 From spec 2.3, step 17 and step 18 state that the MSI address translation is 
always done after the first stage translation is done.


This piece of code isn't doing MSI addr translation. It's preventing the lookup
process by doing an early exit if IOVA==GPA, i.e. there's nothing to translate.

What you described is being done in patch 8 with s-stage and g-stage support.

(...)


+/* Redirect MSI write for given GPA. */
+static MemTxResult riscv_iommu_msi_write(RISCVIOMMUState *s,
+    RISCVIOMMUContext *ctx, uint64_t gpa, uint64_t data,
+    unsigned size, MemTxAttrs attrs)
+{
+    MemTxResult res;
+    dma_addr_t addr;
+    uint64_t intn;
+    uint32_t n190;
+    uint64_t pte[2];
+    int fault_type = RISCV_IOMMU_FQ_TTYPE_UADDR_WR;
+    int cause;
+
+    if (!riscv_iommu_msi_check(s, ctx, gpa)) {

I think we have invoked riscv_iommu_msi_check() before writing to s->trap_as. 
Do we need this check?



You're right. Removed.

(...)


+
+    if (data & RISCV_IOMMU_IPSR_PIP) {
+    pqcsr = riscv_iommu_reg_get32(s, RISCV_IOMMU_REG_PQCSR);
+
+    if (pqcsr & RISCV_IOMMU_PQCSR_PIE &&
+    (pqcsr & RISCV_IOMMU_PQCSR_PQOF ||
+ pqcsr & RISCV_IOMMU_PQCSR_PQMF)) {
+    ipsr_set |= RISCV_IOMMU_IPSR_PIP;
+    } else {
+    ipsr_clr |= RISCV_IOMMU_IPSR_PIP;
+    }
+    } else {
+    ipsr_clr |= RISCV_IOMMU_IPSR_PIP;
+    }
+
+    riscv_iommu_

Re: [PATCH v4 03/14] hw/riscv: add RISC-V IOMMU base emulation

2024-07-04 Thread Jason Chien

Hi Danial,

On 2024/6/25 上午 04:18, Daniel Henrique Barboza wrote:

From: Tomasz Jeznach 

The RISC-V IOMMU specification is now ratified as-per the RISC-V
international process. The latest frozen specifcation can be found at:

https://github.com/riscv-non-isa/riscv-iommu/releases/download/v1.0/riscv-iommu.pdf

Add the foundation of the device emulation for RISC-V IOMMU, which
includes an IOMMU that has no capabilities but MSI interrupt support and
fault queue interfaces. We'll add more features incrementally in the
next patches.

Co-developed-by: Sebastien Boeuf 
Signed-off-by: Sebastien Boeuf 
Signed-off-by: Tomasz Jeznach 
Signed-off-by: Daniel Henrique Barboza 
---
  hw/riscv/Kconfig|4 +
  hw/riscv/meson.build|1 +
  hw/riscv/riscv-iommu-bits.h |2 +
  hw/riscv/riscv-iommu.c  | 1641 +++
  hw/riscv/riscv-iommu.h  |  142 +++
  hw/riscv/trace-events   |   11 +
  hw/riscv/trace.h|1 +
  include/hw/riscv/iommu.h|   36 +
  meson.build |1 +
  9 files changed, 1839 insertions(+)
  create mode 100644 hw/riscv/riscv-iommu.c
  create mode 100644 hw/riscv/riscv-iommu.h
  create mode 100644 hw/riscv/trace-events
  create mode 100644 hw/riscv/trace.h
  create mode 100644 include/hw/riscv/iommu.h

diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index a2030e3a6f..f69d6e3c8e 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -1,3 +1,6 @@
+config RISCV_IOMMU
+bool
+
  config RISCV_NUMA
  bool
  
@@ -47,6 +50,7 @@ config RISCV_VIRT

  select SERIAL
  select RISCV_ACLINT
  select RISCV_APLIC
+select RISCV_IOMMU
  select RISCV_IMSIC
  select SIFIVE_PLIC
  select SIFIVE_TEST
diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build
index f872674093..cbc99c6e8e 100644
--- a/hw/riscv/meson.build
+++ b/hw/riscv/meson.build
@@ -10,5 +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'))
  
  hw_arch += {'riscv': riscv_ss}

diff --git a/hw/riscv/riscv-iommu-bits.h b/hw/riscv/riscv-iommu-bits.h
index f29b916acb..8a1af73685 100644
--- a/hw/riscv/riscv-iommu-bits.h
+++ b/hw/riscv/riscv-iommu-bits.h
@@ -82,6 +82,7 @@ struct riscv_iommu_pq_record {
  
  /* 5.4 Features control register (32bits) */

  #define RISCV_IOMMU_REG_FCTL0x0008
+#define RISCV_IOMMU_FCTL_BE BIT(0)
  #define RISCV_IOMMU_FCTL_WSIBIT(1)
  
  /* 5.5 Device-directory-table pointer (64bits) */

@@ -311,6 +312,7 @@ enum riscv_iommu_fq_causes {
  
  /* Translation attributes fields */

  #define RISCV_IOMMU_PC_TA_V BIT_ULL(0)
+#define RISCV_IOMMU_PC_TA_RESERVED  GENMASK_ULL(63, 32)
  
  /* First stage context fields */

  #define RISCV_IOMMU_PC_FSC_PPN  GENMASK_ULL(43, 0)
diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
new file mode 100644
index 00..37d7d1e657
--- /dev/null
+++ b/hw/riscv/riscv-iommu.c
@@ -0,0 +1,1641 @@
+/*
+ * QEMU emulation of an RISC-V IOMMU
+ *
+ * Copyright (C) 2021-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 .
+ */
+
+#include "qemu/osdep.h"
+#include "qom/object.h"
+#include "hw/pci/pci_bus.h"
+#include "hw/pci/pci_device.h"
+#include "hw/qdev-properties.h"
+#include "hw/riscv/riscv_hart.h"
+#include "migration/vmstate.h"
+#include "qapi/error.h"
+#include "qemu/timer.h"
+
+#include "cpu_bits.h"
+#include "riscv-iommu.h"
+#include "riscv-iommu-bits.h"
+#include "trace.h"
+
+#define LIMIT_CACHE_CTX   (1U << 7)
+#define LIMIT_CACHE_IOT   (1U << 20)
+
+/* Physical page number coversions */
+#define PPN_PHYS(ppn) ((ppn) << TARGET_PAGE_BITS)
+#define PPN_DOWN(phy) ((phy) >> TARGET_PAGE_BITS)
+
+typedef struct RISCVIOMMUContext RISCVIOMMUContext;
+typedef struct RISCVIOMMUEntry RISCVIOMMUEntry;
+
+/* Device assigned I/O address space */
+struct RISCVIOMMUSpace {
+IOMMUMemoryRegion iova_mr;  /* IOVA memory region for attached device */
+AddressSpace iova_as;   /* IOVA address space for attached device */
+RISCVIOMMUState *iommu; /* Managing IOMMU device s

[PATCH v4 03/14] hw/riscv: add RISC-V IOMMU base emulation

2024-06-24 Thread Daniel Henrique Barboza
From: Tomasz Jeznach 

The RISC-V IOMMU specification is now ratified as-per the RISC-V
international process. The latest frozen specifcation can be found at:

https://github.com/riscv-non-isa/riscv-iommu/releases/download/v1.0/riscv-iommu.pdf

Add the foundation of the device emulation for RISC-V IOMMU, which
includes an IOMMU that has no capabilities but MSI interrupt support and
fault queue interfaces. We'll add more features incrementally in the
next patches.

Co-developed-by: Sebastien Boeuf 
Signed-off-by: Sebastien Boeuf 
Signed-off-by: Tomasz Jeznach 
Signed-off-by: Daniel Henrique Barboza 
---
 hw/riscv/Kconfig|4 +
 hw/riscv/meson.build|1 +
 hw/riscv/riscv-iommu-bits.h |2 +
 hw/riscv/riscv-iommu.c  | 1641 +++
 hw/riscv/riscv-iommu.h  |  142 +++
 hw/riscv/trace-events   |   11 +
 hw/riscv/trace.h|1 +
 include/hw/riscv/iommu.h|   36 +
 meson.build |1 +
 9 files changed, 1839 insertions(+)
 create mode 100644 hw/riscv/riscv-iommu.c
 create mode 100644 hw/riscv/riscv-iommu.h
 create mode 100644 hw/riscv/trace-events
 create mode 100644 hw/riscv/trace.h
 create mode 100644 include/hw/riscv/iommu.h

diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index a2030e3a6f..f69d6e3c8e 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -1,3 +1,6 @@
+config RISCV_IOMMU
+bool
+
 config RISCV_NUMA
 bool
 
@@ -47,6 +50,7 @@ config RISCV_VIRT
 select SERIAL
 select RISCV_ACLINT
 select RISCV_APLIC
+select RISCV_IOMMU
 select RISCV_IMSIC
 select SIFIVE_PLIC
 select SIFIVE_TEST
diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build
index f872674093..cbc99c6e8e 100644
--- a/hw/riscv/meson.build
+++ b/hw/riscv/meson.build
@@ -10,5 +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'))
 
 hw_arch += {'riscv': riscv_ss}
diff --git a/hw/riscv/riscv-iommu-bits.h b/hw/riscv/riscv-iommu-bits.h
index f29b916acb..8a1af73685 100644
--- a/hw/riscv/riscv-iommu-bits.h
+++ b/hw/riscv/riscv-iommu-bits.h
@@ -82,6 +82,7 @@ struct riscv_iommu_pq_record {
 
 /* 5.4 Features control register (32bits) */
 #define RISCV_IOMMU_REG_FCTL0x0008
+#define RISCV_IOMMU_FCTL_BE BIT(0)
 #define RISCV_IOMMU_FCTL_WSIBIT(1)
 
 /* 5.5 Device-directory-table pointer (64bits) */
@@ -311,6 +312,7 @@ enum riscv_iommu_fq_causes {
 
 /* Translation attributes fields */
 #define RISCV_IOMMU_PC_TA_V BIT_ULL(0)
+#define RISCV_IOMMU_PC_TA_RESERVED  GENMASK_ULL(63, 32)
 
 /* First stage context fields */
 #define RISCV_IOMMU_PC_FSC_PPN  GENMASK_ULL(43, 0)
diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
new file mode 100644
index 00..37d7d1e657
--- /dev/null
+++ b/hw/riscv/riscv-iommu.c
@@ -0,0 +1,1641 @@
+/*
+ * QEMU emulation of an RISC-V IOMMU
+ *
+ * Copyright (C) 2021-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 .
+ */
+
+#include "qemu/osdep.h"
+#include "qom/object.h"
+#include "hw/pci/pci_bus.h"
+#include "hw/pci/pci_device.h"
+#include "hw/qdev-properties.h"
+#include "hw/riscv/riscv_hart.h"
+#include "migration/vmstate.h"
+#include "qapi/error.h"
+#include "qemu/timer.h"
+
+#include "cpu_bits.h"
+#include "riscv-iommu.h"
+#include "riscv-iommu-bits.h"
+#include "trace.h"
+
+#define LIMIT_CACHE_CTX   (1U << 7)
+#define LIMIT_CACHE_IOT   (1U << 20)
+
+/* Physical page number coversions */
+#define PPN_PHYS(ppn) ((ppn) << TARGET_PAGE_BITS)
+#define PPN_DOWN(phy) ((phy) >> TARGET_PAGE_BITS)
+
+typedef struct RISCVIOMMUContext RISCVIOMMUContext;
+typedef struct RISCVIOMMUEntry RISCVIOMMUEntry;
+
+/* Device assigned I/O address space */
+struct RISCVIOMMUSpace {
+IOMMUMemoryRegion iova_mr;  /* IOVA memory region for attached device */
+AddressSpace iova_as;   /* IOVA address space for attached device */
+RISCVIOMMUState *iommu; /* Managing IOMMU device state */
+uint32_t devid; /* Requester identifier, AKA device_id */
+bool notifier;