@samitouri / QOSamiQemu / commits / b110918bce

hw/arm/tegra241-cmdqv: Implement CMDQV init

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 (CMDQ-V Config page) 0x10000 (CMDQ-V CMDQ Page0) 0x20000 (CMDQ-V CMDQ Page1) 0x30000 (Virtual Interface Page0) 0x40000 (Virtual Interface 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 <nicolinc@nvidia.com> Reviewed-by: Eric Auger <eric.auger@redhat.com> Tested-by: Nicolin Chen <nicolinc@nvidia.com> Tested-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com> Message-id: 20260609112552.378999-12-skolothumtho@nvidia.com Co-developed-by: Shameer Kolothum <skolothumtho@nvidia.com> Signed-off-by: Shameer Kolothum <skolothumtho@nvidia.com> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Nicolin Chen committed Jun 9, 2026 at 12:25 UTC b110918bce7c65bd514c5dfd36e6abc8c21534f5
3 files changed +59 -2
hw/arm/smmuv3-accel.h
+1
@@ -61,6 +61,7 @@ typedef struct SMMUv3AccelState {
61 bool auto_mode;
62 bool auto_finalised;
63 const SMMUv3AccelCmdqvOps *cmdqv_ops;
64 + void *cmdqv; /* vendor specific CMDQV state */
65 } SMMUv3AccelState;
66
67 typedef struct SMMUS1Hwpt {
hw/arm/tegra241-cmdqv.c
+38 -2
@@ -13,6 +13,17 @@
13 #include "smmuv3-accel.h"
14 #include "tegra241-cmdqv.h"
15
16 +static uint64_t tegra241_cmdqv_read_mmio(void *opaque, hwaddr offset,
17 + unsigned size)
18 +{
19 + return 0;
20 +}
21 +
22 +static void tegra241_cmdqv_write_mmio(void *opaque, hwaddr offset,
23 + uint64_t value, unsigned size)
24 +{
25 +}
26 +
27 static void tegra241_cmdqv_free_viommu(SMMUv3State *s)
28 {
29 }
@@ -29,10 +40,35 @@ static void tegra241_cmdqv_reset(SMMUv3State *s)
40 {
41 }
42
43 +static const MemoryRegionOps mmio_cmdqv_ops = {
44 + .read = tegra241_cmdqv_read_mmio,
45 + .write = tegra241_cmdqv_write_mmio,
46 + .endianness = DEVICE_LITTLE_ENDIAN,
47 + .valid = {
48 + .min_access_size = 4,
49 + .max_access_size = 8,
50 + },
51 + .impl = {
52 + .min_access_size = 4,
53 + .max_access_size = 8,
54 + },
55 +};
56 +
57 static bool tegra241_cmdqv_init(SMMUv3State *s, Error **errp)
58 {
34 - error_setg(errp, "NVIDIA Tegra241 CMDQV is unsupported");
35 - return false;
59 + SysBusDevice *sbd = SYS_BUS_DEVICE(OBJECT(s));
60 + SMMUv3AccelState *accel = s->s_accel;
61 + Tegra241CMDQV *cmdqv;
62 +
63 + cmdqv = g_new0(Tegra241CMDQV, 1);
64 + cmdqv->cmdqv_data = g_new0(struct iommu_viommu_tegra241_cmdqv, 1);
65 + memory_region_init_io(&cmdqv->mmio_cmdqv, OBJECT(s), &mmio_cmdqv_ops, cmdqv,
66 + "tegra241-cmdqv", TEGRA241_CMDQV_IO_LEN);
67 + sysbus_init_mmio(sbd, &cmdqv->mmio_cmdqv);
68 + sysbus_init_irq(sbd, &cmdqv->irq);
69 + cmdqv->s_accel = accel;
70 + accel->cmdqv = cmdqv;
71 + return true;
72 }
73
74 static bool tegra241_cmdqv_probe(SMMUv3State *s, HostIOMMUDeviceIOMMUFD *idev,
hw/arm/tegra241-cmdqv.h
+20
@@ -14,6 +14,26 @@
14 #define CMDQV_NUM_CMDQ_LOG2 1
15 #define CMDQV_NUM_SID_PER_VI_LOG2 4
16
17 +/*
18 + * Tegra241 CMDQV MMIO layout (64KB pages)
19 + *
20 + * 0x00000 (CMDQ-V Config page)
21 + * 0x10000 (CMDQ-V CMDQ Page0)
22 + * 0x20000 (CMDQ-V CMDQ Page1)
23 + * 0x30000 (Virtual Interface Page0)
24 + * 0x40000 (Virtual Interface Page1)
25 + */
26 +#define TEGRA241_CMDQV_IO_LEN 0x50000
27 +
28 +struct iommu_viommu_tegra241_cmdqv;
29 +
30 +typedef struct Tegra241CMDQV {
31 + struct iommu_viommu_tegra241_cmdqv *cmdqv_data;
32 + SMMUv3AccelState *s_accel;
33 + MemoryRegion mmio_cmdqv;
34 + qemu_irq irq;
35 +} Tegra241CMDQV;
36 +
37 const SMMUv3AccelCmdqvOps *tegra241_cmdqv_get_ops(void);
38
39 #endif /* HW_ARM_TEGRA241_CMDQV_H */