Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

configs/config.protectli_vp2420: bump for Timeout fix #407

Merged
merged 6 commits into from
Oct 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions Documentation/drivers/cbfs_smbios.md
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions Documentation/drivers/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
5 changes: 4 additions & 1 deletion configs/config.protectli_vp2420
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ CONFIG_I2C_TRANSFER_TIMEOUT_US=500000
CONFIG_DRIVERS_EFI_VARIABLE_STORE=y
CONFIG_SMMSTORE_SIZE=0x40000
CONFIG_SPI_FLASH_NO_FAST_READ=y
CONFIG_DRIVERS_GENERIC_CBFS_SERIAL=y
CONFIG_DRIVERS_GENERIC_CBFS_UUID=y
CONFIG_CBFS_MCACHE_RW_PERCENTAGE=50
CONFIG_VBOOT_KEYBLOCK_VERSION=1
CONFIG_VBOOT_KEYBLOCK_PREAMBLE_FLAGS=0x0
Expand All @@ -32,10 +34,11 @@ CONFIG_POST_DEVICE_LPC=y
CONFIG_POST_IO_PORT=0x80
CONFIG_PAYLOAD_EDK2=y
CONFIG_EDK2_REPOSITORY="https://github.com/Dasharo/edk2"
CONFIG_EDK2_TAG_OR_REV="91d01a5e577475894e7cce06d59e392cbbffba22"
CONFIG_EDK2_TAG_OR_REV="896ab6be9623c4a717044b09536257affcccebdf"
CONFIG_EDK2_USE_EDK2_PLATFORMS=y
CONFIG_EDK2_PLATFORMS_REPOSITORY="https://github.com/Dasharo/edk2-platforms"
CONFIG_EDK2_PLATFORMS_TAG_OR_REV="3323ed481d35096fb6a7eae7b49f35eff00f86cf"
CONFIG_EDK2_CBMEM_LOGGING=y
CONFIG_EDK2_FOLLOW_BGRT_SPEC=y
# CONFIG_EDK2_PS2_SUPPORT is not set
CONFIG_EDK2_SD_MMC_TIMEOUT=10
Expand Down
25 changes: 14 additions & 11 deletions src/drivers/efi/efivars.c
Original file line number Diff line number Diff line change
Expand Up @@ -412,12 +412,13 @@ enum cb_err efi_fv_print_options(struct region_device *rdev)
{
enum cb_err ret;
bool auth_format;
struct region_device store_rdev = *rdev;

ret = efi_fv_init(rdev, &auth_format);
ret = efi_fv_init(&store_rdev, &auth_format);
if (ret != CB_SUCCESS)
return ret;

return walk_variables(rdev, auth_format, print_var, NULL);
return walk_variables(&store_rdev, auth_format, print_var, NULL);
}

/*
Expand All @@ -435,8 +436,9 @@ enum cb_err efi_fv_get_option(struct region_device *rdev,
struct efi_find_args args;
bool auth_format;
enum cb_err ret;
struct region_device store_rdev = *rdev;

ret = efi_fv_init(rdev, &auth_format);
ret = efi_fv_init(&store_rdev, &auth_format);
if (ret != CB_SUCCESS)
return ret;

Expand All @@ -445,7 +447,7 @@ enum cb_err efi_fv_get_option(struct region_device *rdev,
args.size = size;
args.data = dest;

return walk_variables(rdev, auth_format, find_and_copy, &args);
return walk_variables(&store_rdev, auth_format, find_and_copy, &args);
}

static enum cb_err write_auth_hdr(struct region_device *rdev, const EFI_GUID *guid,
Expand Down Expand Up @@ -588,13 +590,14 @@ enum cb_err efi_fv_set_option(struct region_device *rdev,
uint32_t size)
{
struct region_device rdev_old;
struct region_device store_rdev = *rdev;
struct efi_find_compare_args args;
bool found_existing;
VARIABLE_HEADER hdr;
bool auth_format;
enum cb_err ret;

ret = efi_fv_init(rdev, &auth_format);
ret = efi_fv_init(&store_rdev, &auth_format);
if (ret != CB_SUCCESS)
return ret;

Expand All @@ -605,7 +608,7 @@ enum cb_err efi_fv_set_option(struct region_device *rdev,
args.match = false;
args.data = data;

ret = walk_variables(rdev, auth_format, find_and_compare, &args);
ret = walk_variables(&store_rdev, auth_format, find_and_compare, &args);
found_existing = ret == CB_SUCCESS;

if (found_existing) {
Expand All @@ -614,17 +617,17 @@ enum cb_err efi_fv_set_option(struct region_device *rdev,
if (args.match)
return CB_SUCCESS;

rdev_old = *rdev;
rdev_old = store_rdev;

/* Mark as to be deleted */
hdr.State = VAR_IN_DELETED_TRANSITION;
if (rdev_writeat(rdev, &hdr.State, offsetof(VARIABLE_HEADER, State),
if (rdev_writeat(&store_rdev, &hdr.State, offsetof(VARIABLE_HEADER, State),
sizeof(hdr.State)) != sizeof(hdr.State))
return CB_EFI_ACCESS_ERROR;
}

/* Walk to end of variable store */
ret = walk_variables(rdev, auth_format, noop, NULL);
ret = walk_variables(&store_rdev, auth_format, noop, NULL);
if (ret != CB_EFI_OPTION_NOT_FOUND)
return ret;

Expand All @@ -636,9 +639,9 @@ enum cb_err efi_fv_set_option(struct region_device *rdev,
*/

if (auth_format)
ret = write_auth_hdr(rdev, guid, name, data, size);
ret = write_auth_hdr(&store_rdev, guid, name, data, size);
else
ret = write_hdr(rdev, guid, name, data, size);
ret = write_hdr(&store_rdev, guid, name, data, size);
if (ret != CB_SUCCESS)
return ret;

Expand Down
33 changes: 33 additions & 0 deletions src/drivers/generic/cbfs-serial/cbfs-serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,41 @@

#include <cbfs.h>
#include <device/device.h>
#include <drivers/efi/efivars.h>
#include <smmstore.h>
#include <smbios.h>
#include <string.h>

#include <Uefi/UefiBaseType.h>

#define MAX_SERIAL_LENGTH 0x100

static bool get_serial_number_from_efivar(char *serial_number)
{
#if CONFIG(DRIVERS_EFI_VARIABLE_STORE)
struct region_device rdev;
enum cb_err ret;
uint32_t size;
const EFI_GUID dasharo_system_features_guid = {
0xd15b327e, 0xff2d, 0x4fc1, { 0xab, 0xf6, 0xc1, 0x2b, 0xd0, 0x8c, 0x13, 0x59 }
};
if (smmstore_lookup_region(&rdev))
return false;

size = MAX_SERIAL_LENGTH;
ret = efi_fv_get_option(&rdev, &dasharo_system_features_guid, "Type2SN", serial_number, &size);
if (ret != CB_SUCCESS || size > MAX_SERIAL_LENGTH)
return false;

serial_number[size] = '\0';

return true;
#else
/* In absence of EFI variables, follow compilation options */
return false;
#endif
}

const char *smbios_mainboard_serial_number(void)
{
static char serial_number[MAX_SERIAL_LENGTH + 1] = {0};
Expand All @@ -20,6 +50,9 @@ const char *smbios_mainboard_serial_number(void)
return serial_number;
}

if (get_serial_number_from_efivar(serial_number))
return serial_number;

strncpy(serial_number, CONFIG_MAINBOARD_SERIAL_NUMBER,
MAX_SERIAL_LENGTH);

Expand Down
6 changes: 6 additions & 0 deletions src/drivers/generic/cbfs-uuid/Kconfig
Original file line number Diff line number Diff line change
@@ -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.
1 change: 1 addition & 0 deletions src/drivers/generic/cbfs-uuid/Makefile.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ramstage-$(CONFIG_DRIVERS_GENERIC_CBFS_UUID) += cbfs-uuid.c
59 changes: 59 additions & 0 deletions src/drivers/generic/cbfs-uuid/cbfs-uuid.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <lib.h>
#include <cbfs.h>
#include <console/console.h>
#include <device/device.h>
#include <drivers/efi/efivars.h>
#include <smmstore.h>
#include <smbios.h>
#include <string.h>
#include <uuid.h>

#include <Uefi/UefiBaseType.h>


static bool get_uuid_from_efivar(uint8_t *uuid)
{
#if CONFIG(DRIVERS_EFI_VARIABLE_STORE)
struct region_device rdev;
enum cb_err ret;
uint32_t size;
const EFI_GUID dasharo_system_features_guid = {
0xd15b327e, 0xff2d, 0x4fc1, { 0xab, 0xf6, 0xc1, 0x2b, 0xd0, 0x8c, 0x13, 0x59 }
};
if (smmstore_lookup_region(&rdev))
return false;

size = UUID_LEN;
ret = efi_fv_get_option(&rdev, &dasharo_system_features_guid, "Type1UUID", uuid, &size);
if (ret != CB_SUCCESS || size != UUID_LEN)
return false;

return true;
#else
/* In absence of EFI variables, follow compilation options */
return false;
#endif
}

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);
return;
}
}

if (get_uuid_from_efivar(system_uuid))
memcpy(uuid, system_uuid, UUID_LEN);
}
2 changes: 1 addition & 1 deletion src/mainboard/protectli/vault_ehl/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ config VBOOT
select VBOOT_NO_TPM
select VBOOT_VBNV_CMOS
select VBOOT_VBNV_CMOS_BACKUP_TO_FLASH
select VBOOT_SEPARATE_VERSTAGE
select HAS_RECOVERY_MRC_CACHE
select VBOOT_ENABLE_CBFS_FALLBACK

config VBOOT_SLOTS_RW_A
default y if VBOOT
Expand Down
Loading