Pull request for efi-2021-10-rc1-3

Documentation:
	provide Makefile documentation

SMBIOS:
	generate BIOS release date based on UEFI version
	improve error handling in SMBIOS table generation

UEFI:
	correct handling of signed capsule if authentication if off
This commit is contained in:
Tom Rini
2021-07-24 16:41:25 -04:00
16 changed files with 1799 additions and 51 deletions

View File

@@ -695,7 +695,7 @@ R: Alexander Graf <agraf@csgraf.de>
S: Maintained S: Maintained
T: git https://source.denx.de/u-boot/custodians/u-boot-efi.git T: git https://source.denx.de/u-boot/custodians/u-boot-efi.git
F: doc/api/efi.rst F: doc/api/efi.rst
F: doc/uefi/* F: doc/develop/uefi/*
F: doc/usage/bootefi.rst F: doc/usage/bootefi.rst
F: drivers/rtc/emul_rtc.c F: drivers/rtc/emul_rtc.c
F: include/capitalization.h F: include/capitalization.h

View File

@@ -1905,7 +1905,6 @@ define filechk_timestamp.h
LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_DATE "%b %d %C%y"'; \ LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_DATE "%b %d %C%y"'; \
LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_TIME "%T"'; \ LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_TIME "%T"'; \
LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_TZ "%z"'; \ LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_TZ "%z"'; \
LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_DMI_DATE "%m/%d/%Y"'; \
LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_BUILD_DATE 0x%Y%m%d'; \ LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_BUILD_DATE 0x%Y%m%d'; \
LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_EPOCH %s'; \ LC_ALL=C $${DATE} -u -d "$${SOURCE_DATE}" +'#define U_BOOT_EPOCH %s'; \
else \ else \
@@ -1915,7 +1914,6 @@ define filechk_timestamp.h
LC_ALL=C date +'#define U_BOOT_DATE "%b %d %C%y"'; \ LC_ALL=C date +'#define U_BOOT_DATE "%b %d %C%y"'; \
LC_ALL=C date +'#define U_BOOT_TIME "%T"'; \ LC_ALL=C date +'#define U_BOOT_TIME "%T"'; \
LC_ALL=C date +'#define U_BOOT_TZ "%z"'; \ LC_ALL=C date +'#define U_BOOT_TZ "%z"'; \
LC_ALL=C date +'#define U_BOOT_DMI_DATE "%m/%d/%Y"'; \
LC_ALL=C date +'#define U_BOOT_BUILD_DATE 0x%Y%m%d'; \ LC_ALL=C date +'#define U_BOOT_BUILD_DATE 0x%Y%m%d'; \
LC_ALL=C date +'#define U_BOOT_EPOCH %s'; \ LC_ALL=C date +'#define U_BOOT_EPOCH %s'; \
fi) fi)

View File

@@ -3,6 +3,8 @@
* Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com> * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
*/ */
#define LOG_CATEGORY LOGC_BOARD
#include <common.h> #include <common.h>
#include <bloblist.h> #include <bloblist.h>
#include <log.h> #include <log.h>
@@ -96,13 +98,20 @@ int write_tables(void)
return log_msg_ret("bloblist", -ENOBUFS); return log_msg_ret("bloblist", -ENOBUFS);
} }
rom_table_end = table->write(rom_table_start); rom_table_end = table->write(rom_table_start);
rom_table_end = ALIGN(rom_table_end, ROM_TABLE_ALIGN); if (!rom_table_end) {
log_err("Can't create configuration table %d\n", i);
return -EINTR;
}
if (IS_ENABLED(CONFIG_SEABIOS)) { if (IS_ENABLED(CONFIG_SEABIOS)) {
table_size = rom_table_end - rom_table_start; table_size = rom_table_end - rom_table_start;
high_table = (u32)(ulong)high_table_malloc(table_size); high_table = (u32)(ulong)high_table_malloc(table_size);
if (high_table) { if (high_table) {
table->write(high_table); if (!table->write(high_table)) {
log_err("Can't create configuration table %d\n",
i);
return -EINTR;
}
cfg_tables[i].start = high_table; cfg_tables[i].start = high_table;
cfg_tables[i].size = table_size; cfg_tables[i].size = table_size;

View File

@@ -11,4 +11,3 @@ Emulation
qemu-ppce500 qemu-ppce500
qemu-riscv qemu-riscv
qemu-x86 qemu-x86
qemu_capsule_update

View File

@@ -3,8 +3,6 @@
Openpiton RISC-V SoC Openpiton RISC-V SoC
==================== ====================
OpenPiton RISC-V SoC
--------------------
OpenPiton is an open source, manycore processor and research platform. It is a OpenPiton is an open source, manycore processor and research platform. It is a
tiled manycore framework scalable from one to 1/2 billion cores. It supports a tiled manycore framework scalable from one to 1/2 billion cores. It supports a
number of ISAs including RISC-V with its P-Mesh cache coherence protocol and number of ISAs including RISC-V with its P-Mesh cache coherence protocol and
@@ -14,21 +12,23 @@ running full-stack Debian linux.
RISC-V Standard Bootflow RISC-V Standard Bootflow
------------------------- -------------------------
Currently, OpenPiton implements RISC-V standard bootflow in the following steps Currently, OpenPiton implements RISC-V standard bootflow in the following steps
mover.S -> u-boot-spl -> opensbi -> u-boot -> Linux mover.S -> u-boot-spl -> opensbi -> u-boot -> Linux
This board supports S-mode u-boot as well as M-mode SPL This board supports S-mode u-boot as well as M-mode SPL
Building OpenPition Building OpenPition
--------------------- ---------------------
If you'd like to build OpenPiton, please go to OpenPiton github repo If you'd like to build OpenPiton, please go to OpenPiton github repo
(at https://github.com/PrincetonUniversity/openpiton) to build from the latest (at https://github.com/PrincetonUniversity/openpiton) to build from the latest
changes changes
Building Images Building Images
--------------------------- ---------------
SPL SPL
--- ~~~
1. Add the RISC-V toolchain to your PATH. 1. Add the RISC-V toolchain to your PATH.
2. Setup ARCH & cross compilation environment variable: 2. Setup ARCH & cross compilation environment variable:
@@ -42,7 +42,7 @@ SPL
4. make 4. make
U-Boot U-Boot
------ ~~~~~~
1. Add the RISC-V toolchain to your PATH. 1. Add the RISC-V toolchain to your PATH.
2. Setup ARCH & cross compilation environment variable: 2. Setup ARCH & cross compilation environment variable:
@@ -55,9 +55,8 @@ U-Boot
3. make openpiton_riscv64_defconfig 3. make openpiton_riscv64_defconfig
4. make 4. make
opensbi opensbi
------- ~~~~~~~
1. Add the RISC-V toolchain to your PATH. 1. Add the RISC-V toolchain to your PATH.
2. Setup ARCH & cross compilation environment variable: 2. Setup ARCH & cross compilation environment variable:
@@ -70,9 +69,9 @@ opensbi
3. Go to OpenSBI directory 3. Go to OpenSBI directory
4. make PLATFORM=fpga/openpiton FW_PAYLOAD_PATH=<path to u-boot-nodtb.bin> 4. make PLATFORM=fpga/openpiton FW_PAYLOAD_PATH=<path to u-boot-nodtb.bin>
Using fw_payload.bin with Linux
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Using fw_payload.bin with linux
-------------------------------
Put the generated fw_payload.bin into the /boot directory on the root filesystem, Put the generated fw_payload.bin into the /boot directory on the root filesystem,
plug in the SD card, then flash the bitstream. Linux will boot automatically. plug in the SD card, then flash the bitstream. Linux will boot automatically.
@@ -81,7 +80,7 @@ Booting
Once you plugin the sdcard and power up, you should see the U-Boot prompt. Once you plugin the sdcard and power up, you should see the U-Boot prompt.
Sample Dual-core Debian boot log from OpenPiton Sample Dual-core Debian boot log from OpenPiton
----------------------------------------------- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: none .. code-block:: none

View File

@@ -13,6 +13,7 @@ Implementation
driver-model/index driver-model/index
global_data global_data
logging logging
makefiles
menus menus
uefi/index uefi/index
version version

1675
doc/develop/makefiles.rst Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -84,7 +84,6 @@ fields. For example::
#define U_BOOT_DATE "Jan 06 2021" (US format only) #define U_BOOT_DATE "Jan 06 2021" (US format only)
#define U_BOOT_TIME "08:50:36" (24-hour clock) #define U_BOOT_TIME "08:50:36" (24-hour clock)
#define U_BOOT_TZ "-0700" (Time zone in hours) #define U_BOOT_TZ "-0700" (Time zone in hours)
#define U_BOOT_DMI_DATE "01/06/2021" (US format only)
#define U_BOOT_BUILD_DATE 0x20210106 (hex yyyymmdd format) #define U_BOOT_BUILD_DATE 0x20210106 (hex yyyymmdd format)
#define U_BOOT_EPOCH 1609948236 #define U_BOOT_EPOCH 1609948236

View File

@@ -20,10 +20,6 @@
#include <charset.h> #include <charset.h>
#include <pe.h> #include <pe.h>
#ifdef CONFIG_EFI_LOADER
#include <asm/setjmp.h>
#endif
/* UEFI spec version 2.8 */ /* UEFI spec version 2.8 */
#define EFI_SPECIFICATION_VERSION (2 << 16 | 80) #define EFI_SPECIFICATION_VERSION (2 << 16 | 80)

View File

@@ -17,6 +17,7 @@
#include <pe.h> #include <pe.h>
struct blk_desc; struct blk_desc;
struct jmp_buf_data;
static inline int guidcmp(const void *g1, const void *g2) static inline int guidcmp(const void *g1, const void *g2)
{ {

View File

@@ -229,8 +229,11 @@ static inline void fill_smbios_header(void *table, int type,
* This writes SMBIOS table at a given address. * This writes SMBIOS table at a given address.
* *
* @addr: start address to write SMBIOS table. If this is not * @addr: start address to write SMBIOS table. If this is not
* 16-byte-aligned then it will be aligned before the table is written * 16-byte-aligned then it will be aligned before the table is
* @return: end address of SMBIOS table (and start address for next entry) * written.
* Return: end address of SMBIOS table (and start address for next entry)
* or NULL in case of an error
*
*/ */
ulong write_smbios_table(ulong addr); ulong write_smbios_table(ulong addr);

View File

@@ -20,6 +20,7 @@
#include <usb.h> #include <usb.h>
#include <watchdog.h> #include <watchdog.h>
#include <asm/global_data.h> #include <asm/global_data.h>
#include <asm/setjmp.h>
#include <linux/libfdt_env.h> #include <linux/libfdt_env.h>
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;

View File

@@ -218,10 +218,40 @@ skip:
return NULL; return NULL;
} }
#if defined(CONFIG_EFI_CAPSULE_AUTHENTICATE) /**
* efi_remove_auth_hdr - remove authentication data from image
* @image: Pointer to pointer to Image
* @image_size: Pointer to Image size
*
* Remove the authentication data from image if possible.
* Update @image and @image_size.
*
* Return: status code
*/
static efi_status_t efi_remove_auth_hdr(void **image, efi_uintn_t *image_size)
{
struct efi_firmware_image_authentication *auth_hdr;
efi_status_t ret = EFI_INVALID_PARAMETER;
const efi_guid_t efi_guid_capsule_root_cert_guid = auth_hdr = (struct efi_firmware_image_authentication *)*image;
EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID; if (*image_size < sizeof(*auth_hdr))
goto out;
if (auth_hdr->auth_info.hdr.dwLength <=
offsetof(struct win_certificate_uefi_guid, cert_data))
goto out;
*image = (uint8_t *)*image + sizeof(auth_hdr->monotonic_count) +
auth_hdr->auth_info.hdr.dwLength;
*image_size = *image_size - auth_hdr->auth_info.hdr.dwLength -
sizeof(auth_hdr->monotonic_count);
ret = EFI_SUCCESS;
out:
return ret;
}
#if defined(CONFIG_EFI_CAPSULE_AUTHENTICATE)
static int efi_get_public_key_data(void **pkey, efi_uintn_t *pkey_len) static int efi_get_public_key_data(void **pkey, efi_uintn_t *pkey_len)
{ {
@@ -257,21 +287,15 @@ efi_status_t efi_capsule_authenticate(const void *capsule, efi_uintn_t capsule_s
if (capsule == NULL || capsule_size == 0) if (capsule == NULL || capsule_size == 0)
goto out; goto out;
*image = (uint8_t *)capsule;
*image_size = capsule_size;
if (efi_remove_auth_hdr(image, image_size) != EFI_SUCCESS)
goto out;
auth_hdr = (struct efi_firmware_image_authentication *)capsule; auth_hdr = (struct efi_firmware_image_authentication *)capsule;
if (capsule_size < sizeof(*auth_hdr))
goto out;
if (auth_hdr->auth_info.hdr.dwLength <=
offsetof(struct win_certificate_uefi_guid, cert_data))
goto out;
if (guidcmp(&auth_hdr->auth_info.cert_type, &efi_guid_cert_type_pkcs7)) if (guidcmp(&auth_hdr->auth_info.cert_type, &efi_guid_cert_type_pkcs7))
goto out; goto out;
*image = (uint8_t *)capsule + sizeof(auth_hdr->monotonic_count) +
auth_hdr->auth_info.hdr.dwLength;
*image_size = capsule_size - auth_hdr->auth_info.hdr.dwLength -
sizeof(auth_hdr->monotonic_count);
memcpy(&monotonic_count, &auth_hdr->monotonic_count, memcpy(&monotonic_count, &auth_hdr->monotonic_count,
sizeof(monotonic_count)); sizeof(monotonic_count));
@@ -351,7 +375,7 @@ static efi_status_t efi_capsule_update_firmware(
{ {
struct efi_firmware_management_capsule_header *capsule; struct efi_firmware_management_capsule_header *capsule;
struct efi_firmware_management_capsule_image_header *image; struct efi_firmware_management_capsule_image_header *image;
size_t capsule_size; size_t capsule_size, image_binary_size;
void *image_binary, *vendor_code; void *image_binary, *vendor_code;
efi_handle_t *handles; efi_handle_t *handles;
efi_uintn_t no_handles; efi_uintn_t no_handles;
@@ -413,13 +437,30 @@ static efi_status_t efi_capsule_update_firmware(
} }
/* do update */ /* do update */
if (IS_ENABLED(CONFIG_EFI_CAPSULE_AUTHENTICATE) &&
!(image->image_capsule_support &
CAPSULE_SUPPORT_AUTHENTICATION)) {
/* no signature */
ret = EFI_SECURITY_VIOLATION;
goto out;
}
image_binary = (void *)image + sizeof(*image); image_binary = (void *)image + sizeof(*image);
vendor_code = image_binary + image->update_image_size; image_binary_size = image->update_image_size;
vendor_code = image_binary + image_binary_size;
if (!IS_ENABLED(CONFIG_EFI_CAPSULE_AUTHENTICATE) &&
(image->image_capsule_support &
CAPSULE_SUPPORT_AUTHENTICATION)) {
ret = efi_remove_auth_hdr(&image_binary,
&image_binary_size);
if (ret != EFI_SUCCESS)
goto out;
}
abort_reason = NULL; abort_reason = NULL;
ret = EFI_CALL(fmp->set_image(fmp, image->update_image_index, ret = EFI_CALL(fmp->set_image(fmp, image->update_image_index,
image_binary, image_binary,
image->update_image_size, image_binary_size,
vendor_code, NULL, vendor_code, NULL,
&abort_reason)); &abort_reason));
if (ret != EFI_SUCCESS) { if (ret != EFI_SUCCESS) {

View File

@@ -5,6 +5,8 @@
* Copyright (c) 2016 Alexander Graf * Copyright (c) 2016 Alexander Graf
*/ */
#define LOG_CATEGORY LOGC_EFI
#include <common.h> #include <common.h>
#include <efi_loader.h> #include <efi_loader.h>
#include <log.h> #include <log.h>
@@ -43,14 +45,13 @@ efi_status_t efi_smbios_register(void)
* Generate SMBIOS tables - we know that efi_allocate_pages() returns * Generate SMBIOS tables - we know that efi_allocate_pages() returns
* a 4k-aligned address, so it is safe to assume that * a 4k-aligned address, so it is safe to assume that
* write_smbios_table() will write the table at that address. * write_smbios_table() will write the table at that address.
*
* Note that on sandbox, efi_allocate_pages() unfortunately returns a
* pointer even though it uses a uint64_t type. Convert it.
*/ */
assert(!(dmi_addr & 0xf)); assert(!(dmi_addr & 0xf));
dmi = (void *)(uintptr_t)dmi_addr; dmi = (void *)(uintptr_t)dmi_addr;
write_smbios_table(map_to_sysmem(dmi)); if (write_smbios_table(map_to_sysmem(dmi)))
/* Install SMBIOS information as configuration table */
/* And expose them to our EFI payload */ return efi_install_configuration_table(&smbios_guid, dmi);
return efi_install_configuration_table(&smbios_guid, dmi); efi_free_pages(dmi_addr, 1);
log_err("Cannot create SMBIOS table\n");
return EFI_SUCCESS;
} }

View File

@@ -8,6 +8,7 @@
#include <common.h> #include <common.h>
#include <dm.h> #include <dm.h>
#include <env.h> #include <env.h>
#include <linux/stringify.h>
#include <mapmem.h> #include <mapmem.h>
#include <smbios.h> #include <smbios.h>
#include <sysinfo.h> #include <sysinfo.h>
@@ -18,6 +19,28 @@
#include <dm/uclass-internal.h> #include <dm/uclass-internal.h>
#endif #endif
/* Safeguard for checking that U_BOOT_VERSION_NUM macros are compatible with U_BOOT_DMI */
#if U_BOOT_VERSION_NUM < 2000 || U_BOOT_VERSION_NUM > 2099 || \
U_BOOT_VERSION_NUM_PATCH < 1 || U_BOOT_VERSION_NUM_PATCH > 12
#error U_BOOT_VERSION_NUM macros are not compatible with DMI, fix U_BOOT_DMI macros
#endif
/*
* U_BOOT_DMI_DATE contains BIOS Release Date in format mm/dd/yyyy.
* BIOS Release Date is calculated from U-Boot version and fixed day 01.
* So for U-Boot version 2021.04 it is calculated as "04/01/2021".
* BIOS Release Date should contain date when code was released
* and not when it was built or compiled.
*/
#if U_BOOT_VERSION_NUM_PATCH < 10
#define U_BOOT_DMI_MONTH "0" __stringify(U_BOOT_VERSION_NUM_PATCH)
#else
#define U_BOOT_DMI_MONTH __stringify(U_BOOT_VERSION_NUM_PATCH)
#endif
#define U_BOOT_DMI_DAY "01"
#define U_BOOT_DMI_YEAR __stringify(U_BOOT_VERSION_NUM)
#define U_BOOT_DMI_DATE U_BOOT_DMI_MONTH "/" U_BOOT_DMI_DAY "/" U_BOOT_DMI_YEAR
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
/** /**
@@ -507,7 +530,8 @@ ulong write_smbios_table(ulong addr)
*/ */
printf("WARNING: SMBIOS table_address overflow %llx\n", printf("WARNING: SMBIOS table_address overflow %llx\n",
(unsigned long long)table_addr); (unsigned long long)table_addr);
table_addr = 0; addr = 0;
goto out;
} }
se->struct_table_address = table_addr; se->struct_table_address = table_addr;
@@ -518,6 +542,7 @@ ulong write_smbios_table(ulong addr)
isize = sizeof(struct smbios_entry) - SMBIOS_INTERMEDIATE_OFFSET; isize = sizeof(struct smbios_entry) - SMBIOS_INTERMEDIATE_OFFSET;
se->intermediate_checksum = table_compute_checksum(istart, isize); 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 smbios_entry));
out:
unmap_sysmem(se); unmap_sysmem(se);
return addr; return addr;

View File

@@ -85,7 +85,7 @@ class TestEfiCapsuleFirmwareFit(object):
# need to run uefi command to initiate capsule handling # need to run uefi command to initiate capsule handling
output = u_boot_console.run_command( output = u_boot_console.run_command(
'env print -e -all Capsule0000') 'env print -e Capsule0000')
output = u_boot_console.run_command_list([ output = u_boot_console.run_command_list([
'host bind 0 %s' % disk_img, 'host bind 0 %s' % disk_img,
@@ -160,7 +160,7 @@ class TestEfiCapsuleFirmwareFit(object):
# need to run uefi command to initiate capsule handling # need to run uefi command to initiate capsule handling
output = u_boot_console.run_command( output = u_boot_console.run_command(
'env print -e -all Capsule0000') 'env print -e Capsule0000')
output = u_boot_console.run_command_list([ output = u_boot_console.run_command_list([
'host bind 0 %s' % disk_img, 'host bind 0 %s' % disk_img,
@@ -227,7 +227,7 @@ class TestEfiCapsuleFirmwareFit(object):
# need to run uefi command to initiate capsule handling # need to run uefi command to initiate capsule handling
output = u_boot_console.run_command( output = u_boot_console.run_command(
'env print -e -all Capsule0000') 'env print -e Capsule0000')
output = u_boot_console.run_command_list(['efidebug capsule esrt']) output = u_boot_console.run_command_list(['efidebug capsule esrt'])