On 2/26/26 11:50 AM, Shameer Kolothum wrote: > From: Nicolin Chen <[email protected]> > > Tegra241 CMDQV extends SMMUv3 with support for virtual command queues > (VCMDQs) exposed via a CMDQV MMIO region. The CMDQV MMIO space is split > into 64KB pages: > > 0x00000: Global CMDQV registers > 0x10000: Global VCMDQ registers, Page0 > 0x20000: Global VCMDQ registers, Page1 > 0x30000: VINTF0 logical VCMDQ registers, Page0 > 0x40000: VINTF0 logical VCMDQ registers, Page1 > > This patch wires up the Tegra241 CMDQV init callback and allocates > vendor-specific CMDQV state. The state pointer is stored in > SMMUv3AccelState for use by subsequent CMDQV operations. > > The CMDQV MMIO region and a dedicated IRQ line are registered with the > SMMUv3 device. The MMIO read/write handlers are currently stubs and will > be implemented in later patches. > > The CMDQV interrupt is edge-triggered and indicates VCMDQ or VINTF > error conditions. This patch only registers the IRQ line. Interrupt > generation and propagation to the guest will be added in a subsequent > patch. > > Signed-off-by: Nicolin Chen <[email protected]> > Signed-off-by: Shameer Kolothum <[email protected]> > --- > hw/arm/smmuv3-accel.h | 1 + > hw/arm/tegra241-cmdqv.h | 18 ++++++++++++++++++ > hw/arm/tegra241-cmdqv.c | 30 ++++++++++++++++++++++++++++-- > 3 files changed, 47 insertions(+), 2 deletions(-) > > diff --git a/hw/arm/smmuv3-accel.h b/hw/arm/smmuv3-accel.h > index 5bdd01afb5..7d6e4c6b76 100644 > --- a/hw/arm/smmuv3-accel.h > +++ b/hw/arm/smmuv3-accel.h > @@ -42,6 +42,7 @@ typedef struct SMMUv3AccelState { > uint32_t abort_hwpt_id; > QLIST_HEAD(, SMMUv3AccelDevice) device_list; > const SMMUv3AccelCmdqvOps *cmdqv_ops; > + void *cmdqv; /* vendor specific CMDQV state */ > } SMMUv3AccelState; > > typedef struct SMMUS1Hwpt { > diff --git a/hw/arm/tegra241-cmdqv.h b/hw/arm/tegra241-cmdqv.h > index 312064a081..46aa9e8a9f 100644 > --- a/hw/arm/tegra241-cmdqv.h > +++ b/hw/arm/tegra241-cmdqv.h > @@ -15,6 +15,24 @@ > #define TEGRA241_CMDQV_MAX_CMDQ (1U << > TEGRA241_CMDQV_NUM_CMDQ_LOG2) > #define TEGRA241_CMDQV_NUM_SID_PER_VM_LOG2 4 > > +/* > + * Tegra241 CMDQV MMIO layout (64KB pages) > + * > + * 0x00000 TEGRA241_CMDQV_CFG (Global CMDQV configuration) > + * 0x10000 TEGRA241_VCMDQ_PAGE0 (Virtual CMDQ page 0) > + * 0x20000 TEGRA241_VCMDQ_PAGE1 (Virtual CMDQ page 1) > + * 0x30000 TEGRA241_VINTF0_PAGE0 (Virtual interface 0, page 0) > + * 0x40000 TEGRA241_VINTF0_PAGE1 (Virtual interface 0, page 1) > + */ > +#define TEGRA241_CMDQV_IO_LEN 0x50000 > + > +typedef struct Tegra241CMDQV { > + struct iommu_viommu_tegra241_cmdqv cmdqv_data; > + SMMUv3AccelState *s_accel; > + MemoryRegion mmio_cmdqv; > + qemu_irq irq; > +} Tegra241CMDQV; > + > const SMMUv3AccelCmdqvOps *tegra241_cmdqv_get_ops(void); > > #endif /* HW_ARM_TEGRA241_CMDQV_H */ > diff --git a/hw/arm/tegra241-cmdqv.c b/hw/arm/tegra241-cmdqv.c > index a270fa7ce4..6959766129 100644 > --- a/hw/arm/tegra241-cmdqv.c > +++ b/hw/arm/tegra241-cmdqv.c > @@ -13,6 +13,16 @@ > #include "smmuv3-accel.h" > #include "tegra241-cmdqv.h" > > +static uint64_t tegra241_cmdqv_read(void *opaque, hwaddr offset, unsigned > size) > +{ > + return 0; > +} > + > +static void tegra241_cmdqv_write(void *opaque, hwaddr offset, uint64_t value, > + unsigned size) > +{ > +} > + > static void tegra241_cmdqv_free_viommu(SMMUv3State *s) > { > } > @@ -29,10 +39,26 @@ static void tegra241_cmdqv_reset(SMMUv3State *s) > { > } > > +static const MemoryRegionOps mmio_cmdqv_ops = { > + .read = tegra241_cmdqv_read, > + .write = tegra241_cmdqv_write, > + .endianness = DEVICE_LITTLE_ENDIAN, > +}; > + > static bool tegra241_cmdqv_init(SMMUv3State *s, Error **errp) > { > - error_setg(errp, "NVIDIA Tegra241 CMDQV is unsupported"); > - return false; > + SysBusDevice *sbd = SYS_BUS_DEVICE(OBJECT(s)); > + SMMUv3AccelState *accel = s->s_accel; > + Tegra241CMDQV *cmdqv; > + > + cmdqv = g_new0(Tegra241CMDQV, 1); > + memory_region_init_io(&cmdqv->mmio_cmdqv, OBJECT(s), &mmio_cmdqv_ops, > cmdqv, > + "tegra241-cmdqv", TEGRA241_CMDQV_IO_LEN); > + sysbus_init_mmio(sbd, &cmdqv->mmio_cmdqv); > + sysbus_init_irq(sbd, &cmdqv->irq); > + cmdqv->s_accel = accel; > + accel->cmdqv = cmdqv; > + return true; > } > > static bool tegra241_cmdqv_probe(SMMUv3State *s, HostIOMMUDeviceIOMMUFD > *idev, Reviewed-by: Eric Auger <[email protected]> Eric
