]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
acpi: Support writing a UUID
authorSimon Glass <sjg@chromium.org>
Tue, 7 Jul 2020 19:11:55 +0000 (13:11 -0600)
committerBin Meng <bmeng.cn@gmail.com>
Fri, 17 Jul 2020 06:32:24 +0000 (14:32 +0800)
ACPI supports writing a UUID in a special format. Add a function to handle
this.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Wolfgang Wallner <wolfgang.wallner@br-automation.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
include/acpi/acpigen.h
lib/acpi/acpigen.c
test/dm/acpigen.c

index 24aec7fad6f557c6a6aa12f01b3e98419031ddc4..31fa20a806f3895e9bed06bb47fd6b8f2eddc8b6 100644 (file)
@@ -27,6 +27,7 @@ enum {
        DWORD_PREFIX            = 0x0c,
        STRING_PREFIX           = 0x0d,
        QWORD_PREFIX            = 0x0e,
+       BUFFER_OP               = 0x11,
        PACKAGE_OP              = 0x12,
        DUAL_NAME_PREFIX        = 0x2e,
        MULTI_NAME_PREFIX       = 0x2f,
@@ -190,4 +191,16 @@ void acpigen_emit_namestring(struct acpi_ctx *ctx, const char *namepath);
  * @namepath: Name / path to emit
  */
 void acpigen_write_name(struct acpi_ctx *ctx, const char *namepath);
+
+/**
+ * acpigen_write_uuid() - Write a UUID
+ *
+ * This writes out a UUID in the format used by ACPI, with a BUFFER_OP prefix.
+ *
+ * @ctx: ACPI context pointer
+ * @uuid: UUID to write in the form aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
+ * @return 0 if OK, -EINVAL if the format is incorrect
+ */
+int acpigen_write_uuid(struct acpi_ctx *ctx, const char *uuid);
+
 #endif
index 0a6c1e37c5a84638f8362ac37f1be0be7b602f68..3e8374e65e3c07e2d56a3a277d79b75dfd37dff9 100644 (file)
@@ -11,6 +11,7 @@
 #include <common.h>
 #include <dm.h>
 #include <log.h>
+#include <uuid.h>
 #include <acpi/acpigen.h>
 #include <dm/acpi.h>
 
@@ -249,3 +250,40 @@ void acpigen_write_name(struct acpi_ctx *ctx, const char *namepath)
        acpigen_emit_byte(ctx, NAME_OP);
        acpigen_emit_namestring(ctx, namepath);
 }
+
+/*
+ * ToUUID(uuid)
+ *
+ * ACPI 6.3 Section 19.6.142 table 19-438 defines a special output order for the
+ * bytes that make up a UUID Buffer object:
+ *
+ * UUID byte order for input to this function:
+ *   aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
+ *
+ * UUID byte order output by this function:
+ *   ddccbbaa-ffee-hhgg-iijj-kkllmmnnoopp
+ */
+int acpigen_write_uuid(struct acpi_ctx *ctx, const char *uuid)
+{
+       u8 buf[UUID_BIN_LEN];
+       int ret;
+
+       /* Parse UUID string into bytes */
+       ret = uuid_str_to_bin(uuid, buf, UUID_STR_FORMAT_GUID);
+       if (ret)
+               return log_msg_ret("bad hex", -EINVAL);
+
+       /* BufferOp */
+       acpigen_emit_byte(ctx, BUFFER_OP);
+       acpigen_write_len_f(ctx);
+
+       /* Buffer length in bytes */
+       acpigen_write_word(ctx, UUID_BIN_LEN);
+
+       /* Output UUID in expected order */
+       acpigen_emit_stream(ctx, (char *)buf, UUID_BIN_LEN);
+
+       acpigen_pop_len(ctx);
+
+       return 0;
+}
index adfcf887655114a947fdd24e085c8838d3be8c37..1cdbcf21311fa79de078bbfd2563aad381d6073f 100644 (file)
@@ -598,3 +598,36 @@ static int dm_test_acpi_name(struct unit_test_state *uts)
        return 0;
 }
 DM_TEST(dm_test_acpi_name, 0);
+
+/* Test writing a UUID */
+static int dm_test_acpi_uuid(struct unit_test_state *uts)
+{
+       struct acpi_ctx *ctx;
+       u8 *ptr;
+
+       ut_assertok(alloc_context(&ctx));
+
+       ptr = acpigen_get_current(ctx);
+
+       ut_assertok(acpigen_write_uuid(ctx,
+                                      "dbb8e3e6-5886-4ba6-8795-1319f52a966b"));
+       ut_asserteq(23, acpigen_get_current(ctx) - ptr);
+       ut_asserteq(BUFFER_OP, ptr[0]);
+       ut_asserteq(22, get_length(ptr + 1));
+       ut_asserteq(0xdbb8e3e6, get_unaligned((u32 *)(ptr + 7)));
+       ut_asserteq(0x5886, get_unaligned((u16 *)(ptr + 11)));
+       ut_asserteq(0x4ba6, get_unaligned((u16 *)(ptr + 13)));
+       ut_asserteq(0x9587, get_unaligned((u16 *)(ptr + 15)));
+       ut_asserteq(0x2af51913, get_unaligned((u32 *)(ptr + 17)));
+       ut_asserteq(0x6b96, get_unaligned((u16 *)(ptr + 21)));
+
+       /* Try a bad UUID */
+       ut_asserteq(-EINVAL,
+                   acpigen_write_uuid(ctx,
+                                      "dbb8e3e6-5886-4ba6x8795-1319f52a966b"));
+
+       free_context(&ctx);
+
+       return 0;
+}
+DM_TEST(dm_test_acpi_uuid, 0);