[PATCH] Add utility to dump _PLD (Physical Device Location) information (LP: #1281835)

Colin Ian King colin.king at canonical.com
Wed Feb 26 09:15:38 UTC 2014


On 26/02/14 03:41, IvanHu wrote:
> 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?
> 
This field is indexed by a 3 bit integer, so there needs to be 8 items,
I'll re-send with the spelling mistake fixed.  Thanks for spotting that.

> 
>> +
>> +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