qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v3 0/2] ACPI/arm-virt: add DBG2
@ 2015-09-15 14:44 Leif Lindholm
  2015-09-15 14:44 ` [Qemu-devel] [PATCH v3 1/2] ACPI: Add definitions for the DBG2 table Leif Lindholm
  2015-09-15 14:44 ` [Qemu-devel] [PATCH v3 2/2] hw/arm/virt-acpi-build: Add " Leif Lindholm
  0 siblings, 2 replies; 5+ messages in thread
From: Leif Lindholm @ 2015-09-15 14:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, drjones, shannon.zhao, al.stone

The Debug Port Table 2 (DBG2) is mandated by the ARM Server Base Boot
Requirements specification. Add the DBG2 table definitions, and set up
an entry in the ARM virt machine for the pl011 UART.

Changes since v2:
- Typedef format cleanup.
- Restructured to use progressive acpi_data_push() calls for each new
  portion of the table.
  - Added some helper functions to reduce clutter.
  - Added some local variables to track state that could otherwise fall
    foul of shifting pointers in future.
  - Added some boiler plate for oem_data additions (but no actual
    oem_data).

Changes since v1:
- Static structure replaced with separate Header/Device structs.
- Missing cpu_to_le*() transforms added in table construction.
- Added missing setting of address_size_offset.
- Commit message modified to mention SPCR spec version bump.

Leif Lindholm (2):
  ACPI: Add definitions for the DBG2 table
  hw/arm/virt-acpi-build: Add DBG2 table

 hw/arm/virt-acpi-build.c    | 88 ++++++++++++++++++++++++++++++++++++++++++++-
 include/hw/acpi/acpi-defs.h | 33 +++++++++++++++--
 2 files changed, 118 insertions(+), 3 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Qemu-devel] [PATCH v3 1/2] ACPI: Add definitions for the DBG2 table
  2015-09-15 14:44 [Qemu-devel] [PATCH v3 0/2] ACPI/arm-virt: add DBG2 Leif Lindholm
@ 2015-09-15 14:44 ` Leif Lindholm
  2015-09-15 14:44 ` [Qemu-devel] [PATCH v3 2/2] hw/arm/virt-acpi-build: Add " Leif Lindholm
  1 sibling, 0 replies; 5+ messages in thread
From: Leif Lindholm @ 2015-09-15 14:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, drjones, shannon.zhao, al.stone

The DBG2 table can be considered a "companion" to SPCR - it points out
debug consoles available in the system.

Also update SPCR comments to reflect DBG2 is now described in this file,
and update the supported SPCR specification revision (no functional
change).

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
---
 include/hw/acpi/acpi-defs.h | 33 +++++++++++++++++++++++++++++++--
 1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index 2b431e6..3cfc5a6 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -197,10 +197,39 @@ enum {
 };
 
 /*
- * Serial Port Console Redirection Table (SPCR), Rev. 1.02
+ * Debug Port Table 2 (DBG2)
  *
  * For .interface_type see Debug Port Table 2 (DBG2) serial port
- * subtypes in Table 3, Rev. May 22, 2012
+ * subtypes in Table 3, Rev. Aug 10, 2015
+ *
+ */
+struct AcpiDebugPort2Header {
+    ACPI_TABLE_HEADER_DEF
+    uint32_t devices_offset;
+    uint32_t devices_count;
+} QEMU_PACKED;
+typedef struct AcpiDebugPort2Header AcpiDebugPort2Header;
+
+struct AcpiDebugPort2Device {
+    uint8_t  revision;
+    uint16_t length;
+    uint8_t  address_count;
+    uint16_t namepath_length;
+    uint16_t namepath_offset;
+    uint16_t oem_data_length;
+    uint16_t oem_data_offset;
+    uint16_t port_type;
+    uint16_t port_subtype;
+    uint8_t  reserved1[2];
+    uint16_t base_address_offset;
+    uint16_t address_size_offset;
+} QEMU_PACKED;
+typedef struct AcpiDebugPort2Device AcpiDebugPort2Device;
+
+/*
+ * Serial Port Console Redirection Table (SPCR), Rev. 1.03
+ *
+ * .interface_type format same as for DBG2.
  */
 struct AcpiSerialPortConsoleRedirection {
     ACPI_TABLE_HEADER_DEF
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [Qemu-devel] [PATCH v3 2/2] hw/arm/virt-acpi-build: Add DBG2 table
  2015-09-15 14:44 [Qemu-devel] [PATCH v3 0/2] ACPI/arm-virt: add DBG2 Leif Lindholm
  2015-09-15 14:44 ` [Qemu-devel] [PATCH v3 1/2] ACPI: Add definitions for the DBG2 table Leif Lindholm
@ 2015-09-15 14:44 ` Leif Lindholm
  2015-09-15 16:42   ` Andrew Jones
  1 sibling, 1 reply; 5+ messages in thread
From: Leif Lindholm @ 2015-09-15 14:44 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, drjones, shannon.zhao, al.stone

Add a DBG2 table, describing the pl011 UART.

Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
---
 hw/arm/virt-acpi-build.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 87 insertions(+), 1 deletion(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 9088248..763d531 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -351,6 +351,89 @@ build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt)
     return rsdp_table;
 }
 
+static int
+dbg2_addresses_size(int num_addr)
+{
+    return num_addr * (sizeof(struct AcpiGenericAddress) + sizeof(uint32_t));
+}
+
+static int
+dbg2_dev_length(int num_addr, const char *namepath, int oemdata_length)
+{
+    int size;
+
+    size = sizeof(AcpiDebugPort2Device);
+    size += dbg2_addresses_size(num_addr);
+    size += strlen(namepath) + 1;
+    size += oemdata_length;
+
+    return size;
+}
+
+static void
+build_dbg2(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
+{
+    const MemMapEntry *uart_memmap = &guest_info->memmap[VIRT_UART];
+    AcpiDebugPort2Header *dbg2;
+    AcpiDebugPort2Device *dev;
+    struct AcpiGenericAddress *addr;
+    uint32_t *addr_size;
+    char *data;
+    const char namepath[] = ".";
+    int address_count, oem_length, table_revision, table_size;
+
+    address_count = 1;
+    oem_length = 0;
+    table_revision = 0;
+    table_size = sizeof(*dbg2) + dbg2_dev_length(address_count, namepath,
+                                                 oem_length);
+
+    dbg2 = acpi_data_push(table_data, sizeof(*dbg2));
+    dbg2->devices_offset = sizeof(*dbg2);
+    dbg2->devices_count = 1;
+
+    dev = acpi_data_push(table_data, sizeof(*dev));
+    dev->revision = table_revision;
+    dev->length = cpu_to_le16(dbg2_dev_length(address_count, namepath,
+                                              oem_length));
+    dev->address_count = address_count;
+    dev->namepath_length = cpu_to_le16(strlen(namepath));
+    dev->namepath_offset = cpu_to_le16(sizeof(*dev) +
+                                       dbg2_addresses_size(address_count));
+    dev->oem_data_length = cpu_to_le16(oem_length);
+    if (oem_length) {
+        dev->oem_data_offset = cpu_to_le16(dbg2_dev_length(address_count,
+                                                           namepath, 0));
+    } else {
+        dev->oem_data_offset = 0;
+    }
+    dev->port_type = cpu_to_le16(0x8000);    /* Serial */
+    dev->port_subtype = cpu_to_le16(0x3);    /* ARM PL011 UART */
+    dev->base_address_offset = cpu_to_le16(sizeof(*dev));
+    dev->address_size_offset = cpu_to_le16(sizeof(*dev) +
+                                           address_count * sizeof(*addr));
+
+    addr = acpi_data_push(table_data, sizeof(*addr) * address_count);
+    addr->space_id = AML_SYSTEM_MEMORY;
+    addr->bit_width = 8;
+    addr->bit_offset = 0;
+    addr->access_width = 1;
+    addr->address = cpu_to_le64(uart_memmap->base);
+
+    addr_size = acpi_data_push(table_data, sizeof(*addr_size) * address_count);
+    *addr_size = cpu_to_le32(sizeof(*addr));
+
+    data = acpi_data_push(table_data, strlen(namepath) + 1);
+    strcpy(data, namepath);
+
+    if (oem_length) {
+        data = acpi_data_push(table_data, oem_length);
+    }
+
+    build_header(linker, table_data, (void *)dbg2, "DBG2", table_size,
+                 table_revision);
+}
+
 static void
 build_spcr(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
 {
@@ -577,7 +660,7 @@ void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
     dsdt = tables_blob->len;
     build_dsdt(tables_blob, tables->linker, guest_info);
 
-    /* FADT MADT GTDT MCFG SPCR pointed to by RSDT */
+    /* FADT MADT GTDT MCFG DBG2 SPCR pointed to by RSDT */
     acpi_add_table(table_offsets, tables_blob);
     build_fadt(tables_blob, tables->linker, dsdt);
 
@@ -591,6 +674,9 @@ void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
     build_mcfg(tables_blob, tables->linker, guest_info);
 
     acpi_add_table(table_offsets, tables_blob);
+    build_dbg2(tables_blob, tables->linker, guest_info);
+
+    acpi_add_table(table_offsets, tables_blob);
     build_spcr(tables_blob, tables->linker, guest_info);
 
     /* RSDT is pointed to by RSDP */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] [PATCH v3 2/2] hw/arm/virt-acpi-build: Add DBG2 table
  2015-09-15 14:44 ` [Qemu-devel] [PATCH v3 2/2] hw/arm/virt-acpi-build: Add " Leif Lindholm
@ 2015-09-15 16:42   ` Andrew Jones
  2015-09-15 16:45     ` Peter Maydell
  0 siblings, 1 reply; 5+ messages in thread
From: Andrew Jones @ 2015-09-15 16:42 UTC (permalink / raw)
  To: Leif Lindholm; +Cc: peter.maydell, qemu-devel, al.stone, shannon.zhao

On Tue, Sep 15, 2015 at 03:44:41PM +0100, Leif Lindholm wrote:
> Add a DBG2 table, describing the pl011 UART.
> 
> Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
> ---
>  hw/arm/virt-acpi-build.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 87 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> index 9088248..763d531 100644
> --- a/hw/arm/virt-acpi-build.c
> +++ b/hw/arm/virt-acpi-build.c
> @@ -351,6 +351,89 @@ build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt)
>      return rsdp_table;
>  }
>  
> +static int
> +dbg2_addresses_size(int num_addr)
> +{
> +    return num_addr * (sizeof(struct AcpiGenericAddress) + sizeof(uint32_t));
> +}
> +
> +static int
> +dbg2_dev_length(int num_addr, const char *namepath, int oemdata_length)
> +{
> +    int size;
> +
> +    size = sizeof(AcpiDebugPort2Device);
> +    size += dbg2_addresses_size(num_addr);
> +    size += strlen(namepath) + 1;
> +    size += oemdata_length;
> +
> +    return size;
> +}

I think macros should suffice for the above helpers.

> +
> +static void
> +build_dbg2(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
> +{
> +    const MemMapEntry *uart_memmap = &guest_info->memmap[VIRT_UART];
> +    AcpiDebugPort2Header *dbg2;
> +    AcpiDebugPort2Device *dev;
> +    struct AcpiGenericAddress *addr;
> +    uint32_t *addr_size;
> +    char *data;
> +    const char namepath[] = ".";
> +    int address_count, oem_length, table_revision, table_size;
> +
> +    address_count = 1;
> +    oem_length = 0;
> +    table_revision = 0;
> +    table_size = sizeof(*dbg2) + dbg2_dev_length(address_count, namepath,
> +                                                 oem_length);
> +
> +    dbg2 = acpi_data_push(table_data, sizeof(*dbg2));
> +    dbg2->devices_offset = sizeof(*dbg2);
> +    dbg2->devices_count = 1;
> +
> +    dev = acpi_data_push(table_data, sizeof(*dev));
> +    dev->revision = table_revision;

dev->revision and table_revision are presumably independent. I think
they should both get their own explicit '= 0'. Doing so allows us to get
rid of the local variable. I actually find the local variables, which
are constants, a bit crufty, and would prefer to just see the numbers.

> +    dev->length = cpu_to_le16(dbg2_dev_length(address_count, namepath,
> +                                              oem_length));
> +    dev->address_count = address_count;
> +    dev->namepath_length = cpu_to_le16(strlen(namepath));

what happened to the strlen + 1

> +    dev->namepath_offset = cpu_to_le16(sizeof(*dev) +
> +                                       dbg2_addresses_size(address_count));
> +    dev->oem_data_length = cpu_to_le16(oem_length);
> +    if (oem_length) {
> +        dev->oem_data_offset = cpu_to_le16(dbg2_dev_length(address_count,
> +                                                           namepath, 0));
> +    } else {
> +        dev->oem_data_offset = 0;
> +    }

I wouldn't bother with the special oem_data handling now, since we don't
plan to use it. If somebody extends this function for nonzero oem_length
sometime, then they can deal with it.

> +    dev->port_type = cpu_to_le16(0x8000);    /* Serial */
> +    dev->port_subtype = cpu_to_le16(0x3);    /* ARM PL011 UART */
> +    dev->base_address_offset = cpu_to_le16(sizeof(*dev));
> +    dev->address_size_offset = cpu_to_le16(sizeof(*dev) +
> +                                           address_count * sizeof(*addr));

Could create another macro for this offset calculation. Actually could add
a macro for each for consistency.

> +
> +    addr = acpi_data_push(table_data, sizeof(*addr) * address_count);
> +    addr->space_id = AML_SYSTEM_MEMORY;
> +    addr->bit_width = 8;
> +    addr->bit_offset = 0;
> +    addr->access_width = 1;
> +    addr->address = cpu_to_le64(uart_memmap->base);
> +
> +    addr_size = acpi_data_push(table_data, sizeof(*addr_size) * address_count);
> +    *addr_size = cpu_to_le32(sizeof(*addr));
> +
> +    data = acpi_data_push(table_data, strlen(namepath) + 1);

After dropping the oem data handling code, then we can use a better name
than 'data' for this.

> +    strcpy(data, namepath);
> +
> +    if (oem_length) {
> +        data = acpi_data_push(table_data, oem_length);
> +    }
> +
> +    build_header(linker, table_data, (void *)dbg2, "DBG2", table_size,
> +                 table_revision);
> +}
> +
>  static void
>  build_spcr(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
>  {
> @@ -577,7 +660,7 @@ void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
>      dsdt = tables_blob->len;
>      build_dsdt(tables_blob, tables->linker, guest_info);
>  
> -    /* FADT MADT GTDT MCFG SPCR pointed to by RSDT */
> +    /* FADT MADT GTDT MCFG DBG2 SPCR pointed to by RSDT */
>      acpi_add_table(table_offsets, tables_blob);
>      build_fadt(tables_blob, tables->linker, dsdt);
>  
> @@ -591,6 +674,9 @@ void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
>      build_mcfg(tables_blob, tables->linker, guest_info);
>  
>      acpi_add_table(table_offsets, tables_blob);
> +    build_dbg2(tables_blob, tables->linker, guest_info);
> +
> +    acpi_add_table(table_offsets, tables_blob);
>      build_spcr(tables_blob, tables->linker, guest_info);
>  
>      /* RSDT is pointed to by RSDP */
> -- 
> 2.1.4
> 
>

I liked Shannon's suggestion to use more acpi_data_pushing, which this
version provides, but, as we're making assumptions (only one device
and no OEM data), then I think we can further simplify this version.

Thanks,
drew 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] [PATCH v3 2/2] hw/arm/virt-acpi-build: Add DBG2 table
  2015-09-15 16:42   ` Andrew Jones
@ 2015-09-15 16:45     ` Peter Maydell
  0 siblings, 0 replies; 5+ messages in thread
From: Peter Maydell @ 2015-09-15 16:45 UTC (permalink / raw)
  To: Andrew Jones; +Cc: Al Stone, QEMU Developers, Leif Lindholm, Shannon Zhao

On 15 September 2015 at 17:42, Andrew Jones <drjones@redhat.com> wrote:
> On Tue, Sep 15, 2015 at 03:44:41PM +0100, Leif Lindholm wrote:
>> Add a DBG2 table, describing the pl011 UART.
>>
>> Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
>> ---
>>  hw/arm/virt-acpi-build.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++-
>>  1 file changed, 87 insertions(+), 1 deletion(-)
>>
>> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
>> index 9088248..763d531 100644
>> --- a/hw/arm/virt-acpi-build.c
>> +++ b/hw/arm/virt-acpi-build.c
>> @@ -351,6 +351,89 @@ build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt)
>>      return rsdp_table;
>>  }
>>
>> +static int
>> +dbg2_addresses_size(int num_addr)
>> +{
>> +    return num_addr * (sizeof(struct AcpiGenericAddress) + sizeof(uint32_t));
>> +}
>> +
>> +static int
>> +dbg2_dev_length(int num_addr, const char *namepath, int oemdata_length)
>> +{
>> +    int size;
>> +
>> +    size = sizeof(AcpiDebugPort2Device);
>> +    size += dbg2_addresses_size(num_addr);
>> +    size += strlen(namepath) + 1;
>> +    size += oemdata_length;
>> +
>> +    return size;
>> +}
>
> I think macros should suffice for the above helpers.

...but if you can write them as functions then why not do so?
The compiler's smart enough to inline as appropriate, and it's
not like performance is critical with one-time ACPI table
building anyhow.

Incidentally putting a linebreak before the function name is
not the usual QEMU style for function definitions.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2015-09-15 16:45 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-09-15 14:44 [Qemu-devel] [PATCH v3 0/2] ACPI/arm-virt: add DBG2 Leif Lindholm
2015-09-15 14:44 ` [Qemu-devel] [PATCH v3 1/2] ACPI: Add definitions for the DBG2 table Leif Lindholm
2015-09-15 14:44 ` [Qemu-devel] [PATCH v3 2/2] hw/arm/virt-acpi-build: Add " Leif Lindholm
2015-09-15 16:42   ` Andrew Jones
2015-09-15 16:45     ` Peter Maydell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).