aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/Kconfig6
-rw-r--r--cmd/Makefile1
-rw-r--r--cmd/smbios.c191
-rw-r--r--configs/qemu_arm64_defconfig1
-rw-r--r--configs/sandbox_defconfig1
-rw-r--r--doc/usage/cmd/smbios.rst93
-rw-r--r--doc/usage/index.rst1
-rw-r--r--drivers/misc/qfw_smbios.c2
-rw-r--r--include/efi_loader.h1
-rw-r--r--include/smbios.h5
-rw-r--r--lib/efi_loader/efi_tcg2.c19
-rw-r--r--lib/efi_selftest/efi_selftest_tcg2.c97
-rw-r--r--lib/smbios-parser.c9
-rw-r--r--lib/uuid.c4
-rw-r--r--test/py/tests/test_smbios.py41
15 files changed, 407 insertions, 65 deletions
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 06aae30df3..a86b570517 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -232,6 +232,12 @@ config CMD_SBI
help
Display information about the SBI implementation.
+config CMD_SMBIOS
+ bool "smbios"
+ depends on SMBIOS
+ help
+ Display the SMBIOS information.
+
endmenu
menu "Boot commands"
diff --git a/cmd/Makefile b/cmd/Makefile
index e2a2b16ab2..87133cc27a 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -168,6 +168,7 @@ obj-$(CONFIG_CMD_SETEXPR) += setexpr.o
obj-$(CONFIG_CMD_SETEXPR_FMT) += printf.o
obj-$(CONFIG_CMD_SPI) += spi.o
obj-$(CONFIG_CMD_STRINGS) += strings.o
+obj-$(CONFIG_CMD_SMBIOS) += smbios.o
obj-$(CONFIG_CMD_SMC) += smccc.o
obj-$(CONFIG_CMD_SYSBOOT) += sysboot.o
obj-$(CONFIG_CMD_STACKPROTECTOR_TEST) += stackprot_test.o
diff --git a/cmd/smbios.c b/cmd/smbios.c
new file mode 100644
index 0000000000..feebf930b7
--- /dev/null
+++ b/cmd/smbios.c
@@ -0,0 +1,191 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * The 'smbios' command displays information from the SMBIOS table.
+ *
+ * Copyright (c) 2023, Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
+ */
+
+#include <command.h>
+#include <hexdump.h>
+#include <mapmem.h>
+#include <smbios.h>
+#include <tables_csum.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * smbios_get_string() - get SMBIOS string from table
+ *
+ * @table: SMBIOS table
+ * @index: index of the string
+ * Return: address of string, may point to empty string
+ */
+static const char *smbios_get_string(void *table, int index)
+{
+ const char *str = (char *)table +
+ ((struct smbios_header *)table)->length;
+
+ if (!*str)
+ ++str;
+ for (--index; *str && index; --index)
+ str += strlen(str) + 1;
+
+ return str;
+}
+
+static struct smbios_header *next_table(struct smbios_header *table)
+{
+ const char *str;
+
+ if (table->type == SMBIOS_END_OF_TABLE)
+ return NULL;
+
+ str = smbios_get_string(table, 0);
+ return (struct smbios_header *)(++str);
+}
+
+static void smbios_print_generic(struct smbios_header *table)
+{
+ char *str = (char *)table + table->length;
+
+ if (CONFIG_IS_ENABLED(HEXDUMP)) {
+ printf("Header and Data:\n");
+ print_hex_dump("\t", DUMP_PREFIX_OFFSET, 16, 1,
+ table, table->length, false);
+ }
+ if (*str) {
+ printf("Strings:\n");
+ for (int index = 1; *str; ++index) {
+ printf("\tString %u: %s\n", index, str);
+ str += strlen(str) + 1;
+ }
+ }
+}
+
+void smbios_print_str(const char *label, void *table, u8 index)
+{
+ printf("\t%s: %s\n", label, smbios_get_string(table, index));
+}
+
+static void smbios_print_type1(struct smbios_type1 *table)
+{
+ printf("System Information\n");
+ smbios_print_str("Manufacturer", table, table->manufacturer);
+ smbios_print_str("Product Name", table, table->product_name);
+ smbios_print_str("Version", table, table->version);
+ smbios_print_str("Serial Number", table, table->serial_number);
+ if (table->length >= 0x19) {
+ printf("\tUUID %pUl\n", table->uuid);
+ smbios_print_str("Wake Up Type", table, table->serial_number);
+ }
+ if (table->length >= 0x1b) {
+ smbios_print_str("Serial Number", table, table->serial_number);
+ smbios_print_str("SKU Number", table, table->sku_number);
+ }
+}
+
+static void smbios_print_type2(struct smbios_type2 *table)
+{
+ u16 *handle;
+
+ printf("Base Board Information\n");
+ smbios_print_str("Manufacturer", table, table->manufacturer);
+ smbios_print_str("Product Name", table, table->product_name);
+ smbios_print_str("Version", table, table->version);
+ smbios_print_str("Serial Number", table, table->serial_number);
+ smbios_print_str("Asset Tag", table, table->asset_tag_number);
+ printf("\tFeature Flags: 0x%2x\n", table->feature_flags);
+ smbios_print_str("Chassis Location", table, table->chassis_location);
+ printf("\tChassis Handle: 0x%2x\n", table->chassis_handle);
+ smbios_print_str("Board Type", table, table->board_type);
+ printf("\tContained Object Handles: ");
+ handle = (void *)table->eos;
+ for (int i = 0; i < table->number_contained_objects; ++i)
+ printf("0x%04x ", handle[i]);
+ printf("\n");
+}
+
+static void smbios_print_type127(struct smbios_type127 *table)
+{
+ printf("End Of Table\n");
+}
+
+static int do_smbios(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ ulong addr;
+ void *entry;
+ u32 size;
+ char version[12];
+ struct smbios_header *table;
+ static const char smbios_sig[] = "_SM_";
+ static const char smbios3_sig[] = "_SM3_";
+ size_t count = 0;
+ u32 max_struct_size;
+
+ addr = gd_smbios_start();
+ if (!addr) {
+ log_warning("SMBIOS not available\n");
+ return CMD_RET_FAILURE;
+ }
+ entry = map_sysmem(addr, 0);
+ if (!memcmp(entry, smbios3_sig, sizeof(smbios3_sig) - 1)) {
+ struct smbios3_entry *entry3 = entry;
+
+ table = (void *)(uintptr_t)entry3->struct_table_address;
+ snprintf(version, sizeof(version), "%d.%d.%d",
+ entry3->major_ver, entry3->minor_ver, entry3->doc_rev);
+ table = (void *)(uintptr_t)entry3->struct_table_address;
+ size = entry3->length;
+ max_struct_size = entry3->max_struct_size;
+ } else if (!memcmp(entry, smbios_sig, sizeof(smbios_sig) - 1)) {
+ struct smbios_entry *entry2 = entry;
+
+ snprintf(version, sizeof(version), "%d.%d",
+ entry2->major_ver, entry2->minor_ver);
+ table = (void *)(uintptr_t)entry2->struct_table_address;
+ size = entry2->length;
+ max_struct_size = entry2->max_struct_size;
+ } else {
+ log_err("Unknown SMBIOS anchor format\n");
+ return CMD_RET_FAILURE;
+ }
+ if (table_compute_checksum(entry, size)) {
+ log_err("Invalid anchor checksum\n");
+ return CMD_RET_FAILURE;
+ }
+ printf("SMBIOS %s present.\n", version);
+
+ for (struct smbios_header *pos = table; pos; pos = next_table(pos))
+ ++count;
+ printf("%zd structures occupying %d bytes\n", count, max_struct_size);
+ printf("Table at 0x%llx\n", (unsigned long long)map_to_sysmem(table));
+
+ for (struct smbios_header *pos = table; pos; pos = next_table(pos)) {
+ printf("\nHandle 0x%04x, DMI type %d, %d bytes at 0x%llx\n",
+ pos->handle, pos->type, pos->length,
+ (unsigned long long)map_to_sysmem(pos));
+ switch (pos->type) {
+ case 1:
+ smbios_print_type1((struct smbios_type1 *)pos);
+ break;
+ case 2:
+ smbios_print_type2((struct smbios_type2 *)pos);
+ break;
+ case 127:
+ smbios_print_type127((struct smbios_type127 *)pos);
+ break;
+ default:
+ smbios_print_generic(pos);
+ break;
+ }
+ }
+
+ return CMD_RET_SUCCESS;
+}
+
+U_BOOT_LONGHELP(smbios, "- display SMBIOS information");
+
+U_BOOT_CMD(smbios, 1, 0, do_smbios, "display SMBIOS information",
+ smbios_help_text);
diff --git a/configs/qemu_arm64_defconfig b/configs/qemu_arm64_defconfig
index 5100e193be..631d8866f6 100644
--- a/configs/qemu_arm64_defconfig
+++ b/configs/qemu_arm64_defconfig
@@ -27,6 +27,7 @@ CONFIG_USE_PREBOOT=y
# CONFIG_DISPLAY_CPUINFO is not set
# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_PCI_INIT_R=y
+CONFIG_CMD_SMBIOS=y
CONFIG_CMD_BOOTZ=y
CONFIG_CMD_BOOTEFI_SELFTEST=y
CONFIG_CMD_NVEDIT_EFI=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index ea4e2c1ec3..a8df5e635b 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -42,6 +42,7 @@ CONFIG_STACKPROTECTOR=y
CONFIG_ANDROID_AB=y
CONFIG_CMD_CPU=y
CONFIG_CMD_LICENSE=y
+CONFIG_CMD_SMBIOS=y
CONFIG_CMD_BOOTM_PRE_LOAD=y
CONFIG_CMD_BOOTZ=y
CONFIG_BOOTM_OPENRTOS=y
diff --git a/doc/usage/cmd/smbios.rst b/doc/usage/cmd/smbios.rst
new file mode 100644
index 0000000000..1ffd706d7d
--- /dev/null
+++ b/doc/usage/cmd/smbios.rst
@@ -0,0 +1,93 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later:
+
+smbios command
+==============
+
+Synopsis
+--------
+
+::
+
+ smbios
+
+Description
+-----------
+
+The smbios command displays information from the SMBIOS tables.
+
+Examples
+--------
+
+The example below shows an example output of the smbios command.
+
+::
+
+ => smbios
+ SMBIOS 2.8.0 present.
+ 8 structures occupying 81 bytes
+ Table at 0x6d35018
+
+ Handle 0x0100, DMI type 1, 27 bytes at 0x6d35018
+ System Information
+ Manufacturer: QEMU
+ Product Name: Standard PC (i440FX + PIIX, 1996)
+ Version: pc-i440fx-2.5
+ Serial Number:
+ UUID 00000000-0000-0000-0000-000000000000
+ Wake Up Type:
+ Serial Number:
+ SKU Number:
+
+ Handle 0x0300, DMI type 3, 22 bytes at 0x6d35069
+ Header and Data:
+ 00000000: 03 16 00 03 01 01 02 00 00 03 03 03 02 00 00 00
+ 00000010: 00 00 00 00 00 00
+ Strings:
+ String 1: QEMU
+ String 2: pc-i440fx-2.5
+
+ Handle 0x0400, DMI type 4, 42 bytes at 0x6d35093
+ Header and Data:
+ 00000000: 04 2a 00 04 01 03 01 02 63 06 00 00 fd ab 81 07
+ 00000010: 03 00 00 00 d0 07 d0 07 41 01 ff ff ff ff ff ff
+ 00000020: 00 00 00 01 01 01 02 00 01 00
+ Strings:
+ String 1: CPU 0
+ String 2: QEMU
+ String 3: pc-i440fx-2.5
+
+ Handle 0x1000, DMI type 16, 23 bytes at 0x6d350d7
+ Header and Data:
+ 00000000: 10 17 00 10 01 03 06 00 00 02 00 fe ff 01 00 00
+ 00000010: 00 00 00 00 00 00 00
+
+ Handle 0x1100, DMI type 17, 40 bytes at 0x6d350f0
+ Header and Data:
+ 00000000: 11 28 00 11 00 10 fe ff ff ff ff ff 80 00 09 00
+ 00000010: 01 00 07 02 00 00 00 02 00 00 00 00 00 00 00 00
+ 00000020: 00 00 00 00 00 00 00 00
+ Strings:
+ String 1: DIMM 0
+ String 2: QEMU
+
+ Handle 0x1300, DMI type 19, 31 bytes at 0x6d35125
+ Header and Data:
+ 00000000: 13 1f 00 13 00 00 00 00 ff ff 01 00 00 10 01 00
+ 00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+ Handle 0x2000, DMI type 32, 11 bytes at 0x6d35146
+ Header and Data:
+ 00000000: 20 0b 00 20 00 00 00 00 00 00 00
+
+ Handle 0x7f00, DMI type 127, 4 bytes at 0x6d35153
+ End Of Table
+
+Configuration
+-------------
+
+The command is only available if CONFIG_CMD_SMBIOS=y.
+
+Return value
+------------
+
+The return value $? is 0 (true) on success, 1 (false) otherwise.
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index c171c029b8..0d174eefaa 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -103,6 +103,7 @@ Shell commands
cmd/size
cmd/sleep
cmd/sm
+ cmd/smbios
cmd/sound
cmd/source
cmd/temperature
diff --git a/drivers/misc/qfw_smbios.c b/drivers/misc/qfw_smbios.c
index 9019345783..a898cb4eea 100644
--- a/drivers/misc/qfw_smbios.c
+++ b/drivers/misc/qfw_smbios.c
@@ -90,7 +90,7 @@ static int qfw_parse_smbios_anchor(struct udevice *dev,
entry->length = sizeof(struct smbios3_entry);
entry->major_ver = entry2->major_ver;
entry->minor_ver = entry2->minor_ver;
- entry->max_struct_size = entry2->max_struct_size;
+ entry->max_struct_size = entry2->struct_table_length;
} else {
ret = -ENOENT;
goto out;
diff --git a/include/efi_loader.h b/include/efi_loader.h
index d5fca2fa5e..5c5af4f7fd 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -340,6 +340,7 @@ extern const efi_guid_t efi_guid_firmware_management_protocol;
extern const efi_guid_t efi_esrt_guid;
/* GUID of the SMBIOS table */
extern const efi_guid_t smbios_guid;
+extern const efi_guid_t smbios3_guid;
/*GUID of console */
extern const efi_guid_t efi_guid_text_input_protocol;
extern const efi_guid_t efi_guid_text_output_protocol;
diff --git a/include/smbios.h b/include/smbios.h
index b507b9d9d7..e2b7f69584 100644
--- a/include/smbios.h
+++ b/include/smbios.h
@@ -139,6 +139,7 @@ struct __packed smbios_type2 {
u8 chassis_location;
u16 chassis_handle;
u8 board_type;
+ u8 number_contained_objects;
char eos[SMBIOS_STRUCT_EOS_BYTES];
};
@@ -326,10 +327,10 @@ int smbios_update_version_full(void *smbios_tab, const char *version);
* This function clear the device dependent parameters such as
* serial number for the measurement.
*
- * @entry: pointer to a struct smbios_entry
+ * @entry: pointer to a struct smbios3_entry
* @header: pointer to a struct smbios_header
*/
-void smbios_prepare_measurement(const struct smbios_entry *entry,
+void smbios_prepare_measurement(const struct smbios3_entry *entry,
struct smbios_header *header);
#endif /* _SMBIOS_H_ */
diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c
index 8db35d0b3c..85562c50a1 100644
--- a/lib/efi_loader/efi_tcg2.c
+++ b/lib/efi_loader/efi_tcg2.c
@@ -1075,12 +1075,17 @@ error:
*/
static efi_status_t
tcg2_measure_smbios(struct udevice *dev,
- const struct smbios_entry *entry)
+ const struct smbios3_entry *entry)
{
efi_status_t ret;
struct smbios_header *smbios_copy;
struct smbios_handoff_table_pointers2 *event = NULL;
u32 event_size;
+ const char smbios3_anchor[] = "_SM3_";
+
+ /* We only support SMBIOS 3.0 Entry Point structure */
+ if (memcmp(entry->anchor, smbios3_anchor, sizeof(smbios3_anchor) - 1))
+ return EFI_UNSUPPORTED;
/*
* TCG PC Client PFP Spec says
@@ -1093,7 +1098,7 @@ tcg2_measure_smbios(struct udevice *dev,
*/
event_size = sizeof(struct smbios_handoff_table_pointers2) +
FIELD_SIZEOF(struct efi_configuration_table, guid) +
- entry->struct_table_length;
+ entry->max_struct_size;
event = calloc(1, event_size);
if (!event) {
ret = EFI_OUT_OF_RESOURCES;
@@ -1104,11 +1109,11 @@ tcg2_measure_smbios(struct udevice *dev,
memcpy(event->table_description, SMBIOS_HANDOFF_TABLE_DESC,
sizeof(SMBIOS_HANDOFF_TABLE_DESC));
put_unaligned_le64(1, &event->number_of_tables);
- guidcpy(&event->table_entry[0].guid, &smbios_guid);
+ guidcpy(&event->table_entry[0].guid, &smbios3_guid);
smbios_copy = (struct smbios_header *)((uintptr_t)&event->table_entry[0].table);
memcpy(&event->table_entry[0].table,
(void *)((uintptr_t)entry->struct_table_address),
- entry->struct_table_length);
+ entry->max_struct_size);
smbios_prepare_measurement(entry, smbios_copy);
@@ -1133,7 +1138,7 @@ static void *find_smbios_table(void)
u32 i;
for (i = 0; i < systab.nr_tables; i++) {
- if (!guidcmp(&smbios_guid, &systab.tables[i].guid))
+ if (!guidcmp(&smbios3_guid, &systab.tables[i].guid))
return systab.tables[i].table;
}
@@ -1360,7 +1365,7 @@ efi_status_t efi_tcg2_measure_efi_app_invocation(struct efi_loaded_image_obj *ha
u32 pcr_index;
struct udevice *dev;
u32 event = 0;
- struct smbios_entry *entry;
+ struct smbios3_entry *entry;
if (!is_tcg2_protocol_installed())
return EFI_SUCCESS;
@@ -1382,7 +1387,7 @@ efi_status_t efi_tcg2_measure_efi_app_invocation(struct efi_loaded_image_obj *ha
if (ret != EFI_SUCCESS)
goto out;
- entry = (struct smbios_entry *)find_smbios_table();
+ entry = (struct smbios3_entry *)find_smbios_table();
if (entry) {
ret = tcg2_measure_smbios(dev, entry);
if (ret != EFI_SUCCESS)
diff --git a/lib/efi_selftest/efi_selftest_tcg2.c b/lib/efi_selftest/efi_selftest_tcg2.c
index 67a886efaa..fb8b997653 100644
--- a/lib/efi_selftest/efi_selftest_tcg2.c
+++ b/lib/efi_selftest/efi_selftest_tcg2.c
@@ -126,41 +126,40 @@ static u8 boot_order[] = {0x02, 0x10, 0x00, 0x10, 0x01, 0x10};
static void *orig_smbios_table;
static u64 dmi_addr = U32_MAX;
-#define SMBIOS_ENTRY_HEADER_SIZE 0x20
+#define SMBIOS3_ENTRY_HEADER_SIZE 0x18
/* smbios table for the measurement test */
-static u8 smbios_table_test[] = {
-0x5f, 0x53, 0x4d, 0x5f, 0x2c, 0x1f, 0x03, 0x00, 0x54, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x5f, 0x44, 0x4d, 0x49, 0x5f, 0xe4, 0x5c, 0x01,
-0x20, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
-0x01, 0x02, 0x00, 0x00, 0x03, 0x00, 0x80, 0x08, 0x01, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x0c, 0x15, 0x0a, 0xff, 0xff, 0x55, 0x2d, 0x42, 0x6f,
-0x6f, 0x74, 0x00, 0x32, 0x30, 0x32, 0x31, 0x2e, 0x31, 0x30, 0x2d, 0x72,
-0x63, 0x34, 0x2d, 0x30, 0x30, 0x30, 0x30, 0x35, 0x2d, 0x67, 0x37, 0x32,
-0x37, 0x63, 0x33, 0x66, 0x33, 0x32, 0x35, 0x39, 0x2d, 0x64, 0x69, 0x72,
-0x74, 0x79, 0x00, 0x31, 0x30, 0x2f, 0x30, 0x31, 0x2f, 0x32, 0x30, 0x32,
-0x31, 0x00, 0x00, 0x01, 0x1b, 0x01, 0x00, 0x01, 0x02, 0x00, 0x03, 0x31,
-0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77,
-0x6e, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x50, 0x72,
-0x6f, 0x64, 0x75, 0x63, 0x74, 0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
-0x37, 0x38, 0x00, 0x00, 0x02, 0x0e, 0x02, 0x00, 0x01, 0x02, 0x00, 0x04,
-0x03, 0x01, 0x01, 0x01, 0x00, 0x0a, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77,
-0x6e, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x50, 0x72,
-0x6f, 0x64, 0x75, 0x63, 0x74, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
-0x33, 0x33, 0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00,
-0x00, 0x03, 0x15, 0x03, 0x00, 0x01, 0x03, 0x00, 0x02, 0x03, 0x03, 0x03,
-0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x6e,
-0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
-0x37, 0x38, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00,
-0x00, 0x04, 0x30, 0x04, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x01, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x03, 0x04,
-0x04, 0x04, 0x08, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x08, 0x00, 0x01,
-0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x31, 0x32, 0x33,
-0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
-0x33, 0x33, 0x00, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x00,
-0x00, 0x20, 0x0b, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x7f, 0x04, 0x06, 0x00, 0x00, 0x00
+static u8 smbios3_table_test[] = {
+0x5f, 0x53, 0x4d, 0x33, 0x5f, 0x00, 0x18, 0x03, 0x07, 0x00, 0x01, 0x00,
+0x5c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x03, 0x00, 0x80, 0x08,
+0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x15, 0x0a, 0xff, 0xff,
+0x55, 0x2d, 0x42, 0x6f, 0x6f, 0x74, 0x00, 0x32, 0x30, 0x32, 0x31, 0x2e,
+0x31, 0x30, 0x2d, 0x72, 0x63, 0x34, 0x2d, 0x30, 0x30, 0x30, 0x30, 0x35,
+0x2d, 0x67, 0x37, 0x32, 0x37, 0x63, 0x33, 0x66, 0x33, 0x32, 0x35, 0x39,
+0x2d, 0x64, 0x69, 0x72, 0x74, 0x79, 0x00, 0x31, 0x30, 0x2f, 0x30, 0x31,
+0x2f, 0x32, 0x30, 0x32, 0x31, 0x00, 0x00, 0x01, 0x1b, 0x01, 0x00, 0x01,
+0x02, 0x00, 0x03, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x55, 0x6e,
+0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77,
+0x6e, 0x20, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x00, 0x31, 0x32,
+0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x00, 0x02, 0x0e, 0x02, 0x00,
+0x01, 0x02, 0x00, 0x04, 0x03, 0x01, 0x01, 0x01, 0x00, 0x0a, 0x55, 0x6e,
+0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77,
+0x6e, 0x20, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x00, 0x33, 0x33,
+0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x31, 0x32, 0x33, 0x34, 0x35,
+0x36, 0x37, 0x38, 0x00, 0x00, 0x03, 0x15, 0x03, 0x00, 0x01, 0x03, 0x00,
+0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x31, 0x32,
+0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33,
+0x33, 0x33, 0x33, 0x00, 0x00, 0x04, 0x30, 0x04, 0x00, 0x00, 0x03, 0x02,
+0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0x02, 0x03, 0x04, 0x04, 0x04, 0x08, 0x00, 0x00, 0x02, 0x00, 0x08,
+0x00, 0x08, 0x00, 0x01, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e,
+0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x33, 0x33,
+0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x35, 0x35, 0x35, 0x35, 0x35,
+0x35, 0x35, 0x35, 0x00, 0x00, 0x20, 0x0b, 0x05, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x04, 0x06, 0x00, 0x00, 0x00
};
#define IDX_ARRAY_SZ 3 /* support 24 PCRs */
@@ -179,10 +178,10 @@ static u8 expected_pcrs[EFI_TCG2_MAX_PCR_INDEX + 1][TPM2_SHA256_DIGEST_SIZE] = {
0x7b, 0xb9, 0xfe, 0xa1, 0xcd, 0x64, 0x49, 0xdd,
0xed, 0xe2, 0x65, 0x82, 0xc5, 0x3e, 0xf4, 0xc4},
- {0xf5, 0x79, 0xf3, 0x20, 0x62, 0x6e, 0x8b, 0x58,
- 0x62, 0xa3, 0x4e, 0x2f, 0xb7, 0x10, 0xac, 0x34,
- 0x4e, 0x68, 0x94, 0x37, 0x87, 0x29, 0xc4, 0xbe,
- 0xa3, 0xc4, 0xd9, 0x14, 0x2b, 0x66, 0x79, 0x9b},
+ {0x75, 0xb5, 0x91, 0x54, 0x12, 0xa8, 0xa4, 0x25,
+ 0x73, 0x79, 0xa7, 0x47, 0xd9, 0x32, 0x54, 0x78,
+ 0x9a, 0x80, 0x3f, 0xa8, 0x34, 0xfe, 0xd2, 0xae,
+ 0x76, 0xd3, 0x16, 0x4a, 0xb2, 0x03, 0xac, 0xe6},
{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea,
0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d,
@@ -543,7 +542,7 @@ static void *find_smbios_table(const struct efi_system_table *systable)
u32 i;
for (i = 0; i < systable->nr_tables; i++) {
- if (!guidcmp(&smbios_guid, &systable->tables[i].guid))
+ if (!guidcmp(&smbios3_guid, &systable->tables[i].guid))
return systable->tables[i].table;
}
@@ -558,14 +557,12 @@ static void *find_smbios_table(const struct efi_system_table *systable)
*/
static efi_status_t setup_smbios_table(const struct efi_system_table *systable)
{
- struct smbios_entry *se;
+ struct smbios3_entry *se;
efi_status_t ret;
/* Map within the low 32 bits, to allow for 32bit SMBIOS tables */
void *dmi;
- char *istart;
- int isize;
- if (sizeof(smbios_table_test) > EFI_PAGE_SIZE)
+ if (sizeof(smbios3_table_test) > EFI_PAGE_SIZE)
return EFI_OUT_OF_RESOURCES;
orig_smbios_table = find_smbios_table(systable);
@@ -586,19 +583,15 @@ static efi_status_t setup_smbios_table(const struct efi_system_table *systable)
dmi = (void *)(uintptr_t)dmi_addr;
se = dmi;
- boottime->copy_mem(se, smbios_table_test, sizeof(smbios_table_test));
+ boottime->copy_mem(se, smbios3_table_test, sizeof(smbios3_table_test));
/* update smbios table start address */
- se->struct_table_address = (uintptr_t)((u8 *)dmi + SMBIOS_ENTRY_HEADER_SIZE);
+ se->struct_table_address = (uintptr_t)((u8 *)dmi + SMBIOS3_ENTRY_HEADER_SIZE);
- /* calculate checksums */
- istart = (char *)se + SMBIOS_INTERMEDIATE_OFFSET;
- isize = sizeof(struct smbios_entry) - SMBIOS_INTERMEDIATE_OFFSET;
- se->intermediate_checksum = table_compute_checksum(istart, isize);
- se->checksum = table_compute_checksum(se, sizeof(struct smbios_entry));
+ se->checksum = table_compute_checksum(se, sizeof(struct smbios3_entry));
/* Install SMBIOS information as configuration table */
- ret = boottime->install_configuration_table(&smbios_guid, dmi);
+ ret = boottime->install_configuration_table(&smbios3_guid, dmi);
if (ret != EFI_SUCCESS) {
efi_st_error("Cannot install SMBIOS table\n");
boottime->free_pages(dmi_addr, 1);
@@ -992,7 +985,7 @@ static int efi_st_tcg2_teardown(void)
* If orig_smbios_table is NULL, calling install_configuration_table()
* removes dummy SMBIOS table form systab.
*/
- r = boottime->install_configuration_table(&smbios_guid, orig_smbios_table);
+ r = boottime->install_configuration_table(&smbios3_guid, orig_smbios_table);
if (r != EFI_SUCCESS) {
efi_st_error("Failed to restore SMBOIS table\n");
return EFI_ST_FAILURE;
diff --git a/lib/smbios-parser.c b/lib/smbios-parser.c
index ac9a367a87..f48d743657 100644
--- a/lib/smbios-parser.c
+++ b/lib/smbios-parser.c
@@ -223,21 +223,24 @@ static void clear_smbios_table(struct smbios_header *header,
}
}
-void smbios_prepare_measurement(const struct smbios_entry *entry,
+void smbios_prepare_measurement(const struct smbios3_entry *entry,
struct smbios_header *smbios_copy)
{
u32 i, j;
+ void *table_end;
struct smbios_header *header;
+ table_end = (void *)((u8 *)smbios_copy + entry->max_struct_size);
+
for (i = 0; i < ARRAY_SIZE(smbios_filter_tables); i++) {
header = smbios_copy;
- for (j = 0; j < entry->struct_count; j++) {
+ for (j = 0; (void *)header < table_end; j++) {
if (header->type == smbios_filter_tables[i].type)
break;
header = get_next_header(header);
}
- if (j >= entry->struct_count)
+ if ((void *)header >= table_end)
continue;
clear_smbios_table(header,
diff --git a/lib/uuid.c b/lib/uuid.c
index 0be22bc05f..2d7d99535e 100644
--- a/lib/uuid.c
+++ b/lib/uuid.c
@@ -177,6 +177,10 @@ static const struct {
SMBIOS_TABLE_GUID,
},
{
+ "SMBIOS3 table",
+ SMBIOS3_TABLE_GUID,
+ },
+ {
"Runtime properties",
EFI_RT_PROPERTIES_TABLE_GUID,
},
diff --git a/test/py/tests/test_smbios.py b/test/py/tests/test_smbios.py
new file mode 100644
index 0000000000..82b0b68983
--- /dev/null
+++ b/test/py/tests/test_smbios.py
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+"""Test smbios command"""
+
+import pytest
+
+@pytest.mark.buildconfigspec('cmd_smbios')
+@pytest.mark.notbuildconfigspec('qfw_smbios')
+@pytest.mark.notbuildconfigspec('sandbox')
+def test_cmd_smbios(u_boot_console):
+ """Run the smbios command"""
+ output = u_boot_console.run_command('smbios')
+ assert 'DMI type 127,' in output
+
+@pytest.mark.buildconfigspec('cmd_smbios')
+@pytest.mark.buildconfigspec('qfw_smbios')
+@pytest.mark.notbuildconfigspec('sandbox')
+# TODO:
+# QEMU v8.2.0 lacks SMBIOS support for RISC-V
+# Once support is available in our Docker image we can remove the constraint.
+@pytest.mark.notbuildconfigspec('riscv')
+def test_cmd_smbios_qemu(u_boot_console):
+ """Run the smbios command on QEMU"""
+ output = u_boot_console.run_command('smbios')
+ assert 'DMI type 1,' in output
+ assert 'Manufacturer: QEMU' in output
+ assert 'DMI type 127,' in output
+
+@pytest.mark.buildconfigspec('cmd_smbios')
+@pytest.mark.buildconfigspec('sandbox')
+def test_cmd_smbios_sandbox(u_boot_console):
+ """Run the smbios command on the sandbox"""
+ output = u_boot_console.run_command('smbios')
+ assert 'DMI type 0,' in output
+ assert 'String 1: U-Boot' in output
+ assert 'DMI type 1,' in output
+ assert 'Manufacturer: sandbox' in output
+ assert 'DMI type 2,' in output
+ assert 'DMI type 3,' in output
+ assert 'DMI type 4,' in output
+ assert 'DMI type 127,' in output