[PATCH 1/2][V2] esrtdump: add dumping for esrt table (LP: #1532103)
Ivan Hu
ivan.hu at canonical.com
Mon Jan 11 07:24:42 UTC 2016
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)
--
1.9.1
More information about the fwts-devel
mailing list