[v3,2/2] ARM: Virt: ACPI: Build an IORT table with RC and ITS nodes
diff mbox

Message ID 1476707466-14300-3-git-send-email-eric.auger@redhat.com
State New
Headers show

Commit Message

Auger Eric Oct. 17, 2016, 12:31 p.m. UTC
From: Prem Mallappa <prem.mallappa@broadcom.com>

This patch builds an IORT table that features a root complex node and
an ITS node. This complements the ITS description in the ACPI MADT
table and allows vhost-net on ACPI guest.

Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
Signed-off-by: Eric Auger <eric.auger@redhat.com>

---
v2 -> v3:
- used sizeof(*iort) as node_offset
- removed idmap->flags = 0;
- misc cosmetic cleanups

v1 -> v2:
- its_class_name() || !guest_info->no_its now wraps acpi_add_table
  and build_iort
- add cpu_to_le*
- CCA = CPM = DACS = 1
- cleanup according to Drew's comments
- remove comments listing tables and spec revisions
---
 hw/arm/virt-acpi-build.c | 71 ++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 60 insertions(+), 11 deletions(-)

Comments

Andrew Jones Oct. 17, 2016, 2:07 p.m. UTC | #1
On Mon, Oct 17, 2016 at 02:31:06PM +0200, Eric Auger wrote:
> From: Prem Mallappa <prem.mallappa@broadcom.com>
> 
> This patch builds an IORT table that features a root complex node and
> an ITS node. This complements the ITS description in the ACPI MADT
> table and allows vhost-net on ACPI guest.
> 
> Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> 
> ---
> v2 -> v3:
> - used sizeof(*iort) as node_offset
> - removed idmap->flags = 0;
> - misc cosmetic cleanups
> 
> v1 -> v2:
> - its_class_name() || !guest_info->no_its now wraps acpi_add_table
>   and build_iort
> - add cpu_to_le*
> - CCA = CPM = DACS = 1
> - cleanup according to Drew's comments
> - remove comments listing tables and spec revisions
> ---
>  hw/arm/virt-acpi-build.c | 71 ++++++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 60 insertions(+), 11 deletions(-)
> 
> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> index fa0655a..5fc10df 100644
> --- a/hw/arm/virt-acpi-build.c
> +++ b/hw/arm/virt-acpi-build.c
> @@ -384,6 +384,61 @@ build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset)
>  }
>  
>  static void
> +build_iort(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
> +{
> +    int iort_start = table_data->len;
> +    AcpiIortIdMapping *idmap;
> +    AcpiIortItsGroup *its;
> +    AcpiIortTable *iort;
> +    size_t node_size, iort_length;
> +    AcpiIortRC *rc;
> +
> +    iort = acpi_data_push(table_data, sizeof(*iort));
> +
> +    iort_length = sizeof(*iort);
> +    iort->node_count = cpu_to_le32(2); /* RC and ITS nodes */
> +    iort->node_offset = cpu_to_le32(sizeof(*iort));
> +
> +    /* ITS group node */
> +    node_size =  sizeof(*its) + sizeof(uint32_t);
> +    iort_length += node_size;
> +    its = acpi_data_push(table_data, node_size);
> +
> +    its->type = ACPI_IORT_NODE_ITS_GROUP;
> +    its->length = cpu_to_le16(node_size);
> +    its->its_count = cpu_to_le32(1);
> +    its->identifiers[0] = 0; /* MADT translation_id */
> +
> +    /* Root Complex Node */
> +    node_size = sizeof(*rc) + sizeof(*idmap);
> +    iort_length += node_size;
> +    rc = acpi_data_push(table_data, node_size);
> +
> +    rc->type = ACPI_IORT_NODE_PCI_ROOT_COMPLEX;
> +    rc->length = cpu_to_le16(node_size);
> +    rc->mapping_count = cpu_to_le32(1);
> +    rc->mapping_offset = cpu_to_le32(sizeof(*rc));
> +
> +    /* fully coherent device */
> +    rc->memory_properties.cache_coherency = cpu_to_le32(1);
> +    rc->memory_properties.memory_flags = 0x3; /* CCA = CPM = DCAS = 1 */
> +    rc->pci_segment_number = 0; /* MCFG pci_segment */
> +
> +    /* Identity RID mapping covering the whole input RID range */
> +    idmap = &rc->id_mapping_array[0];
> +    idmap->input_base = 0;
> +    idmap->id_count = cpu_to_le32(0xFFFF);
> +    idmap->output_base = 0;
> +    /* output IORT node is the ITS group node (the first node) */
> +    idmap->output_reference = cpu_to_le32(iort->node_offset);
> +
> +    iort->length = cpu_to_le32(iort_length);
> +
> +    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)
>  {
>      AcpiSerialPortConsoleRedirection *spcr;
> @@ -667,17 +722,6 @@ void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
>                               ACPI_BUILD_TABLE_FILE, tables_blob,
>                               64, false /* high memory */);
>  
> -    /*
> -     * The ACPI v5.1 tables for Hardware-reduced ACPI platform are:
> -     * RSDP
> -     * RSDT
> -     * FADT
> -     * GTDT
> -     * MADT
> -     * MCFG
> -     * DSDT
> -     */
> -

I guess it's still debatable if the above change should be a separate
patch or not. It'd probably be best if it was, or at least the commit
message should contain an 'Also ...' sentence. Anyway, I'll leave it
to the maintainers to decide.

>      /* DSDT is pointed to by FADT */
>      dsdt = tables_blob->len;
>      build_dsdt(tables_blob, tables->linker, guest_info);
> @@ -703,6 +747,11 @@ void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
>          build_srat(tables_blob, tables->linker, guest_info);
>      }
>  
> +    if (its_class_name() && !guest_info->no_its) {
> +        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);
> -- 
> 2.5.5
> 

Reviewed-by: Andrew Jones <drjones@redhat.com>
Peter Maydell Oct. 24, 2016, 12:29 p.m. UTC | #2
On 17 October 2016 at 15:07, Andrew Jones <drjones@redhat.com> wrote:
> On Mon, Oct 17, 2016 at 02:31:06PM +0200, Eric Auger wrote:
>> From: Prem Mallappa <prem.mallappa@broadcom.com>
>>
>> This patch builds an IORT table that features a root complex node and
>> an ITS node. This complements the ITS description in the ACPI MADT
>> table and allows vhost-net on ACPI guest.
>>
>> Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>

>> @@ -667,17 +722,6 @@ void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
>>                               ACPI_BUILD_TABLE_FILE, tables_blob,
>>                               64, false /* high memory */);
>>
>> -    /*
>> -     * The ACPI v5.1 tables for Hardware-reduced ACPI platform are:
>> -     * RSDP
>> -     * RSDT
>> -     * FADT
>> -     * GTDT
>> -     * MADT
>> -     * MCFG
>> -     * DSDT
>> -     */
>> -
>
> I guess it's still debatable if the above change should be a separate
> patch or not. It'd probably be best if it was, or at least the commit
> message should contain an 'Also ...' sentence. Anyway, I'll leave it
> to the maintainers to decide.

Did you want to suggest a suitable addition to the commit message?
I have no idea; I'm just going to apply these to target-arm on the
basis of your review...

thanks
-- PMM
Andrew Jones Oct. 24, 2016, 12:45 p.m. UTC | #3
On Mon, Oct 24, 2016 at 01:29:42PM +0100, Peter Maydell wrote:
> On 17 October 2016 at 15:07, Andrew Jones <drjones@redhat.com> wrote:
> > On Mon, Oct 17, 2016 at 02:31:06PM +0200, Eric Auger wrote:
> >> From: Prem Mallappa <prem.mallappa@broadcom.com>
> >>
> >> This patch builds an IORT table that features a root complex node and
> >> an ITS node. This complements the ITS description in the ACPI MADT
> >> table and allows vhost-net on ACPI guest.
> >>
> >> Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
> >> Signed-off-by: Eric Auger <eric.auger@redhat.com>
> 
> >> @@ -667,17 +722,6 @@ void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
> >>                               ACPI_BUILD_TABLE_FILE, tables_blob,
> >>                               64, false /* high memory */);
> >>
> >> -    /*
> >> -     * The ACPI v5.1 tables for Hardware-reduced ACPI platform are:
> >> -     * RSDP
> >> -     * RSDT
> >> -     * FADT
> >> -     * GTDT
> >> -     * MADT
> >> -     * MCFG
> >> -     * DSDT
> >> -     */
> >> -
> >
> > I guess it's still debatable if the above change should be a separate
> > patch or not. It'd probably be best if it was, or at least the commit
> > message should contain an 'Also ...' sentence. Anyway, I'll leave it
> > to the maintainers to decide.
> 
> Did you want to suggest a suitable addition to the commit message?
> I have no idea; I'm just going to apply these to target-arm on the
> basis of your review...

How about

"Also remove the comment block in virt_acpi_build that lists all the
 generated tables, rather than update it. It's redundant with the code,
 at best, and otherwise incomplete/misleading."

Thanks,
drew

Patch
diff mbox

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index fa0655a..5fc10df 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -384,6 +384,61 @@  build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset)
 }
 
 static void
+build_iort(GArray *table_data, BIOSLinker *linker, VirtGuestInfo *guest_info)
+{
+    int iort_start = table_data->len;
+    AcpiIortIdMapping *idmap;
+    AcpiIortItsGroup *its;
+    AcpiIortTable *iort;
+    size_t node_size, iort_length;
+    AcpiIortRC *rc;
+
+    iort = acpi_data_push(table_data, sizeof(*iort));
+
+    iort_length = sizeof(*iort);
+    iort->node_count = cpu_to_le32(2); /* RC and ITS nodes */
+    iort->node_offset = cpu_to_le32(sizeof(*iort));
+
+    /* ITS group node */
+    node_size =  sizeof(*its) + sizeof(uint32_t);
+    iort_length += node_size;
+    its = acpi_data_push(table_data, node_size);
+
+    its->type = ACPI_IORT_NODE_ITS_GROUP;
+    its->length = cpu_to_le16(node_size);
+    its->its_count = cpu_to_le32(1);
+    its->identifiers[0] = 0; /* MADT translation_id */
+
+    /* Root Complex Node */
+    node_size = sizeof(*rc) + sizeof(*idmap);
+    iort_length += node_size;
+    rc = acpi_data_push(table_data, node_size);
+
+    rc->type = ACPI_IORT_NODE_PCI_ROOT_COMPLEX;
+    rc->length = cpu_to_le16(node_size);
+    rc->mapping_count = cpu_to_le32(1);
+    rc->mapping_offset = cpu_to_le32(sizeof(*rc));
+
+    /* fully coherent device */
+    rc->memory_properties.cache_coherency = cpu_to_le32(1);
+    rc->memory_properties.memory_flags = 0x3; /* CCA = CPM = DCAS = 1 */
+    rc->pci_segment_number = 0; /* MCFG pci_segment */
+
+    /* Identity RID mapping covering the whole input RID range */
+    idmap = &rc->id_mapping_array[0];
+    idmap->input_base = 0;
+    idmap->id_count = cpu_to_le32(0xFFFF);
+    idmap->output_base = 0;
+    /* output IORT node is the ITS group node (the first node) */
+    idmap->output_reference = cpu_to_le32(iort->node_offset);
+
+    iort->length = cpu_to_le32(iort_length);
+
+    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)
 {
     AcpiSerialPortConsoleRedirection *spcr;
@@ -667,17 +722,6 @@  void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
                              ACPI_BUILD_TABLE_FILE, tables_blob,
                              64, false /* high memory */);
 
-    /*
-     * The ACPI v5.1 tables for Hardware-reduced ACPI platform are:
-     * RSDP
-     * RSDT
-     * FADT
-     * GTDT
-     * MADT
-     * MCFG
-     * DSDT
-     */
-
     /* DSDT is pointed to by FADT */
     dsdt = tables_blob->len;
     build_dsdt(tables_blob, tables->linker, guest_info);
@@ -703,6 +747,11 @@  void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
         build_srat(tables_blob, tables->linker, guest_info);
     }
 
+    if (its_class_name() && !guest_info->no_its) {
+        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);