x86: Move DSDT table to a writer function
authorSimon Glass <sjg@chromium.org>
Wed, 1 Dec 2021 16:02:52 +0000 (09:02 -0700)
committerSimon Glass <sjg@chromium.org>
Tue, 25 Jan 2022 18:44:36 +0000 (11:44 -0700)
Move this table over to use a writer function, moving the code from the
x86 implementation.

Add a pointer to the DSDT in struct acpi_ctx so we can reference it later.

Disable this table for sandbox since we don't actually compile real ASL
code.

Signed-off-by: Simon Glass <sjg@chromium.org>
arch/x86/lib/acpi_table.c
include/dm/acpi.h
lib/acpi/Makefile
lib/acpi/base.c
lib/acpi/dsdt.c [new file with mode: 0644]
lib/acpi/facs.c

index 22f34a4..e0c76ab 100644 (file)
 #include <dm/acpi.h>
 #include <linux/err.h>
 
-/*
- * IASL compiles the dsdt entries and writes the hex values
- * to a C array AmlCode[] (see dsdt.c).
- */
-extern const unsigned char AmlCode[];
-
 /* ACPI RSDP address to be used in boot parameters */
 static ulong acpi_rsdp_addr;
 
@@ -491,8 +485,6 @@ static int acpi_create_ssdt(struct acpi_ctx *ctx,
 static int write_acpi_tables_x86(struct acpi_ctx *ctx,
                                 const struct acpi_writer *entry)
 {
-       const int thl = sizeof(struct acpi_table_header);
-       struct acpi_table_header *dsdt;
        struct acpi_fadt *fadt;
        struct acpi_table_header *ssdt;
        struct acpi_mcfg *mcfg;
@@ -500,42 +492,14 @@ static int write_acpi_tables_x86(struct acpi_ctx *ctx,
        struct acpi_madt *madt;
        struct acpi_csrt *csrt;
        struct acpi_spcr *spcr;
-       int aml_len;
        ulong addr;
        int ret;
        int i;
 
-       debug("ACPI:    * DSDT\n");
-       dsdt = ctx->current;
-
-       /* 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;
-
-               acpi_inject_dsdt(ctx);
-               log_debug("Added %x bytes from inject_dsdt, now at %p\n",
-                         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);
-       }
-
-       dsdt->length = ctx->current - (void *)dsdt;
-       acpi_align(ctx);
-       log_debug("Updated DSDT length to %x, total %x\n", dsdt->length,
-                 ctx->current - (void *)dsdt);
-
        if (!IS_ENABLED(CONFIG_ACPI_GNVS_EXTERNAL)) {
                /* Pack GNVS into the ACPI table area */
-               for (i = 0; i < dsdt->length; i++) {
-                       u32 *gnvs = (u32 *)((u32)dsdt + i);
+               for (i = 0; i < ctx->dsdt->length; i++) {
+                       u32 *gnvs = (u32 *)((u32)ctx->dsdt + i);
 
                        if (*gnvs == ACPI_GNVS_ADDR) {
                                *gnvs = map_to_sysmem(ctx->current);
@@ -561,8 +525,9 @@ static int write_acpi_tables_x86(struct acpi_ctx *ctx,
         * the GNVS address. Set the checksum to zero since it is part of the
         * region being checksummed.
         */
-       dsdt->checksum = 0;
-       dsdt->checksum = table_compute_checksum((void *)dsdt, dsdt->length);
+       ctx->dsdt->checksum = 0;
+       ctx->dsdt->checksum = table_compute_checksum((void *)ctx->dsdt,
+                                                    ctx->dsdt->length);
 
        /*
         * Fill in platform-specific global NVS variables. If this fails we
@@ -577,7 +542,7 @@ static int write_acpi_tables_x86(struct acpi_ctx *ctx,
        debug("ACPI:    * FADT\n");
        fadt = ctx->current;
        acpi_inc_align(ctx, sizeof(struct acpi_fadt));
-       acpi_create_fadt(fadt, ctx->facs, dsdt);
+       acpi_create_fadt(fadt, ctx->facs, ctx->dsdt);
        acpi_add_table(ctx, fadt);
 
        debug("ACPI:     * SSDT\n");
@@ -644,7 +609,7 @@ static int write_acpi_tables_x86(struct acpi_ctx *ctx,
 
        return 0;
 }
-ACPI_WRITER(2x86, NULL, write_acpi_tables_x86, 0);
+ACPI_WRITER(9x86, NULL, write_acpi_tables_x86, 0);
 
 ulong acpi_get_rsdp_addr(void)
 {
index c4baeb6..815a887 100644 (file)
@@ -53,6 +53,7 @@ enum acpi_dump_option {
  * @rsdt: Pointer to the Root System Description Table
  * @xsdt: Pointer to the Extended System Description Table
  * @facs: Pointer to the Firmware ACPI Control Structure
+ * @dsdt: Pointer to the Differentiated System Description Table
  * @nhlt: Intel Non-High-Definition-Audio Link Table (NHLT) pointer, used to
  *     build up information that audio codecs need to provide in the NHLT ACPI
  *     table
@@ -67,6 +68,7 @@ struct acpi_ctx {
        struct acpi_rsdt *rsdt;
        struct acpi_xsdt *xsdt;
        struct acpi_facs *facs;
+       struct acpi_table_header *dsdt;
        struct nhlt *nhlt;
        char *len_stack[ACPIGEN_LENSTACK_SIZE];
        int ltop;
index 9f70fe6..ccdf428 100644 (file)
@@ -10,5 +10,11 @@ obj-y += acpi_writer.o
 # With QEMU the ACPI tables come from there, not from U-Boot
 ifndef CONFIG_QEMU
 obj-y += base.o
+
+# Sandbox does not build a .asl file
+ifndef CONFIG_SANDBOX
+obj-y += dsdt.o
+endif
+
 obj-y += facs.o
 endif
index 3e8d703..2057bd2 100644 (file)
@@ -5,6 +5,8 @@
  * Copyright 2021 Google LLC
  */
 
+#define LOG_CATEGORY LOGC_ACPI
+
 #include <common.h>
 #include <acpi/acpi_table.h>
 #include <dm/acpi.h>
diff --git a/lib/acpi/dsdt.c b/lib/acpi/dsdt.c
new file mode 100644 (file)
index 0000000..db98cc2
--- /dev/null
@@ -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 <common.h>
+#include <acpi/acpi_table.h>
+#include <dm/acpi.h>
+#include <tables_csum.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);
index 8a1568f..e89f43c 100644 (file)
@@ -5,6 +5,8 @@
  * Copyright 2021 Google LLC
  */
 
+#define LOG_CATEGORY LOGC_ACPI
+
 #include <common.h>
 #include <acpi/acpi_table.h>
 #include <dm/acpi.h>