ACK: [PATCH] dsddump: add utility to dump _DSDD (Device Specific Data)
Colin Ian King
colin.king at canonical.com
Fri Jan 11 18:38:43 UTC 2019
On 09/01/2019 00:44, Alex Hung wrote:
> Buglink: https://bugs.launchpad.net/bugs/1433643
>
> In addition to ACPI spec, this patch also refers to two documents:
>
> - Device Properties UUID For _DSD
> - Hierarchical Data Extension UUID For _DSD
>
> Both documents can be found @ http://uefi.org/acpi
>
> Signed-off-by: Alex Hung <alex.hung at canonical.com>
> ---
> src/Makefile.am | 1 +
> src/acpi/dsddump/dsddump.c | 196 +++++++++++++++++++++++++++++++++++++
> 2 files changed, 197 insertions(+)
> create mode 100644 src/acpi/dsddump/dsddump.c
>
> diff --git a/src/Makefile.am b/src/Makefile.am
> index 52c637dd..8339f306 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -80,6 +80,7 @@ fwts_SOURCES = main.c \
> acpi/dmar/dmar.c \
> acpi/dppt/dppt.c \
> acpi/drtm/drtm.c \
> + acpi/dsddump/dsddump.c \
> acpi/ecdt/ecdt.c \
> acpi/einj/einj.c \
> acpi/erst/erst.c \
> diff --git a/src/acpi/dsddump/dsddump.c b/src/acpi/dsddump/dsddump.c
> new file mode 100644
> index 00000000..611789b3
> --- /dev/null
> +++ b/src/acpi/dsddump/dsddump.c
> @@ -0,0 +1,196 @@
> +/*
> + * Copyright (C) 2019 Canonical
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + */
> +#include "fwts.h"
> +
> +#if defined(FWTS_HAS_ACPI)
> +
> +#include <stdint.h>
> +#include <stdbool.h>
> +#include <unistd.h>
> +#include <stdint.h>
> +#include <inttypes.h>
> +#include "fwts_acpi_object_eval.h"
> +
> +#define DEVICE_PROPERITY_UUID "DAFFD814-6EBA-4D8C-8A91-BC9BBF4AA301"
> +#define HIERARCHICAL_DATA_EXTENSION "DBB8E3E6-5886-4BA6-8795-1319F52A966B"
> +
> +/*
> + * dsddump_init()
> + * initialize ACPI
> + */
> +static int dsddump_init(fwts_framework *fw)
> +{
> + if (fwts_acpi_init(fw) != FWTS_OK) {
> + fwts_log_error(fw, "Cannot initialise ACPI.");
> + return FWTS_ERROR;
> + }
> +
> + return FWTS_OK;
> +}
> +
> +/*
> + * dsddump_deinit
> + * de-intialize ACPI
> + */
> +static int dsddump_deinit(fwts_framework *fw)
> +{
> + return fwts_acpi_deinit(fw);
> +}
> +
> +static void print_package_element(fwts_framework *fw, ACPI_OBJECT *obj)
> +{
> + char full_name[128];
> + ACPI_STATUS status;
> + ACPI_BUFFER buffer;
> +
> + switch (obj->Type) {
> + case ACPI_TYPE_INTEGER:
> + fwts_log_info_verbatim(fw, " Value: 0x%8.8" PRIx64, obj->Integer.Value);
> + break;
> + case ACPI_TYPE_STRING:
> + fwts_log_info_verbatim(fw, " Value: %s", obj->String.Pointer);
> + break;
> + case ACPI_TYPE_LOCAL_REFERENCE:
> + status = AcpiGetName(obj->Reference.Handle, ACPI_FULL_PATHNAME, &buffer);
> + if (ACPI_SUCCESS(status))
> + fwts_log_info_verbatim(fw, " Value: %s", full_name);
> + break;
> + default:
> + fwts_log_info_verbatim(fw, " Value: %s", "Unknown");
> + break;
> + }
> +}
> +
> +static void parse_device_properity(fwts_framework *fw, ACPI_OBJECT *pkg)
> +{
> + uint32_t i;
> +
> + fwts_log_info_verbatim(fw, " Package:");
> + for (i = 0; i < pkg->Package.Count; i++) {
> + ACPI_OBJECT *element = &pkg->Package.Elements[i];
> +
> + fwts_log_info_verbatim(fw, " Key: %s", element->Package.Elements[0].String.Pointer);
> +
> + if (element->Package.Elements[1].Type == ACPI_TYPE_PACKAGE) {
> + ACPI_OBJECT *sub_pkg = &element->Package.Elements[1];
> + uint32_t j;
> +
> + for (j = 0; i < sub_pkg->Package.Count; j++)
> + print_package_element(fw, &sub_pkg->Package.Elements[j]);
> + } else
> + print_package_element(fw, &element->Package.Elements[1]);
> + }
> +}
> +
> +static void parse_hierarchical_data_ext(fwts_framework *fw, ACPI_OBJECT *pkg)
> +{
> + uint32_t i;
> +
> + fwts_log_info_verbatim(fw, " Package:");
> + for (i = 0; i < pkg->Package.Count; i++) {
> + ACPI_OBJECT *element = &pkg->Package.Elements[i]> + fwts_log_info_verbatim(fw, " Key: %s",
element->Package.Elements[0].String.Pointer);
> + print_package_element(fw, &element->Package.Elements[1]);
> + }
> +}
> +
> +static void dsddump_package(
> + fwts_framework *fw,
> + ACPI_OBJECT *uuid,
> + ACPI_OBJECT *pkg)
> +{
> + char guid[37];
> +
> + fwts_guid_buf_to_str(uuid->Buffer.Pointer, guid, sizeof(guid));
> +
> + if (!strncmp(guid, DEVICE_PROPERITY_UUID, sizeof(guid))) {
> + fwts_log_info_verbatim(fw, " Device Properties UUID: %s", guid);
> + parse_device_properity(fw, pkg);
> + } else if (!strncmp(guid, HIERARCHICAL_DATA_EXTENSION, sizeof(guid))) {
> + fwts_log_info_verbatim(fw, " Hierarchical Data Extension UUID: %s", guid);
> + parse_hierarchical_data_ext(fw, pkg);
> + }
> +}
> +
> +static int dsddump_test1(fwts_framework *fw)
> +{
> + const size_t name_len = 4;
> + fwts_list_link *item;
> + fwts_list *objects;
> + bool found = false;
> +
> + if ((objects = fwts_acpi_object_get_names()) == NULL) {
> + fwts_log_info(fw, "Cannot find any ACPI objects");
> + return FWTS_ERROR;
> + }
> +
> + fwts_list_foreach(item, objects) {
> + char *name = fwts_list_data(char *, item);
> + const size_t len = strlen(name);
> +
> + if (!strncmp("_DSD", name + len - name_len, name_len)) {
> + ACPI_OBJECT_LIST arg_list;
> + ACPI_OBJECT *obj;
> + ACPI_BUFFER buf;
> + uint32_t i;
> + int ret;
> +
> + arg_list.Count = 0;
> + arg_list.Pointer = NULL;
> +
> + ret = fwts_acpi_object_evaluate(fw, name, &arg_list, &buf);
> + if ((ACPI_FAILURE(ret) != AE_OK) || (buf.Pointer == NULL))
> + continue;
> +
> + /* Do we have a valid buffer in the package to dump? */
> + obj = buf.Pointer;
> + if ((obj->Type == ACPI_TYPE_PACKAGE) &&
> + (obj->Package.Count) &&
> + (obj->Package.Elements[0].Type == ACPI_TYPE_BUFFER) &&
> + (obj->Package.Elements[0].Buffer.Pointer != NULL) &&
> + (obj->Package.Elements[0].Buffer.Length == 16)) {
> +
> + fwts_log_info_verbatim(fw, "Name: %s", name);
> + for (i = 0; i < obj->Package.Count; i += 2)
> + dsddump_package(fw, &obj->Package.Elements[i], &obj->Package.Elements[i+1]);
> +
> + fwts_log_nl(fw);
> + found = true;
> + }
> + free(buf.Pointer);
> + }
> + }
> +
> + if (!found)
> + fwts_log_info_verbatim(fw, "No _DSD objects found.");
> +
> + return FWTS_OK;
> +}
> +
> +static fwts_framework_minor_test dsddump_tests[] = {
> + { dsddump_test1, "Dump ACPI _DSD (Device Specific Data)." },
> + { NULL, NULL }
> +};
> +
> +static fwts_framework_ops dsddump_ops = {
> + .description = "Dump ACPI _DSD (Device Specific Data).",
> + .init = dsddump_init,
> + .deinit = dsddump_deinit,
> + .minor_tests = dsddump_tests
> +};
> +
> +FWTS_REGISTER("dsddump", &dsddump_ops, FWTS_TEST_ANYTIME, FWTS_FLAG_UTILS)
> +
> +#endif
>
Looks OK to me. Do we have any _DSDD test data - can we add a regression
test for this too?
Thanks
Acked-by: Colin Ian King <colin.king at canonical.com>
More information about the fwts-devel
mailing list