mirror of
https://github.com/smaeul/u-boot.git
synced 2025-10-19 15:18:13 +01:00
Pull request efi-2022-01-rc4-2
UEFI: * correctly handle missing TPM device * prepare for block devices for U-Boot as EFI app -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEbcT5xx8ppvoGt20zxIHbvCwFGsQFAmGzHfAACgkQxIHbvCwF GsQYeA/+LFCXTVOLWtShHc71kMUdjX5tCnm3LrYEnJgc9fmo2zWD+kSbAWV7RIZG WJ1OVkLKw8+O5kvRwW/dxpZVU1fULn/vzVJxoKVM7I48XJ0JbnO9Up3GCl91i+2t h55gQ/bmt5LpOvQIAhVqQKfMhJz1fTZV77ZtKKdDKw6oeDGlL5F3WZ0RRGGhSXLY pLVKRDTm+B7HvSTth052MVjrfpfkivujDfCO+rYgw3pA4M3MdC51J4gpIWJt2SRz q/p3Fc5fU1d47KEJIfDnm6Hv76yZO3aNU6zivQoSfCqDlNYRvbNcWr4VIkvrIn4D eugMO5f0lWRqDAItq0bcslHEqLPygNJopHB190n4rPUuUfIs/Iq/x6WGBi632aYr utMWqpRrEBGMTLWburl/aZi4+Jsd/zTZsqPzDUC5Ok/KmBvrewq//lWRauRd8GXY Ka2hbMX65C9wDabOGLOTE7jDeTQqCNi4/L1Ie3yiZ/Pg83QSYpP+Jt58FyugMMuw hEEdqbH1uzVrhksaBxG1vzgkdR64i01kEt2CyOtcJnfzkkCxc2DAAFVcDq5oLbdT RCKKdP+To9/D+hvvKMQv7cqjumBUYoeFb8yoJK7UvJehrgXaazO/OSiILjTsA3Lq l9CtdorVl0FvLzgqZmoBA1H9ovkJFYswt7vZbY3VXGJuj04mvVI= =jVT6 -----END PGP SIGNATURE----- Merge tag 'efi-2022-01-rc4-2' of https://source.denx.de/u-boot/custodians/u-boot-efi Pull request efi-2022-01-rc4-2 UEFI: * correctly handle missing TPM device * prepare for block devices for U-Boot as EFI app # gpg: Signature made Fri 10 Dec 2021 04:29:20 AM EST # gpg: using RSA key 6DC4F9C71F29A6FA06B76D33C481DBBC2C051AC4 # gpg: Good signature from "Heinrich Schuchardt <xypron.glpk@gmx.de>" [unknown] # gpg: aka "[jpeg image of size 1389]" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 6DC4 F9C7 1F29 A6FA 06B7 6D33 C481 DBBC 2C05 1AC4
This commit is contained in:
commit
a1c01b17c5
@ -713,8 +713,11 @@ W: https://u-boot.readthedocs.io/en/latest/develop/uefi/u-boot_on_efi.html
|
|||||||
F: board/efi/efi-x86_app
|
F: board/efi/efi-x86_app
|
||||||
F: configs/efi-x86_app*
|
F: configs/efi-x86_app*
|
||||||
F: doc/develop/uefi/u-boot_on_efi.rst
|
F: doc/develop/uefi/u-boot_on_efi.rst
|
||||||
|
F: drivers/block/efi-media-uclass.c
|
||||||
|
F: drivers/block/sb_efi_media.c
|
||||||
F: lib/efi/efi_app.c
|
F: lib/efi/efi_app.c
|
||||||
F: scripts/build-efi.sh
|
F: scripts/build-efi.sh
|
||||||
|
F: test/dm/efi_media.c
|
||||||
|
|
||||||
EFI PAYLOAD
|
EFI PAYLOAD
|
||||||
M: Heinrich Schuchardt <xypron.glpk@gmx.de>
|
M: Heinrich Schuchardt <xypron.glpk@gmx.de>
|
||||||
|
@ -498,6 +498,10 @@
|
|||||||
compatible = "sandbox,clk-ccf";
|
compatible = "sandbox,clk-ccf";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
efi-media {
|
||||||
|
compatible = "sandbox,efi-media";
|
||||||
|
};
|
||||||
|
|
||||||
eth@10002000 {
|
eth@10002000 {
|
||||||
compatible = "sandbox,eth";
|
compatible = "sandbox,eth";
|
||||||
reg = <0x10002000 0x1000>;
|
reg = <0x10002000 0x1000>;
|
||||||
|
@ -296,8 +296,11 @@ static void print_part_header(const char *type, struct blk_desc *dev_desc)
|
|||||||
case IF_TYPE_VIRTIO:
|
case IF_TYPE_VIRTIO:
|
||||||
puts("VirtIO");
|
puts("VirtIO");
|
||||||
break;
|
break;
|
||||||
|
case IF_TYPE_EFI_MEDIA:
|
||||||
|
puts("EFI");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
puts ("UNKNOWN");
|
puts("UNKNOWN");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
printf (" device %d -- Partition Type: %s\n\n",
|
printf (" device %d -- Partition Type: %s\n\n",
|
||||||
|
@ -620,12 +620,12 @@ EFI_DRIVER_BINDING_PROTOCOL implementation for the UEFI drivers.
|
|||||||
|
|
||||||
A linker created list is used to keep track of the UEFI drivers. To create an
|
A linker created list is used to keep track of the UEFI drivers. To create an
|
||||||
entry in the list the UEFI driver uses the U_BOOT_DRIVER macro specifying
|
entry in the list the UEFI driver uses the U_BOOT_DRIVER macro specifying
|
||||||
UCLASS_EFI as the ID of its uclass, e.g::
|
UCLASS_EFI_LOADER as the ID of its uclass, e.g::
|
||||||
|
|
||||||
/* Identify as UEFI driver */
|
/* Identify as UEFI driver */
|
||||||
U_BOOT_DRIVER(efi_block) = {
|
U_BOOT_DRIVER(efi_block) = {
|
||||||
.name = "EFI block driver",
|
.name = "EFI block driver",
|
||||||
.id = UCLASS_EFI,
|
.id = UCLASS_EFI_LOADER,
|
||||||
.ops = &driver_ops,
|
.ops = &driver_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -651,8 +651,8 @@ UEFI block IO driver
|
|||||||
The UEFI block IO driver supports devices exposing the EFI_BLOCK_IO_PROTOCOL.
|
The UEFI block IO driver supports devices exposing the EFI_BLOCK_IO_PROTOCOL.
|
||||||
|
|
||||||
When connected it creates a new U-Boot block IO device with interface type
|
When connected it creates a new U-Boot block IO device with interface type
|
||||||
IF_TYPE_EFI, adds child controllers mapping the partitions, and installs the
|
IF_TYPE_EFI_LOADER, adds child controllers mapping the partitions, and installs
|
||||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL on these. This can be used together with the
|
the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL on these. This can be used together with the
|
||||||
software iPXE to boot from iSCSI network drives [4].
|
software iPXE to boot from iSCSI network drives [4].
|
||||||
|
|
||||||
This driver is only available if U-Boot is configured with::
|
This driver is only available if U-Boot is configured with::
|
||||||
|
@ -102,7 +102,7 @@ Manually Loading and Applying Overlays
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
=> fdtaddr $fdtaddr
|
=> fdt addr $fdtaddr
|
||||||
|
|
||||||
4. Grow it enough so it can encompass all applied overlays
|
4. Grow it enough so it can encompass all applied overlays
|
||||||
|
|
||||||
|
@ -61,6 +61,39 @@ config TPL_BLOCK_CACHE
|
|||||||
help
|
help
|
||||||
This option enables the disk-block cache in TPL
|
This option enables the disk-block cache in TPL
|
||||||
|
|
||||||
|
config EFI_MEDIA
|
||||||
|
bool "Support EFI media drivers"
|
||||||
|
default y if EFI || SANDBOX
|
||||||
|
help
|
||||||
|
Enable this to support media devices on top of UEFI. This enables
|
||||||
|
just the uclass so you also need a specific driver to make this do
|
||||||
|
anything.
|
||||||
|
|
||||||
|
For sandbox there is a test driver.
|
||||||
|
|
||||||
|
if EFI_MEDIA
|
||||||
|
|
||||||
|
config EFI_MEDIA_SANDBOX
|
||||||
|
bool "Sandbox EFI media driver"
|
||||||
|
depends on SANDBOX
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Enables a simple sandbox media driver, used for testing just the
|
||||||
|
EFI_MEDIA uclass. It does not do anything useful, since sandbox does
|
||||||
|
not actually support running on top of UEFI.
|
||||||
|
|
||||||
|
config EFI_MEDIA_BLK
|
||||||
|
bool "EFI media block driver"
|
||||||
|
depends on EFI_APP
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Enables a block driver for providing access to UEFI devices. This
|
||||||
|
allows use of block devices detected by the underlying UEFI
|
||||||
|
implementation. With this it is possible to use filesystems on these
|
||||||
|
devices, for example.
|
||||||
|
|
||||||
|
endif # EFI_MEDIA
|
||||||
|
|
||||||
config IDE
|
config IDE
|
||||||
bool "Support IDE controllers"
|
bool "Support IDE controllers"
|
||||||
select HAVE_BLOCK_DEVICE
|
select HAVE_BLOCK_DEVICE
|
||||||
|
@ -14,3 +14,7 @@ obj-$(CONFIG_IDE) += ide.o
|
|||||||
endif
|
endif
|
||||||
obj-$(CONFIG_SANDBOX) += sandbox.o
|
obj-$(CONFIG_SANDBOX) += sandbox.o
|
||||||
obj-$(CONFIG_$(SPL_TPL_)BLOCK_CACHE) += blkcache.o
|
obj-$(CONFIG_$(SPL_TPL_)BLOCK_CACHE) += blkcache.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_EFI_MEDIA) += efi-media-uclass.o
|
||||||
|
obj-$(CONFIG_EFI_MEDIA_SANDBOX) += sb_efi_media.o
|
||||||
|
obj-$(CONFIG_EFI_MEDIA_BLK) += efi_blk.o
|
||||||
|
@ -28,7 +28,8 @@ static const char *if_typename_str[IF_TYPE_COUNT] = {
|
|||||||
[IF_TYPE_SATA] = "sata",
|
[IF_TYPE_SATA] = "sata",
|
||||||
[IF_TYPE_HOST] = "host",
|
[IF_TYPE_HOST] = "host",
|
||||||
[IF_TYPE_NVME] = "nvme",
|
[IF_TYPE_NVME] = "nvme",
|
||||||
[IF_TYPE_EFI] = "efi",
|
[IF_TYPE_EFI_MEDIA] = "efi",
|
||||||
|
[IF_TYPE_EFI_LOADER] = "efiloader",
|
||||||
[IF_TYPE_VIRTIO] = "virtio",
|
[IF_TYPE_VIRTIO] = "virtio",
|
||||||
[IF_TYPE_PVBLOCK] = "pvblock",
|
[IF_TYPE_PVBLOCK] = "pvblock",
|
||||||
};
|
};
|
||||||
@ -44,7 +45,8 @@ static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = {
|
|||||||
[IF_TYPE_SATA] = UCLASS_AHCI,
|
[IF_TYPE_SATA] = UCLASS_AHCI,
|
||||||
[IF_TYPE_HOST] = UCLASS_ROOT,
|
[IF_TYPE_HOST] = UCLASS_ROOT,
|
||||||
[IF_TYPE_NVME] = UCLASS_NVME,
|
[IF_TYPE_NVME] = UCLASS_NVME,
|
||||||
[IF_TYPE_EFI] = UCLASS_EFI,
|
[IF_TYPE_EFI_MEDIA] = UCLASS_EFI_MEDIA,
|
||||||
|
[IF_TYPE_EFI_LOADER] = UCLASS_EFI_LOADER,
|
||||||
[IF_TYPE_VIRTIO] = UCLASS_VIRTIO,
|
[IF_TYPE_VIRTIO] = UCLASS_VIRTIO,
|
||||||
[IF_TYPE_PVBLOCK] = UCLASS_PVBLOCK,
|
[IF_TYPE_PVBLOCK] = UCLASS_PVBLOCK,
|
||||||
};
|
};
|
||||||
|
15
drivers/block/efi-media-uclass.c
Normal file
15
drivers/block/efi-media-uclass.c
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* Uclass for EFI media devices
|
||||||
|
*
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
|
|
||||||
|
UCLASS_DRIVER(efi_media) = {
|
||||||
|
.id = UCLASS_EFI_MEDIA,
|
||||||
|
.name = "efi_media",
|
||||||
|
.flags = DM_UC_FLAG_SEQ_ALIAS,
|
||||||
|
};
|
115
drivers/block/efi_blk.c
Normal file
115
drivers/block/efi_blk.c
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* Block driver for EFI devices
|
||||||
|
* This supports a media driver of UCLASS_EFI with a child UCLASS_BLK
|
||||||
|
* It allows block-level access to EFI devices made available via EFI boot
|
||||||
|
* services
|
||||||
|
*
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <blk.h>
|
||||||
|
#include <dm.h>
|
||||||
|
#include <efi.h>
|
||||||
|
#include <efi_api.h>
|
||||||
|
|
||||||
|
struct efi_block_plat {
|
||||||
|
struct efi_block_io *blkio;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read from block device
|
||||||
|
*
|
||||||
|
* @dev: device
|
||||||
|
* @blknr: first block to be read
|
||||||
|
* @blkcnt: number of blocks to read
|
||||||
|
* @buffer: output buffer
|
||||||
|
* Return: number of blocks transferred
|
||||||
|
*/
|
||||||
|
static ulong efi_bl_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
|
||||||
|
void *buffer)
|
||||||
|
{
|
||||||
|
struct efi_block_plat *plat = dev_get_plat(dev);
|
||||||
|
struct efi_block_io *io = plat->blkio;
|
||||||
|
efi_status_t ret;
|
||||||
|
|
||||||
|
log_debug("read buf=%p, block=%lx, count=%lx: ", buffer, (ulong)blknr,
|
||||||
|
(ulong)blkcnt);
|
||||||
|
ret = io->read_blocks(io, io->media->media_id, blknr,
|
||||||
|
blkcnt * io->media->block_size, buffer);
|
||||||
|
log_debug("ret=%lx (dec %ld)\n", ret & ~EFI_ERROR_MASK,
|
||||||
|
ret & ~EFI_ERROR_MASK);
|
||||||
|
if (ret)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return blkcnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write to block device
|
||||||
|
*
|
||||||
|
* @dev: device
|
||||||
|
* @blknr: first block to be write
|
||||||
|
* @blkcnt: number of blocks to write
|
||||||
|
* @buffer: input buffer
|
||||||
|
* Return: number of blocks transferred
|
||||||
|
*/
|
||||||
|
static ulong efi_bl_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
|
||||||
|
const void *buffer)
|
||||||
|
{
|
||||||
|
struct efi_block_plat *plat = dev_get_plat(dev);
|
||||||
|
struct efi_block_io *io = plat->blkio;
|
||||||
|
efi_status_t ret;
|
||||||
|
|
||||||
|
log_debug("write buf=%p, block=%lx, count=%lx: ", buffer, (ulong)blknr,
|
||||||
|
(ulong)blkcnt);
|
||||||
|
ret = io->write_blocks(io, io->media->media_id, blknr,
|
||||||
|
blkcnt * io->media->block_size, (void *)buffer);
|
||||||
|
log_debug("ret=%lx (dec %ld)\n", ret & ~EFI_ERROR_MASK,
|
||||||
|
ret & ~EFI_ERROR_MASK);
|
||||||
|
if (ret)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return blkcnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Block device driver operators */
|
||||||
|
static const struct blk_ops efi_blk_ops = {
|
||||||
|
.read = efi_bl_read,
|
||||||
|
.write = efi_bl_write,
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(efi_block) = {
|
||||||
|
.name = "efi_block",
|
||||||
|
.id = UCLASS_BLK,
|
||||||
|
.ops = &efi_blk_ops,
|
||||||
|
.plat_auto = sizeof(struct efi_block_plat),
|
||||||
|
};
|
||||||
|
|
||||||
|
static int efi_media_bind(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct efi_media_plat *plat = dev_get_plat(dev);
|
||||||
|
struct efi_block_plat *blk_plat;
|
||||||
|
struct udevice *blk;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = blk_create_devicef(dev, "efi_block", "blk", IF_TYPE_EFI_MEDIA,
|
||||||
|
dev_seq(dev), plat->blkio->media->block_size,
|
||||||
|
plat->blkio->media->last_block, &blk);
|
||||||
|
if (ret) {
|
||||||
|
debug("Cannot create block device\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
blk_plat = dev_get_plat(blk);
|
||||||
|
blk_plat->blkio = plat->blkio;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(efi_media) = {
|
||||||
|
.name = "efi_media",
|
||||||
|
.id = UCLASS_EFI_MEDIA,
|
||||||
|
.bind = efi_media_bind,
|
||||||
|
.plat_auto = sizeof(struct efi_media_plat),
|
||||||
|
};
|
20
drivers/block/sb_efi_media.c
Normal file
20
drivers/block/sb_efi_media.c
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* EFI_MEDIA driver for sandbox
|
||||||
|
*
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
|
|
||||||
|
static const struct udevice_id sandbox_efi_media_ids[] = {
|
||||||
|
{ .compatible = "sandbox,efi-media" },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(sandbox_efi_media) = {
|
||||||
|
.name = "sandbox_efi_media",
|
||||||
|
.id = UCLASS_EFI_MEDIA,
|
||||||
|
.of_match = sandbox_efi_media_ids,
|
||||||
|
};
|
@ -34,9 +34,10 @@ enum if_type {
|
|||||||
IF_TYPE_SATA,
|
IF_TYPE_SATA,
|
||||||
IF_TYPE_HOST,
|
IF_TYPE_HOST,
|
||||||
IF_TYPE_NVME,
|
IF_TYPE_NVME,
|
||||||
IF_TYPE_EFI,
|
IF_TYPE_EFI_LOADER,
|
||||||
IF_TYPE_PVBLOCK,
|
IF_TYPE_PVBLOCK,
|
||||||
IF_TYPE_VIRTIO,
|
IF_TYPE_VIRTIO,
|
||||||
|
IF_TYPE_EFI_MEDIA,
|
||||||
|
|
||||||
IF_TYPE_COUNT, /* Number of interface types */
|
IF_TYPE_COUNT, /* Number of interface types */
|
||||||
};
|
};
|
||||||
|
@ -48,7 +48,8 @@ enum uclass_id {
|
|||||||
UCLASS_DMA, /* Direct Memory Access */
|
UCLASS_DMA, /* Direct Memory Access */
|
||||||
UCLASS_DSA, /* Distributed (Ethernet) Switch Architecture */
|
UCLASS_DSA, /* Distributed (Ethernet) Switch Architecture */
|
||||||
UCLASS_ECDSA, /* Elliptic curve cryptographic device */
|
UCLASS_ECDSA, /* Elliptic curve cryptographic device */
|
||||||
UCLASS_EFI, /* EFI managed devices */
|
UCLASS_EFI_LOADER, /* Devices created by UEFI applications */
|
||||||
|
UCLASS_EFI_MEDIA, /* Devices provided by UEFI firmware */
|
||||||
UCLASS_ETH, /* Ethernet device */
|
UCLASS_ETH, /* Ethernet device */
|
||||||
UCLASS_ETH_PHY, /* Ethernet PHY device */
|
UCLASS_ETH_PHY, /* Ethernet PHY device */
|
||||||
UCLASS_FIRMWARE, /* Firmware */
|
UCLASS_FIRMWARE, /* Firmware */
|
||||||
|
@ -414,6 +414,17 @@ struct efi_priv {
|
|||||||
void *next_hdr;
|
void *next_hdr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EFI attributes of the udevice handled by efi_media driver
|
||||||
|
*
|
||||||
|
* @handle: handle of the controller on which this driver is installed
|
||||||
|
* @blkio: block io protocol proxied by this driver
|
||||||
|
*/
|
||||||
|
struct efi_media_plat {
|
||||||
|
efi_handle_t handle;
|
||||||
|
struct efi_block_io *blkio;
|
||||||
|
};
|
||||||
|
|
||||||
/* Base address of the EFI image */
|
/* Base address of the EFI image */
|
||||||
extern char image_base[];
|
extern char image_base[];
|
||||||
|
|
||||||
|
@ -525,6 +525,8 @@ efi_status_t efi_disk_register(void);
|
|||||||
efi_status_t efi_rng_register(void);
|
efi_status_t efi_rng_register(void);
|
||||||
/* Called by efi_init_obj_list() to install EFI_TCG2_PROTOCOL */
|
/* Called by efi_init_obj_list() to install EFI_TCG2_PROTOCOL */
|
||||||
efi_status_t efi_tcg2_register(void);
|
efi_status_t efi_tcg2_register(void);
|
||||||
|
/* Called by efi_init_obj_list() to do initial measurement */
|
||||||
|
efi_status_t efi_tcg2_do_initial_measurement(void);
|
||||||
/* measure the pe-coff image, extend PCR and add Event Log */
|
/* measure the pe-coff image, extend PCR and add Event Log */
|
||||||
efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size,
|
efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size,
|
||||||
struct efi_loaded_image_obj *handle,
|
struct efi_loaded_image_obj *handle,
|
||||||
|
@ -147,7 +147,7 @@ static int efi_bl_bind(efi_handle_t handle, void *interface)
|
|||||||
if (!obj)
|
if (!obj)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
devnum = blk_find_max_devnum(IF_TYPE_EFI);
|
devnum = blk_find_max_devnum(IF_TYPE_EFI_LOADER);
|
||||||
if (devnum == -ENODEV)
|
if (devnum == -ENODEV)
|
||||||
devnum = 0;
|
devnum = 0;
|
||||||
else if (devnum < 0)
|
else if (devnum < 0)
|
||||||
@ -159,8 +159,8 @@ static int efi_bl_bind(efi_handle_t handle, void *interface)
|
|||||||
sprintf(name, "efiblk#%d", devnum);
|
sprintf(name, "efiblk#%d", devnum);
|
||||||
|
|
||||||
/* Create driver model udevice for the EFI block io device */
|
/* Create driver model udevice for the EFI block io device */
|
||||||
ret = blk_create_device(parent, "efi_blk", name, IF_TYPE_EFI, devnum,
|
ret = blk_create_device(parent, "efi_blk", name, IF_TYPE_EFI_LOADER,
|
||||||
io->media->block_size,
|
devnum, io->media->block_size,
|
||||||
(lbaint_t)io->media->last_block, &bdev);
|
(lbaint_t)io->media->last_block, &bdev);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
@ -209,6 +209,6 @@ static const struct efi_driver_ops driver_ops = {
|
|||||||
/* Identify as EFI driver */
|
/* Identify as EFI driver */
|
||||||
U_BOOT_DRIVER(efi_block) = {
|
U_BOOT_DRIVER(efi_block) = {
|
||||||
.name = "EFI block driver",
|
.name = "EFI block driver",
|
||||||
.id = UCLASS_EFI,
|
.id = UCLASS_EFI_LOADER,
|
||||||
.ops = &driver_ops,
|
.ops = &driver_ops,
|
||||||
};
|
};
|
||||||
|
@ -308,7 +308,7 @@ efi_status_t efi_driver_init(void)
|
|||||||
log_debug("Initializing EFI driver framework\n");
|
log_debug("Initializing EFI driver framework\n");
|
||||||
for (drv = ll_entry_start(struct driver, driver);
|
for (drv = ll_entry_start(struct driver, driver);
|
||||||
drv < ll_entry_end(struct driver, driver); ++drv) {
|
drv < ll_entry_end(struct driver, driver); ++drv) {
|
||||||
if (drv->id == UCLASS_EFI) {
|
if (drv->id == UCLASS_EFI_LOADER) {
|
||||||
ret = efi_add_driver(drv);
|
ret = efi_add_driver(drv);
|
||||||
if (ret != EFI_SUCCESS) {
|
if (ret != EFI_SUCCESS) {
|
||||||
log_err("Failed to add EFI driver %s\n",
|
log_err("Failed to add EFI driver %s\n",
|
||||||
@ -328,7 +328,7 @@ efi_status_t efi_driver_init(void)
|
|||||||
*/
|
*/
|
||||||
static int efi_uc_init(struct uclass *class)
|
static int efi_uc_init(struct uclass *class)
|
||||||
{
|
{
|
||||||
log_debug("Initializing UCLASS_EFI\n");
|
log_debug("Initializing UCLASS_EFI_LOADER\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,13 +340,13 @@ static int efi_uc_init(struct uclass *class)
|
|||||||
*/
|
*/
|
||||||
static int efi_uc_destroy(struct uclass *class)
|
static int efi_uc_destroy(struct uclass *class)
|
||||||
{
|
{
|
||||||
log_debug("Destroying UCLASS_EFI\n");
|
log_debug("Destroying UCLASS_EFI_LOADER\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
UCLASS_DRIVER(efi) = {
|
UCLASS_DRIVER(efi) = {
|
||||||
.name = "efi",
|
.name = "efi",
|
||||||
.id = UCLASS_EFI,
|
.id = UCLASS_EFI_LOADER,
|
||||||
.init = efi_uc_init,
|
.init = efi_uc_init,
|
||||||
.destroy = efi_uc_destroy,
|
.destroy = efi_uc_destroy,
|
||||||
};
|
};
|
||||||
|
@ -308,6 +308,8 @@ config EFI_TCG2_PROTOCOL
|
|||||||
bool "EFI_TCG2_PROTOCOL support"
|
bool "EFI_TCG2_PROTOCOL support"
|
||||||
default y
|
default y
|
||||||
depends on TPM_V2
|
depends on TPM_V2
|
||||||
|
# Sandbox TPM currently fails on GetCapabilities needed for TCG2
|
||||||
|
depends on !SANDBOX
|
||||||
select SHA1
|
select SHA1
|
||||||
select SHA256
|
select SHA256
|
||||||
select SHA384
|
select SHA384
|
||||||
|
@ -3016,9 +3016,12 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
|
|||||||
if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)) {
|
if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)) {
|
||||||
if (image_obj->image_type == IMAGE_SUBSYSTEM_EFI_APPLICATION) {
|
if (image_obj->image_type == IMAGE_SUBSYSTEM_EFI_APPLICATION) {
|
||||||
ret = efi_tcg2_measure_efi_app_invocation(image_obj);
|
ret = efi_tcg2_measure_efi_app_invocation(image_obj);
|
||||||
if (ret != EFI_SUCCESS) {
|
if (ret == EFI_SECURITY_VIOLATION) {
|
||||||
log_warning("tcg2 measurement fails(0x%lx)\n",
|
/*
|
||||||
ret);
|
* TCG2 Protocol is installed but no TPM device found,
|
||||||
|
* this is not expected.
|
||||||
|
*/
|
||||||
|
return EFI_EXIT(EFI_SECURITY_VIOLATION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -934,9 +934,16 @@ efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle,
|
|||||||
|
|
||||||
#if CONFIG_IS_ENABLED(EFI_TCG2_PROTOCOL)
|
#if CONFIG_IS_ENABLED(EFI_TCG2_PROTOCOL)
|
||||||
/* Measure an PE/COFF image */
|
/* Measure an PE/COFF image */
|
||||||
if (tcg2_measure_pe_image(efi, efi_size, handle,
|
ret = tcg2_measure_pe_image(efi, efi_size, handle, loaded_image_info);
|
||||||
loaded_image_info))
|
if (ret == EFI_SECURITY_VIOLATION) {
|
||||||
log_err("PE image measurement failed\n");
|
/*
|
||||||
|
* TCG2 Protocol is installed but no TPM device found,
|
||||||
|
* this is not expected.
|
||||||
|
*/
|
||||||
|
log_err("PE image measurement failed, no tpm device found\n");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Copy PE headers */
|
/* Copy PE headers */
|
||||||
|
@ -241,6 +241,10 @@ efi_status_t efi_init_obj_list(void)
|
|||||||
ret = efi_tcg2_register();
|
ret = efi_tcg2_register();
|
||||||
if (ret != EFI_SUCCESS)
|
if (ret != EFI_SUCCESS)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
ret = efi_tcg2_do_initial_measurement();
|
||||||
|
if (ret == EFI_SECURITY_VIOLATION)
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Secure boot */
|
/* Secure boot */
|
||||||
|
@ -153,6 +153,15 @@ static u16 alg_to_len(u16 hash_alg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_tcg2_protocol_installed(void)
|
||||||
|
{
|
||||||
|
struct efi_handler *handler;
|
||||||
|
efi_status_t ret;
|
||||||
|
|
||||||
|
ret = efi_search_protocol(efi_root, &efi_guid_tcg2_protocol, &handler);
|
||||||
|
return ret == EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static u32 tcg_event_final_size(struct tpml_digest_values *digest_list)
|
static u32 tcg_event_final_size(struct tpml_digest_values *digest_list)
|
||||||
{
|
{
|
||||||
u32 len;
|
u32 len;
|
||||||
@ -963,9 +972,12 @@ efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size,
|
|||||||
IMAGE_NT_HEADERS32 *nt;
|
IMAGE_NT_HEADERS32 *nt;
|
||||||
struct efi_handler *handler;
|
struct efi_handler *handler;
|
||||||
|
|
||||||
|
if (!is_tcg2_protocol_installed())
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
ret = platform_get_tpm2_device(&dev);
|
ret = platform_get_tpm2_device(&dev);
|
||||||
if (ret != EFI_SUCCESS)
|
if (ret != EFI_SUCCESS)
|
||||||
return ret;
|
return EFI_SECURITY_VIOLATION;
|
||||||
|
|
||||||
switch (handle->image_type) {
|
switch (handle->image_type) {
|
||||||
case IMAGE_SUBSYSTEM_EFI_APPLICATION:
|
case IMAGE_SUBSYSTEM_EFI_APPLICATION:
|
||||||
@ -1664,6 +1676,14 @@ void tcg2_uninit(void)
|
|||||||
event_log.buffer = NULL;
|
event_log.buffer = NULL;
|
||||||
efi_free_pool(event_log.final_buffer);
|
efi_free_pool(event_log.final_buffer);
|
||||||
event_log.final_buffer = NULL;
|
event_log.final_buffer = NULL;
|
||||||
|
|
||||||
|
if (!is_tcg2_protocol_installed())
|
||||||
|
return;
|
||||||
|
|
||||||
|
ret = efi_remove_protocol(efi_root, &efi_guid_tcg2_protocol,
|
||||||
|
(void *)&efi_tcg2_protocol);
|
||||||
|
if (ret != EFI_SUCCESS)
|
||||||
|
log_err("Failed to remove EFI TCG2 protocol\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2172,12 +2192,15 @@ efi_status_t efi_tcg2_measure_efi_app_invocation(struct efi_loaded_image_obj *ha
|
|||||||
u32 event = 0;
|
u32 event = 0;
|
||||||
struct smbios_entry *entry;
|
struct smbios_entry *entry;
|
||||||
|
|
||||||
|
if (!is_tcg2_protocol_installed())
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
if (tcg2_efi_app_invoked)
|
if (tcg2_efi_app_invoked)
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
ret = platform_get_tpm2_device(&dev);
|
ret = platform_get_tpm2_device(&dev);
|
||||||
if (ret != EFI_SUCCESS)
|
if (ret != EFI_SUCCESS)
|
||||||
return ret;
|
return EFI_SECURITY_VIOLATION;
|
||||||
|
|
||||||
ret = tcg2_measure_boot_variable(dev);
|
ret = tcg2_measure_boot_variable(dev);
|
||||||
if (ret != EFI_SUCCESS)
|
if (ret != EFI_SUCCESS)
|
||||||
@ -2222,6 +2245,9 @@ efi_status_t efi_tcg2_measure_efi_app_exit(void)
|
|||||||
efi_status_t ret;
|
efi_status_t ret;
|
||||||
struct udevice *dev;
|
struct udevice *dev;
|
||||||
|
|
||||||
|
if (!is_tcg2_protocol_installed())
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
ret = platform_get_tpm2_device(&dev);
|
ret = platform_get_tpm2_device(&dev);
|
||||||
if (ret != EFI_SUCCESS)
|
if (ret != EFI_SUCCESS)
|
||||||
return ret;
|
return ret;
|
||||||
@ -2247,6 +2273,12 @@ efi_tcg2_notify_exit_boot_services(struct efi_event *event, void *context)
|
|||||||
EFI_ENTRY("%p, %p", event, context);
|
EFI_ENTRY("%p, %p", event, context);
|
||||||
|
|
||||||
event_log.ebs_called = true;
|
event_log.ebs_called = true;
|
||||||
|
|
||||||
|
if (!is_tcg2_protocol_installed()) {
|
||||||
|
ret = EFI_SUCCESS;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
ret = platform_get_tpm2_device(&dev);
|
ret = platform_get_tpm2_device(&dev);
|
||||||
if (ret != EFI_SUCCESS)
|
if (ret != EFI_SUCCESS)
|
||||||
goto out;
|
goto out;
|
||||||
@ -2276,6 +2308,9 @@ efi_status_t efi_tcg2_notify_exit_boot_services_failed(void)
|
|||||||
struct udevice *dev;
|
struct udevice *dev;
|
||||||
efi_status_t ret;
|
efi_status_t ret;
|
||||||
|
|
||||||
|
if (!is_tcg2_protocol_installed())
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
ret = platform_get_tpm2_device(&dev);
|
ret = platform_get_tpm2_device(&dev);
|
||||||
if (ret != EFI_SUCCESS)
|
if (ret != EFI_SUCCESS)
|
||||||
goto out;
|
goto out;
|
||||||
@ -2345,12 +2380,37 @@ error:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* efi_tcg2_do_initial_measurement() - do initial measurement
|
||||||
|
*
|
||||||
|
* Return: status code
|
||||||
|
*/
|
||||||
|
efi_status_t efi_tcg2_do_initial_measurement(void)
|
||||||
|
{
|
||||||
|
efi_status_t ret;
|
||||||
|
struct udevice *dev;
|
||||||
|
|
||||||
|
if (!is_tcg2_protocol_installed())
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
|
ret = platform_get_tpm2_device(&dev);
|
||||||
|
if (ret != EFI_SUCCESS)
|
||||||
|
return EFI_SECURITY_VIOLATION;
|
||||||
|
|
||||||
|
ret = tcg2_measure_secure_boot_variable(dev);
|
||||||
|
if (ret != EFI_SUCCESS)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* efi_tcg2_register() - register EFI_TCG2_PROTOCOL
|
* efi_tcg2_register() - register EFI_TCG2_PROTOCOL
|
||||||
*
|
*
|
||||||
* If a TPM2 device is available, the TPM TCG2 Protocol is registered
|
* If a TPM2 device is available, the TPM TCG2 Protocol is registered
|
||||||
*
|
*
|
||||||
* Return: An error status is only returned if adding the protocol fails.
|
* Return: status code
|
||||||
*/
|
*/
|
||||||
efi_status_t efi_tcg2_register(void)
|
efi_status_t efi_tcg2_register(void)
|
||||||
{
|
{
|
||||||
@ -2373,8 +2433,10 @@ efi_status_t efi_tcg2_register(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = efi_init_event_log();
|
ret = efi_init_event_log();
|
||||||
if (ret != EFI_SUCCESS)
|
if (ret != EFI_SUCCESS) {
|
||||||
|
tcg2_uninit();
|
||||||
goto fail;
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
ret = efi_add_protocol(efi_root, &efi_guid_tcg2_protocol,
|
ret = efi_add_protocol(efi_root, &efi_guid_tcg2_protocol,
|
||||||
(void *)&efi_tcg2_protocol);
|
(void *)&efi_tcg2_protocol);
|
||||||
@ -2391,24 +2453,9 @@ efi_status_t efi_tcg2_register(void)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = tcg2_measure_secure_boot_variable(dev);
|
|
||||||
if (ret != EFI_SUCCESS) {
|
|
||||||
tcg2_uninit();
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
log_err("Cannot install EFI_TCG2_PROTOCOL\n");
|
log_err("Cannot install EFI_TCG2_PROTOCOL\n");
|
||||||
/*
|
return ret;
|
||||||
* Return EFI_SUCCESS and don't stop the EFI subsystem.
|
|
||||||
* That's done for 2 reasons
|
|
||||||
* - If the protocol is not installed the PCRs won't be extended. So
|
|
||||||
* someone later in the boot flow will notice that and take the
|
|
||||||
* necessary actions.
|
|
||||||
* - The TPM sandbox is limited and we won't be able to run any efi
|
|
||||||
* related tests with TCG2 enabled
|
|
||||||
*/
|
|
||||||
return EFI_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ obj-$(CONFIG_DMA) += dma.o
|
|||||||
obj-$(CONFIG_VIDEO_MIPI_DSI) += dsi_host.o
|
obj-$(CONFIG_VIDEO_MIPI_DSI) += dsi_host.o
|
||||||
obj-$(CONFIG_DM_DSA) += dsa.o
|
obj-$(CONFIG_DM_DSA) += dsa.o
|
||||||
obj-$(CONFIG_ECDSA_VERIFY) += ecdsa.o
|
obj-$(CONFIG_ECDSA_VERIFY) += ecdsa.o
|
||||||
|
obj-$(CONFIG_EFI_MEDIA_SANDBOX) += efi_media.o
|
||||||
obj-$(CONFIG_DM_ETH) += eth.o
|
obj-$(CONFIG_DM_ETH) += eth.o
|
||||||
ifneq ($(CONFIG_EFI_PARTITION),)
|
ifneq ($(CONFIG_EFI_PARTITION),)
|
||||||
obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fastboot.o
|
obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fastboot.o
|
||||||
|
24
test/dm/efi_media.c
Normal file
24
test/dm/efi_media.c
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* Test for EFI_MEDIA uclass
|
||||||
|
*
|
||||||
|
* Copyright 2021 Google LLC
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <dm.h>
|
||||||
|
#include <asm/test.h>
|
||||||
|
#include <dm/test.h>
|
||||||
|
#include <test/test.h>
|
||||||
|
#include <test/ut.h>
|
||||||
|
|
||||||
|
/* Test that we can use the EFI_MEDIA uclass */
|
||||||
|
static int dm_test_efi_media(struct unit_test_state *uts)
|
||||||
|
{
|
||||||
|
struct udevice *dev;
|
||||||
|
|
||||||
|
ut_assertok(uclass_first_device_err(UCLASS_EFI_MEDIA, &dev));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DM_TEST(dm_test_efi_media, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
|
Loading…
x
Reference in New Issue
Block a user