@@ -382,6 +382,45 @@ build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset)
return rsdp_table;
}
+/*
+ * TODO: Simple IORT for now, will add ID mappings as we go
+ * basic idea is to instantiate SMMU from ACPI
+ */
+static void
+build_iort(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
+{
+ int iort_start = table_data->len;
+ AcpiIortTable *iort;
+ AcpiIortNode *iort_node;
+ AcpiIortSmmu3 *smmu;
+ AcpiIortRC *rc;
+ const MemMapEntry *memmap = guest_info->memmap;
+
+ iort = acpi_data_push(table_data, sizeof(*iort));
+
+ iort->length = sizeof(*iort);
+ iort->node_offset = table_data->len - iort_start;
+ iort->num_nodes++;
+
+ smmu = acpi_data_push(table_data, sizeof(*smmu));
+ iort_node = &smmu->iort_node;
+ iort_node->type = 0x04; /* SMMUv3 */
+ iort_node->length = sizeof(*smmu);
+ smmu->base_addr = cpu_to_le64(memmap[VIRT_SMMU].base);
+
+ iort->num_nodes++;
+
+ rc = acpi_data_push(table_data, sizeof(*rc));
+ iort_node = &rc->iort_node;
+ iort_node->type = 0x02; /* RC */
+ iort_node->length = sizeof(*rc);
+ rc->ats_attr = 1;
+ rc->pci_seg_num = 0;
+
+ build_header(linker, table_data, (void *)(table_data->data + iort_start),
+ "IORT", table_data->len - iort_start, 0, NULL, NULL);
+}
+
static void
build_spcr(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
{
@@ -667,6 +706,7 @@ void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
* MADT
* MCFG
* DSDT
+ * IORT = ACPI 6.0
*/
/* DSDT is pointed to by FADT */
@@ -694,6 +734,9 @@ void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
build_srat(tables_blob, tables->linker, guest_info);
}
+ acpi_add_table(table_offsets, tables_blob);
+ build_iort(tables_blob, tables->linker, guest_info);
+
/* RSDT is pointed to by RSDP */
rsdt = tables_blob->len;
build_rsdt(tables_blob, tables->linker, table_offsets, NULL, NULL);
@@ -259,6 +259,90 @@ typedef struct AcpiFacsDescriptorRev1 AcpiFacsDescriptorRev1;
*/
/*
+ * IORT Table
+ */
+struct AcpiIortTable
+{
+ ACPI_TABLE_HEADER_DEF /* ACPI common table header */
+ uint32_t num_nodes;
+ uint32_t node_offset;
+ uint32_t reserved;
+} QEMU_PACKED;
+typedef struct AcpiIortTable AcpiIortTable;
+
+struct AcpiIortIdMapping
+{
+ uint32_t input_base;
+ uint32_t num_ids;
+ uint32_t output_base;
+ uint32_t output_ref;
+ uint32_t flags;
+} QEMU_PACKED;
+typedef struct AcpiIortIdMapping AcpiIortIdMapping;
+
+struct AcpiIortNode
+{
+ uint8_t type;
+ uint16_t length;
+ uint8_t revision;
+ uint32_t reserved1;
+ uint32_t num_id_maps;
+ uint32_t id_array_offset;
+} QEMU_PACKED;
+typedef struct AcpiIortNode AcpiIortNode;
+
+struct AcpiIortSmmu2
+{
+ AcpiIortNode iort_node;
+ uint64_t base_addr;
+ uint64_t span;
+ uint32_t model;
+ uint32_t flags;
+ uint32_t gbl_intr_array_off;
+ uint32_t ctx_intr_cnt;
+ uint32_t ctx_intr_array_off;
+ uint32_t pmr_intr_cnt;
+ uint32_t pmr_intr_array_off;
+
+ // Global interrupt array
+ uint32_t gintr;
+ uint32_t gintr_flags;
+ uint32_t gcfgintr;
+ uint32_t gcfgintr_flags;
+
+ //AcpiIortIdMapping id_mapping_array[0];
+} QEMU_PACKED;
+typedef struct AcpiIortSmmu2 AcpiIortSmmu2;
+
+struct AcpiIortSmmu3
+{
+ AcpiIortNode iort_node;
+ uint64_t base_addr;
+ uint32_t flags;
+ uint32_t reserved2;
+ uint64_t vatos_addr;
+ uint32_t model;
+ uint32_t event_irq;
+ uint32_t pri_irq;
+ uint32_t gerr_irq;
+ uint32_t sync_irq;
+
+ //AcpiIortIdMapping id_mapping_array[0];
+} QEMU_PACKED;
+typedef struct AcpiIortSmmu3 AcpiIortSmmu3;
+
+struct AcpiIortRC
+{
+ AcpiIortNode iort_node;
+ uint64_t mem_access_prop;
+ uint32_t ats_attr;
+ uint32_t pci_seg_num;
+
+ AcpiIortIdMapping id_mapping_array[0];
+} QEMU_PACKED;
+typedef struct AcpiIortRC AcpiIortRC;
+
+/*
* MADT values and structures
*/
Added ACPI IORT tables, was needed for internal project purpose, but posting here for anyone looking for testing ACPI on ARM platforms. (P.S: Linux side IORT patches are WIP) Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com> --- hw/arm/virt-acpi-build.c | 43 +++++++++++++++++++++++ include/hw/acpi/acpi-defs.h | 84 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+)