[PATCH] Add utility to dump _PLD (Physical Device Location) information (LP: #1281835)
IvanHu
ivan.hu at canonical.com
Wed Feb 26 03:41:45 UTC 2014
On 02/19/2014 07:33 AM, Colin King wrote:
> From: Colin Ian King <colin.king at canonical.com>
>
> Add human readable _PLD dump util.
>
> Signed-off-by: Colin Ian King <colin.king at canonical.com>
> ---
> src/Makefile.am | 1 +
> src/acpi/plddump/plddump.c | 268 +++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 269 insertions(+)
> create mode 100644 src/acpi/plddump/plddump.c
>
> diff --git a/src/Makefile.am b/src/Makefile.am
> index bd6cf01..d3c1f45 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -43,6 +43,7 @@ fwts_SOURCES = main.c \
> acpi/osilinux/osilinux.c \
> acpi/pcc/pcc.c \
> acpi/powerbutton/powerbutton.c \
> + acpi/plddump/plddump.c \
> acpi/s3/s3.c \
> acpi/s3power/s3power.c \
> acpi/s4/s4.c \
> diff --git a/src/acpi/plddump/plddump.c b/src/acpi/plddump/plddump.c
> new file mode 100644
> index 0000000..843de59
> --- /dev/null
> +++ b/src/acpi/plddump/plddump.c
> @@ -0,0 +1,268 @@
> +/*
> + * Copyright (C) 2014 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.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
> + *
> + */
> +#include "fwts.h"
> +#include <stdint.h>
> +#include <stdbool.h>
> +#include <unistd.h>
> +
> +/* acpica headers */
> +#include "acpi.h"
> +#include "fwts_acpi_object_eval.h"
> +
> +/*
> + * plddump_init()
> + * initialize ACPI
> + */
> +static int plddump_init(fwts_framework *fw)
> +{
> + if (fwts_acpi_init(fw) != FWTS_OK) {
> + fwts_log_error(fw, "Cannot initialise ACPI.");
> + return FWTS_ERROR;
> + }
> +
> + return FWTS_OK;
> +}
> +
> +/*
> + * plddump_deinit
> + * de-intialize ACPI
> + */
> +static int plddump_deinit(fwts_framework *fw)
> +{
> + return fwts_acpi_deinit(fw);
> +}
> +
> +static inline uint64_t get_bit(
> + const uint8_t *data,
> + const uint32_t offset)
> +{
> + return (data[offset / 8] >> (offset % 8)) & 1;
> +}
> +
> +static uint64_t get_bits(
> + const uint8_t *data,
> + const uint32_t offset,
> + const uint32_t nbits)
> +{
> + uint64_t val = 0;
> + uint32_t i;
> +
> + for (i = 0; i < nbits; i++)
> + val |= (get_bit(data, offset + i) << i);
> +
> + return val;
> +}
> +
> +static const char *yesno[] = {
> + "No",
> + "Yes"
> +};
> +
> +static const char *panel_surface[] = {
> + "Top",
> + "Bottom",
> + "Left",
> + "Right",
> + "Front",
> + "Back",
> + "Unknown",
> + "Unknowm"
> +};
Duplicate Unknown(m) here?
> +
> +static const char *vertical_position[] = {
> + "Upper",
> + "Center",
> + "Lower",
> + "Unknown"
> +};
> +
> +static const char *horizontal_position[] = {
> + "Left",
> + "Center",
> + "Right",
> + "Unknown"
> +};
> +
> +static const char *shape[] = {
> + "Round",
> + "Oval",
> + "Square",
> + "Vertical Rectangle",
> + "Horizontal Rectangle",
> + "Veritical Trapezoid",
> + "Horizontal Trapezoid",
> + "Unknown",
> + "Chamfered",
> + "Reserved",
> + "Reserved",
> + "Reserved",
> + "Reserved",
> + "Reserved",
> + "Reserved",
> + "Reserved"
> +};
> +
> +static void plddump_buffer(
> + fwts_framework *fw,
> + const char *name,
> + const void *data,
> + const uint32_t length)
> +{
> + fwts_log_nl(fw);
> + fwts_log_info_verbatum(fw, "Name: %s", name);
> + fwts_log_info_verbatum(fw, " Revision: %" PRIu64,
> + get_bits(data, 0, 7));
> + fwts_log_info_verbatum(fw, " Ignore Color: %" PRIu64 " (%s)",
> + get_bits(data, 7, 1),
> + yesno[get_bits(data, 7, 1)]);
> + if (!get_bits(data, 7, 1)) {
> + fwts_log_info_verbatum(fw, " Red: 0x%2.2" PRIx64,
> + get_bits(data, 8, 8));
> + fwts_log_info_verbatum(fw, " Green: 0x%2.2" PRIx64,
> + get_bits(data, 16, 8));
> + fwts_log_info_verbatum(fw, " Blue: 0x%2.2" PRIx64,
> + get_bits(data, 24, 8));
> + }
> + fwts_log_info_verbatum(fw, " Width: %" PRIu64 " mm",
> + get_bits(data, 32, 16));
> + fwts_log_info_verbatum(fw, " Height: %" PRIu64 " mm",
> + get_bits(data, 48, 16));
> + fwts_log_info_verbatum(fw, " User Visible: %" PRIu64 " (%s)",
> + get_bits(data, 64, 1),
> + yesno[get_bits(data, 64, 1)]);
> + fwts_log_info_verbatum(fw, " Dock: %" PRIu64 " (%s)",
> + get_bits(data, 65, 1),
> + yesno[get_bits(data, 65, 1)]);
> + fwts_log_info_verbatum(fw, " Lid: %" PRIu64 " (%s)",
> + get_bits(data, 66, 1),
> + yesno[get_bits(data, 66, 1)]);
> + fwts_log_info_verbatum(fw, " Panel Surface: %" PRIu64 " (%s)",
> + get_bits(data, 67, 3),
> + panel_surface[get_bits(data, 67, 3)]);
> + if (get_bits(data, 67, 3) < 6) {
> + fwts_log_info_verbatum(fw, " Vertical Position: %" PRIu64 " (%s)",
> + get_bits(data, 70, 2),
> + vertical_position[get_bits(data, 70, 2)]);
> + fwts_log_info_verbatum(fw, " Horizontal Position: %" PRIu64 " (%s)",
> + get_bits(data, 72, 2),
> + horizontal_position[get_bits(data, 72, 2)]);
> + }
> + fwts_log_info_verbatum(fw, " Shape: %" PRIu64 " (%s)",
> + get_bits(data, 74, 4),
> + shape[get_bits(data, 74, 4)]);
> + fwts_log_info_verbatum(fw, " Group Orientation: %" PRIu64,
> + get_bits(data, 78, 1));
> + fwts_log_info_verbatum(fw, " Group Token: %" PRIu64,
> + get_bits(data, 79, 8));
> + fwts_log_info_verbatum(fw, " Group Position: %" PRIu64,
> + get_bits(data, 87, 8));
> + fwts_log_info_verbatum(fw, " Bay: %" PRIu64 " (%s)",
> + get_bits(data, 95, 1),
> + yesno[get_bits(data, 95, 1)]);
> + fwts_log_info_verbatum(fw, " Ejectable: %" PRIu64 " (%s)",
> + get_bits(data, 96, 1),
> + yesno[get_bits(data, 96, 1)]);
> + fwts_log_info_verbatum(fw, " OSPM Ejection Rqd: %" PRIu64 " (%s)",
> + get_bits(data, 97, 1),
> + yesno[get_bits(data, 97, 1)]);
> + fwts_log_info_verbatum(fw, " Cabinet Number: %" PRIu64,
> + get_bits(data, 98, 8));
> + fwts_log_info_verbatum(fw, " Card Cage Number: %" PRIu64,
> + get_bits(data, 106, 8));
> + fwts_log_info_verbatum(fw, " Reference: %" PRIu64 " (%s)",
> + get_bits(data, 114, 1),
> + yesno[get_bits(data, 114, 1)]);
> + fwts_log_info_verbatum(fw, " Rotation: %" PRIu64 " (%" PRIu64 " degrees)",
> + get_bits(data, 115, 3),
> + get_bits(data, 115, 3) * 45);
> + fwts_log_info_verbatum(fw, " Order: %" PRIu64,
> + get_bits(data, 119, 5));
> + if (length >= 20) {
> + fwts_log_info_verbatum(fw, " Vertical Offset: %" PRIu64 " mm",
> + get_bits(data, 128, 16));
> + fwts_log_info_verbatum(fw, " Horizontal Offset: %" PRIu64 " mm",
> + get_bits(data, 144, 16));
> + }
> +}
> +
> +static int plddump_test1(fwts_framework *fw)
> +{
> + fwts_list_link *item;
> + fwts_list *objects;
> + const size_t name_len = 4;
> + 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("_PLD", name + len - name_len, name_len)) {
> + ACPI_OBJECT_LIST arg_list;
> + ACPI_BUFFER buf;
> + ACPI_OBJECT *obj;
> + 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)) {
> + plddump_buffer(fw,
> + name,
> + obj->Package.Elements[0].Buffer.Pointer,
> + obj->Package.Elements[0].Buffer.Length);
> + found = true;
> + }
> + free(buf.Pointer);
> + }
> + }
> +
> + if (!found)
> + fwts_log_info_verbatum(fw, "No _PLD objects found.");
> +
> + return FWTS_OK;
> +}
> +
> +static fwts_framework_minor_test plddump_tests[] = {
> + { plddump_test1, "Dump ACPI _PLD (Physical Device Location)." },
> + { NULL, NULL }
> +};
> +
> +static fwts_framework_ops plddump_ops = {
> + .description = "Dump ACPI _PLD (Physical Device Location).",
> + .init = plddump_init,
> + .deinit = plddump_deinit,
> + .minor_tests = plddump_tests
> +};
> +
> +FWTS_REGISTER("plddump", &plddump_ops, FWTS_TEST_ANYTIME, FWTS_FLAG_UTILS);
>
More information about the fwts-devel
mailing list