All of lore.kernel.org
 help / color / mirror / Atom feed
From: Simon Glass <sjg@chromium.org>
To: u-boot@lists.denx.de
Subject: [PATCH v1 22/35] acpi: Add support for various misc ACPI opcodes
Date: Tue, 28 Apr 2020 20:21:46 -0600	[thread overview]
Message-ID: <20200429022159.254271-20-sjg@chromium.org> (raw)
In-Reply-To: <20200429022159.254271-1-sjg@chromium.org>

Add more functions to handle some miscellaneous ACPI opcodes.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

Changes in v1: None

 include/acpi/acpigen.h | 114 +++++++++++++++++++++++++++++++++++++++++
 lib/acpi/acpigen.c     |  83 ++++++++++++++++++++++++++++++
 test/dm/acpigen.c      |  75 +++++++++++++++++++++++++++
 3 files changed, 272 insertions(+)

diff --git a/include/acpi/acpigen.h b/include/acpi/acpigen.h
index 16b33ebe66..c595bb9efa 100644
--- a/include/acpi/acpigen.h
+++ b/include/acpi/acpigen.h
@@ -26,9 +26,26 @@ enum {
 	QWORD_PREFIX		= 0x0e,
 	BUFFER_OP		= 0x11,
 	PACKAGE_OP		= 0x12,
+	METHOD_OP		= 0x14,
+	SLEEP_OP		= 0x22,
 	DUAL_NAME_PREFIX	= 0x2e,
 	MULTI_NAME_PREFIX	= 0x2f,
+	DEBUG_OP		= 0x31,
+	EXT_OP_PREFIX		= 0x5b,
 	ROOT_PREFIX		= 0x5c,
+	LOCAL0_OP		= 0x60,
+	LOCAL1_OP		= 0x61,
+	LOCAL2_OP		= 0x62,
+	LOCAL3_OP		= 0x63,
+	LOCAL4_OP		= 0x64,
+	LOCAL5_OP		= 0x65,
+	LOCAL6_OP		= 0x66,
+	LOCAL7_OP		= 0x67,
+	STORE_OP		= 0x70,
+	AND_OP			= 0x7b,
+	OR_OP			= 0x7d,
+	NOT_OP			= 0x80,
+	RETURN_OP		= 0xa4,
 };
 
 /**
@@ -196,4 +213,101 @@ void acpigen_write_name(struct acpi_ctx *ctx, const char *namepath);
  */
 int acpigen_write_uuid(struct acpi_ctx *ctx, const char *uuid);
 
+/**
+ * acpigen_emit_ext_op() - Emit an extended op with the EXT_OP_PREFIX prefix
+ *
+ * @ctx: ACPI context pointer
+ * @op: Operation code (e.g. SLEEP_OP)
+ */
+void acpigen_emit_ext_op(struct acpi_ctx *ctx, uint op);
+
+/**
+ * acpigen_write_method() - Write a method header
+ *
+ * @ctx: ACPI context pointer
+ * @name: Method name (4 characters)
+ * @nargs: Number of method arguments (0 if none)
+ */
+void acpigen_write_method(struct acpi_ctx *ctx, const char *name, int nargs);
+
+/**
+ * acpigen_write_method_serialized() - Write a method header
+ *
+ * This sets the 'serialized' flag so that the method is thread-safe
+ *
+ * @ctx: ACPI context pointer
+ * @name: Method name (4 characters)
+ * @nargs: Number of method arguments (0 if none)
+ */
+void acpigen_write_method_serialized(struct acpi_ctx *ctx, const char *name,
+				     int nargs);
+
+/**
+ * acpigen_write_sta() - Write a _STA method
+ *
+ * @ctx: ACPI context pointer
+ * @status: Status value to return
+ */
+void acpigen_write_sta(struct acpi_ctx *ctx, uint status);
+
+/**
+ * acpigen_write_sleep() - Write a sleep operation
+ *
+ * @ctx: ACPI context pointer
+ * @sleep_ms: Number of milliseconds to sleep for
+ */
+void acpigen_write_sleep(struct acpi_ctx *ctx, u64 sleep_ms);
+
+/**
+ * acpigen_write_store() - Write a store operation
+ *
+ * @ctx: ACPI context pointer
+ */
+void acpigen_write_store(struct acpi_ctx *ctx);
+
+/**
+ * acpigen_write_debug_string() - Write a debug string
+ *
+ * This writes a debug operation with an associated string
+ *
+ * @ctx: ACPI context pointer
+ * @str: String to write
+ */
+void acpigen_write_debug_string(struct acpi_ctx *ctx, const char *str);
+
+/**
+ * acpigen_write_or() - Write a bitwise OR operation
+ *
+ * res = arg1 | arg2
+ *
+ * @ctx: ACPI context pointer
+ * @arg1: ACPI opcode for operand 1 (e.g. LOCAL0_OP)
+ * @arg2: ACPI opcode for operand 2 (e.g. LOCAL1_OP)
+ * @res: ACPI opcode for result (e.g. LOCAL2_OP)
+ */
+void acpigen_write_or(struct acpi_ctx *ctx, u8 arg1, u8 arg2, u8 res);
+
+/**
+ * acpigen_write_and() - Write a bitwise AND operation
+ *
+ * res = arg1 & arg2
+ *
+ * @ctx: ACPI context pointer
+ * @arg1: ACPI opcode for operand 1 (e.g. LOCAL0_OP)
+ * @arg2: ACPI opcode for operand 2 (e.g. LOCAL1_OP)
+ * @res: ACPI opcode for result (e.g. LOCAL2_OP)
+ */
+void acpigen_write_and(struct acpi_ctx *ctx, u8 arg1, u8 arg2, u8 res);
+
+/**
+ * acpigen_write_or() - Write a bitwise NOT operation
+ *
+ * res = ~arg1
+ *
+ * @ctx: ACPI context pointer
+ * @arg: ACPI opcode for operand (e.g. LOCAL0_OP)
+ * @res: ACPI opcode for result (e.g. LOCAL2_OP)
+ */
+void acpigen_write_not(struct acpi_ctx *ctx, u8 arg, u8 res);
+
 #endif
diff --git a/lib/acpi/acpigen.c b/lib/acpi/acpigen.c
index c28f7b87b9..82c8b1e18f 100644
--- a/lib/acpi/acpigen.c
+++ b/lib/acpi/acpigen.c
@@ -72,6 +72,12 @@ void acpigen_pop_len(struct acpi_ctx *ctx)
 	p[2] = (len >> 12 & 0xff);
 }
 
+void acpigen_emit_ext_op(struct acpi_ctx *ctx, uint op)
+{
+	acpigen_emit_byte(ctx, EXT_OP_PREFIX);
+	acpigen_emit_byte(ctx, op);
+}
+
 char *acpigen_write_package(struct acpi_ctx *ctx, int nr_el)
 {
 	char *p;
@@ -251,6 +257,37 @@ void acpigen_write_name(struct acpi_ctx *ctx, const char *namepath)
 	acpigen_emit_namestring(ctx, namepath);
 }
 
+static void acpigen_write_method_(struct acpi_ctx *ctx, const char *name,
+				  uint flags)
+{
+	acpigen_emit_byte(ctx, METHOD_OP);
+	acpigen_write_len_f(ctx);
+	acpigen_emit_namestring(ctx, name);
+	acpigen_emit_byte(ctx, flags);
+}
+
+/* Method (name, nargs, NotSerialized) */
+void acpigen_write_method(struct acpi_ctx *ctx, const char *name, int nargs)
+{
+	acpigen_write_method_(ctx, name, nargs & 7);
+}
+
+/* Method (name, nargs, Serialized) */
+void acpigen_write_method_serialized(struct acpi_ctx *ctx, const char *name,
+				     int nargs)
+{
+	acpigen_write_method_(ctx, name, (nargs & 7) | (1 << 3));
+}
+
+void acpigen_write_sta(struct acpi_ctx *ctx, uint status)
+{
+	/* Method (_STA, 0, NotSerialized) { Return (status) } */
+	acpigen_write_method(ctx, "_STA", 0);
+	acpigen_emit_byte(ctx, RETURN_OP);
+	acpigen_write_byte(ctx, status);
+	acpigen_pop_len(ctx);
+}
+
 /*
  * ToUUID(uuid)
  *
@@ -288,3 +325,49 @@ int acpigen_write_uuid(struct acpi_ctx *ctx, const char *uuid)
 
 	return 0;
 }
+
+/* Sleep (ms) */
+void acpigen_write_sleep(struct acpi_ctx *ctx, u64 sleep_ms)
+{
+	acpigen_emit_ext_op(ctx, SLEEP_OP);
+	acpigen_write_integer(ctx, sleep_ms);
+}
+
+void acpigen_write_store(struct acpi_ctx *ctx)
+{
+	acpigen_emit_byte(ctx, STORE_OP);
+}
+
+/* Or (arg1, arg2, res) */
+void acpigen_write_or(struct acpi_ctx *ctx, u8 arg1, u8 arg2, u8 res)
+{
+	acpigen_emit_byte(ctx, OR_OP);
+	acpigen_emit_byte(ctx, arg1);
+	acpigen_emit_byte(ctx, arg2);
+	acpigen_emit_byte(ctx, res);
+}
+
+/* And (arg1, arg2, res) */
+void acpigen_write_and(struct acpi_ctx *ctx, u8 arg1, u8 arg2, u8 res)
+{
+	acpigen_emit_byte(ctx, AND_OP);
+	acpigen_emit_byte(ctx, arg1);
+	acpigen_emit_byte(ctx, arg2);
+	acpigen_emit_byte(ctx, res);
+}
+
+/* Not (arg, res) */
+void acpigen_write_not(struct acpi_ctx *ctx, u8 arg, u8 res)
+{
+	acpigen_emit_byte(ctx, NOT_OP);
+	acpigen_emit_byte(ctx, arg);
+	acpigen_emit_byte(ctx, res);
+}
+
+/* Store (str, DEBUG) */
+void acpigen_write_debug_string(struct acpi_ctx *ctx, const char *str)
+{
+	acpigen_write_store(ctx);
+	acpigen_write_string(ctx, str);
+	acpigen_emit_ext_op(ctx, DEBUG_OP);
+}
diff --git a/test/dm/acpigen.c b/test/dm/acpigen.c
index db8cad47d8..e059d6f80d 100644
--- a/test/dm/acpigen.c
+++ b/test/dm/acpigen.c
@@ -621,3 +621,78 @@ static int dm_test_acpi_uuid(struct unit_test_state *uts)
 	return 0;
 }
 DM_TEST(dm_test_acpi_uuid, 0);
+
+/* Test writing misc ACPI codes */
+static int dm_test_acpi_misc(struct unit_test_state *uts)
+{
+	struct acpi_ctx *ctx;
+	const int flags = 3;
+	const int nargs = 4;
+	u8 *ptr;
+
+	ut_assertok(alloc_context(&ctx));
+
+	ptr = acpigen_get_current(ctx);
+	acpigen_write_sleep(ctx, TEST_INT64);
+	ut_asserteq_64(TEST_INT64, get_unaligned((u64 *)(ptr + 3)));
+	ptr += 11;
+
+	acpigen_write_store(ctx);
+	ut_asserteq(STORE_OP, *ptr);
+	ptr++;
+
+	acpigen_write_debug_string(ctx, TEST_STRING);
+	ut_asserteq_str(TEST_STRING, (char *)ptr + 2);
+	ptr += 2 +  sizeof(TEST_STRING);
+	ut_asserteq(EXT_OP_PREFIX, ptr[0]);
+	ut_asserteq(DEBUG_OP, ptr[1]);
+	ptr += 2;
+
+	acpigen_write_sta(ctx, flags);
+	ut_asserteq(METHOD_OP, ptr[0]);
+	ut_asserteq(11, get_length(ptr + 1));
+	ut_asserteq_strn("_STA", (char *)ptr + 4);
+	ut_asserteq(0, ptr[8]);
+	ut_asserteq(RETURN_OP, ptr[9]);
+	ut_asserteq(BYTE_PREFIX, ptr[10]);
+	ut_asserteq(flags, ptr[11]);
+	ptr += 12;
+
+	acpigen_write_sleep(ctx, TEST_INT16);
+	ut_asserteq(SLEEP_OP, ptr[1]);
+	ut_asserteq(TEST_INT16, get_unaligned((u16 *)(ptr + 3)));
+	ptr += 5;
+
+	acpigen_write_method_serialized(ctx, "FRED", nargs);
+	ut_asserteq(METHOD_OP, ptr[0]);
+	ut_asserteq_strn("FRED", (char *)ptr + 4);
+	ut_asserteq(1 << 3 | nargs, ptr[8]);
+	ut_asserteq(1, ctx->ltop);	/* method is unfinished */
+
+	ptr += 9;
+	acpigen_write_or(ctx, LOCAL0_OP, LOCAL1_OP, LOCAL2_OP);
+	acpigen_write_and(ctx, LOCAL3_OP, LOCAL4_OP, LOCAL5_OP);
+	acpigen_write_not(ctx, LOCAL6_OP, LOCAL7_OP);
+	ut_asserteq(OR_OP, ptr[0]);
+	ut_asserteq(LOCAL0_OP, ptr[1]);
+	ut_asserteq(LOCAL1_OP, ptr[2]);
+	ut_asserteq(LOCAL2_OP, ptr[3]);
+
+	ptr += 4;
+	ut_asserteq(AND_OP, ptr[0]);
+	ut_asserteq(LOCAL3_OP, ptr[1]);
+	ut_asserteq(LOCAL4_OP, ptr[2]);
+	ut_asserteq(LOCAL5_OP, ptr[3]);
+
+	ptr += 4;
+	ut_asserteq(NOT_OP, ptr[0]);
+	ut_asserteq(LOCAL6_OP, ptr[1]);
+	ut_asserteq(LOCAL7_OP, ptr[2]);
+	ptr += 3;
+	ut_asserteq_ptr(ptr, ctx->current);
+
+	free_context(&ctx);
+
+	return 0;
+}
+DM_TEST(dm_test_acpi_misc, 0);
-- 
2.26.2.303.gf8c07b1a785-goog

  parent reply	other threads:[~2020-04-29  2:21 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-29  2:21 [PATCH v1 00/35] dm: Add programmatic generation of ACPI tables (part B) Simon Glass
2020-04-29  2:21 ` [PATCH v1 01/35] dm: core: Add an ACPI name for the root node Simon Glass
2020-04-30 12:44   ` Antwort: " Wolfgang Wallner
2020-04-29  2:21 ` [PATCH v1 02/35] acpi: Add a function to get a device path and scope Simon Glass
2020-04-29  2:21 ` [PATCH v1 03/35] acpi: Add a way to check device status Simon Glass
2020-04-29  2:21 ` [PATCH v1 04/35] irq: Add a method to convert an interrupt to ACPI Simon Glass
2020-04-29  2:21 ` [PATCH v1 05/35] acpi: Support generation of ACPI code Simon Glass
2020-04-29  2:21 ` [PATCH v1 06/35] acpi: Support generation of interrupt descriptor Simon Glass
2020-04-29  2:21 ` [PATCH v1 07/35] gpio: Add a method to convert a GPIO to ACPI Simon Glass
2020-04-29  2:21 ` [PATCH v1 08/35] acpi: Support string output Simon Glass
2020-04-29  2:21 ` [PATCH v1 09/35] acpi: Support generation of GPIO descriptor Simon Glass
2020-04-29  2:21 ` [PATCH v1 10/35] acpi: Support generation of a GPIO/irq for a device Simon Glass
2020-04-29  2:21 ` [PATCH v1 11/35] acpi: Support generation of I2C descriptor Simon Glass
2020-04-29  2:21 ` [PATCH v1 12/35] acpi: Support generation of SPI descriptor Simon Glass
2020-04-29  2:21 ` [PATCH v1 13/35] acpigen: Support writing a length Simon Glass
2020-04-29  2:21 ` [PATCH v1 14/35] acpigen: Support writing a package Simon Glass
2020-04-29  2:21 ` [PATCH v1 15/35] acpi: Support writing an integer Simon Glass
2020-04-29  2:21 ` [PATCH v1 16/35] acpi: Support writing a string Simon Glass
2020-04-29  2:21 ` [PATCH v1 17/35] acpi: Support writing a name Simon Glass
2020-04-29  2:21 ` [PATCH v1 18/35] acpi: Support writing a UUID Simon Glass
2020-04-29  2:21 ` [PATCH v1 19/35] acpi: Support writing Device Properties objects via _DSD Simon Glass
2020-04-29  2:21 ` [PATCH v1 20/35] acpi: Support writing a GPIO Simon Glass
2020-04-29  2:21 ` [PATCH v1 21/35] acpi: Support copying properties from device tree to ACPI Simon Glass
2020-04-29  2:21 ` Simon Glass [this message]
2020-04-29  2:21 ` [PATCH v1 23/35] acpi: Add support for writing a Power Resource Simon Glass
2020-04-29  2:21 ` [PATCH v1 24/35] acpi: Add support for writing a GPIO power sequence Simon Glass
2020-04-29  2:21 ` [PATCH v1 25/35] acpi: Add support for a generic " Simon Glass
2020-04-29  2:21 ` [PATCH v1 26/35] acpi: Add support for SSDT generation Simon Glass
2020-04-29  2:21 ` [PATCH v1 27/35] x86: acpi: Move MADT down a bit Simon Glass
2020-04-29  2:21 ` [PATCH v1 28/35] acpi: Record the items added to SSDT Simon Glass
2020-04-29  2:21 ` [PATCH v1 29/35] acpi: Support ordering SSDT data by device Simon Glass
2020-04-29  2:21 ` [PATCH v1 30/35] x86: Allow devices to write an SSDT Simon Glass
2020-04-29  2:21 ` [PATCH v1 31/35] acpi: Add support for DSDT generation Simon Glass
2020-04-29  2:21 ` [PATCH v1 32/35] x86: Allow devices to write to DSDT Simon Glass
2020-04-29  2:21 ` [PATCH v1 33/35] pci: Avoid a crash in device_is_on_pci_bus() Simon Glass
2020-04-29  2:21 ` [PATCH v1 34/35] dm: acpi: Enhance acpi_get_name() Simon Glass
2020-04-29  2:21 ` [PATCH v1 35/35] acpi: Add an acpi split command Simon Glass
2020-04-30 13:52 ` Antwort: [PATCH v1 02/35] acpi: Add a function to get a device path and scope Wolfgang Wallner

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=20200429022159.254271-20-sjg@chromium.org \
    --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.