qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v1 8/8] [optional] arm: smmu-v3: ACPI IORT initial s


From: Prem Mallappa
Subject: [Qemu-devel] [PATCH v1 8/8] [optional] arm: smmu-v3: ACPI IORT initial support
Date: Thu, 23 Jun 2016 11:52:21 +0530

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 <address@hidden>
---
 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.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]