summaryrefslogtreecommitdiff
path: root/lib/acpi/dsdt.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/acpi/dsdt.c')
-rw-r--r--lib/acpi/dsdt.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/lib/acpi/dsdt.c b/lib/acpi/dsdt.c
new file mode 100644
index 00000000000..206e1e2678f
--- /dev/null
+++ b/lib/acpi/dsdt.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Write the ACPI Differentiated System Description Table (DSDT)
+ *
+ * Copyright 2021 Google LLC
+ */
+
+#define LOG_CATEGORY LOGC_ACPI
+
+#include <acpi/acpi_table.h>
+#include <dm/acpi.h>
+#include <tables_csum.h>
+#include <linux/string.h>
+
+/*
+ * IASL compiles the dsdt entries and writes the hex values
+ * to a C array AmlCode[] (see dsdt.c).
+ */
+extern const unsigned char AmlCode[];
+
+int acpi_write_dsdt(struct acpi_ctx *ctx, const struct acpi_writer *entry)
+{
+ const int thl = sizeof(struct acpi_table_header);
+ struct acpi_table_header *dsdt = ctx->current;
+ int aml_len;
+
+ /* Put the table header first */
+ memcpy(dsdt, &AmlCode, thl);
+ acpi_inc(ctx, thl);
+ log_debug("DSDT starts at %p, hdr ends at %p\n", dsdt, ctx->current);
+
+ /* If the table is not empty, allow devices to inject things */
+ aml_len = dsdt->length - thl;
+ if (aml_len) {
+ void *base = ctx->current;
+ int ret;
+
+ ret = acpi_inject_dsdt(ctx);
+ if (ret)
+ return log_msg_ret("inject", ret);
+ log_debug("Added %lx bytes from inject_dsdt, now at %p\n",
+ (ulong)(ctx->current - base), ctx->current);
+ log_debug("Copy AML code size %x to %p\n", aml_len,
+ ctx->current);
+ memcpy(ctx->current, AmlCode + thl, aml_len);
+ acpi_inc(ctx, aml_len);
+ }
+
+ ctx->dsdt = dsdt;
+ dsdt->length = ctx->current - (void *)dsdt;
+ log_debug("Updated DSDT length to %x\n", dsdt->length);
+
+ return 0;
+}
+ACPI_WRITER(3dsdt, "DSDT", acpi_write_dsdt, 0);