diff mbox

[RFC,v2,09/11] hw/arm/virt-acpi-build: Generate XSDT table

Message ID 1422520633-13456-10-git-send-email-zhaoshenglong@huawei.com
State New
Headers show

Commit Message

Shannon Zhao Jan. 29, 2015, 8:37 a.m. UTC
XDST points to other tables except FACS & DSDT.

Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
---
 hw/arm/virt-acpi-build.c    |   32 +++++++++++++++++++++++++++++++-
 include/hw/acpi/acpi-defs.h |    9 +++++++++
 2 files changed, 40 insertions(+), 1 deletions(-)

Comments

Igor Mammedov Feb. 3, 2015, 4:19 p.m. UTC | #1
On Thu, 29 Jan 2015 16:37:11 +0800
Shannon Zhao <zhaoshenglong@huawei.com> wrote:

> XDST points to other tables except FACS & DSDT.
Is there any reason to use XSDT instead of RSDT?
If ACPI tables are below 4Gb which probably would
be the case then RSDT could be used just fine and
we could share more code between x86 and ARM.

Laszlo,
Do you know if OVMF allocates memory below 4G address range?

> 
> Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
> ---
>  hw/arm/virt-acpi-build.c    |   32 +++++++++++++++++++++++++++++++-
>  include/hw/acpi/acpi-defs.h |    9 +++++++++
>  2 files changed, 40 insertions(+), 1 deletions(-)
> 
> diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
> index ac0a864..2a2b2ab 100644
> --- a/hw/arm/virt-acpi-build.c
> +++ b/hw/arm/virt-acpi-build.c
> @@ -176,6 +176,32 @@ static void acpi_dsdt_add_virtio(AcpiAml *scope, const hwaddr *mmio_addrs,
>      }
>  }
>  
> +
> +/* XSDT */
> +static void
> +build_xsdt(GArray *table_data, GArray *linker, GArray *table_offsets)
> +{
> +    AcpiXsdtDescriptor *xsdt;
> +    size_t xsdt_len;
> +    int i;
> +
> +    xsdt_len = sizeof(*xsdt) + sizeof(uint64_t) * table_offsets->len;
> +    xsdt = acpi_data_push(table_data, xsdt_len);
> +    memcpy(xsdt->table_offset_entry, table_offsets->data,
> +           sizeof(uint64_t) * table_offsets->len);
> +    for (i = 0; i < table_offsets->len; ++i) {
> +        /* xsdt->table_offset_entry to be filled by Guest linker */
> +        bios_linker_loader_add_pointer(linker,
> +                                       ACPI_BUILD_TABLE_FILE,
> +                                       ACPI_BUILD_TABLE_FILE,
> +                                       table_data, &xsdt->table_offset_entry[i],
> +                                       sizeof(uint64_t));
> +    }
> +    build_header(linker, table_data, (void *)xsdt, "XSDT",
> +                 ACPI_BUILD_APPNAME6, ACPI_BUILD_APPNAME4,
> +                 xsdt_len, 1);
> +}
> +
>  /* GTDT */
>  static void
>  build_gtdt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
> @@ -311,7 +337,7 @@ static
>  void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
>  {
>      GArray *table_offsets;
> -    unsigned dsdt;
> +    unsigned dsdt, xsdt;
>      VirtAcpiCpuInfo cpuinfo;
>  
>      virt_acpi_get_cpu_info(&cpuinfo);
> @@ -346,6 +372,10 @@ void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
>      acpi_add_table(table_offsets, tables->table_data.buf);
>      build_gtdt(tables->table_data.buf, tables->linker, guest_info);
>  
> +    /* XSDT is pointed to by RSDP */
> +    xsdt = tables->table_data.buf->len;
> +    build_xsdt(tables->table_data.buf, tables->linker, table_offsets);
> +
>      /* Cleanup memory that's no longer used. */
>      g_array_free(table_offsets, true);
>  }
> diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
> index ee40a5e..47c8c41 100644
> --- a/include/hw/acpi/acpi-defs.h
> +++ b/include/hw/acpi/acpi-defs.h
> @@ -88,6 +88,15 @@ struct AcpiTableHeader         /* ACPI common table header */
>  typedef struct AcpiTableHeader AcpiTableHeader;
>  
>  /*
> + * Extended System Description Table (XSDT)
> + */
> +struct AcpiXsdtDescriptor {
> +    ACPI_TABLE_HEADER_DEF
> +    uint64_t table_offset_entry[1]; /* Array of pointers to ACPI tables */
> +} QEMU_PACKED;
> +typedef struct AcpiXsdtDescriptor AcpiXsdtDescriptor;
> +
> +/*
>   * ACPI Fixed ACPI Description Table (FADT)
>   */
>  #define ACPI_FADT_COMMON_DEF         /* FADT common definition */ \
Laszlo Ersek Feb. 3, 2015, 4:51 p.m. UTC | #2
On 02/03/15 17:19, Igor Mammedov wrote:
> On Thu, 29 Jan 2015 16:37:11 +0800
> Shannon Zhao <zhaoshenglong@huawei.com> wrote:
> 
>> XDST points to other tables except FACS & DSDT.
> Is there any reason to use XSDT instead of RSDT?
> If ACPI tables are below 4Gb which probably would
> be the case then RSDT could be used just fine and
> we could share more code between x86 and ARM.
> 
> Laszlo,
> Do you know if OVMF allocates memory below 4G address range?

Yes, it does.

https://github.com/tianocore/edk2/blob/master/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpi.c#L162

RSDT should suffice.

Thanks,
Laszlo
Shannon Zhao Feb. 7, 2015, 2:04 a.m. UTC | #3
On 2015/2/4 0:51, Laszlo Ersek wrote:
> On 02/03/15 17:19, Igor Mammedov wrote:
>> On Thu, 29 Jan 2015 16:37:11 +0800
>> Shannon Zhao <zhaoshenglong@huawei.com> wrote:
>>
>>> XDST points to other tables except FACS & DSDT.
>> Is there any reason to use XSDT instead of RSDT?
>> If ACPI tables are below 4Gb which probably would
>> be the case then RSDT could be used just fine and
>> we could share more code between x86 and ARM.
>>
>> Laszlo,
>> Do you know if OVMF allocates memory below 4G address range?
> 
> Yes, it does.
> 
> https://github.com/tianocore/edk2/blob/master/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpi.c#L162
> 
> RSDT should suffice.
> 

Ok, will rethink about this.
diff mbox

Patch

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index ac0a864..2a2b2ab 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -176,6 +176,32 @@  static void acpi_dsdt_add_virtio(AcpiAml *scope, const hwaddr *mmio_addrs,
     }
 }
 
+
+/* XSDT */
+static void
+build_xsdt(GArray *table_data, GArray *linker, GArray *table_offsets)
+{
+    AcpiXsdtDescriptor *xsdt;
+    size_t xsdt_len;
+    int i;
+
+    xsdt_len = sizeof(*xsdt) + sizeof(uint64_t) * table_offsets->len;
+    xsdt = acpi_data_push(table_data, xsdt_len);
+    memcpy(xsdt->table_offset_entry, table_offsets->data,
+           sizeof(uint64_t) * table_offsets->len);
+    for (i = 0; i < table_offsets->len; ++i) {
+        /* xsdt->table_offset_entry to be filled by Guest linker */
+        bios_linker_loader_add_pointer(linker,
+                                       ACPI_BUILD_TABLE_FILE,
+                                       ACPI_BUILD_TABLE_FILE,
+                                       table_data, &xsdt->table_offset_entry[i],
+                                       sizeof(uint64_t));
+    }
+    build_header(linker, table_data, (void *)xsdt, "XSDT",
+                 ACPI_BUILD_APPNAME6, ACPI_BUILD_APPNAME4,
+                 xsdt_len, 1);
+}
+
 /* GTDT */
 static void
 build_gtdt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info)
@@ -311,7 +337,7 @@  static
 void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
 {
     GArray *table_offsets;
-    unsigned dsdt;
+    unsigned dsdt, xsdt;
     VirtAcpiCpuInfo cpuinfo;
 
     virt_acpi_get_cpu_info(&cpuinfo);
@@ -346,6 +372,10 @@  void virt_acpi_build(VirtGuestInfo *guest_info, AcpiBuildTables *tables)
     acpi_add_table(table_offsets, tables->table_data.buf);
     build_gtdt(tables->table_data.buf, tables->linker, guest_info);
 
+    /* XSDT is pointed to by RSDP */
+    xsdt = tables->table_data.buf->len;
+    build_xsdt(tables->table_data.buf, tables->linker, table_offsets);
+
     /* Cleanup memory that's no longer used. */
     g_array_free(table_offsets, true);
 }
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index ee40a5e..47c8c41 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -88,6 +88,15 @@  struct AcpiTableHeader         /* ACPI common table header */
 typedef struct AcpiTableHeader AcpiTableHeader;
 
 /*
+ * Extended System Description Table (XSDT)
+ */
+struct AcpiXsdtDescriptor {
+    ACPI_TABLE_HEADER_DEF
+    uint64_t table_offset_entry[1]; /* Array of pointers to ACPI tables */
+} QEMU_PACKED;
+typedef struct AcpiXsdtDescriptor AcpiXsdtDescriptor;
+
+/*
  * ACPI Fixed ACPI Description Table (FADT)
  */
 #define ACPI_FADT_COMMON_DEF         /* FADT common definition */ \