]> xenbits.xensource.com Git - people/royger/xen.git/commitdiff
libxl/arm: Estimate the size of ACPI tables
authorShannon Zhao <shannon.zhao@linaro.org>
Thu, 29 Sep 2016 01:18:50 +0000 (18:18 -0700)
committerWei Liu <wei.liu2@citrix.com>
Fri, 30 Sep 2016 10:47:26 +0000 (11:47 +0100)
Estimate the size of ACPI tables and reserve a memory map space for ACPI
tables.

Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Acked-by: Wei Liu <wei.liu2@citrix.com>
tools/libxl/libxl_arm_acpi.c
xen/include/acpi/actbl1.h

index 06dff5f4e397f2fb1d2dfe3d6c2a791d1450c249..bc9ab84acd1c763dde12754ec5be19c645dde392 100644 (file)
@@ -34,11 +34,104 @@ extern const unsigned char dsdt_anycpu_arm[];
 _hidden
 extern const int dsdt_anycpu_arm_len;
 
+enum {
+    RSDP,
+    XSDT,
+    GTDT,
+    MADT,
+    FADT,
+    DSDT,
+    MAX_TABLE_NUMS,
+};
+
+struct acpitable {
+    uint64_t addr;
+    size_t size;
+};
+
+static int libxl__estimate_madt_size(libxl__gc *gc,
+                                     const libxl_domain_build_info *info,
+                                     size_t *size)
+{
+    int rc = 0;
+
+    switch (info->arch_arm.gic_version) {
+    case LIBXL_GIC_VERSION_V2:
+        *size = sizeof(struct acpi_table_madt) +
+                ACPI_MADT_GICC_SIZE_v5 * info->max_vcpus +
+                sizeof(struct acpi_madt_generic_distributor);
+        break;
+    case LIBXL_GIC_VERSION_V3:
+        *size = sizeof(struct acpi_table_madt) +
+                ACPI_MADT_GICC_SIZE_v5 * info->max_vcpus +
+                sizeof(struct acpi_madt_generic_distributor) +
+                sizeof(struct acpi_madt_generic_redistributor);
+        break;
+    default:
+        LOG(ERROR, "Unknown GIC version");
+        rc = ERROR_FAIL;
+        break;
+    }
+
+    return rc;
+}
+
+static int libxl__allocate_acpi_tables(libxl__gc *gc,
+                                       libxl_domain_build_info *info,
+                                       struct xc_dom_image *dom,
+                                       struct acpitable acpitables[])
+{
+    int rc;
+    size_t size;
+
+    acpitables[RSDP].addr = GUEST_ACPI_BASE;
+    acpitables[RSDP].size = sizeof(struct acpi_table_rsdp);
+    dom->acpi_modules[0].length += ROUNDUP(acpitables[RSDP].size, 3);
+
+    acpitables[XSDT].addr = GUEST_ACPI_BASE + dom->acpi_modules[0].length;
+    /*
+     * Currently only 3 tables(GTDT, FADT, MADT) are pointed by XSDT. Alloc
+     * entries for them.
+     */
+    acpitables[XSDT].size = sizeof(struct acpi_table_xsdt) +
+                            sizeof(uint64_t) * 2;
+    dom->acpi_modules[0].length += ROUNDUP(acpitables[XSDT].size, 3);
+
+    acpitables[GTDT].addr = GUEST_ACPI_BASE + dom->acpi_modules[0].length;
+    acpitables[GTDT].size = sizeof(struct acpi_table_gtdt);
+    dom->acpi_modules[0].length += ROUNDUP(acpitables[GTDT].size, 3);
+
+    acpitables[MADT].addr = GUEST_ACPI_BASE + dom->acpi_modules[0].length;
+
+    rc = libxl__estimate_madt_size(gc, info, &size);
+    if (rc < 0)
+        goto out;
+
+    acpitables[MADT].size = size;
+    dom->acpi_modules[0].length += ROUNDUP(acpitables[MADT].size, 3);
+
+    acpitables[FADT].addr = GUEST_ACPI_BASE + dom->acpi_modules[0].length;
+    acpitables[FADT].size = sizeof(struct acpi_table_fadt);
+    dom->acpi_modules[0].length += ROUNDUP(acpitables[FADT].size, 3);
+
+    acpitables[DSDT].addr = GUEST_ACPI_BASE + dom->acpi_modules[0].length;
+    acpitables[DSDT].size = dsdt_anycpu_arm_len;
+    dom->acpi_modules[0].length += ROUNDUP(acpitables[DSDT].size, 3);
+
+    assert(dom->acpi_modules[0].length <= GUEST_ACPI_SIZE);
+    dom->acpi_modules[0].data = libxl__zalloc(gc, dom->acpi_modules[0].length);
+
+    rc = 0;
+out:
+    return rc;
+}
+
 int libxl__prepare_acpi(libxl__gc *gc, libxl_domain_build_info *info,
                         struct xc_dom_image *dom)
 {
     const libxl_version_info *vers;
     int rc = 0;
+    struct acpitable acpitables[MAX_TABLE_NUMS];
 
     vers = libxl_get_version_info(CTX);
     if (vers == NULL) {
@@ -53,6 +146,8 @@ int libxl__prepare_acpi(libxl__gc *gc, libxl_domain_build_info *info,
     dom->acpi_modules[0].length = 0;
     dom->acpi_modules[0].guest_addr_out = GUEST_ACPI_BASE;
 
+    rc = libxl__allocate_acpi_tables(gc, info, dom, acpitables);
+
 out:
     return rc;
 }
index ed5cd2d05fbe69ca659809170d956df0dc8d40a5..e1991362dc61589bd2ef57f99b536f8d6d58f9d1 100644 (file)
@@ -786,6 +786,8 @@ struct acpi_madt_generic_interrupt {
        u8 reserved2[3];
 };
 
+#define ACPI_MADT_GICC_SIZE_v5          76
+
 /* Masks for Flags field above */
 
 /* ACPI_MADT_ENABLED                    (1)      Processor is usable if set */