]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
x86: Move base tables to a writer function
authorSimon Glass <sjg@chromium.org>
Wed, 1 Dec 2021 16:02:50 +0000 (09:02 -0700)
committerSimon Glass <sjg@chromium.org>
Tue, 25 Jan 2022 18:44:36 +0000 (11:44 -0700)
Use the new ACPI writer to write the base tables at the start of the area,
moving this code from the x86 implementation.

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

index 321faaeb1854d55a85a7d572ac0b35dcd980f6f5..e6aa3c5a7098ab8d8aa55cb6ad5a5e3bef9c7c4f 100644 (file)
@@ -521,8 +521,6 @@ static int write_acpi_tables_x86(struct acpi_ctx *ctx,
        int ret;
        int i;
 
-       acpi_setup_base_tables(ctx);
-
        debug("ACPI:    * FACS\n");
        facs = ctx->current;
        acpi_inc_align(ctx, sizeof(struct acpi_facs));
index f34bd6311a118ab9e7b61aa0de010a532fd567d6..fcc9caaddfd0ba3e5dccccbb908b97e1ec721101 100644 (file)
@@ -678,16 +678,6 @@ void acpi_inc_align(struct acpi_ctx *ctx, uint amount);
  */
 int acpi_add_table(struct acpi_ctx *ctx, void *table);
 
-/**
- * acpi_setup_base_tables() - Set up base tables - RSDP, RSDT and XSDT
- *
- * Writes the basic tables to the given context, which must first be set up with
- * acpi_setup_ctx().
- *
- * @ctx: Context to write base tables to
- */
-void acpi_setup_base_tables(struct acpi_ctx *ctx);
-
 /**
  * acpi_write_rsdp() - Write out an RSDP indicating where the ACPI tables are
  *
index f6e54793f793195010578f0fd013df9c0bdaa910..2021a6903090ddb5a12afed258e6940a8f1a57be 100644 (file)
@@ -72,9 +72,11 @@ struct acpi_ctx {
 
 /**
  * enum acpi_writer_flags_t - flags to use for the ACPI writers
+ *
+ * ACPIWF_ALIGN64 - align to 64 bytes after writing this one (default is 16)
  */
 enum acpi_writer_flags_t {
-       ACPIWF_ALIGN64_,
+       ACPIWF_ALIGN64  = 1 << 0,
 };
 
 struct acpi_writer;
@@ -103,7 +105,7 @@ struct acpi_writer {
        int flags;
 };
 
-/* Declare a new ACPI table writer */
+/* Declare a new ACPI-table writer */
 #define ACPI_WRITER(_name, _table, _write, _flags)                                     \
        ll_entry_declare(struct acpi_writer, _name, acpi_writer) = {    \
                .name = #_name,                                         \
@@ -112,6 +114,10 @@ struct acpi_writer {
                .flags = _flags,                                        \
        }
 
+/* Get a pointer to a given ACPI-table writer */
+#define ACPI_WRITER_GET(_name)                                         \
+       ll_entry_get(struct acpi_writer, _name, acpi_writer)
+
 /**
  * struct acpi_ops - ACPI operations supported by driver model
  */
@@ -309,6 +315,19 @@ int acpi_write_one(struct acpi_ctx *ctx, const struct acpi_writer *entry);
  */
 void acpi_setup_ctx(struct acpi_ctx *ctx, ulong start);
 
+/**
+ * acpi_write_one() - Call a single ACPI writer entry
+ *
+ * This handles aligning the context afterwards, if the entry flags indicate
+ * that.
+ *
+ * @ctx: ACPI context to use
+ * @entry: Entry to call
+ * @return 0 if OK, -ENOENT if this writer produced an empty entry, other -ve
+ * value on error
+ */
+int acpi_write_one(struct acpi_ctx *ctx, const struct acpi_writer *entry);
+
 #endif /* __ACPI__ */
 
 #endif
index 1318e83dfc47459cf3bd59f4e61ef40f61a62c4f..4674a9287f66abd398023b2adfc5604444e83143 100644 (file)
@@ -6,3 +6,8 @@ obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_device.o
 obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_dp.o
 obj-$(CONFIG_$(SPL_)ACPIGEN) += acpi_table.o
 obj-y += acpi_writer.o
+
+# With QEMU the ACPI tables come from there, not from U-Boot
+ifndef CONFIG_QEMU
+obj-y += base.o
+endif
index 284b5a9afb896f51e7f242df421f9389f4b2bb96..f8642f9942085f071bbc7af06a807f46bbade32d 100644 (file)
@@ -201,81 +201,6 @@ int acpi_add_table(struct acpi_ctx *ctx, void *table)
        return 0;
 }
 
-void acpi_write_rsdp(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt,
-                    struct acpi_xsdt *xsdt)
-{
-       memset(rsdp, 0, sizeof(struct acpi_rsdp));
-
-       memcpy(rsdp->signature, RSDP_SIG, 8);
-       memcpy(rsdp->oem_id, OEM_ID, 6);
-
-       rsdp->length = sizeof(struct acpi_rsdp);
-       rsdp->rsdt_address = map_to_sysmem(rsdt);
-
-       rsdp->xsdt_address = map_to_sysmem(xsdt);
-       rsdp->revision = ACPI_RSDP_REV_ACPI_2_0;
-
-       /* Calculate checksums */
-       rsdp->checksum = table_compute_checksum(rsdp, 20);
-       rsdp->ext_checksum = table_compute_checksum(rsdp,
-                                                   sizeof(struct acpi_rsdp));
-}
-
-static void acpi_write_rsdt(struct acpi_rsdt *rsdt)
-{
-       struct acpi_table_header *header = &rsdt->header;
-
-       /* Fill out header fields */
-       acpi_fill_header(header, "RSDT");
-       header->length = sizeof(struct acpi_rsdt);
-       header->revision = 1;
-
-       /* Entries are filled in later, we come with an empty set */
-
-       /* Fix checksum */
-       header->checksum = table_compute_checksum(rsdt,
-                                                 sizeof(struct acpi_rsdt));
-}
-
-static void acpi_write_xsdt(struct acpi_xsdt *xsdt)
-{
-       struct acpi_table_header *header = &xsdt->header;
-
-       /* Fill out header fields */
-       acpi_fill_header(header, "XSDT");
-       header->length = sizeof(struct acpi_xsdt);
-       header->revision = 1;
-
-       /* Entries are filled in later, we come with an empty set */
-
-       /* Fix checksum */
-       header->checksum = table_compute_checksum(xsdt,
-                                                 sizeof(struct acpi_xsdt));
-}
-
-void acpi_setup_base_tables(struct acpi_ctx *ctx)
-{
-       /* We need at least an RSDP and an RSDT Table */
-       ctx->rsdp = ctx->current;
-       acpi_inc_align(ctx, sizeof(struct acpi_rsdp));
-       ctx->rsdt = ctx->current;
-       acpi_inc_align(ctx, sizeof(struct acpi_rsdt));
-       ctx->xsdt = ctx->current;
-       acpi_inc_align(ctx, sizeof(struct acpi_xsdt));
-
-       /* clear all table memory */
-       memset(ctx->base, '\0', ctx->current - ctx->base);
-
-       acpi_write_rsdp(ctx->rsdp, ctx->rsdt, ctx->xsdt);
-       acpi_write_rsdt(ctx->rsdt);
-       acpi_write_xsdt(ctx->xsdt);
-       /*
-        * Per ACPI spec, the FACS table address must be aligned to a 64 byte
-        * boundary (Windows checks this, but Linux does not).
-        */
-       acpi_align64(ctx);
-}
-
 void acpi_create_dbg2(struct acpi_dbg2_header *dbg2,
                      int port_type, int port_subtype,
                      struct acpi_gen_regaddr *address, u32 address_size,
index 53fc753aeeb2b2a82573f8b0cd7971e954bc80dc..d2505e6eaa4120134715f2840e14988a3c787cbf 100644 (file)
@@ -35,7 +35,10 @@ int acpi_write_one(struct acpi_ctx *ctx, const struct acpi_writer *entry)
        if (ret)
                return log_msg_ret("write", ret);
 
-       acpi_align(ctx);
+       if (entry->flags & ACPIWF_ALIGN64)
+               acpi_align64(ctx);
+       else
+               acpi_align(ctx);
 
        return 0;
 }
diff --git a/lib/acpi/base.c b/lib/acpi/base.c
new file mode 100644 (file)
index 0000000..3e8d703
--- /dev/null
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Write base ACPI tables
+ *
+ * Copyright 2021 Google LLC
+ */
+
+#include <common.h>
+#include <acpi/acpi_table.h>
+#include <dm/acpi.h>
+#include <mapmem.h>
+#include <tables_csum.h>
+
+void acpi_write_rsdp(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt,
+                    struct acpi_xsdt *xsdt)
+{
+       memset(rsdp, 0, sizeof(struct acpi_rsdp));
+
+       memcpy(rsdp->signature, RSDP_SIG, 8);
+       memcpy(rsdp->oem_id, OEM_ID, 6);
+
+       rsdp->length = sizeof(struct acpi_rsdp);
+       rsdp->rsdt_address = map_to_sysmem(rsdt);
+
+       rsdp->xsdt_address = map_to_sysmem(xsdt);
+       rsdp->revision = ACPI_RSDP_REV_ACPI_2_0;
+
+       /* Calculate checksums */
+       rsdp->checksum = table_compute_checksum(rsdp, 20);
+       rsdp->ext_checksum = table_compute_checksum(rsdp,
+                                                   sizeof(struct acpi_rsdp));
+}
+
+static void acpi_write_rsdt(struct acpi_rsdt *rsdt)
+{
+       struct acpi_table_header *header = &rsdt->header;
+
+       /* Fill out header fields */
+       acpi_fill_header(header, "RSDT");
+       header->length = sizeof(struct acpi_rsdt);
+       header->revision = 1;
+
+       /* Entries are filled in later, we come with an empty set */
+
+       /* Fix checksum */
+       header->checksum = table_compute_checksum(rsdt,
+                                                 sizeof(struct acpi_rsdt));
+}
+
+static void acpi_write_xsdt(struct acpi_xsdt *xsdt)
+{
+       struct acpi_table_header *header = &xsdt->header;
+
+       /* Fill out header fields */
+       acpi_fill_header(header, "XSDT");
+       header->length = sizeof(struct acpi_xsdt);
+       header->revision = 1;
+
+       /* Entries are filled in later, we come with an empty set */
+
+       /* Fix checksum */
+       header->checksum = table_compute_checksum(xsdt,
+                                                 sizeof(struct acpi_xsdt));
+}
+
+static int acpi_write_base(struct acpi_ctx *ctx,
+                          const struct acpi_writer *entry)
+{
+       /* We need at least an RSDP and an RSDT Table */
+       ctx->rsdp = ctx->current;
+       acpi_inc_align(ctx, sizeof(struct acpi_rsdp));
+       ctx->rsdt = ctx->current;
+       acpi_inc_align(ctx, sizeof(struct acpi_rsdt));
+       ctx->xsdt = ctx->current;
+       acpi_inc_align(ctx, sizeof(struct acpi_xsdt));
+
+       /* clear all table memory */
+       memset(ctx->base, '\0', ctx->current - ctx->base);
+
+       acpi_write_rsdp(ctx->rsdp, ctx->rsdt, ctx->xsdt);
+       acpi_write_rsdt(ctx->rsdt);
+       acpi_write_xsdt(ctx->xsdt);
+
+       return 0;
+}
+/*
+ * Per ACPI spec, the FACS table address must be aligned to a 64-byte boundary
+ * (Windows checks this, but Linux does not).
+ *
+ * Use the '0' prefix to put this one first
+ */
+ACPI_WRITER(0base, NULL, acpi_write_base, ACPIWF_ALIGN64);
index 49b71bec3c0026dd2515d1d1b44b205e3b0143e6..da728692528688ad17b4e3906cfbebca41721bd0 100644 (file)
@@ -53,10 +53,15 @@ struct testacpi_plat {
  *
  * @ctx: Context to set up
  */
-static int setup_ctx_and_base_tables(struct acpi_ctx *ctx, ulong start)
+static int setup_ctx_and_base_tables(struct unit_test_state *uts,
+                                    struct acpi_ctx *ctx, ulong start)
 {
+       struct acpi_writer *entry = ACPI_WRITER_GET(0base);
+
        acpi_setup_ctx(ctx, start);
-       acpi_setup_base_tables(ctx);
+
+       ctx->tab_start = ctx->current;
+       ut_assertok(acpi_write_one(ctx, entry));
 
        return 0;
 }
@@ -264,7 +269,7 @@ static int dm_test_acpi_write_tables(struct unit_test_state *uts)
        ut_assertnonnull(buf);
        addr = map_to_sysmem(buf);
 
-       setup_ctx_and_base_tables(&ctx, addr);
+       ut_assertok(setup_ctx_and_base_tables(uts, &ctx, addr));
        dmar = ctx.current;
        ut_assertok(acpi_write_dev_tables(&ctx));
 
@@ -339,7 +344,7 @@ static int dm_test_setup_ctx_and_base_tables(struct unit_test_state *uts)
        buf = memalign(64, BUF_SIZE);
        ut_assertnonnull(buf);
        addr = map_to_sysmem(buf);
-       setup_ctx_and_base_tables(&ctx, addr + 4);
+       ut_assertok(setup_ctx_and_base_tables(uts, &ctx, addr + 4));
        ut_asserteq(map_to_sysmem(PTR_ALIGN(buf + 4, 16)), gd_acpi_start());
 
        rsdp = buf + 16;
@@ -382,7 +387,7 @@ static int dm_test_acpi_cmd_list(struct unit_test_state *uts)
        buf = memalign(16, BUF_SIZE);
        ut_assertnonnull(buf);
        addr = map_to_sysmem(buf);
-       setup_ctx_and_base_tables(&ctx, addr);
+       ut_assertok(setup_ctx_and_base_tables(uts, &ctx, addr));
 
        ut_assertok(acpi_write_dev_tables(&ctx));
 
@@ -424,7 +429,7 @@ static int dm_test_acpi_cmd_dump(struct unit_test_state *uts)
        buf = memalign(16, BUF_SIZE);
        ut_assertnonnull(buf);
        addr = map_to_sysmem(buf);
-       setup_ctx_and_base_tables(&ctx, addr);
+       ut_assertok(setup_ctx_and_base_tables(uts, &ctx, addr));
 
        ut_assertok(acpi_write_dev_tables(&ctx));