From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44924) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bbruW-0001bs-Mk for qemu-devel@nongnu.org; Mon, 22 Aug 2016 12:17:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bbruU-0002hZ-BH for qemu-devel@nongnu.org; Mon, 22 Aug 2016 12:17:15 -0400 Received: from mail-pf0-x22a.google.com ([2607:f8b0:400e:c00::22a]:35408) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bbruS-0002hA-U6 for qemu-devel@nongnu.org; Mon, 22 Aug 2016 12:17:14 -0400 Received: by mail-pf0-x22a.google.com with SMTP id x72so33836752pfd.2 for ; Mon, 22 Aug 2016 09:17:11 -0700 (PDT) From: Prem Mallappa Date: Mon, 22 Aug 2016 21:47:40 +0530 Message-Id: <20160822161740.4252-10-prem.mallappa@broadcom.com> In-Reply-To: <20160822161740.4252-1-prem.mallappa@broadcom.com> References: <20160822161740.4252-1-prem.mallappa@broadcom.com> Subject: [Qemu-devel] [PATCH v2 9/9] [optional] arm: smmu-v3: ACPI IORT initial support List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Peter Maydell , "Edgar E . Iglesias" , qemu-devel@nongnu.org Cc: Prem Mallappa 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 --- hw/arm/virt-acpi-build.c | 43 +++++++++++++++++++++++ include/hw/acpi/acpi-defs.h | 84 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 1fa0581..d5fb69e 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -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); diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h index 850a962..d60f390 100644 --- a/include/hw/acpi/acpi-defs.h +++ b/include/hw/acpi/acpi-defs.h @@ -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 */ -- 2.9.3