diff mbox

[Xen-devel,v2,13/17] libxl/arm: Link all ACPI tables into one buffer

Message ID 1466651824-6964-14-git-send-email-zhaoshenglong@huawei.com
State New
Headers show

Commit Message

Shannon Zhao June 23, 2016, 3:17 a.m. UTC
From: Shannon Zhao <shannon.zhao@linaro.org>

Link all ACPI tables into one buffer, fill in the addresses of
tables and update checksum of each table.

Reserve a memory map space for ACPI tables.

Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
---
 tools/libxl/libxl_arm_acpi.c  | 58 +++++++++++++++++++++++++++++++++++++++++++
 xen/include/public/arch-arm.h |  4 +++
 2 files changed, 62 insertions(+)

Comments

Julien Grall June 23, 2016, 5:10 p.m. UTC | #1
Hi Shannon,

On 23/06/16 04:17, Shannon Zhao wrote:
> From: Shannon Zhao <shannon.zhao@linaro.org>
>
> Link all ACPI tables into one buffer, fill in the addresses of
> tables and update checksum of each table.

Is there any reason to not allocate the acpitable_blob buffer before 
hand (and even reallocate if not enough space) and write the table 
directly in it?

Regards,

>
> Reserve a memory map space for ACPI tables.
>
> Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
> ---
>   tools/libxl/libxl_arm_acpi.c  | 58 +++++++++++++++++++++++++++++++++++++++++++
>   xen/include/public/arch-arm.h |  4 +++
>   2 files changed, 62 insertions(+)
>
> diff --git a/tools/libxl/libxl_arm_acpi.c b/tools/libxl/libxl_arm_acpi.c
> index d8779af..263b5de 100644
> --- a/tools/libxl/libxl_arm_acpi.c
> +++ b/tools/libxl/libxl_arm_acpi.c
> @@ -285,6 +285,63 @@ static void calculate_checksum(void *table, uint32_t checksum_offset,
>       p[checksum_offset] = -sum;
>   }
>
> +static void link_acpi_tables(libxl__gc *gc, struct xc_dom_image *dom)
> +{
> +    uint64_t offset = 0;
> +    struct acpi_table_xsdt *xsdt;
> +    struct acpi_table_rsdp *rsdp;
> +    struct acpi_table_fadt *fadt;
> +
> +    assert(dom->acpitable_size <= GUEST_ACPI_SIZE);
> +    dom->acpitable_blob = libxl__zalloc(gc, dom->acpitable_size);
> +
> +    rsdp = (struct acpi_table_rsdp *)(dom->acpitable_blob + offset);
> +    memcpy(dom->acpitable_blob + offset, acpitables[RSDP].table,
> +           acpitables[RSDP].size);
> +    offset += ROUNDUP(acpitables[RSDP].size, 3);
> +
> +    xsdt = (struct acpi_table_xsdt *)(dom->acpitable_blob + offset);
> +    memcpy(dom->acpitable_blob + offset, acpitables[XSDT].table,
> +           acpitables[XSDT].size);
> +    rsdp->xsdt_physical_address = GUEST_ACPI_BASE + offset;
> +    calculate_checksum(rsdp, offsetof(struct acpi_table_header, checksum),
> +                       acpitables[RSDP].size);
> +    offset += ROUNDUP(acpitables[XSDT].size, 3);
> +
> +    memcpy(dom->acpitable_blob + offset, acpitables[MADT].table,
> +           acpitables[MADT].size);
> +    calculate_checksum(dom->acpitable_blob + offset,
> +                       offsetof(struct acpi_table_header, checksum),
> +                       acpitables[MADT].size);
> +    xsdt->table_offset_entry[0] = GUEST_ACPI_BASE + offset;
> +    offset += ROUNDUP(acpitables[MADT].size, 3);
> +
> +    memcpy(dom->acpitable_blob + offset, acpitables[GTDT].table,
> +           acpitables[GTDT].size);
> +    calculate_checksum(dom->acpitable_blob + offset,
> +                       offsetof(struct acpi_table_header, checksum),
> +                       acpitables[GTDT].size);
> +    xsdt->table_offset_entry[1] = GUEST_ACPI_BASE + offset;
> +    offset += ROUNDUP(acpitables[GTDT].size, 3);
> +
> +    fadt = (struct acpi_table_fadt *)(dom->acpitable_blob + offset);
> +    memcpy(dom->acpitable_blob + offset, acpitables[FADT].table,
> +           acpitables[FADT].size);
> +    xsdt->table_offset_entry[2] = GUEST_ACPI_BASE + offset;
> +    calculate_checksum(xsdt, offsetof(struct acpi_table_header, checksum),
> +                       acpitables[XSDT].size);
> +    offset += ROUNDUP(acpitables[FADT].size, 3);
> +
> +    memcpy(dom->acpitable_blob + offset, acpitables[DSDT].table,
> +           acpitables[DSDT].size);
> +    calculate_checksum(dom->acpitable_blob + offset,
> +                       offsetof(struct acpi_table_header, checksum),
> +                       acpitables[DSDT].size);
> +    fadt->dsdt = GUEST_ACPI_BASE + offset;
> +    calculate_checksum(fadt, offsetof(struct acpi_table_header, checksum),
> +                       acpitables[FADT].size);
> +}
> +
>   int libxl__prepare_acpi(libxl__gc *gc, libxl_domain_build_info *info,
>                           libxl__domain_build_state *state,
>                           struct xc_dom_image *dom)
> @@ -314,6 +371,7 @@ int libxl__prepare_acpi(libxl__gc *gc, libxl_domain_build_info *info,
>
>       make_acpi_fadt(gc, dom);
>       make_acpi_dsdt(gc, dom);
> +    link_acpi_tables(gc, dom);
>
>       return 0;
>   }
> diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
> index 05e4a58..0911d16 100644
> --- a/xen/include/public/arch-arm.h
> +++ b/xen/include/public/arch-arm.h
> @@ -407,6 +407,10 @@ typedef uint64_t xen_callback_t;
>   #define GUEST_GICV3_GICR0_BASE     0x03020000ULL    /* vCPU0 - vCPU127 */
>   #define GUEST_GICV3_GICR0_SIZE     0x01000000ULL
>
> +/* ACPI tables physical address */
> +#define GUEST_ACPI_BASE 0x20000000ULL
> +#define GUEST_ACPI_SIZE 0x00200000ULL
> +
>   /*
>    * 16MB == 4096 pages reserved for guest to use as a region to map its
>    * grant table in.
>
diff mbox

Patch

diff --git a/tools/libxl/libxl_arm_acpi.c b/tools/libxl/libxl_arm_acpi.c
index d8779af..263b5de 100644
--- a/tools/libxl/libxl_arm_acpi.c
+++ b/tools/libxl/libxl_arm_acpi.c
@@ -285,6 +285,63 @@  static void calculate_checksum(void *table, uint32_t checksum_offset,
     p[checksum_offset] = -sum;
 }
 
+static void link_acpi_tables(libxl__gc *gc, struct xc_dom_image *dom)
+{
+    uint64_t offset = 0;
+    struct acpi_table_xsdt *xsdt;
+    struct acpi_table_rsdp *rsdp;
+    struct acpi_table_fadt *fadt;
+
+    assert(dom->acpitable_size <= GUEST_ACPI_SIZE);
+    dom->acpitable_blob = libxl__zalloc(gc, dom->acpitable_size);
+
+    rsdp = (struct acpi_table_rsdp *)(dom->acpitable_blob + offset);
+    memcpy(dom->acpitable_blob + offset, acpitables[RSDP].table,
+           acpitables[RSDP].size);
+    offset += ROUNDUP(acpitables[RSDP].size, 3);
+
+    xsdt = (struct acpi_table_xsdt *)(dom->acpitable_blob + offset);
+    memcpy(dom->acpitable_blob + offset, acpitables[XSDT].table,
+           acpitables[XSDT].size);
+    rsdp->xsdt_physical_address = GUEST_ACPI_BASE + offset;
+    calculate_checksum(rsdp, offsetof(struct acpi_table_header, checksum),
+                       acpitables[RSDP].size);
+    offset += ROUNDUP(acpitables[XSDT].size, 3);
+
+    memcpy(dom->acpitable_blob + offset, acpitables[MADT].table,
+           acpitables[MADT].size);
+    calculate_checksum(dom->acpitable_blob + offset,
+                       offsetof(struct acpi_table_header, checksum),
+                       acpitables[MADT].size);
+    xsdt->table_offset_entry[0] = GUEST_ACPI_BASE + offset;
+    offset += ROUNDUP(acpitables[MADT].size, 3);
+
+    memcpy(dom->acpitable_blob + offset, acpitables[GTDT].table,
+           acpitables[GTDT].size);
+    calculate_checksum(dom->acpitable_blob + offset,
+                       offsetof(struct acpi_table_header, checksum),
+                       acpitables[GTDT].size);
+    xsdt->table_offset_entry[1] = GUEST_ACPI_BASE + offset;
+    offset += ROUNDUP(acpitables[GTDT].size, 3);
+
+    fadt = (struct acpi_table_fadt *)(dom->acpitable_blob + offset);
+    memcpy(dom->acpitable_blob + offset, acpitables[FADT].table,
+           acpitables[FADT].size);
+    xsdt->table_offset_entry[2] = GUEST_ACPI_BASE + offset;
+    calculate_checksum(xsdt, offsetof(struct acpi_table_header, checksum),
+                       acpitables[XSDT].size);
+    offset += ROUNDUP(acpitables[FADT].size, 3);
+
+    memcpy(dom->acpitable_blob + offset, acpitables[DSDT].table,
+           acpitables[DSDT].size);
+    calculate_checksum(dom->acpitable_blob + offset,
+                       offsetof(struct acpi_table_header, checksum),
+                       acpitables[DSDT].size);
+    fadt->dsdt = GUEST_ACPI_BASE + offset;
+    calculate_checksum(fadt, offsetof(struct acpi_table_header, checksum),
+                       acpitables[FADT].size);
+}
+
 int libxl__prepare_acpi(libxl__gc *gc, libxl_domain_build_info *info,
                         libxl__domain_build_state *state,
                         struct xc_dom_image *dom)
@@ -314,6 +371,7 @@  int libxl__prepare_acpi(libxl__gc *gc, libxl_domain_build_info *info,
 
     make_acpi_fadt(gc, dom);
     make_acpi_dsdt(gc, dom);
+    link_acpi_tables(gc, dom);
 
     return 0;
 }
diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
index 05e4a58..0911d16 100644
--- a/xen/include/public/arch-arm.h
+++ b/xen/include/public/arch-arm.h
@@ -407,6 +407,10 @@  typedef uint64_t xen_callback_t;
 #define GUEST_GICV3_GICR0_BASE     0x03020000ULL    /* vCPU0 - vCPU127 */
 #define GUEST_GICV3_GICR0_SIZE     0x01000000ULL
 
+/* ACPI tables physical address */
+#define GUEST_ACPI_BASE 0x20000000ULL
+#define GUEST_ACPI_SIZE 0x00200000ULL
+
 /*
  * 16MB == 4096 pages reserved for guest to use as a region to map its
  * grant table in.