[PATCH 16/40] x86: Move base tables to a writer function

Simon Glass sjg at chromium.org
Wed Dec 1 17:02:50 CET 2021


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 at chromium.org>
---

 arch/x86/lib/acpi_table.c |  2 -
 include/acpi/acpi_table.h | 10 -----
 include/dm/acpi.h         | 23 +++++++++-
 lib/acpi/Makefile         |  5 +++
 lib/acpi/acpi_table.c     | 75 -------------------------------
 lib/acpi/acpi_writer.c    |  5 ++-
 lib/acpi/base.c           | 92 +++++++++++++++++++++++++++++++++++++++
 test/dm/acpi.c            | 17 +++++---
 8 files changed, 133 insertions(+), 96 deletions(-)
 create mode 100644 lib/acpi/base.c

diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c
index 321faaeb185..e6aa3c5a709 100644
--- a/arch/x86/lib/acpi_table.c
+++ b/arch/x86/lib/acpi_table.c
@@ -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));
diff --git a/include/acpi/acpi_table.h b/include/acpi/acpi_table.h
index a720017283d..87674e2cc0d 100644
--- a/include/acpi/acpi_table.h
+++ b/include/acpi/acpi_table.h
@@ -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
  *
diff --git a/include/dm/acpi.h b/include/dm/acpi.h
index 5069e879268..ac60b11116f 100644
--- a/include/dm/acpi.h
+++ b/include/dm/acpi.h
@@ -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
diff --git a/lib/acpi/Makefile b/lib/acpi/Makefile
index 1318e83dfc4..4674a9287f6 100644
--- a/lib/acpi/Makefile
+++ b/lib/acpi/Makefile
@@ -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
diff --git a/lib/acpi/acpi_table.c b/lib/acpi/acpi_table.c
index 284b5a9afb8..f8642f99420 100644
--- a/lib/acpi/acpi_table.c
+++ b/lib/acpi/acpi_table.c
@@ -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,
diff --git a/lib/acpi/acpi_writer.c b/lib/acpi/acpi_writer.c
index 53fc753aeeb..d2505e6eaa4 100644
--- a/lib/acpi/acpi_writer.c
+++ b/lib/acpi/acpi_writer.c
@@ -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
index 00000000000..3e8d703934e
--- /dev/null
+++ b/lib/acpi/base.c
@@ -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);
diff --git a/test/dm/acpi.c b/test/dm/acpi.c
index 49b71bec3c0..da728692528 100644
--- a/test/dm/acpi.c
+++ b/test/dm/acpi.c
@@ -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));
 
-- 
2.34.0.rc2.393.gf8c9666880-goog



More information about the U-Boot mailing list