ACK: [PATCH 1/2][V2] esrtdump: add dumping for esrt table (LP: #1532103)
Alex Hung
alex.hung at canonical.com
Tue Jan 12 02:07:27 UTC 2016
On 2016-01-11 03:24 PM, Ivan Hu wrote:
> EFI System Resource Table (ESRT) provides an optional mechanism for identifying
> device and system firmware resources for the purposes of targeting firmware
> updates to those resources, which was defined on UEFI spec. 2.5, chapter 22.3.
> Add dumping for this UEFI resoure table.
>
> Signed-off-by: Ivan Hu <ivan.hu at canonical.com>
> ---
> src/Makefile.am | 3 +-
> src/lib/include/fwts_uefi.h | 14 +++
> src/uefi/esrtdump/esrtdump.c | 207 +++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 223 insertions(+), 1 deletion(-)
> create mode 100644 src/uefi/esrtdump/esrtdump.c
>
> diff --git a/src/Makefile.am b/src/Makefile.am
> index f257a7f..2de2585 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -129,7 +129,8 @@ fwts_SOURCES = main.c \
> uefi/securebootcert/securebootcert.c \
> uefi/uefivarinfo/uefivarinfo.c \
> uefi/uefibootpath/uefibootpath.c \
> - uefi/uefirtauthvar/uefirtauthvar.c
> + uefi/uefirtauthvar/uefirtauthvar.c \
> + uefi/esrtdump/esrtdump.c
>
> fwts_LDFLAGS = -lm `pkg-config --libs glib-2.0 gio-2.0`
>
> diff --git a/src/lib/include/fwts_uefi.h b/src/lib/include/fwts_uefi.h
> index 7919006..1a6b20b 100644
> --- a/src/lib/include/fwts_uefi.h
> +++ b/src/lib/include/fwts_uefi.h
> @@ -97,6 +97,20 @@ enum {
> #define EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED 0x0000000000000008
> #define EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED 0x0000000000000010
>
> +#define ESRT_FW_TYPE_UNKNOWN 0x00000000
> +#define ESRT_FW_TYPE_SYSTEMFIRMWARE 0x00000001
> +#define ESRT_FW_TYPE_DEVICEFIRMWARE 0x00000002
> +#define ESRT_FW_TYPE_UEFIDRIVER 0x00000003
> +
> +#define LAST_ATTEMPT_STATUS_SUCCESS 0x00000000
> +#define LAST_ATTEMPT_STATUS_ERR_UNSUCCESSFUL 0x00000001
> +#define LAST_ATTEMPT_STATUS_ERR_INSUFFICIENT_RESOURCES 0x00000002
> +#define LAST_ATTEMPT_STATUS_ERR_INCORRECT_VERSION 0x00000003
> +#define LAST_ATTEMPT_STATUS_ERR_INVALID_FORMAT 0x00000004
> +#define LAST_ATTEMPT_STATUS_ERR_AUTH_ERROR 0x00000005
> +#define LAST_ATTEMPT_STATUS_ERR_PWR_EVT_AC 0x00000006
> +#define LAST_ATTEMPT_STATUS_ERR_PWR_EVT_BATT 0x00000007
> +
> #define EFI_CERT_SHA256_GUID \
> { 0xc1c41626, 0x504c, 0x4092, { 0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28 }}
>
> diff --git a/src/uefi/esrtdump/esrtdump.c b/src/uefi/esrtdump/esrtdump.c
> new file mode 100644
> index 0000000..c42e6a1
> --- /dev/null
> +++ b/src/uefi/esrtdump/esrtdump.c
> @@ -0,0 +1,207 @@
> +/*
> + * Copyright (C) 2016 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 <sys/types.h>
> +#include <dirent.h>
> +
> +#include "fwts.h"
> +#include "fwts_uefi.h"
> +
> +#define FWTS_ESRT_DIR_PATH "/sys/firmware/efi/esrt/entries"
> +#define FWTS_ESRT_RES_COUNT_PATH "/sys/firmware/efi/esrt/fw_resource_count"
> +#define FWTS_ESRT_RES_COUNT_MAX_PATH "/sys/firmware/efi/esrt/fw_resource_count_max"
> +#define FWTS_ESRT_RES_VERSION_PATH "/sys/firmware/efi/esrt/fw_resource_version"
> +
> +static int esrtdump_init(fwts_framework *fw)
> +{
> + if (fwts_firmware_detect() != FWTS_FIRMWARE_UEFI) {
> + fwts_log_info(fw, "Cannot detect any UEFI firmware. Aborted.");
> + return FWTS_ABORTED;
> + }
> + return FWTS_OK;
> +}
> +
> +static int get_entries_info(fwts_framework *fw)
> +{
> + DIR *dir;
> + struct dirent *entry;
> +
> + if (!(dir = opendir(FWTS_ESRT_DIR_PATH))) {
> + fwts_log_error(fw, "Cannot open directory %s", FWTS_ESRT_DIR_PATH);
> + return FWTS_ERROR;
> + }
> +
> + do {
> + entry = readdir(dir);
> + if (entry && strstr(entry->d_name, "entry")) {
> + char path[PATH_MAX];
> + char *str, *str_info;
> + int count = -1;
> +
> + fwts_log_nl(fw);
> + fwts_log_info_verbatum(fw, "%s", entry->d_name);
> +
> + snprintf(path, sizeof(path), FWTS_ESRT_DIR_PATH "/%s/fw_class", entry->d_name);
> + if ((str = fwts_get(path)) == NULL) {
> + fwts_log_error(fw, "Failed to get FwClass");
> + } else {
> + fwts_log_info_verbatum(fw, " FwClass: %s", str);
> + free(str);
> + }
> +
> + snprintf(path, sizeof(path), FWTS_ESRT_DIR_PATH "/%s/fw_type", entry->d_name);
> + if ((fwts_get_int(path, &count)) != FWTS_OK) {
> + fwts_log_error(fw, "Failed to get FwType");
> + } else {
> + switch (count) {
> + case ESRT_FW_TYPE_UNKNOWN:
> + str_info = "(Unknown)";
> + break;
> + case ESRT_FW_TYPE_SYSTEMFIRMWARE:
> + str_info = "(System Firmware)";
> + break;
> + case ESRT_FW_TYPE_DEVICEFIRMWARE:
> + str_info = "(Device Firmware)";
> + break;
> + case ESRT_FW_TYPE_UEFIDRIVER:
> + str_info = "(UEFI Driver)";
> + break;
> + default:
> + str_info = "";
> + break;
> + }
> + fwts_log_info_verbatum(fw, " FwType: %d %s", count, str_info);
> + }
> +
> + snprintf(path, sizeof(path), FWTS_ESRT_DIR_PATH "/%s/fw_version", entry->d_name);
> + if ((str = fwts_get(path)) == NULL) {
> + fwts_log_error(fw, "Failed to get FwVersion");
> + } else {
> + fwts_log_info_verbatum(fw, " FwVersion: %s", str);
> + free(str);
> + }
> +
> + snprintf(path, sizeof(path), FWTS_ESRT_DIR_PATH "/%s/lowest_supported_fw_version", entry->d_name);
> + if ((str = fwts_get(path)) == NULL) {
> + fwts_log_error(fw, "Failed to get LowestSupportedFwVersion");
> + } else {
> + fwts_log_info_verbatum(fw, " LowestSupportedFwVersion: %s", str);
> + free(str);
> + }
> +
> + snprintf(path, sizeof(path), FWTS_ESRT_DIR_PATH "/%s/capsule_flags", entry->d_name);
> + if ((str = fwts_get(path)) == NULL) {
> + fwts_log_error(fw, "Failed to get CapsuleFlags");
> + } else {
> + fwts_log_info_verbatum(fw, " CapsuleFlags: %s", str);
> + free(str);
> + }
> +
> + snprintf(path, sizeof(path), FWTS_ESRT_DIR_PATH "/%s/last_attempt_version", entry->d_name);
> + if ((str = fwts_get(path)) == NULL) {
> + fwts_log_error(fw, "Failed to get LastAttemptVersion");
> + } else {
> + fwts_log_info_verbatum(fw, " LastAttemptVersion: %s", str);
> + free(str);
> + }
> +
> + snprintf(path, sizeof(path), FWTS_ESRT_DIR_PATH "/%s/last_attempt_status", entry->d_name);
> + if ((fwts_get_int(path, &count)) != FWTS_OK) {
> + fwts_log_error(fw, "Failed to get LastAttemptStatus");
> + } else {
> + switch (count) {
> + case LAST_ATTEMPT_STATUS_SUCCESS:
> + str_info = "(Success)";
> + break;
> + case LAST_ATTEMPT_STATUS_ERR_UNSUCCESSFUL:
> + str_info = "(Unsuccessful)";
> + break;
> + case LAST_ATTEMPT_STATUS_ERR_INSUFFICIENT_RESOURCES:
> + str_info = "(Insufficient Resources)";
> + break;
> + case LAST_ATTEMPT_STATUS_ERR_INCORRECT_VERSION:
> + str_info = "(Incorrect Version)";
> + break;
> + case LAST_ATTEMPT_STATUS_ERR_INVALID_FORMAT:
> + str_info = "(Invalid Format)";
> + break;
> + case LAST_ATTEMPT_STATUS_ERR_AUTH_ERROR:
> + str_info = "(Auth Error)";
> + break;
> + case LAST_ATTEMPT_STATUS_ERR_PWR_EVT_AC:
> + str_info = "(PWR EVT AC)";
> + break;
> + case LAST_ATTEMPT_STATUS_ERR_PWR_EVT_BATT:
> + str_info = "(PWR EVT BATT)";
> + break;
> + default:
> + str_info = "";
> + break;
> + }
> + fwts_log_info_verbatum(fw, " LastAttemptStatus: %d %s", count, str_info);
> + }
> + }
> + } while (entry);
> +
> + closedir(dir);
> + return FWTS_OK;
> +}
> +
> +static int esrtdump_test1(fwts_framework *fw)
> +{
> + char *str;
> +
> + if ((str = fwts_get(FWTS_ESRT_RES_COUNT_PATH)) == NULL)
> + fwts_log_error(fw, "Failed to get FwResourceCount");
> + else {
> + fwts_log_info_verbatum(fw, " FwResourceCount: %s", str);
> + free(str);
> + }
> +
> + if ((str = fwts_get(FWTS_ESRT_RES_COUNT_MAX_PATH)) == NULL)
> + fwts_log_error(fw, "Failed to get FwResourceCountMax");
> + else {
> + fwts_log_info_verbatum(fw, " FwResourceCountMax: %s", str);
> + free(str);
> + }
> +
> + if ((str = fwts_get(FWTS_ESRT_RES_VERSION_PATH)) == NULL)
> + fwts_log_error(fw, "Failed to get FwResourceVersion");
> + else {
> + fwts_log_info_verbatum(fw, " FwResourceVersion: %s", str);
> + free(str);
> + }
> +
> + /* find entries */
> + return get_entries_info(fw);
> +
> +}
> +
> +static fwts_framework_minor_test esrtdump_tests[] = {
> + { esrtdump_test1, "Dump ESRT Table." },
> + { NULL, NULL }
> +};
> +
> +static fwts_framework_ops esrtdump_ops = {
> + .description = "Dump ESRT table.",
> + .init = esrtdump_init,
> + .minor_tests = esrtdump_tests
> +};
> +
> +FWTS_REGISTER("esrtdump", &esrtdump_ops, FWTS_TEST_ANYTIME, FWTS_FLAG_UTILS | FWTS_FLAG_ROOT_PRIV)
>
Acked-by: Alex Hung <alex.hung at canonical.com>
More information about the fwts-devel
mailing list