On Fri, Feb 06, 2026 at 02:48:09PM +0000, Shameer Kolothum wrote:
> +static uint64_t tegra241_cmdqv_read_vintf(Tegra241CMDQV *cmdqv, hwaddr
> offset)
> +{
> + int i;
> +
> + switch (offset) {
> + case A_VINTF0_CONFIG:
> + return cmdqv->vintf_config;
> + case A_VINTF0_STATUS:
> + return cmdqv->vintf_status;
> + case A_VINTF0_LVCMDQ_ERR_MAP_0 ... A_VINTF0_LVCMDQ_ERR_MAP_3:
> + i = (offset - A_VINTF0_LVCMDQ_ERR_MAP_0) / 4;
> + return cmdqv->vintf_cmdq_err_map[i];
> + default:
> + qemu_log_mask(LOG_UNIMP, "%s unhandled read access at 0x%" PRIx64
> "\n",
> + __func__, offset);
> + return 0;
I wonder if we'd still need to implement VINTF0_SID_MATCH/REPLACE
registers as it's a part of HW spec. They don't need to associate
with anything but register cache alone to support MMIO.
> +static void tegra241_cmdqv_write_vintf(Tegra241CMDQV *cmdqv, hwaddr offset,
> + uint64_t value)
> +{
> + switch (offset) {
> + case A_VINTF0_CONFIG:
> + /* Strip off HYP_OWN setting from guest kernel */
> + value &= ~R_VINTF0_CONFIG_HYP_OWN_MASK;
> +
> + cmdqv->vintf_config = value;
> + if (value & R_VINTF0_CONFIG_ENABLE_MASK) {
> + cmdqv->vintf_status |= R_VINTF0_STATUS_ENABLE_OK_MASK;
> + } else {
> + cmdqv->vintf_status &= ~R_VINTF0_STATUS_ENABLE_OK_MASK;
> + }
To emulate the HW perfectly, VINTF_EN = 0 might have to disable
the VCMDQ feature, i.e. deallocate HW_QUEUEs and munmap page0.
Otherwise, guest could continue using the vcmdq "hardware" after
disabling it, which doesn't make sense.
This means that HW_QUEUE allocations would have to be delayed,
until VINTF_EN=1 and corresponding VCMDQ_EN=1.
> @@ -59,6 +129,36 @@ static void tegra241_cmdqv_write(void *opaque, hwaddr
> offset, uint64_t value,
> + switch (offset) {
> + case A_CONFIG:
> + cmdqv->config = value;
> + if (value & R_CONFIG_CMDQV_EN_MASK) {
> + cmdqv->status |= R_STATUS_CMDQV_ENABLED_MASK;
> + } else {
> + cmdqv->status &= ~R_STATUS_CMDQV_ENABLED_MASK;
> + }
We'd need to do something about this as well. VINTF/VCMDQ should
not be functional when CMDQV_EN=0.
Thanks
Nicolin