On 5/19/26 12:36 PM, Shameer Kolothum wrote:
> From: Nicolin Chen <[email protected]>
>
> Tegra241 CMDQV exposes per-VCMDQ register windows through two MMIO
> apertures:
>
>   Direct VCMDQ aperture (0x10000/0x20000): VCMDQ Page0/Page1
>   VINTF logical aperture (0x30000/0x40000): VINTF0 LVCMDQ Page0/Page1
>
> Both apertures are hardware aliases of the same underlying registers:
>
>   Page 0 (control/status): CONS_INDX, PROD_INDX, CONFIG, STATUS,
>                            GERROR, GERRORN
>   Page 1 (base/DRAM):      BASE_L/H, CONS_INDX_BASE_DRAM_L/H
>
> The direct aperture Page 0 is programmable at any time so long as
> CMDQV_EN is enabled. The VINTF (logical) aperture Page 0 is
> programmable only once SW has mapped a VCMDQ to a VINTF; the
> "logical" view is local to that VINTF.
>
> Add read emulation for both apertures, backed by a single per-VCMDQ
> register cache. VINTF aperture reads are translated to their
> equivalent direct-aperture offset and served from the same cached
> state.
>
> Once IOMMU_HW_QUEUE_ALLOC and viommu_mmap are wired up in a
> subsequent patch, Page 0 reads will be served directly from the
> hardware-backed mmap'd page instead of the cache. Page 1 is also a
> hardware alias, but the kernel only exposes mmap for Page 0, so
> Page 1 reads always trap to QEMU and are served from cache.
>
> Signed-off-by: Nicolin Chen <[email protected]>
> Co-developed-by: Shameer Kolothum <[email protected]>
> Signed-off-by: Shameer Kolothum <[email protected]>
> ---
>  hw/arm/tegra241-cmdqv.h | 215 ++++++++++++++++++++++++++++++++++++++++
>  hw/arm/tegra241-cmdqv.c |  95 ++++++++++++++++++
>  hw/arm/trace-events     |   2 +
>  3 files changed, 312 insertions(+)
>
> diff --git a/hw/arm/tegra241-cmdqv.h b/hw/arm/tegra241-cmdqv.h
> index ace327443a..6b21a407af 100644
> --- a/hw/arm/tegra241-cmdqv.h
> +++ b/hw/arm/tegra241-cmdqv.h
> @@ -30,6 +30,13 @@
>   */
>  #define TEGRA241_CMDQV_IO_LEN 0x50000
>  
> +/* CMDQV MMIO aperture bases and VCMDQ stride */
> +#define CMDQV_VCMDQ_PAGE0_BASE  0x10000  /* CMDQV_CMDQ_BASE */
> +#define CMDQV_VCMDQ_PAGE1_BASE  0x20000
> +#define CMDQV_VINTF_PAGE0_BASE  0x30000  /* CMDQV_VI_CMDQ_BASE */
> +#define CMDQV_VINTF_PAGE1_BASE  0x40000
> +#define CMDQV_VCMDQ_STRIDE      0x80
> +
>  typedef struct Tegra241CMDQV {
>      struct iommu_viommu_tegra241_cmdqv cmdqv_data;
>      SMMUv3AccelState *s_accel;
> @@ -52,6 +59,19 @@ typedef struct Tegra241CMDQV {
>      uint32_t vintf_sid_match[TEGRA241_CMDQV_MAX_NUM_SID];
>      uint32_t vintf_sid_replace[TEGRA241_CMDQV_MAX_NUM_SID];
>      uint32_t vintf_cmdq_err_map[4];
> +    /*
> +     * VCMDQ register cache. The direct (VCMDQ aperture) and logical
> +     * (VINTF aperture) views are hardware aliases; both are served from
> +     * this single cached copy.
> +     */
> +    uint32_t vcmdq_cons_indx[TEGRA241_CMDQV_MAX_CMDQ];
> +    uint32_t vcmdq_prod_indx[TEGRA241_CMDQV_MAX_CMDQ];
> +    uint32_t vcmdq_config[TEGRA241_CMDQV_MAX_CMDQ];
> +    uint32_t vcmdq_status[TEGRA241_CMDQV_MAX_CMDQ];
> +    uint32_t vcmdq_gerror[TEGRA241_CMDQV_MAX_CMDQ];
> +    uint32_t vcmdq_gerrorn[TEGRA241_CMDQV_MAX_CMDQ];
> +    uint64_t vcmdq_base[TEGRA241_CMDQV_MAX_CMDQ];
> +    uint64_t vcmdq_cons_indx_base[TEGRA241_CMDQV_MAX_CMDQ];
>  } Tegra241CMDQV;
>  
>  /* CMDQ-V Config page registers (offset 0x00000) */
> @@ -143,6 +163,201 @@ REG32(VINTF0_LVCMDQ_ERR_MAP_0, 0x10c0)
>  FIELD(VINTF0_LVCMDQ_ERR_MAP_0, LVCMDQ_ERR_MAP, 0, 32)
>  #define A_VINTF0_LVCMDQ_ERR_MAP_3 (A_VINTF0_LVCMDQ_ERR_MAP_0 + 3 * 4)
>  
> +/*
> + * VCMDQ Page 0 register window @ CMDQV_VCMDQ_PAGE0_BASE.
> + * Direct VCMDQ aperture; control and status registers.
> + */
> +#define SMMU_CMDQV_VCMDQi_CONS_INDX_(i)                     \
> +    REG32(VCMDQ##i##_CONS_INDX,                             \
> +          CMDQV_VCMDQ_PAGE0_BASE + i * CMDQV_VCMDQ_STRIDE)  \
> +    FIELD(VCMDQ##i##_CONS_INDX, RD, 0, 20)                  \
> +    FIELD(VCMDQ##i##_CONS_INDX, ERR, 24, 7)
> +
> +SMMU_CMDQV_VCMDQi_CONS_INDX_(0)
> +SMMU_CMDQV_VCMDQi_CONS_INDX_(1)
> +
> +#define V_VCMDQ_CONS_INDX_ERR_CERROR_NONE         0
> +#define V_VCMDQ_CONS_INDX_ERR_CERROR_ILL_OPCODE   1
> +#define V_VCMDQ_CONS_INDX_ERR_CERROR_ABT          2
> +#define V_VCMDQ_CONS_INDX_ERR_CERROR_ATC_INV_SYNC 3
> +#define V_VCMDQ_CONS_INDX_ERR_CERROR_ILL_ACCESS   4
> +
> +#define SMMU_CMDQV_VCMDQi_PROD_INDX_(i)                          \
> +    REG32(VCMDQ##i##_PROD_INDX,                                  \
> +          CMDQV_VCMDQ_PAGE0_BASE + 0x4 + i * CMDQV_VCMDQ_STRIDE) \
> +    FIELD(VCMDQ##i##_PROD_INDX, WR, 0, 20)
> +
> +SMMU_CMDQV_VCMDQi_PROD_INDX_(0)
> +SMMU_CMDQV_VCMDQi_PROD_INDX_(1)
> +
> +#define SMMU_CMDQV_VCMDQi_CONFIG_(i)                             \
> +    REG32(VCMDQ##i##_CONFIG,                                     \
> +          CMDQV_VCMDQ_PAGE0_BASE + 0x8 + i * CMDQV_VCMDQ_STRIDE) \
> +    FIELD(VCMDQ##i##_CONFIG, CMDQ_EN, 0, 1)
> +
> +SMMU_CMDQV_VCMDQi_CONFIG_(0)
> +SMMU_CMDQV_VCMDQi_CONFIG_(1)
> +
> +#define SMMU_CMDQV_VCMDQi_STATUS_(i)                             \
> +    REG32(VCMDQ##i##_STATUS,                                     \
> +          CMDQV_VCMDQ_PAGE0_BASE + 0xc + i * CMDQV_VCMDQ_STRIDE) \
> +    FIELD(VCMDQ##i##_STATUS, CMDQ_EN_OK, 0, 1)
> +
> +SMMU_CMDQV_VCMDQi_STATUS_(0)
> +SMMU_CMDQV_VCMDQi_STATUS_(1)
> +
> +#define SMMU_CMDQV_VCMDQi_GERROR_(i)                              \
> +    REG32(VCMDQ##i##_GERROR,                                      \
> +          CMDQV_VCMDQ_PAGE0_BASE + 0x10 + i * CMDQV_VCMDQ_STRIDE) \
> +    FIELD(VCMDQ##i##_GERROR, CMDQ_ERR, 0, 1)                      \
> +    FIELD(VCMDQ##i##_GERROR, CONS_DRAM_WR_ABT_ERR, 1, 1)          \
> +    FIELD(VCMDQ##i##_GERROR, CMDQ_INIT_ERR, 2, 1)
> +
> +SMMU_CMDQV_VCMDQi_GERROR_(0)
> +SMMU_CMDQV_VCMDQi_GERROR_(1)
> +
> +#define SMMU_CMDQV_VCMDQi_GERRORN_(i)                             \
> +    REG32(VCMDQ##i##_GERRORN,                                     \
> +          CMDQV_VCMDQ_PAGE0_BASE + 0x14 + i * CMDQV_VCMDQ_STRIDE) \
> +    FIELD(VCMDQ##i##_GERRORN, CMDQ_ERR, 0, 1)                     \
> +    FIELD(VCMDQ##i##_GERRORN, CONS_DRAM_WR_ABT_ERR, 1, 1)         \
> +    FIELD(VCMDQ##i##_GERRORN, CMDQ_INIT_ERR, 2, 1)
> +
> +SMMU_CMDQV_VCMDQi_GERRORN_(0)
> +SMMU_CMDQV_VCMDQi_GERRORN_(1)


nit, what I meant in my v4 comments is I would prefer we group the
eventual register definition to represent the actual layout of each
page, instead of interleaving them with actual macros:
This would look like:

/* page 0 */

/* vcmdq0 */

+SMMU_CMDQV_VCMDQi_CONS_INDX_(0)
+SMMU_CMDQV_VCMDQi_PROD_INDX_(0)
+SMMU_CMDQV_VCMDQi_CONFIG_(0)
+SMMU_CMDQV_VCMDQi_STATUS_(0)
+SMMU_CMDQV_VCMDQi_GERROR_(0)
+SMMU_CMDQV_VCMDQi_GERRORN_(0)

/* vcmdq1 */

+SMMU_CMDQV_VCMDQi_CONS_INDX_(1)
+SMMU_CMDQV_VCMDQi_PROD_INDX_(1)
+SMMU_CMDQV_VCMDQi_CONFIG_(1)
+SMMU_CMDQV_VCMDQi_STATUS_(1)
+SMMU_CMDQV_VCMDQi_GERROR_(1)
+SMMU_CMDQV_VCMDQi_GERRORN_(1)

same for page 1

To me it looks easier to remember the layout without looking at the spec.


Taste & colors, what do you prefer? 






> +
> +/*
> + * VCMDQ Page 1 register window @ CMDQV_VCMDQ_PAGE1_BASE.
> + * Direct VCMDQ aperture; base and DRAM address registers.
> + */
> +#define SMMU_CMDQV_VCMDQi_BASE_L_(i)                                         
>  \
> +    REG32(VCMDQ##i##_BASE_L, CMDQV_VCMDQ_PAGE1_BASE + i * 
> CMDQV_VCMDQ_STRIDE) \
> +    FIELD(VCMDQ##i##_BASE_L, LOG2SIZE, 0, 5)                                 
>  \
> +    FIELD(VCMDQ##i##_BASE_L, ADDR, 5, 27)
> +
> +SMMU_CMDQV_VCMDQi_BASE_L_(0)
> +SMMU_CMDQV_VCMDQi_BASE_L_(1)
> +
> +#define SMMU_CMDQV_VCMDQi_BASE_H_(i)                             \
> +    REG32(VCMDQ##i##_BASE_H,                                     \
> +          CMDQV_VCMDQ_PAGE1_BASE + 0x4 + i * CMDQV_VCMDQ_STRIDE) \
> +    FIELD(VCMDQ##i##_BASE_H, ADDR, 0, 16)
> +
> +SMMU_CMDQV_VCMDQi_BASE_H_(0)
> +SMMU_CMDQV_VCMDQi_BASE_H_(1)
> +
> +#define SMMU_CMDQV_VCMDQi_CONS_INDX_BASE_DRAM_L_(i)              \
> +    REG32(VCMDQ##i##_CONS_INDX_BASE_DRAM_L,                      \
> +          CMDQV_VCMDQ_PAGE1_BASE + 0x8 + i * CMDQV_VCMDQ_STRIDE) \
> +    FIELD(VCMDQ##i##_CONS_INDX_BASE_DRAM_L, ADDR, 0, 32)
> +
> +SMMU_CMDQV_VCMDQi_CONS_INDX_BASE_DRAM_L_(0)
> +SMMU_CMDQV_VCMDQi_CONS_INDX_BASE_DRAM_L_(1)
> +
> +#define SMMU_CMDQV_VCMDQi_CONS_INDX_BASE_DRAM_H_(i)              \
> +    REG32(VCMDQ##i##_CONS_INDX_BASE_DRAM_H,                      \
> +          CMDQV_VCMDQ_PAGE1_BASE + 0xc + i * CMDQV_VCMDQ_STRIDE) \
> +    FIELD(VCMDQ##i##_CONS_INDX_BASE_DRAM_H, ADDR, 0, 16)
> +
> +SMMU_CMDQV_VCMDQi_CONS_INDX_BASE_DRAM_H_(0)
> +SMMU_CMDQV_VCMDQi_CONS_INDX_BASE_DRAM_H_(1)
> +
> +/*
> + * VINTF0 LVCMDQ Page 0 register window @ CMDQV_VINTF_PAGE0_BASE.
> + * Logical VCMDQ aperture (VCMDQs mapped via VINTF); control and
> + * status registers. Hardware alias of VCMDQ Page 0 above.
> + */
> +#define SMMU_CMDQV_VI_VCMDQi_CONS_INDX_(i)                  \
> +    REG32(VI_VCMDQ##i##_CONS_INDX,                          \
> +          CMDQV_VINTF_PAGE0_BASE + i * CMDQV_VCMDQ_STRIDE)  \
> +    FIELD(VI_VCMDQ##i##_CONS_INDX, RD, 0, 20)               \
> +    FIELD(VI_VCMDQ##i##_CONS_INDX, ERR, 24, 7)
> +
> +SMMU_CMDQV_VI_VCMDQi_CONS_INDX_(0)
> +SMMU_CMDQV_VI_VCMDQi_CONS_INDX_(1)
> +
> +#define SMMU_CMDQV_VI_VCMDQi_PROD_INDX_(i)                       \
> +    REG32(VI_VCMDQ##i##_PROD_INDX,                               \
> +          CMDQV_VINTF_PAGE0_BASE + 0x4 + i * CMDQV_VCMDQ_STRIDE) \
> +    FIELD(VI_VCMDQ##i##_PROD_INDX, WR, 0, 20)
> +
> +SMMU_CMDQV_VI_VCMDQi_PROD_INDX_(0)
> +SMMU_CMDQV_VI_VCMDQi_PROD_INDX_(1)
> +
> +#define SMMU_CMDQV_VI_VCMDQi_CONFIG_(i)                          \
> +    REG32(VI_VCMDQ##i##_CONFIG,                                  \
> +          CMDQV_VINTF_PAGE0_BASE + 0x8 + i * CMDQV_VCMDQ_STRIDE) \
> +    FIELD(VI_VCMDQ##i##_CONFIG, CMDQ_EN, 0, 1)
> +
> +SMMU_CMDQV_VI_VCMDQi_CONFIG_(0)
> +SMMU_CMDQV_VI_VCMDQi_CONFIG_(1)
> +
> +#define SMMU_CMDQV_VI_VCMDQi_STATUS_(i)                          \
> +    REG32(VI_VCMDQ##i##_STATUS,                                  \
> +          CMDQV_VINTF_PAGE0_BASE + 0xc + i * CMDQV_VCMDQ_STRIDE) \
> +    FIELD(VI_VCMDQ##i##_STATUS, CMDQ_EN_OK, 0, 1)
> +
> +SMMU_CMDQV_VI_VCMDQi_STATUS_(0)
> +SMMU_CMDQV_VI_VCMDQi_STATUS_(1)
> +
> +#define SMMU_CMDQV_VI_VCMDQi_GERROR_(i)                           \
> +    REG32(VI_VCMDQ##i##_GERROR,                                   \
> +          CMDQV_VINTF_PAGE0_BASE + 0x10 + i * CMDQV_VCMDQ_STRIDE) \
> +    FIELD(VI_VCMDQ##i##_GERROR, CMDQ_ERR, 0, 1)                   \
> +    FIELD(VI_VCMDQ##i##_GERROR, CONS_DRAM_WR_ABT_ERR, 1, 1)       \
> +    FIELD(VI_VCMDQ##i##_GERROR, CMDQ_INIT_ERR, 2, 1)
> +
> +SMMU_CMDQV_VI_VCMDQi_GERROR_(0)
> +SMMU_CMDQV_VI_VCMDQi_GERROR_(1)
> +
> +#define SMMU_CMDQV_VI_VCMDQi_GERRORN_(i)                          \
> +    REG32(VI_VCMDQ##i##_GERRORN,                                  \
> +          CMDQV_VINTF_PAGE0_BASE + 0x14 + i * CMDQV_VCMDQ_STRIDE) \
> +    FIELD(VI_VCMDQ##i##_GERRORN, CMDQ_ERR, 0, 1)                  \
> +    FIELD(VI_VCMDQ##i##_GERRORN, CONS_DRAM_WR_ABT_ERR, 1, 1)      \
> +    FIELD(VI_VCMDQ##i##_GERRORN, CMDQ_INIT_ERR, 2, 1)
> +
> +SMMU_CMDQV_VI_VCMDQi_GERRORN_(0)
> +SMMU_CMDQV_VI_VCMDQi_GERRORN_(1)
> +
> +/*
> + * VINTF0 LVCMDQ Page 1 register window @ CMDQV_VINTF_PAGE1_BASE.
> + * Logical VCMDQ aperture (VCMDQs mapped via VINTF); base and DRAM
> + * address registers. Hardware alias of VCMDQ Page 1 above.
> + */
> +#define SMMU_CMDQV_VI_VCMDQi_BASE_L_(i)                     \
> +    REG32(VI_VCMDQ##i##_BASE_L,                             \
> +          CMDQV_VINTF_PAGE1_BASE + i * CMDQV_VCMDQ_STRIDE)  \
> +    FIELD(VI_VCMDQ##i##_BASE_L, LOG2SIZE, 0, 5)             \
> +    FIELD(VI_VCMDQ##i##_BASE_L, ADDR, 5, 27)
> +
> +SMMU_CMDQV_VI_VCMDQi_BASE_L_(0)
> +SMMU_CMDQV_VI_VCMDQi_BASE_L_(1)
> +
> +#define SMMU_CMDQV_VI_VCMDQi_BASE_H_(i)                          \
> +    REG32(VI_VCMDQ##i##_BASE_H,                                  \
> +          CMDQV_VINTF_PAGE1_BASE + 0x4 + i * CMDQV_VCMDQ_STRIDE) \
> +    FIELD(VI_VCMDQ##i##_BASE_H, ADDR, 0, 16)
> +
> +SMMU_CMDQV_VI_VCMDQi_BASE_H_(0)
> +SMMU_CMDQV_VI_VCMDQi_BASE_H_(1)
> +
> +#define SMMU_CMDQV_VI_VCMDQi_CONS_INDX_BASE_DRAM_L_(i)           \
> +    REG32(VI_VCMDQ##i##_CONS_INDX_BASE_DRAM_L,                   \
> +          CMDQV_VINTF_PAGE1_BASE + 0x8 + i * CMDQV_VCMDQ_STRIDE) \
> +    FIELD(VI_VCMDQ##i##_CONS_INDX_BASE_DRAM_L, ADDR, 0, 32)
> +
> +SMMU_CMDQV_VI_VCMDQi_CONS_INDX_BASE_DRAM_L_(0)
> +SMMU_CMDQV_VI_VCMDQi_CONS_INDX_BASE_DRAM_L_(1)
> +
> +#define SMMU_CMDQV_VI_VCMDQi_CONS_INDX_BASE_DRAM_H_(i)           \
> +    REG32(VI_VCMDQ##i##_CONS_INDX_BASE_DRAM_H,                   \
> +          CMDQV_VINTF_PAGE1_BASE + 0xc + i * CMDQV_VCMDQ_STRIDE) \
> +    FIELD(VI_VCMDQ##i##_CONS_INDX_BASE_DRAM_H, ADDR, 0, 16)
> +
> +SMMU_CMDQV_VI_VCMDQi_CONS_INDX_BASE_DRAM_H_(0)
> +SMMU_CMDQV_VI_VCMDQi_CONS_INDX_BASE_DRAM_H_(1)
> +
>  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 813b9a61ce..f859126ad6 100644
> --- a/hw/arm/tegra241-cmdqv.c
> +++ b/hw/arm/tegra241-cmdqv.c
> @@ -16,6 +16,75 @@
>  #include "tegra241-cmdqv.h"
>  #include "trace.h"
>  
> +/*
> + * Read a VCMDQ Page 0 register (control/status) using VCMDQ0_* offsets.
> + *
> + * The caller normalizes the MMIO offset such that @offset0 always refers
> + * to a VCMDQ0_* register, while @index selects the VCMDQ instance.
> + */
> +static uint64_t tegra241_cmdqv_read_vcmdq_page0(Tegra241CMDQV *cmdqv,
> +                                                hwaddr offset0, int index)
> +{
> +    uint64_t val = 0;
> +
> +    switch (offset0) {
> +    case A_VCMDQ0_CONS_INDX:
> +        val = cmdqv->vcmdq_cons_indx[index];
> +        break;
> +    case A_VCMDQ0_PROD_INDX:
> +        val = cmdqv->vcmdq_prod_indx[index];
> +        break;
> +    case A_VCMDQ0_CONFIG:
> +        val = cmdqv->vcmdq_config[index];
> +        break;
> +    case A_VCMDQ0_STATUS:
> +        val = cmdqv->vcmdq_status[index];
> +        break;
> +    case A_VCMDQ0_GERROR:
> +        val = cmdqv->vcmdq_gerror[index];
> +        break;
> +    case A_VCMDQ0_GERRORN:
> +        val = cmdqv->vcmdq_gerrorn[index];
> +        break;
> +    default:
> +        qemu_log_mask(LOG_UNIMP,
> +                      "%s unhandled read access at 0x%" PRIx64 "\n",
> +                      __func__, offset0);
> +    }
> +    trace_tegra241_cmdqv_read_vcmdq_page0(index, offset0, val);
> +    return val;
> +}
> +
> +/*
> + * Read a VCMDQ Page 1 register (base / DRAM address) using VCMDQ0_* offsets.
> + */
> +static uint64_t tegra241_cmdqv_read_vcmdq_page1(Tegra241CMDQV *cmdqv,
> +                                                hwaddr offset0, int index)
> +{
> +    uint64_t val = 0;
> +
> +    switch (offset0) {
> +    case A_VCMDQ0_BASE_L:
> +        val = cmdqv->vcmdq_base[index];
> +        break;
> +    case A_VCMDQ0_BASE_H:
> +        val = cmdqv->vcmdq_base[index] >> 32;
> +        break;
> +    case A_VCMDQ0_CONS_INDX_BASE_DRAM_L:
> +        val = cmdqv->vcmdq_cons_indx_base[index];
> +        break;
> +    case A_VCMDQ0_CONS_INDX_BASE_DRAM_H:
> +        val = cmdqv->vcmdq_cons_indx_base[index] >> 32;
> +        break;
> +    default:
> +        qemu_log_mask(LOG_UNIMP,
> +                      "%s unhandled read access at 0x%" PRIx64 "\n",
> +                      __func__, offset0);
> +    }
> +    trace_tegra241_cmdqv_read_vcmdq_page1(index, offset0, val);
> +    return val;
> +}
> +
>  static uint64_t tegra241_cmdqv_config_vintf_read(Tegra241CMDQV *cmdqv,
>                                                   hwaddr offset)
>  {
> @@ -93,6 +162,7 @@ static uint64_t tegra241_cmdqv_read_mmio(void *opaque, 
> hwaddr offset,
>  {
>      Tegra241CMDQV *cmdqv = (Tegra241CMDQV *)opaque;
>      uint64_t val = 0;
> +    int index;
>  
>      if (offset >= TEGRA241_CMDQV_IO_LEN) {
>          qemu_log_mask(LOG_UNIMP,
> @@ -126,6 +196,31 @@ static uint64_t tegra241_cmdqv_read_mmio(void *opaque, 
> hwaddr offset,
>      case A_VINTF0_CONFIG ... A_VINTF0_LVCMDQ_ERR_MAP_3:
>          val = tegra241_cmdqv_config_vintf_read(cmdqv, offset);
>          break;
> +    case A_VI_VCMDQ0_CONS_INDX ... A_VI_VCMDQ1_GERRORN:
> +        /*
> +         * VINTF Page0 registers are hardware aliases of VCMDQ Page0 
> registers.
> +         * Translate the VINTF aperture offset to its VCMDQ Page0 equivalent
> +         * and fall through to the Page0 dispatch below.
> +         */
> +        offset -= CMDQV_VINTF_PAGE0_BASE - CMDQV_VCMDQ_PAGE0_BASE;
> +        QEMU_FALLTHROUGH;
> +    case A_VCMDQ0_CONS_INDX ... A_VCMDQ1_GERRORN:
> +        /*
> +         * Decode a per-VCMDQ Page 0 access. Each VCMDQ occupies a
> +         * CMDQV_VCMDQ_STRIDE-byte window; extract the index and normalize
> +         * to the VCMDQ0_* offset before calling the Page 0 helper.
> +         */
> +        index = (offset - CMDQV_VCMDQ_PAGE0_BASE) / CMDQV_VCMDQ_STRIDE;
> +        return tegra241_cmdqv_read_vcmdq_page0(cmdqv,
> +                offset - index * CMDQV_VCMDQ_STRIDE, index);
> +    case A_VI_VCMDQ0_BASE_L ... A_VI_VCMDQ1_CONS_INDX_BASE_DRAM_H:
> +        /* Same VINTF-to-VCMDQ translation as VINTF Page0 case above. */
> +        offset -= CMDQV_VINTF_PAGE1_BASE - CMDQV_VCMDQ_PAGE1_BASE;
> +        QEMU_FALLTHROUGH;
> +    case A_VCMDQ0_BASE_L ... A_VCMDQ1_CONS_INDX_BASE_DRAM_H:
> +        index = (offset - CMDQV_VCMDQ_PAGE1_BASE) / CMDQV_VCMDQ_STRIDE;
> +        return tegra241_cmdqv_read_vcmdq_page1(cmdqv,
> +                offset - index * CMDQV_VCMDQ_STRIDE, index);
>      default:
>          qemu_log_mask(LOG_UNIMP, "%s unhandled read access at 0x%" PRIx64 
> "\n",
>                        __func__, offset);
> diff --git a/hw/arm/trace-events b/hw/arm/trace-events
> index 8c61d66a26..8c34a04b24 100644
> --- a/hw/arm/trace-events
> +++ b/hw/arm/trace-events
> @@ -75,6 +75,8 @@ smmuv3_accel_install_ste(uint32_t vsid, const char * type, 
> uint32_t hwpt_id) "vS
>  # tegra241-cmdqv
>  tegra241_cmdqv_read_mmio(uint64_t offset, uint64_t val, unsigned size) 
> "offset: 0x%"PRIx64" val: 0x%"PRIx64" size: 0x%x"
>  tegra241_cmdqv_write_mmio(uint64_t offset, uint64_t val, unsigned size) 
> "offset: 0x%"PRIx64" val: 0x%"PRIx64" size: 0x%x"
> +tegra241_cmdqv_read_vcmdq_page0(int index, uint64_t offset0, uint64_t val) 
> "vcmdq[%d] page0 offset0: 0x%"PRIx64" val: 0x%"PRIx64
> +tegra241_cmdqv_read_vcmdq_page1(int index, uint64_t offset0, uint64_t val) 
> "vcmdq[%d] page1 offset0: 0x%"PRIx64" val: 0x%"PRIx64
>  
>  # strongarm.c
>  strongarm_uart_update_parameters(const char *label, int speed, char parity, 
> int data_bits, int stop_bits) "%s speed=%d parity=%c data=%d stop=%d"
Besides looks good to me

Reviewed-by: Eric Auger <[email protected]>

Eric


Reply via email to