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