* [PATCH 0/2] RISC-V: ACPI: Add support for RIMT @ 2025-03-14 5:15 Sunil V L 2025-03-14 5:15 ` [PATCH 1/2] hw/riscv/virt: Add the BDF of IOMMU to RISCVVirtState structure Sunil V L 2025-03-14 5:15 ` [PATCH 2/2] hw/riscv/virt-acpi-build: Add support for RIMT Sunil V L 0 siblings, 2 replies; 5+ messages in thread From: Sunil V L @ 2025-03-14 5:15 UTC (permalink / raw) To: qemu-riscv, qemu-devel Cc: Alistair Francis, Palmer Dabbelt, Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, Andrew Jones, Anup Patel, Atish Patra, Sunil V L RISC-V IO Mapping Table (RIMT) is a new static ACPI table used to communicate IOMMU and topology information to the OS. Add support for creating this table when the IOMMU is present. The specification is frozen and available at [1]. [1] - https://github.com/riscv-non-isa/riscv-acpi-rimt/releases/download/v0.99/rimt-spec.pdf Sunil V L (2): hw/riscv/virt: Add the BDF of IOMMU to RISCVVirtState structure hw/riscv/virt-acpi-build: Add support for RIMT hw/riscv/virt-acpi-build.c | 215 +++++++++++++++++++++++++++++++++++++ hw/riscv/virt.c | 1 + include/hw/riscv/virt.h | 1 + 3 files changed, 217 insertions(+) -- 2.43.0 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/2] hw/riscv/virt: Add the BDF of IOMMU to RISCVVirtState structure 2025-03-14 5:15 [PATCH 0/2] RISC-V: ACPI: Add support for RIMT Sunil V L @ 2025-03-14 5:15 ` Sunil V L 2025-03-19 12:40 ` Daniel Henrique Barboza 2025-03-14 5:15 ` [PATCH 2/2] hw/riscv/virt-acpi-build: Add support for RIMT Sunil V L 1 sibling, 1 reply; 5+ messages in thread From: Sunil V L @ 2025-03-14 5:15 UTC (permalink / raw) To: qemu-riscv, qemu-devel Cc: Alistair Francis, Palmer Dabbelt, Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, Andrew Jones, Anup Patel, Atish Patra, Sunil V L When the IOMMU is implemented as a PCI device, its BDF is created locally in virt.c. However, the same BDF is also required in virt-acpi-build.c to support ACPI. Therefore, make this information part of the global RISCVVirtState structure so that it can be accessed outside of virt.c as well. Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> --- hw/riscv/virt.c | 1 + include/hw/riscv/virt.h | 1 + 2 files changed, 2 insertions(+) diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index dae46f4733..ce256fb3b3 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -1116,6 +1116,7 @@ static void create_fdt_iommu(RISCVVirtState *s, uint16_t bdf) qemu_fdt_setprop_cells(fdt, pci_node, "iommu-map", 0, iommu_phandle, 0, bdf, bdf + 1, iommu_phandle, bdf + 1, 0xffff - bdf); + s->pci_iommu_bdf = bdf; } static void finalize_fdt(RISCVVirtState *s) diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index 48a14bea2e..7b4c2c8b7d 100644 --- a/include/hw/riscv/virt.h +++ b/include/hw/riscv/virt.h @@ -63,6 +63,7 @@ struct RISCVVirtState { const MemMapEntry *memmap; struct GPEXHost *gpex_host; OnOffAuto iommu_sys; + uint16_t pci_iommu_bdf; }; enum { -- 2.43.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] hw/riscv/virt: Add the BDF of IOMMU to RISCVVirtState structure 2025-03-14 5:15 ` [PATCH 1/2] hw/riscv/virt: Add the BDF of IOMMU to RISCVVirtState structure Sunil V L @ 2025-03-19 12:40 ` Daniel Henrique Barboza 0 siblings, 0 replies; 5+ messages in thread From: Daniel Henrique Barboza @ 2025-03-19 12:40 UTC (permalink / raw) To: Sunil V L, qemu-riscv, qemu-devel Cc: Alistair Francis, Palmer Dabbelt, Weiwei Li, Liu Zhiwei, Andrew Jones, Anup Patel, Atish Patra On 3/14/25 2:15 AM, Sunil V L wrote: > When the IOMMU is implemented as a PCI device, its BDF is created > locally in virt.c. However, the same BDF is also required in > virt-acpi-build.c to support ACPI. Therefore, make this information part > of the global RISCVVirtState structure so that it can be accessed > outside of virt.c as well. > > Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> > --- Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> > hw/riscv/virt.c | 1 + > include/hw/riscv/virt.h | 1 + > 2 files changed, 2 insertions(+) > > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c > index dae46f4733..ce256fb3b3 100644 > --- a/hw/riscv/virt.c > +++ b/hw/riscv/virt.c > @@ -1116,6 +1116,7 @@ static void create_fdt_iommu(RISCVVirtState *s, uint16_t bdf) > qemu_fdt_setprop_cells(fdt, pci_node, "iommu-map", > 0, iommu_phandle, 0, bdf, > bdf + 1, iommu_phandle, bdf + 1, 0xffff - bdf); > + s->pci_iommu_bdf = bdf; > } > > static void finalize_fdt(RISCVVirtState *s) > diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h > index 48a14bea2e..7b4c2c8b7d 100644 > --- a/include/hw/riscv/virt.h > +++ b/include/hw/riscv/virt.h > @@ -63,6 +63,7 @@ struct RISCVVirtState { > const MemMapEntry *memmap; > struct GPEXHost *gpex_host; > OnOffAuto iommu_sys; > + uint16_t pci_iommu_bdf; > }; > > enum { ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2/2] hw/riscv/virt-acpi-build: Add support for RIMT 2025-03-14 5:15 [PATCH 0/2] RISC-V: ACPI: Add support for RIMT Sunil V L 2025-03-14 5:15 ` [PATCH 1/2] hw/riscv/virt: Add the BDF of IOMMU to RISCVVirtState structure Sunil V L @ 2025-03-14 5:15 ` Sunil V L 2025-03-19 12:40 ` Daniel Henrique Barboza 1 sibling, 1 reply; 5+ messages in thread From: Sunil V L @ 2025-03-14 5:15 UTC (permalink / raw) To: qemu-riscv, qemu-devel Cc: Alistair Francis, Palmer Dabbelt, Weiwei Li, Daniel Henrique Barboza, Liu Zhiwei, Andrew Jones, Anup Patel, Atish Patra, Sunil V L RISC-V IO Mapping Table (RIMT) is a new static ACPI table used to communicate IOMMU information to the OS. Add support for creating this table when the IOMMU is present. The specification is frozen and available at [1]. [1] - https://github.com/riscv-non-isa/riscv-acpi-rimt/releases/download/v0.99/rimt-spec.pdf Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> --- hw/riscv/virt-acpi-build.c | 215 +++++++++++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c index 1ad6800508..2b4f5b2cea 100644 --- a/hw/riscv/virt-acpi-build.c +++ b/hw/riscv/virt-acpi-build.c @@ -198,6 +198,32 @@ acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap, aml_append(scope, dev); } +/* + * Add DSDT entry for the IOMMU platform device. + * ACPI ID for IOMMU is defined in the section 6.2 of RISC-V BRS spec. + * https://github.com/riscv-non-isa/riscv-brs/releases/download/v0.8/riscv-brs-spec.pdf + */ +static void acpi_dsdt_add_iommu_sys(Aml *scope, const MemMapEntry *iommu_memmap, + uint32_t iommu_irq) +{ + uint32_t i; + + Aml *dev = aml_device("IMU0"); + aml_append(dev, aml_name_decl("_HID", aml_string("RSCV0004"))); + aml_append(dev, aml_name_decl("_UID", aml_int(0))); + + Aml *crs = aml_resource_template(); + aml_append(crs, aml_memory32_fixed(iommu_memmap->base, + iommu_memmap->size, AML_READ_WRITE)); + for (i = iommu_irq; i < iommu_irq + 4; i++) { + aml_append(crs, aml_interrupt(AML_CONSUMER, AML_EDGE, AML_ACTIVE_LOW, + AML_EXCLUSIVE, &i, 1)); + } + + aml_append(dev, aml_name_decl("_CRS", crs)); + aml_append(scope, dev); +} + /* * Serial Port Console Redirection Table (SPCR) * Rev: 1.10 @@ -450,6 +476,9 @@ static void build_dsdt(GArray *table_data, } acpi_dsdt_add_uart(scope, &memmap[VIRT_UART0], UART0_IRQ); + if (virt_is_iommu_sys_enabled(s)) { + acpi_dsdt_add_iommu_sys(scope, &memmap[VIRT_IOMMU_SYS], IOMMU_SYS_IRQ); + } if (socket_count == 1) { virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base, @@ -602,6 +631,187 @@ static void build_madt(GArray *table_data, acpi_table_end(linker, &table); } +#define ID_MAPPING_ENTRY_SIZE 20 +#define IOMMU_ENTRY_SIZE 40 +#define RISCV_INTERRUPT_WIRE_OFFSSET 40 +#define ROOT_COMPLEX_ENTRY_SIZE 20 +#define RIMT_NODE_OFFSET 48 + +/* + * ID Mapping Structure + */ +static void build_rimt_id_mapping(GArray *table_data, uint32_t source_id_base, + uint32_t num_ids, uint32_t dest_id_base) +{ + /* Source ID Base */ + build_append_int_noprefix(table_data, source_id_base, 4); + /* Number of IDs */ + build_append_int_noprefix(table_data, num_ids, 4); + /* Destination Device ID Base */ + build_append_int_noprefix(table_data, source_id_base, 4); + /* Destination IOMMU Offset */ + build_append_int_noprefix(table_data, dest_id_base, 4); + /* Flags */ + build_append_int_noprefix(table_data, 0, 4); +} + +struct AcpiRimtIdMapping { + uint32_t source_id_base; + uint32_t num_ids; +}; +typedef struct AcpiRimtIdMapping AcpiRimtIdMapping; + +/* Build the rimt ID mapping to IOMMU for a given PCI host bridge */ +static int rimt_host_bridges(Object *obj, void *opaque) +{ + GArray *idmap_blob = opaque; + + if (object_dynamic_cast(obj, TYPE_PCI_HOST_BRIDGE)) { + PCIBus *bus = PCI_HOST_BRIDGE(obj)->bus; + + if (bus && !pci_bus_bypass_iommu(bus)) { + int min_bus, max_bus; + + pci_bus_range(bus, &min_bus, &max_bus); + + AcpiRimtIdMapping idmap = { + .source_id_base = min_bus << 8, + .num_ids = (max_bus - min_bus + 1) << 8, + }; + g_array_append_val(idmap_blob, idmap); + } + } + + return 0; +} + +static int rimt_idmap_compare(gconstpointer a, gconstpointer b) +{ + AcpiRimtIdMapping *idmap_a = (AcpiRimtIdMapping *)a; + AcpiRimtIdMapping *idmap_b = (AcpiRimtIdMapping *)b; + + return idmap_a->source_id_base - idmap_b->source_id_base; +} + +/* + * RISC-V IO Mapping Table (RIMT) + * https://github.com/riscv-non-isa/riscv-acpi-rimt/releases/download/v0.99/rimt-spec.pdf + */ +static void build_rimt(GArray *table_data, BIOSLinker *linker, + RISCVVirtState *s) +{ + int i, nb_nodes, rc_mapping_count; + size_t node_size, iommu_offset = 0; + uint32_t id = 0; + GArray *iommu_idmaps = g_array_new(false, true, sizeof(AcpiRimtIdMapping)); + + AcpiTable table = { .sig = "RIMT", .rev = 1, .oem_id = s->oem_id, + .oem_table_id = s->oem_table_id }; + + acpi_table_begin(&table, table_data); + + object_child_foreach_recursive(object_get_root(), + rimt_host_bridges, iommu_idmaps); + + /* Sort the ID mapping by Source ID Base*/ + g_array_sort(iommu_idmaps, rimt_idmap_compare); + + nb_nodes = 2; /* RC, IOMMU */ + rc_mapping_count = iommu_idmaps->len; + /* Number of RIMT Nodes */ + build_append_int_noprefix(table_data, nb_nodes, 4); + + /* Offset to Array of RIMT Nodes */ + build_append_int_noprefix(table_data, RIMT_NODE_OFFSET, 4); + build_append_int_noprefix(table_data, 0, 4); /* Reserved */ + + iommu_offset = table_data->len - table.table_offset; + /* IOMMU Device Structure */ + build_append_int_noprefix(table_data, 0, 1); /* Type - IOMMU*/ + build_append_int_noprefix(table_data, 1, 1); /* Revision */ + node_size = IOMMU_ENTRY_SIZE; + build_append_int_noprefix(table_data, node_size, 2); /* Length */ + build_append_int_noprefix(table_data, 0, 2); /* Reserved */ + build_append_int_noprefix(table_data, id++, 2); /* ID */ + if (virt_is_iommu_sys_enabled(s)) { + /* Hardware ID */ + build_append_int_noprefix(table_data, 'R', 1); + build_append_int_noprefix(table_data, 'S', 1); + build_append_int_noprefix(table_data, 'C', 1); + build_append_int_noprefix(table_data, 'V', 1); + build_append_int_noprefix(table_data, '0', 1); + build_append_int_noprefix(table_data, '0', 1); + build_append_int_noprefix(table_data, '0', 1); + build_append_int_noprefix(table_data, '4', 1); + /* Base Address */ + build_append_int_noprefix(table_data, + s->memmap[VIRT_IOMMU_SYS].base, 8); + build_append_int_noprefix(table_data, 0, 4); /* Flags */ + } else { + /* Hardware ID */ + build_append_int_noprefix(table_data, '0', 1); + build_append_int_noprefix(table_data, '0', 1); + build_append_int_noprefix(table_data, '1', 1); + build_append_int_noprefix(table_data, '0', 1); + build_append_int_noprefix(table_data, '0', 1); + build_append_int_noprefix(table_data, '0', 1); + build_append_int_noprefix(table_data, '1', 1); + build_append_int_noprefix(table_data, '4', 1); + + build_append_int_noprefix(table_data, 0, 8); /* Base Address */ + build_append_int_noprefix(table_data, 1, 4); /* Flags */ + } + + build_append_int_noprefix(table_data, 0, 4); /* Proximity Domain */ + build_append_int_noprefix(table_data, 0, 2); /* PCI Segment number */ + /* PCIe B/D/F */ + if (virt_is_iommu_sys_enabled(s)) { + build_append_int_noprefix(table_data, 0, 2); + } else { + build_append_int_noprefix(table_data, s->pci_iommu_bdf, 2); + } + /* Number of interrupt wires */ + build_append_int_noprefix(table_data, 0, 2); + /* Interrupt wire array offset */ + build_append_int_noprefix(table_data, RISCV_INTERRUPT_WIRE_OFFSSET, 2); + + /* PCIe Root Complex Node */ + build_append_int_noprefix(table_data, 1, 1); /* Type */ + build_append_int_noprefix(table_data, 1, 1); /* Revision */ + node_size = ROOT_COMPLEX_ENTRY_SIZE + + ID_MAPPING_ENTRY_SIZE * rc_mapping_count; + build_append_int_noprefix(table_data, node_size, 2); /* Length */ + build_append_int_noprefix(table_data, 0, 2); /* Reserved */ + build_append_int_noprefix(table_data, id++, 2); /* ID */ + build_append_int_noprefix(table_data, 0, 4); /* Flags */ + build_append_int_noprefix(table_data, 0, 2); /* Reserved */ + /* PCI Segment number */ + build_append_int_noprefix(table_data, 0, 2); + /* ID mapping array offset */ + build_append_int_noprefix(table_data, ROOT_COMPLEX_ENTRY_SIZE, 2); + /* Number of ID mappings */ + build_append_int_noprefix(table_data, rc_mapping_count, 2); + + /* Output Reference */ + AcpiRimtIdMapping *range; + + /* ID mapping array */ + for (i = 0; i < iommu_idmaps->len; i++) { + range = &g_array_index(iommu_idmaps, AcpiRimtIdMapping, i); + if (virt_is_iommu_sys_enabled(s)) { + range->source_id_base = 0; + } else { + range->source_id_base = s->pci_iommu_bdf + 1; + } + range->num_ids = 0xffff - s->pci_iommu_bdf; + build_rimt_id_mapping(table_data, range->source_id_base, + range->num_ids, iommu_offset); + } + + acpi_table_end(linker, &table); + g_array_free(iommu_idmaps, true); +} + /* * ACPI spec, Revision 6.5+ * 5.2.16 System Resource Affinity Table (SRAT) @@ -679,6 +889,11 @@ static void virt_acpi_build(RISCVVirtState *s, AcpiBuildTables *tables) acpi_add_table(table_offsets, tables_blob); build_rhct(tables_blob, tables->linker, s); + if (virt_is_iommu_sys_enabled(s) || s->pci_iommu_bdf) { + acpi_add_table(table_offsets, tables_blob); + build_rimt(tables_blob, tables->linker, s); + } + acpi_add_table(table_offsets, tables_blob); spcr_setup(tables_blob, tables->linker, s); -- 2.43.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 2/2] hw/riscv/virt-acpi-build: Add support for RIMT 2025-03-14 5:15 ` [PATCH 2/2] hw/riscv/virt-acpi-build: Add support for RIMT Sunil V L @ 2025-03-19 12:40 ` Daniel Henrique Barboza 0 siblings, 0 replies; 5+ messages in thread From: Daniel Henrique Barboza @ 2025-03-19 12:40 UTC (permalink / raw) To: Sunil V L, qemu-riscv, qemu-devel Cc: Alistair Francis, Palmer Dabbelt, Weiwei Li, Liu Zhiwei, Andrew Jones, Anup Patel, Atish Patra On 3/14/25 2:15 AM, Sunil V L wrote: > RISC-V IO Mapping Table (RIMT) is a new static ACPI table used to > communicate IOMMU information to the OS. Add support for creating this > table when the IOMMU is present. The specification is frozen and > available at [1]. > > [1] - https://github.com/riscv-non-isa/riscv-acpi-rimt/releases/download/v0.99/rimt-spec.pdf > > Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> > --- > hw/riscv/virt-acpi-build.c | 215 +++++++++++++++++++++++++++++++++++++ > 1 file changed, 215 insertions(+) > > diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c > index 1ad6800508..2b4f5b2cea 100644 > --- a/hw/riscv/virt-acpi-build.c > +++ b/hw/riscv/virt-acpi-build.c > @@ -198,6 +198,32 @@ acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap, > aml_append(scope, dev); > } > > +/* > + * Add DSDT entry for the IOMMU platform device. > + * ACPI ID for IOMMU is defined in the section 6.2 of RISC-V BRS spec. > + * https://github.com/riscv-non-isa/riscv-brs/releases/download/v0.8/riscv-brs-spec.pdf > + */ > +static void acpi_dsdt_add_iommu_sys(Aml *scope, const MemMapEntry *iommu_memmap, > + uint32_t iommu_irq) > +{ > + uint32_t i; > + > + Aml *dev = aml_device("IMU0"); > + aml_append(dev, aml_name_decl("_HID", aml_string("RSCV0004"))); > + aml_append(dev, aml_name_decl("_UID", aml_int(0))); > + > + Aml *crs = aml_resource_template(); > + aml_append(crs, aml_memory32_fixed(iommu_memmap->base, > + iommu_memmap->size, AML_READ_WRITE)); > + for (i = iommu_irq; i < iommu_irq + 4; i++) { > + aml_append(crs, aml_interrupt(AML_CONSUMER, AML_EDGE, AML_ACTIVE_LOW, > + AML_EXCLUSIVE, &i, 1)); > + } > + > + aml_append(dev, aml_name_decl("_CRS", crs)); > + aml_append(scope, dev); > +} > + > /* > * Serial Port Console Redirection Table (SPCR) > * Rev: 1.10 > @@ -450,6 +476,9 @@ static void build_dsdt(GArray *table_data, > } > > acpi_dsdt_add_uart(scope, &memmap[VIRT_UART0], UART0_IRQ); > + if (virt_is_iommu_sys_enabled(s)) { > + acpi_dsdt_add_iommu_sys(scope, &memmap[VIRT_IOMMU_SYS], IOMMU_SYS_IRQ); > + } > > if (socket_count == 1) { > virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base, > @@ -602,6 +631,187 @@ static void build_madt(GArray *table_data, > acpi_table_end(linker, &table); > } > > +#define ID_MAPPING_ENTRY_SIZE 20 > +#define IOMMU_ENTRY_SIZE 40 > +#define RISCV_INTERRUPT_WIRE_OFFSSET 40 > +#define ROOT_COMPLEX_ENTRY_SIZE 20 > +#define RIMT_NODE_OFFSET 48 > + > +/* > + * ID Mapping Structure > + */ > +static void build_rimt_id_mapping(GArray *table_data, uint32_t source_id_base, > + uint32_t num_ids, uint32_t dest_id_base) > +{ > + /* Source ID Base */ > + build_append_int_noprefix(table_data, source_id_base, 4); > + /* Number of IDs */ > + build_append_int_noprefix(table_data, num_ids, 4); > + /* Destination Device ID Base */ > + build_append_int_noprefix(table_data, source_id_base, 4); > + /* Destination IOMMU Offset */ > + build_append_int_noprefix(table_data, dest_id_base, 4); > + /* Flags */ > + build_append_int_noprefix(table_data, 0, 4); > +} > + > +struct AcpiRimtIdMapping { > + uint32_t source_id_base; > + uint32_t num_ids; > +}; > +typedef struct AcpiRimtIdMapping AcpiRimtIdMapping; > + > +/* Build the rimt ID mapping to IOMMU for a given PCI host bridge */ > +static int rimt_host_bridges(Object *obj, void *opaque) > +{ > + GArray *idmap_blob = opaque; > + > + if (object_dynamic_cast(obj, TYPE_PCI_HOST_BRIDGE)) { > + PCIBus *bus = PCI_HOST_BRIDGE(obj)->bus; > + > + if (bus && !pci_bus_bypass_iommu(bus)) { > + int min_bus, max_bus; > + > + pci_bus_range(bus, &min_bus, &max_bus); > + > + AcpiRimtIdMapping idmap = { > + .source_id_base = min_bus << 8, > + .num_ids = (max_bus - min_bus + 1) << 8, > + }; > + g_array_append_val(idmap_blob, idmap); > + } > + } > + > + return 0; > +} > + > +static int rimt_idmap_compare(gconstpointer a, gconstpointer b) > +{ > + AcpiRimtIdMapping *idmap_a = (AcpiRimtIdMapping *)a; > + AcpiRimtIdMapping *idmap_b = (AcpiRimtIdMapping *)b; > + > + return idmap_a->source_id_base - idmap_b->source_id_base; > +} > + > +/* > + * RISC-V IO Mapping Table (RIMT) > + * https://github.com/riscv-non-isa/riscv-acpi-rimt/releases/download/v0.99/rimt-spec.pdf > + */ > +static void build_rimt(GArray *table_data, BIOSLinker *linker, > + RISCVVirtState *s) > +{ > + int i, nb_nodes, rc_mapping_count; > + size_t node_size, iommu_offset = 0; > + uint32_t id = 0; > + GArray *iommu_idmaps = g_array_new(false, true, sizeof(AcpiRimtIdMapping)); I suggest using g_autoptr(GArray) *iommu_idmaps = g_array_new(false, true, sizeof(AcpiRimtIdMapping)); And then you can get rid of the g_array_free() in the end. With this change: Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> > + > + AcpiTable table = { .sig = "RIMT", .rev = 1, .oem_id = s->oem_id, > + .oem_table_id = s->oem_table_id }; > + > + acpi_table_begin(&table, table_data); > + > + object_child_foreach_recursive(object_get_root(), > + rimt_host_bridges, iommu_idmaps); > + > + /* Sort the ID mapping by Source ID Base*/ > + g_array_sort(iommu_idmaps, rimt_idmap_compare); > + > + nb_nodes = 2; /* RC, IOMMU */ > + rc_mapping_count = iommu_idmaps->len; > + /* Number of RIMT Nodes */ > + build_append_int_noprefix(table_data, nb_nodes, 4); > + > + /* Offset to Array of RIMT Nodes */ > + build_append_int_noprefix(table_data, RIMT_NODE_OFFSET, 4); > + build_append_int_noprefix(table_data, 0, 4); /* Reserved */ > + > + iommu_offset = table_data->len - table.table_offset; > + /* IOMMU Device Structure */ > + build_append_int_noprefix(table_data, 0, 1); /* Type - IOMMU*/ > + build_append_int_noprefix(table_data, 1, 1); /* Revision */ > + node_size = IOMMU_ENTRY_SIZE; > + build_append_int_noprefix(table_data, node_size, 2); /* Length */ > + build_append_int_noprefix(table_data, 0, 2); /* Reserved */ > + build_append_int_noprefix(table_data, id++, 2); /* ID */ > + if (virt_is_iommu_sys_enabled(s)) { > + /* Hardware ID */ > + build_append_int_noprefix(table_data, 'R', 1); > + build_append_int_noprefix(table_data, 'S', 1); > + build_append_int_noprefix(table_data, 'C', 1); > + build_append_int_noprefix(table_data, 'V', 1); > + build_append_int_noprefix(table_data, '0', 1); > + build_append_int_noprefix(table_data, '0', 1); > + build_append_int_noprefix(table_data, '0', 1); > + build_append_int_noprefix(table_data, '4', 1); > + /* Base Address */ > + build_append_int_noprefix(table_data, > + s->memmap[VIRT_IOMMU_SYS].base, 8); > + build_append_int_noprefix(table_data, 0, 4); /* Flags */ > + } else { > + /* Hardware ID */ > + build_append_int_noprefix(table_data, '0', 1); > + build_append_int_noprefix(table_data, '0', 1); > + build_append_int_noprefix(table_data, '1', 1); > + build_append_int_noprefix(table_data, '0', 1); > + build_append_int_noprefix(table_data, '0', 1); > + build_append_int_noprefix(table_data, '0', 1); > + build_append_int_noprefix(table_data, '1', 1); > + build_append_int_noprefix(table_data, '4', 1); > + > + build_append_int_noprefix(table_data, 0, 8); /* Base Address */ > + build_append_int_noprefix(table_data, 1, 4); /* Flags */ > + } > + > + build_append_int_noprefix(table_data, 0, 4); /* Proximity Domain */ > + build_append_int_noprefix(table_data, 0, 2); /* PCI Segment number */ > + /* PCIe B/D/F */ > + if (virt_is_iommu_sys_enabled(s)) { > + build_append_int_noprefix(table_data, 0, 2); > + } else { > + build_append_int_noprefix(table_data, s->pci_iommu_bdf, 2); > + } > + /* Number of interrupt wires */ > + build_append_int_noprefix(table_data, 0, 2); > + /* Interrupt wire array offset */ > + build_append_int_noprefix(table_data, RISCV_INTERRUPT_WIRE_OFFSSET, 2); > + > + /* PCIe Root Complex Node */ > + build_append_int_noprefix(table_data, 1, 1); /* Type */ > + build_append_int_noprefix(table_data, 1, 1); /* Revision */ > + node_size = ROOT_COMPLEX_ENTRY_SIZE + > + ID_MAPPING_ENTRY_SIZE * rc_mapping_count; > + build_append_int_noprefix(table_data, node_size, 2); /* Length */ > + build_append_int_noprefix(table_data, 0, 2); /* Reserved */ > + build_append_int_noprefix(table_data, id++, 2); /* ID */ > + build_append_int_noprefix(table_data, 0, 4); /* Flags */ > + build_append_int_noprefix(table_data, 0, 2); /* Reserved */ > + /* PCI Segment number */ > + build_append_int_noprefix(table_data, 0, 2); > + /* ID mapping array offset */ > + build_append_int_noprefix(table_data, ROOT_COMPLEX_ENTRY_SIZE, 2); > + /* Number of ID mappings */ > + build_append_int_noprefix(table_data, rc_mapping_count, 2); > + > + /* Output Reference */ > + AcpiRimtIdMapping *range; > + > + /* ID mapping array */ > + for (i = 0; i < iommu_idmaps->len; i++) { > + range = &g_array_index(iommu_idmaps, AcpiRimtIdMapping, i); > + if (virt_is_iommu_sys_enabled(s)) { > + range->source_id_base = 0; > + } else { > + range->source_id_base = s->pci_iommu_bdf + 1; > + } > + range->num_ids = 0xffff - s->pci_iommu_bdf; > + build_rimt_id_mapping(table_data, range->source_id_base, > + range->num_ids, iommu_offset); > + } > + > + acpi_table_end(linker, &table); > + g_array_free(iommu_idmaps, true); > +} > + > /* > * ACPI spec, Revision 6.5+ > * 5.2.16 System Resource Affinity Table (SRAT) > @@ -679,6 +889,11 @@ static void virt_acpi_build(RISCVVirtState *s, AcpiBuildTables *tables) > acpi_add_table(table_offsets, tables_blob); > build_rhct(tables_blob, tables->linker, s); > > + if (virt_is_iommu_sys_enabled(s) || s->pci_iommu_bdf) { > + acpi_add_table(table_offsets, tables_blob); > + build_rimt(tables_blob, tables->linker, s); > + } > + > acpi_add_table(table_offsets, tables_blob); > spcr_setup(tables_blob, tables->linker, s); > ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-03-19 12:41 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-03-14 5:15 [PATCH 0/2] RISC-V: ACPI: Add support for RIMT Sunil V L 2025-03-14 5:15 ` [PATCH 1/2] hw/riscv/virt: Add the BDF of IOMMU to RISCVVirtState structure Sunil V L 2025-03-19 12:40 ` Daniel Henrique Barboza 2025-03-14 5:15 ` [PATCH 2/2] hw/riscv/virt-acpi-build: Add support for RIMT Sunil V L 2025-03-19 12:40 ` Daniel Henrique Barboza
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.