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


Reply via email to