[PATCH 1/2] acpi: Add UEFI ACPI data table test (LP: #1471698)

Ivan Hu ivan.hu at canonical.com
Mon Jul 6 09:17:30 UTC 2015


Add the UEFI ACPI data table which defined in UEFI spec. Appendix O.
Register the test name as uefitable to avoid confusing with other UEFI
catagory and tests.

Signed-off-by: Ivan Hu <ivan.hu at canonical.com>
---
 src/Makefile.am      |   1 +
 src/acpi/uefi/uefi.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 136 insertions(+)
 create mode 100644 src/acpi/uefi/uefi.c

diff --git a/src/Makefile.am b/src/Makefile.am
index 3ee3b4e..3a77196 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -77,6 +77,7 @@ fwts_SOURCES = main.c 				\
 	acpi/tcpa/tcpa.c 			\
 	acpi/srat/srat.c 			\
 	acpi/syntaxcheck/syntaxcheck.c 		\
+	acpi/uefi/uefi.c			\
 	acpi/waet/waet.c			\
 	acpi/wakealarm/wakealarm.c 		\
 	acpi/wmi/wmi.c 				\
diff --git a/src/acpi/uefi/uefi.c b/src/acpi/uefi/uefi.c
new file mode 100644
index 0000000..5a21a16
--- /dev/null
+++ b/src/acpi/uefi/uefi.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2015 Canonical
+ *
+ * Portions of this code original from the Linux-ready Firmware Developer Kit
+ *
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <string.h>
+#include <ctype.h>
+
+static fwts_acpi_table_info *table;
+
+static int uefi_init(fwts_framework *fw)
+{
+	if (fwts_acpi_find_table(fw, "UEFI", 0, &table) != FWTS_OK) {
+		fwts_log_error(fw, "Cannot read ACPI tables.");
+		return FWTS_ERROR;
+	}
+	if (table == NULL || (table && table->length == 0)) {
+		fwts_log_error(fw, "ACPI UEFI table does not exist, skipping test");
+		return FWTS_SKIP;
+	}
+	return FWTS_OK;
+}
+
+/*
+ *  UEFI ACPI DATA Table
+ *  See UEFI specification Apppendix O.
+ */
+static int uefi_test1(fwts_framework *fw)
+{
+	fwts_acpi_table_uefi *uefi = (fwts_acpi_table_uefi *)table->data;
+	bool passed = true;
+	uint32_t i;
+	char guid[37];
+
+	/*
+	 * GUID for SMM Communication ACPI Table
+	 * {0xc68ed8e2, 0x9dc6, 0x4cbd, 0x9d, 0x94, 0xdb, 0x65, 0xac, 0xc5, 0xc3, 0x32}
+	 */
+	static const uint8_t guid_smm[16] = { 0xe2, 0xd8, 0x8e, 0xc6, 0xc6, 0x9d, 0xbd, 0x4c,
+						0x9d, 0x94, 0xdb, 0x65, 0xac, 0xc5, 0xc3, 0x32 };
+
+	/* Enough length for the uefi table? */
+	if (table->length < sizeof(fwts_acpi_table_uefi)) {
+		passed = false;
+		fwts_failed(fw, LOG_LEVEL_HIGH,
+			"UEFITooShort",
+			"UEFI table too short, expecting %zu bytes, "
+			"instead got %zu bytes",
+			sizeof(fwts_acpi_table_uefi), table->length);
+		goto done;
+	}
+
+	fwts_guid_buf_to_str(uefi->uuid, guid, sizeof(guid));
+
+	fwts_log_info_verbatum(fw, "UEFI ACPI Data Table:");
+	fwts_log_info_verbatum(fw, "  Identifier: %s", guid);
+	fwts_log_info_verbatum(fw, "  DataOffset: 0x%4.4" PRIx16, uefi->dataoffset);
+
+	/* Sanity check the dataoffset */
+	if (uefi->dataoffset > table->length) {
+		passed = false;
+		fwts_failed(fw, LOG_LEVEL_HIGH,
+			"UEFIDataOffset",
+			"Invalid UEFI DataOffset, exceed the whole table length "
+			"%zu bytes, instead got %" PRIu16 " offset bytes"
+			, table->length, uefi->dataoffset);
+	}
+
+	/* check the GUID for SMM Communication ACPI table */
+	if (memcmp(uefi->uuid, guid_smm, 16) == 0) {
+		fwts_acpi_table_uefi_smmcomm *uefi_smmcomm = (fwts_acpi_table_uefi_smmcomm *)table->data;
+
+		/* chekc the dataoffset for SMM Comm table */
+		if (uefi_smmcomm->boot.dataoffset != 54) {
+			passed = false;
+			fwts_failed(fw, LOG_LEVEL_HIGH,
+				"UEFIDataOffset",
+				"Invalid UEFI DataOffset for SMM Communication table, "
+				"DataOffset should be 54, instead got %" PRIu16 " offset bytes"
+				, uefi_smmcomm->boot.dataoffset);
+		}
+
+		fwts_log_info_verbatum(fw, "  SW SMI Number: 0x%8.8" PRIx32, uefi_smmcomm->sw_smi_number);
+		fwts_log_info_verbatum(fw, "  Buffer Ptr Address: 0x%16.16" PRIx64, uefi_smmcomm->buf_ptr_addr);
+	} else {
+		/* dump the remaining data */
+		fwts_log_info_verbatum(fw, "  Data:");
+		for (i = 0; i < (table->length - uefi->dataoffset) ; i += 16) {
+			int left = table->length - uefi->dataoffset -i;
+			char buffer[128];
+			fwts_dump_raw_data(buffer,sizeof(buffer), uefi->data + i, i, left > 16 ? 16 : left);
+			fwts_log_info_verbatum(fw, "%s", buffer);
+		}
+	}
+
+done:
+	if (passed)
+		fwts_passed(fw, "No issues found in UEFI table.");
+
+	return FWTS_OK;
+}
+
+static fwts_framework_minor_test uefi_tests[] = {
+	{ uefi_test1, "UEFI Data Table test." },
+	{ NULL, NULL }
+};
+
+static fwts_framework_ops uefi_ops = {
+	.description = "UEFI Data Table test.",
+	.init        = uefi_init,
+	.minor_tests = uefi_tests
+};
+
+FWTS_REGISTER("uefitable", &uefi_ops, FWTS_TEST_ANYTIME, FWTS_FLAG_BATCH | FWTS_FLAG_TEST_ACPI)
-- 
1.9.1




More information about the fwts-devel mailing list