x86: Allow devices to write to DSDT

Call the new core function to inject ASL programmatically into the DSDT.
This is made up of fragments generated by devices that have the
inject_dsdt() method. The normal, compiled ASL file is added after this.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c
index 4658d88..eeacfe9 100644
--- a/arch/x86/lib/acpi_table.c
+++ b/arch/x86/lib/acpi_table.c
@@ -406,11 +406,20 @@
 
 	debug("ACPI:    * DSDT\n");
 	dsdt = ctx->current;
+
+	/* Put the table header first */
 	memcpy(dsdt, &AmlCode, sizeof(struct acpi_table_header));
 	acpi_inc(ctx, sizeof(struct acpi_table_header));
+
+	/* If the table is not empty, allow devices to inject things */
+	if (dsdt->length >= sizeof(struct acpi_table_header))
+		acpi_inject_dsdt(ctx);
+
+	/* Copy in the AML code itself if any (after the header) */
 	memcpy(ctx->current,
 	       (char *)&AmlCode + sizeof(struct acpi_table_header),
 	       dsdt->length - sizeof(struct acpi_table_header));
+
 	acpi_inc_align(ctx, dsdt->length - sizeof(struct acpi_table_header));
 
 	/* Pack GNVS into the ACPI table area */
@@ -425,7 +434,12 @@
 		}
 	}
 
-	/* Update DSDT checksum since we patched the GNVS address */
+	/*
+	 * Recalculate the length and update the DSDT checksum since we patched
+	 * the GNVS address. Set the checksum to zero since it is part of the
+	 * region being checksummed.
+	 */
+	dsdt->length = ctx->current - (void *)dsdt;
 	dsdt->checksum = 0;
 	dsdt->checksum = table_compute_checksum((void *)dsdt, dsdt->length);