All of lore.kernel.org
 help / color / mirror / Atom feed
From: Simon Glass <sjg@chromium.org>
To: u-boot@lists.denx.de
Subject: [PATCH v4 24/31] acpi: Add a method to write tables for a device
Date: Tue,  7 Apr 2020 21:01:00 -0600	[thread overview]
Message-ID: <20200407210023.v4.24.I04c496e973a0d5eb09ed6f6e4674c300fc34b605@changeid> (raw)
In-Reply-To: <20200408030107.168474-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 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     | 10 ++++++
 test/dm/acpi.c            | 71 +++++++++++++++++++++++++++++++++++++++
 7 files changed, 187 insertions(+), 9 deletions(-)

diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 5fa951ad4b6..1204c14b079 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -210,6 +210,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 4832364f3ca..98f97208339 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 0e64c21bf5b..8a6570c3b95 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_MAX);
@@ -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 16048437a3f..7f44b0434b9 100644
--- a/include/acpi/acpi_table.h
+++ b/include/acpi/acpi_table.h
@@ -507,6 +507,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 ee218b44e85..9a0a437dd03 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 ec354102f87..372f19b16d5 100644
--- a/lib/acpi/acpi_table.c
+++ b/lib/acpi/acpi_table.c
@@ -9,6 +9,7 @@
 #include <acpi/acpi_table.h>
 #include <dm.h>
 #include <cpu.h>
+#include <version.h>
 
 int acpi_create_dmar(struct acpi_dmar *dmar, enum dmar_flags flags)
 {
@@ -88,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 21ed7c74409..5743530a3a5 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[] = {
@@ -80,3 +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);
+
+/* 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.0.292.g33ef6b2f38-goog

  parent reply	other threads:[~2020-04-08  3:01 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-08  3:00 [PATCH v4 00/31] dm: Add programmatic generation of ACPI tables (part A) Simon Glass
2020-04-08  3:00 ` [PATCH v4 01/31] test: Add the beginnings of some string tests Simon Glass
2020-04-08  3:00 ` [PATCH v4 02/31] lib: Add a function to convert a string to upper case Simon Glass
2020-04-08  4:18   ` Heinrich Schuchardt
2020-04-08  4:28     ` Heinrich Schuchardt
2020-04-08 14:20       ` Simon Glass
2020-04-09  5:32         ` Heinrich Schuchardt
2020-04-08  3:00 ` [PATCH v4 03/31] cpu: Support querying the address width Simon Glass
2020-04-08  3:00 ` [PATCH v4 04/31] spi: Add SPI mode enums Simon Glass
2020-04-08  3:00 ` [PATCH v4 05/31] tpm: cr50: Release locality on exit Simon Glass
2020-04-08  3:00 ` [PATCH v4 06/31] tpm: cr50: Add a comment for cr50_priv Simon Glass
2020-04-08  3:00 ` [PATCH v4 07/31] tpm: cr50: Use the correct GPIO binding Simon Glass
2020-04-08  3:00 ` [PATCH v4 08/31] tpm: Don't cleanup unless an error happens Simon Glass
2020-04-08  3:00 ` [PATCH v4 09/31] dm: pci: Allow disabling auto-config for a device Simon Glass
2020-04-08  3:00 ` [PATCH v4 10/31] x86: Correct wording of coreboot source code Simon Glass
2020-04-08  3:00 ` [PATCH v4 11/31] x86: apl: Move p2sb ofdata reading to the correct method Simon Glass
2020-04-08  3:00 ` [PATCH v4 12/31] pci: Adjust dm_pci_read_bar32() to return errors correctly Simon Glass
2020-04-08  3:00 ` [PATCH v4 13/31] x86: apl: Add Global NVS table header Simon Glass
2020-04-08 17:14   ` Andy Shevchenko
2020-04-08  3:00 ` [PATCH v4 14/31] dm: core: Add basic ACPI support Simon Glass
2020-04-08  3:00 ` [PATCH v4 15/31] dts: Add a binding for hid-over-i2c Simon Glass
2020-04-08  3:00 ` [PATCH v4 16/31] acpi: Add a binding for ACPI settings in the device tree Simon Glass
2020-04-08  3:00 ` [PATCH v4 17/31] acpi: Add a simple sandbox test Simon Glass
2020-04-08  3:00 ` [PATCH v4 18/31] x86: Move acpi_s3.h to include/acpi/ Simon Glass
2020-04-08  3:00 ` [PATCH v4 19/31] x86: Move acpi_table header to main include/ directory Simon Glass
2020-04-08  3:00 ` [PATCH v4 20/31] acpi: Add an __ACPI__ preprocessor symbol Simon Glass
2020-04-08  3:00 ` [PATCH v4 21/31] acpi: Add a central location for table version numbers Simon Glass
2020-04-08 17:20   ` Andy Shevchenko
2020-04-08 19:32     ` Simon Glass
2020-04-08  3:00 ` [PATCH v4 22/31] acpi: Add support for DMAR Simon Glass
2020-04-08  3:00 ` [PATCH v4 23/31] test: Add hexdump.h to the unit test header Simon Glass
2020-04-08  3:01 ` Simon Glass [this message]
2020-04-08  3:01 ` [PATCH v4 25/31] acpi: Convert part of acpi_table to use acpi_ctx Simon Glass
2020-04-08  3:01 ` [PATCH v4 26/31] x86: Allow devices to write ACPI tables Simon Glass
2020-04-08  3:01 ` [PATCH v4 27/31] acpi: Drop code for missing XSDT from acpi_write_rsdp() Simon Glass
2020-04-08  3:01 ` [PATCH v4 28/31] acpi: Move acpi_add_table() to generic code Simon Glass
2020-04-08  3:01 ` [PATCH v4 29/31] acpi: Put table-setup code in its own function Simon Glass
2020-04-08  3:01 ` [PATCH v4 30/31] acpi: Move the xsdt pointer to acpi_ctx Simon Glass
2020-04-08  3:01 ` [PATCH v4 31/31] acpi: Add an acpi command Simon Glass
2020-04-08 17:02 ` [PATCH v4 00/31] dm: Add programmatic generation of ACPI tables (part A) Andy Shevchenko
2020-04-08 22:22   ` 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=20200407210023.v4.24.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.