From a3bd8e96185b064cce6bbe2aa9b6e81b59efa486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Tue, 24 May 2022 13:26:55 +0200 Subject: [PATCH] drivers/generic/cbfs-uuid: Add driver to include UUID from CBFS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When system_uuid CBFS file is present and contains the UUID in a string format, the driver will parse it and convert to binary format to populate the SMBIOS type 1 UUID field. TEST=Add UUID file and boot MSI PRO Z690-A DDR4 WIFI and check with dmidecode if the UUID is populated correctly. Signed-off-by: Michał Żygowski Change-Id: I22f22f4e8742716283d2fcaba4894c06cef3a4bf Reviewed-on: https://review.coreboot.org/c/coreboot/+/64639 Reviewed-by: Krystian Hebel Tested-by: build bot (Jenkins) --- Documentation/drivers/cbfs_smbios.md | 65 ++++++++++++++++++++++ Documentation/drivers/index.md | 1 + src/drivers/generic/cbfs-uuid/Kconfig | 6 ++ src/drivers/generic/cbfs-uuid/Makefile.inc | 1 + src/drivers/generic/cbfs-uuid/cbfs-uuid.c | 23 ++++++++ 5 files changed, 96 insertions(+) create mode 100644 Documentation/drivers/cbfs_smbios.md create mode 100644 src/drivers/generic/cbfs-uuid/Kconfig create mode 100644 src/drivers/generic/cbfs-uuid/Makefile.inc create mode 100644 src/drivers/generic/cbfs-uuid/cbfs-uuid.c diff --git a/Documentation/drivers/cbfs_smbios.md b/Documentation/drivers/cbfs_smbios.md new file mode 100644 index 0000000000..54b7ca4179 --- /dev/null +++ b/Documentation/drivers/cbfs_smbios.md @@ -0,0 +1,65 @@ +# CBFS SMBIOS hooks + +The document describes the coreboot options how to make CBFS files populate +platform-unique SMBIOS data. + +## SMBIOS System UUID + +The [DMTF SMBIOS specification] defines a field in the type 1 System +Information Structure called System UUID. It is a 16 bytes value compliant with +[RFC4122] and assumed to be unique per platform. Certain mainboard ports have +SMBIOS hooks to generate the UUID from external data, e.g. Lenovo Thinkpads +(see DRIVER_LENOVO_SERIALS). This driver aims to provide an option to populate +the UUID from CBFS for boards that can't generate the UUID from any source. + +### Usage + +In the coreboot configuration menu (`make menuconfig`) go to `Generic Drivers` +and select an option `System UUID in CBFS`. The Kconfig system will enable +`DRIVERS_GENERIC_CBFS_UUID` and the relevant code parts will be compiled into +coreboot image. + +After the coreboot build for your board completes, use the cbfstool to include +the file containing the UUID: + +```shell +./build/cbfstool build/coreboot.rom add -n system_uuid -t raw -f /path/to/uuid_file.txt +``` + +Where `uuid_file.txt` is the unterminated string representation of the SMBIOS +type 1 UUID, e.g. `4c4c4544-0051-3410-8051-b5c04f375931`. If you use vboot with +1 or 2 RW partitions you will have to specify the RW regions where the file is +going to be added too. By default the RW CBFS partitions are truncated, so the +files would probably not fit, one needs to expand them first. + +```shell +./build/cbfstool build/coreboot.rom expand -r FW_MAIN_A +./build/cbfstool build/coreboot.rom add -n system_uuid -t raw \ + -f /path/to/uuid_file.txt -r FW_MAIN_A +./build/cbfstool build/coreboot.rom truncate -r FW_MAIN_A + +./build/cbfstool build/coreboot.rom expand -r FW_MAIN_B +./build/cbfstool build/coreboot.rom add -n system_uuid -t raw \ + -f /path/to/uuid_file.txt -r FW_MAIN_B +./build/cbfstool build/coreboot.rom truncate -r FW_MAIN_B +``` + +By default cbfstool adds files to COREBOOT region only, so when vboot is +enabled and the platform is booting from RW partition, the file would not be +picked up by the driver. + +One may retrieve the UUID from running system (if it exists) using the +following command: + +```shell +echo -n `sudo dmidecode -s system-uuid` > uuid_file.txt +``` + +The above command ensures the file does not end with whitespaces like LF and/or +CR. The above command will not add any whitespaces. But the driver will handle +situations where up to 2 additional bytes like CR and LF will be included in +the file. Any more than that will make the driver fail to populate UUID in +SMBIOS. + +[DMTF SMBIOS specification]: https://www.dmtf.org/standards/smbios +[RFC4122]: https://www.ietf.org/rfc/rfc4122.txt diff --git a/Documentation/drivers/index.md b/Documentation/drivers/index.md index ac9b0141cb..95c1e312a0 100644 --- a/Documentation/drivers/index.md +++ b/Documentation/drivers/index.md @@ -14,3 +14,4 @@ Some of the drivers currently available include: * [SMMSTOREv2](smmstorev2.md) * [SoundWire](soundwire.md) * [USB4 Retimer](retimer.md) +* [CBFS SMBIOS hooks](cbfs_smbios.md) diff --git a/src/drivers/generic/cbfs-uuid/Kconfig b/src/drivers/generic/cbfs-uuid/Kconfig new file mode 100644 index 0000000000..136c6011b3 --- /dev/null +++ b/src/drivers/generic/cbfs-uuid/Kconfig @@ -0,0 +1,6 @@ +config DRIVERS_GENERIC_CBFS_UUID + bool "System UUID in CBFS" + default n + help + Enable this option to read the SMBIOS system UUID from a + text file located in CBFS. diff --git a/src/drivers/generic/cbfs-uuid/Makefile.inc b/src/drivers/generic/cbfs-uuid/Makefile.inc new file mode 100644 index 0000000000..b1344076dd --- /dev/null +++ b/src/drivers/generic/cbfs-uuid/Makefile.inc @@ -0,0 +1 @@ +ramstage-$(CONFIG_DRIVERS_GENERIC_CBFS_UUID) += cbfs-uuid.c diff --git a/src/drivers/generic/cbfs-uuid/cbfs-uuid.c b/src/drivers/generic/cbfs-uuid/cbfs-uuid.c new file mode 100644 index 0000000000..e657bdd922 --- /dev/null +++ b/src/drivers/generic/cbfs-uuid/cbfs-uuid.c @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include + +void smbios_system_set_uuid(u8 *uuid) +{ + /* Add 3 more bytes: 2 for possible CRLF and third for NULL char */ + char uuid_str[UUID_STRLEN + 3] = {0}; + uint8_t system_uuid[UUID_LEN]; + + size_t uuid_len = cbfs_load("system_uuid", uuid_str, UUID_STRLEN); + + if (uuid_len >= UUID_STRLEN && uuid_len <= UUID_STRLEN + 3) { + /* Cut off any trailing whitespace like CR or LF */ + uuid_str[UUID_STRLEN] = '\0'; + if (!parse_uuid(system_uuid, uuid_str)) + memcpy(uuid, system_uuid, UUID_LEN); + } +}