acpi: Support writing a UUID

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>
This commit is contained in:
Simon Glass 2020-07-07 13:11:55 -06:00 committed by Bin Meng
parent 7aed90d44c
commit 29df845204
3 changed files with 84 additions and 0 deletions

View 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

View 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;
}

View 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);