On 2/6/26 3:48 PM, Shameer Kolothum wrote: > From: Nicolin Chen <[email protected]> > > Add ACPI DSDT support for Tegra241 CMDQV when the SMMUv3 instance is > created with tegra241-cmdqv. > > The SMMUv3 device identifier is used as the ACPI _UID. This matches > the Identifier field of the corresponding SMMUv3 IORT node, allowing > the CMDQV DSDT device to be correctly associated with its SMMU. > > Because virt-acpi-build.c now includes CONFIG_DEVICES via the Tegra241 > CMDQV header, the Meson file entry is updated to build it as part of > arm_ss instead of arm_common_ss > > Signed-off-by: Nicolin Chen <[email protected]> > Signed-off-by: Shameer Kolothum <[email protected]> > --- > hw/arm/meson.build | 2 +- > hw/arm/trace-events | 1 + > hw/arm/virt-acpi-build.c | 73 ++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 75 insertions(+), 1 deletion(-) > > diff --git a/hw/arm/meson.build b/hw/arm/meson.build > index 4ec91db50a..af0b516df1 100644 > --- a/hw/arm/meson.build > +++ b/hw/arm/meson.build > @@ -1,7 +1,7 @@ > arm_ss = ss.source_set() > arm_common_ss = ss.source_set() > arm_common_ss.add(when: 'CONFIG_ARM_VIRT', if_true: files('virt.c')) > -arm_common_ss.add(when: 'CONFIG_ACPI', if_true: files('virt-acpi-build.c')) > +arm_ss.add(when: 'CONFIG_ACPI', if_true: files('virt-acpi-build.c')) > arm_common_ss.add(when: 'CONFIG_DIGIC', if_true: files('digic_boards.c')) > arm_common_ss.add(when: 'CONFIG_EMCRAFT_SF2', if_true: files('msf2-som.c')) > arm_common_ss.add(when: 'CONFIG_HIGHBANK', if_true: files('highbank.c')) > diff --git a/hw/arm/trace-events b/hw/arm/trace-events > index ef495c040c..e7e3ccfe9f 100644 > --- a/hw/arm/trace-events > +++ b/hw/arm/trace-events > @@ -9,6 +9,7 @@ omap1_lpg_led(const char *onoff) "omap1 LPG: LED is %s" > > # virt-acpi-build.c > virt_acpi_setup(void) "No fw cfg or ACPI disabled. Bailing out." > +virt_acpi_dsdt_tegra241_cmdqv(int smmu_id, uint64_t base, uint32_t irq) > "DSDT: add cmdqv node for (id=%d), base=0x%" PRIx64 ", irq=%d" > > # smmu-common.c > smmu_add_mr(const char *name) "%s" > diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c > index 046e930ca5..fe2925baaf 100644 > --- a/hw/arm/virt-acpi-build.c > +++ b/hw/arm/virt-acpi-build.c > @@ -65,6 +65,8 @@ > #include "target/arm/cpu.h" > #include "target/arm/multiprocessing.h" > > +#include "tegra241-cmdqv.h" > + > #define ARM_SPI_BASE 32 > > #define ACPI_BUILD_TABLE_SIZE 0x20000 > @@ -1121,6 +1123,75 @@ static void build_fadt_rev6(GArray *table_data, > BIOSLinker *linker, > build_fadt(table_data, linker, &fadt, vms->oem_id, vms->oem_table_id); > } > > +static int smmuv3_cmdqv_devices(Object *obj, void *opaque) > +{ > + VirtMachineState *vms = VIRT_MACHINE(qdev_get_machine()); > + GArray *sdev_blob = opaque; > + PlatformBusDevice *pbus; > + AcpiSMMUv3Dev sdev; > + SysBusDevice *sbdev; > + > + if (!object_dynamic_cast(obj, TYPE_ARM_SMMUV3)) { > + return 0; > + } > + > + if (!object_property_get_bool(obj, "tegra241-cmdqv", NULL)) { > + return 0; > + } > + > + sdev.id = object_property_get_uint(obj, "identifier", &error_abort); > + pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev); > + sbdev = SYS_BUS_DEVICE(obj); > + sdev.base = platform_bus_get_mmio_addr(pbus, sbdev, 1); > + sdev.base += vms->memmap[VIRT_PLATFORM_BUS].base; > + sdev.irq = platform_bus_get_irqn(pbus, sbdev, NUM_SMMU_IRQS); > + sdev.irq += vms->irqmap[VIRT_PLATFORM_BUS]; > + sdev.irq += ARM_SPI_BASE; > + g_array_append_val(sdev_blob, sdev); > + return 0; > +} > + > +static void acpi_dsdt_add_tegra241_cmdqv(Aml *scope, VirtMachineState *vms) > +{ > + GArray *smmuv3_devs = g_array_new(false, true, sizeof(AcpiSMMUv3Dev)); wonder if it wouldn't be possible to compute and store the blob in vms once and reuse that for both iort and dsdt? Eric > + int i; > + > + if (vms->legacy_smmuv3_present) { > + return; > + } > + > + object_child_foreach_recursive(object_get_root(), smmuv3_cmdqv_devices, > + smmuv3_devs); > + > + for (i = 0; i < smmuv3_devs->len; i++) { > + AcpiSMMUv3Dev *sdev; > + Aml *dev, *crs, *addr; > + > + sdev = &g_array_index(smmuv3_devs, AcpiSMMUv3Dev, i); > + > + dev = aml_device("CV%.02u", sdev->id); > + aml_append(dev, aml_name_decl("_HID", aml_string("NVDA200C"))); > + aml_append(dev, aml_name_decl("_UID", aml_int(sdev->id))); > + aml_append(dev, aml_name_decl("_CCA", aml_int(1))); > + > + crs = aml_resource_template(); > + addr = aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED, > + AML_CACHEABLE, AML_READ_WRITE, 0x0, > sdev->base, > + sdev->base + TEGRA241_CMDQV_IO_LEN - 0x1, > 0x0, > + TEGRA241_CMDQV_IO_LEN); > + aml_append(crs, addr); > + aml_append(crs, aml_interrupt(AML_CONSUMER, AML_EDGE, > + AML_ACTIVE_HIGH, AML_EXCLUSIVE, > + (uint32_t *)&sdev->irq, 1)); > + aml_append(dev, aml_name_decl("_CRS", crs)); > + > + aml_append(scope, dev); > + > + trace_virt_acpi_dsdt_tegra241_cmdqv(sdev->id, sdev->base, sdev->irq); > + } > + g_array_free(smmuv3_devs, true); > +} > + > /* DSDT */ > static void > build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) > @@ -1185,6 +1256,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, > VirtMachineState *vms) > acpi_dsdt_add_tpm(scope, vms); > #endif > > + acpi_dsdt_add_tegra241_cmdqv(scope, vms); > + > aml_append(dsdt, scope); > > pci0_scope = aml_scope("\\_SB.PCI0");
