All of lore.kernel.org
 help / color / mirror / Atom feed
From: Simon Glass <sjg@chromium.org>
To: u-boot@lists.denx.de
Subject: [PATCH v7 2/9] acpi: Add a method to write tables for a device
Date: Sun, 19 Apr 2020 14:36:50 -0600	[thread overview]
Message-ID: <20200419143624.v7.2.I04c496e973a0d5eb09ed6f6e4674c300fc34b605@changeid> (raw)
In-Reply-To: <20200419203657.163143-1-sjg@chromium.org>

A device may want to write out ACPI tables to describe itself to Linux.
Add a method to permit this.

Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v7: None
Changes in v5:
- Drop bisectability changes

Changes in v4:
- Separate out the log newline

Changes in v3: None
Changes in v2:
- Drop definition of ACPI_TABLE_CREATOR
- Make _acpi_write_dev_tables() static and switch argument order
- Generalise the ACPI function recursion with acpi_recurse_method()

 arch/sandbox/dts/test.dts |  4 +++
 arch/x86/lib/acpi_table.c |  9 -----
 drivers/core/acpi.c       | 62 ++++++++++++++++++++++++++++++++
 include/acpi/acpi_table.h | 10 ++++++
 include/dm/acpi.h         | 30 ++++++++++++++++
 lib/acpi/acpi_table.c     | 13 +++++--
 test/dm/acpi.c            | 74 +++++++++++++++++++++++++++++++++++++--
 7 files changed, 187 insertions(+), 15 deletions(-)

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index df9f1835c9..4bccfbe6e1 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -226,6 +226,10 @@
 		compatible = "denx,u-boot-acpi-test";
 	};
 
+	acpi-test2 {
+		compatible = "denx,u-boot-acpi-test";
+	};
+
 	clocks {
 		clk_fixed: clk-fixed {
 			compatible = "fixed-clock";
diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c
index 9346e165d8..235fc2268b 100644
--- a/arch/x86/lib/acpi_table.c
+++ b/arch/x86/lib/acpi_table.c
@@ -60,15 +60,6 @@ static void acpi_write_rsdp(struct acpi_rsdp *rsdp, struct acpi_rsdt *rsdt,
 			sizeof(struct acpi_rsdp));
 }
 
-void acpi_fill_header(struct acpi_table_header *header, char *signature)
-{
-	memcpy(header->signature, signature, 4);
-	memcpy(header->oem_id, OEM_ID, 6);
-	memcpy(header->oem_table_id, OEM_TABLE_ID, 8);
-	header->oem_revision = U_BOOT_BUILD_DATE;
-	memcpy(header->aslc_id, ASLC_ID, 4);
-}
-
 static void acpi_write_rsdt(struct acpi_rsdt *rsdt)
 {
 	struct acpi_table_header *header = &(rsdt->header);
diff --git a/drivers/core/acpi.c b/drivers/core/acpi.c
index ba50d688fe..e09905cf2a 100644
--- a/drivers/core/acpi.c
+++ b/drivers/core/acpi.c
@@ -11,8 +11,17 @@
 #include <common.h>
 #include <dm.h>
 #include <dm/acpi.h>
+#include <dm/device-internal.h>
 #include <dm/root.h>
 
+/* Type of method to call */
+enum method_t {
+	METHOD_WRITE_TABLES,
+};
+
+/* Prototype for all methods */
+typedef int (*acpi_method)(const struct udevice *dev, struct acpi_ctx *ctx);
+
 int acpi_copy_name(char *out_name, const char *name)
 {
 	strncpy(out_name, name, ACPI_NAME_LEN);
@@ -31,3 +40,56 @@ int acpi_get_name(const struct udevice *dev, char *out_name)
 
 	return -ENOSYS;
 }
+
+acpi_method acpi_get_method(struct udevice *dev, enum method_t method)
+{
+	struct acpi_ops *aops;
+
+	aops = device_get_acpi_ops(dev);
+	if (aops) {
+		switch (method) {
+		case METHOD_WRITE_TABLES:
+			return aops->write_tables;
+		}
+	}
+
+	return NULL;
+}
+
+int acpi_recurse_method(struct acpi_ctx *ctx, struct udevice *parent,
+			enum method_t method)
+{
+	struct udevice *dev;
+	acpi_method func;
+	int ret;
+
+	func = acpi_get_method(parent, method);
+	if (func) {
+		log_debug("\n");
+		log_debug("- %s %p\n", parent->name, func);
+		ret = device_ofdata_to_platdata(parent);
+		if (ret)
+			return log_msg_ret("ofdata", ret);
+		ret = func(parent, ctx);
+		if (ret)
+			return log_msg_ret("func", ret);
+	}
+	device_foreach_child(dev, parent) {
+		ret = acpi_recurse_method(ctx, dev, method);
+		if (ret)
+			return log_msg_ret("recurse", ret);
+	}
+
+	return 0;
+}
+
+int acpi_write_dev_tables(struct acpi_ctx *ctx)
+{
+	int ret;
+
+	log_debug("Writing device tables\n");
+	ret = acpi_recurse_method(ctx, dm_root(), METHOD_WRITE_TABLES);
+	log_debug("Writing finished, err=%d\n", ret);
+
+	return ret;
+}
diff --git a/include/acpi/acpi_table.h b/include/acpi/acpi_table.h
index 194be9aa58..a2bd929c92 100644
--- a/include/acpi/acpi_table.h
+++ b/include/acpi/acpi_table.h
@@ -505,6 +505,16 @@ int acpi_get_table_revision(enum acpi_tables table);
  */
 int acpi_create_dmar(struct acpi_dmar *dmar, enum dmar_flags flags);
 
+/**
+ * acpi_fill_header() - Set up a new table header
+ *
+ * This sets all fields except length, revision, checksum and aslc_revision
+ *
+ * @header: ACPI header to update
+ * @signature: Table signature to use (4 characters)
+ */
+void acpi_fill_header(struct acpi_table_header *header, char *signature);
+
 #endif /* !__ACPI__*/
 
 #include <asm/acpi_table.h>
diff --git a/include/dm/acpi.h b/include/dm/acpi.h
index 49257914ff..69d69d7f42 100644
--- a/include/dm/acpi.h
+++ b/include/dm/acpi.h
@@ -24,6 +24,17 @@
 
 #if !defined(__ACPI__)
 
+/**
+ * struct acpi_ctx - Context used for writing ACPI tables
+ *
+ * This contains a few useful pieces of information used when writing
+ *
+ * @current: Current address for writing
+ */
+struct acpi_ctx {
+	void *current;
+};
+
 /**
  * struct acpi_ops - ACPI operations supported by driver model
  */
@@ -38,6 +49,15 @@ struct acpi_ops {
 	 *	other error
 	 */
 	int (*get_name)(const struct udevice *dev, char *out_name);
+
+	/**
+	 * write_tables() - Write out any tables required by this device
+	 *
+	 * @dev: Device to write
+	 * @ctx: ACPI context to use
+	 * @return 0 if OK, -ve on error
+	 */
+	int (*write_tables)(const struct udevice *dev, struct acpi_ctx *ctx);
 };
 
 #define device_get_acpi_ops(dev)	((dev)->driver->acpi_ops)
@@ -72,6 +92,16 @@ int acpi_get_name(const struct udevice *dev, char *out_name);
  */
 int acpi_copy_name(char *out_name, const char *name);
 
+/**
+ * acpi_write_dev_tables() - Write ACPI tables required by devices
+ *
+ * This scans through all devices and tells them to write any tables they want
+ * to write.
+ *
+ * @return 0 if OK, -ve if any device returned an error
+ */
+int acpi_write_dev_tables(struct acpi_ctx *ctx);
+
 #endif /* __ACPI__ */
 
 #endif
diff --git a/lib/acpi/acpi_table.c b/lib/acpi/acpi_table.c
index 4633dcb948..372f19b16d 100644
--- a/lib/acpi/acpi_table.c
+++ b/lib/acpi/acpi_table.c
@@ -9,9 +9,8 @@
 #include <acpi/acpi_table.h>
 #include <dm.h>
 #include <cpu.h>
+#include <version.h>
 
-/* Temporary change to ensure bisectability */
-#ifndef CONFIG_SANDBOX
 int acpi_create_dmar(struct acpi_dmar *dmar, enum dmar_flags flags)
 {
 	struct acpi_table_header *header = &dmar->header;
@@ -37,7 +36,6 @@ int acpi_create_dmar(struct acpi_dmar *dmar, enum dmar_flags flags)
 
 	return 0;
 }
-#endif
 
 int acpi_get_table_revision(enum acpi_tables table)
 {
@@ -91,3 +89,12 @@ int acpi_get_table_revision(enum acpi_tables table)
 		return -EINVAL;
 	}
 }
+
+void acpi_fill_header(struct acpi_table_header *header, char *signature)
+{
+	memcpy(header->signature, signature, 4);
+	memcpy(header->oem_id, OEM_ID, 6);
+	memcpy(header->oem_table_id, OEM_TABLE_ID, 8);
+	header->oem_revision = U_BOOT_BUILD_DATE;
+	memcpy(header->aslc_id, ASLC_ID, 4);
+}
diff --git a/test/dm/acpi.c b/test/dm/acpi.c
index e7b8abd556..fb7b7e46b2 100644
--- a/test/dm/acpi.c
+++ b/test/dm/acpi.c
@@ -8,12 +8,26 @@
 
 #include <common.h>
 #include <dm.h>
+#include <version.h>
 #include <acpi/acpi_table.h>
 #include <dm/acpi.h>
 #include <dm/test.h>
 #include <test/ut.h>
 
 #define ACPI_TEST_DEV_NAME	"ABCD"
+#define BUF_SIZE		4096
+
+static int testacpi_write_tables(const struct udevice *dev,
+				 struct acpi_ctx *ctx)
+{
+	struct acpi_dmar *dmar;
+
+	dmar = (struct acpi_dmar *)ctx->current;
+	acpi_create_dmar(dmar, DMAR_INTR_REMAP);
+	ctx->current += sizeof(struct acpi_dmar);
+
+	return 0;
+}
 
 static int testacpi_get_name(const struct udevice *dev, char *out_name)
 {
@@ -22,6 +36,7 @@ static int testacpi_get_name(const struct udevice *dev, char *out_name)
 
 struct acpi_ops testacpi_ops = {
 	.get_name	= testacpi_get_name,
+	.write_tables	= testacpi_write_tables,
 };
 
 static const struct udevice_id testacpi_ids[] = {
@@ -68,8 +83,6 @@ static int dm_test_acpi_get_table_revision(struct unit_test_state *uts)
 DM_TEST(dm_test_acpi_get_table_revision,
 	DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
 
-/* Temporary change to ensure bisectability */
-#ifndef CONFIG_SANDBOX
 /* Test acpi_create_dmar() */
 static int dm_test_acpi_create_dmar(struct unit_test_state *uts)
 {
@@ -82,4 +95,59 @@ static int dm_test_acpi_create_dmar(struct unit_test_state *uts)
 	return 0;
 }
 DM_TEST(dm_test_acpi_create_dmar, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
-#endif
+
+/* Test acpi_fill_header() */
+static int dm_test_acpi_fill_header(struct unit_test_state *uts)
+{
+	struct acpi_table_header hdr;
+
+	/* Make sure these 5 fields are not changed */
+	hdr.length = 0x11;
+	hdr.revision = 0x22;
+	hdr.checksum = 0x33;
+	hdr.aslc_revision = 0x44;
+	acpi_fill_header(&hdr, "ABCD");
+
+	ut_asserteq_mem("ABCD", hdr.signature, sizeof(hdr.signature));
+	ut_asserteq(0x11, hdr.length);
+	ut_asserteq(0x22, hdr.revision);
+	ut_asserteq(0x33, hdr.checksum);
+	ut_asserteq_mem(OEM_ID, hdr.oem_id, sizeof(hdr.oem_id));
+	ut_asserteq_mem(OEM_TABLE_ID, hdr.oem_table_id,
+			sizeof(hdr.oem_table_id));
+	ut_asserteq(U_BOOT_BUILD_DATE, hdr.oem_revision);
+	ut_asserteq_mem(ASLC_ID, hdr.aslc_id, sizeof(hdr.aslc_id));
+	ut_asserteq(0x44, hdr.aslc_revision);
+
+	return 0;
+}
+DM_TEST(dm_test_acpi_fill_header, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test ACPI write_tables() */
+static int dm_test_acpi_write_tables(struct unit_test_state *uts)
+{
+	struct acpi_dmar *dmar;
+	struct acpi_ctx ctx;
+	void *buf;
+
+	buf = malloc(BUF_SIZE);
+	ut_assertnonnull(buf);
+
+	ctx.current = buf;
+	ut_assertok(acpi_write_dev_tables(&ctx));
+	dmar = buf;
+
+	/*
+	 * We should have two dmar tables, one for each "denx,u-boot-acpi-test"
+	 * device
+	 */
+	ut_asserteq_ptr(dmar + 2, ctx.current);
+	ut_asserteq(DMAR_INTR_REMAP, dmar->flags);
+	ut_asserteq(32 - 1, dmar->host_address_width);
+
+	ut_asserteq(DMAR_INTR_REMAP, dmar[1].flags);
+	ut_asserteq(32 - 1, dmar[1].host_address_width);
+
+	return 0;
+}
+DM_TEST(dm_test_acpi_write_tables, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
-- 
2.26.1.301.g55bc3eb7cb9-goog

  parent reply	other threads:[~2020-04-19 20:36 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-19 20:36 [PATCH v7 0/9] dm: Add programmatic generation of ACPI tables (part A) Simon Glass
2020-04-19 20:36 ` [PATCH v7 1/9] acpi: Add a binding for ACPI settings in the device tree Simon Glass
2020-04-21 12:25   ` Bin Meng
2020-04-21 12:29     ` Andy Shevchenko
2020-04-21 13:07   ` Antwort: " Wolfgang Wallner
2020-04-21 14:40     ` Andy Shevchenko
2020-04-21 14:56     ` Antwort: Re: " Wolfgang Wallner
2020-04-19 20:36 ` Simon Glass [this message]
2020-04-19 20:36 ` [PATCH v7 3/9] acpi: Convert part of acpi_table to use acpi_ctx Simon Glass
2020-04-19 20:36 ` [PATCH v7 4/9] x86: Allow devices to write ACPI tables Simon Glass
2020-04-19 20:36 ` [PATCH v7 5/9] acpi: Drop code for missing XSDT from acpi_write_rsdp() Simon Glass
2020-04-19 20:36 ` [PATCH v7 6/9] acpi: Move acpi_add_table() to generic code Simon Glass
2020-04-19 20:36 ` [PATCH v7 7/9] acpi: Put table-setup code in its own function Simon Glass
2020-04-23  9:38   ` Bin Meng
2020-04-26 19:45     ` Simon Glass
2020-04-27  6:36     ` Antwort: " Wolfgang Wallner
2020-04-27  7:10       ` Bin Meng
2020-04-19 20:36 ` [PATCH v7 8/9] acpi: Move the xsdt pointer to acpi_ctx Simon Glass
2020-04-19 20:36 ` [PATCH v7 9/9] acpi: Add an acpi command Simon Glass
2020-04-21 17:42 ` [PATCH v7 0/9] dm: Add programmatic generation of ACPI tables (part A) Andy Shevchenko
2020-04-21 21:37   ` Simon Glass
2020-04-23  9:46     ` Bin Meng
2020-04-23  9:58       ` Bin Meng
2020-04-27  5:58         ` Bin Meng
2020-04-27 17:02           ` Simon Glass
2020-04-29 18:09 ` Heinrich Schuchardt
2020-05-01 13:14   ` Simon Glass

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200419143624.v7.2.I04c496e973a0d5eb09ed6f6e4674c300fc34b605@changeid \
    --to=sjg@chromium.org \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.