All of lore.kernel.org
 help / color / mirror / Atom feed
From: Heinrich Schuchardt <xypron.glpk@gmx.de>
To: Simon Glass <sjg@chromium.org>,
	U-Boot Mailing List <u-boot@lists.denx.de>
Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>,
	Bin Meng <bmeng.cn@gmail.com>, Tom Rini <trini@konsulko.com>,
	Christian Melki <christian.melki@t2data.com>,
	Alexander Graf <agraf@csgraf.de>
Subject: Re: [PATCH 14/35] efi: Locate all block devices in the app
Date: Wed, 8 Sep 2021 20:14:30 +0200	[thread overview]
Message-ID: <2924c018-6a5b-4261-cff3-0ad1a416ef98@gmx.de> (raw)
In-Reply-To: <20210908073355.14.I0774d3540ebe726f31838b851815e829fb6a4056@changeid>

On 9/8/21 3:33 PM, Simon Glass wrote:
> When starting the app, locate all block devices and make them available
> to U-Boot. This allows listing partitions and accessing files in
> filesystems.
>
> EFI also has the concept of 'disks', meaning boot media. For now, this
> is not obviously useful in U-Boot, but add code to at least locate these.
> This can be expanded later as needed.

UEFI firmware handles with the EFI_BLOCK_IO_PROTOCOL for raw access to
disks and partitions. It further provides the
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL on these handles to access files on
formatted media.

>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
>   include/efi.h     |  15 ++++++
>   include/efi_api.h |  15 ++++++
>   lib/efi/efi_app.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 149 insertions(+)
>
> diff --git a/include/efi.h b/include/efi.h
> index 0ec5913ddd1..c0fddf7f6cd 100644
> --- a/include/efi.h
> +++ b/include/efi.h
> @@ -529,4 +529,19 @@ void efi_putc(struct efi_priv *priv, const char ch);
>    */
>   int efi_info_get(enum efi_entry_t type, void **datap, int *sizep);
>
> +/**
> + * efi_bind_block() - bind a new block device to an EFI device
> + *
> + * Binds a new top-level EFI_MEDIA device as well as a child block device so
> + * that the block device can be accessed in U-Boot.
> + *
> + * The device can then be accessed using 'part list efi 0', 'fat ls efi 0:1',
> + * for example, just like any other interface type.
> + *
> + * @handle: handle of the controller on which this driver is installed
> + * @blkio: block io protocol proxied by this driver
> + * @return 0 if OK, -ve on error
> + */
> +int efi_bind_block(efi_handle_t handle, struct efi_block_io *blkio);
> +
>   #endif /* _LINUX_EFI_H */
> diff --git a/include/efi_api.h b/include/efi_api.h
> index c8f959bb720..0e88b3e5dbe 100644
> --- a/include/efi_api.h
> +++ b/include/efi_api.h
> @@ -1994,4 +1994,19 @@ struct efi_firmware_management_protocol {
>   			const u16 *package_version_name);
>   };
>
> +#define EFI_DISK_IO_PROTOCOL_GUID	\
> +	EFI_GUID(0xce345171, 0xba0b, 0x11d2, 0x8e, 0x4f, \
> +		 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
> +
> +struct efi_disk {
> +	u64 revision;
> +	efi_status_t (EFIAPI *read_disk)(struct efi_disk *this, u32 media_id,
> +					 u64 offset, efi_uintn_t buffer_size,
> +					 void *buffer);
> +
> +	efi_status_t (EFIAPI *write_disk)(struct efi_disk *this, u32 media_id,
> +					  u64 offset, efi_uintn_t buffer_size,
> +					  void *buffer);
> +};
> +
>   #endif
> diff --git a/lib/efi/efi_app.c b/lib/efi/efi_app.c
> index f61665686c5..9ba48517422 100644
> --- a/lib/efi/efi_app.c
> +++ b/lib/efi/efi_app.c
> @@ -21,6 +21,9 @@
>   #include <efi.h>
>   #include <efi_api.h>
>   #include <sysreset.h>
> +#include <dm/device-internal.h>
> +#include <dm/lists.h>
> +#include <dm/root.h>
>
>   DECLARE_GLOBAL_DATA_PTR;
>
> @@ -46,6 +49,33 @@ int efi_info_get(enum efi_entry_t type, void **datap, int *sizep)
>   	return -ENOSYS;
>   }
>
> +/**
> + * Create a block device so U-Boot can access an EFI device
> + *
> + * @handle:	EFI handle to bind
> + * @blkio:	block io protocol
> + * Return:	0 = success
> + */
> +int efi_bind_block(efi_handle_t handle, struct efi_block_io *blkio)
> +{
> +	struct efi_media_plat plat;
> +	struct udevice *dev;
> +	char name[18];
> +	int ret;
> +
> +	plat.handle = handle;
> +	plat.blkio = blkio;
> +	ret = device_bind(dm_root(), DM_DRIVER_GET(efi_media), "efi_media",
> +			  &plat, ofnode_null(), &dev);
> +	if (ret)
> +		return log_msg_ret("bind", ret);
> +
> +	snprintf(name, sizeof(name), "efi_media_%x", dev_seq(dev));
> +	device_set_name(dev, name);
> +
> +	return 0;
> +}
> +
>   static efi_status_t setup_memory(struct efi_priv *priv)
>   {
>   	struct efi_boot_services *boot = priv->boot;
> @@ -105,6 +135,95 @@ static void free_memory(struct efi_priv *priv)
>   	global_data_ptr = NULL;
>   }
>
> +static int setup_disks(void)
> +{
> +	/* This is not fully implemented yet */
> +	return 0;
> +
> +	efi_guid_t efi_disk_guid = EFI_DISK_IO_PROTOCOL_GUID;
> +	struct efi_boot_services *boot = efi_get_boot();
> +	struct efi_disk *disk;
> +	int ret;
> +
> +	if (!boot)
> +		return log_msg_ret("sys", -ENOSYS);
> +	ret = boot->locate_protocol(&efi_disk_guid, NULL, (void **)&disk);
> +	if (ret)
> +		return log_msg_ret("prot", -ENOTSUPP);
> +
> +	return 0;
> +}
> +
> +static int setup_block(void)
> +{
> +	efi_guid_t efi_blkio_guid = EFI_BLOCK_IO_PROTOCOL_GUID;
> +	efi_guid_t efi_devpath_guid = EFI_DEVICE_PATH_PROTOCOL_GUID;
> +	struct efi_boot_services *boot = efi_get_boot();
> +	struct efi_block_io *blkio;
> +	struct efi_device_path device_path;
> +	efi_handle_t handle[100];
> +	efi_uintn_t buf_size;
> +	int num_handles;
> +	int ret, i;
> +
> +	if (!boot)
> +		return log_msg_ret("sys", -ENOSYS);
> +
> +	buf_size = sizeof(handle);
> +	ret = boot->locate_handle(BY_PROTOCOL, &efi_blkio_guid, NULL,
> +				  &buf_size, handle);

You could use LocateHandleBuffer() here which will allocate enough
memory for all matching handles.

> +	if (ret)
> +		return log_msg_ret("loc", -ENOTSUPP);
> +
> +	num_handles = buf_size / sizeof(efi_handle_t);
> +	log_info("Found %d EFI handles\n", num_handles);
> +
> +	for (i = 0; i < num_handles; i++) {
> +		ret = boot->handle_protocol(handle[i], &efi_devpath_guid,
> +					    (void **)&device_path);


Why do you read the devicepath if you don't use it?

> +		if (ret) {
> +			log_warning("- devpath %d failed (ret=%d)\n", i, ret);
> +			continue;
> +		}

Here some analysis of devicepaths and installed protocols is missing to
find out which of the handles represents a block device and which
represents a partition:

If the last devicepath node is type 4 , Media Device Path with SubType 1
Hard Drive and the partition number is non-zero it is a partition.

If the devicepath without the last node relates to a handle with the
EFI_BLOCK_IO_PROTOCOL, this also indicates that the current handle is
for a partition.

Best regards

Heinrich

> +
> +		ret = boot->handle_protocol(handle[i], &efi_blkio_guid,
> +					    (void **)&blkio);
> +		if (ret) {
> +			log_warning("- blkio %d failed (ret=%d)\n", i, ret);
> +			continue;
> +		}
> +
> +		ret = efi_bind_block(handle[i], blkio);
> +		if (ret) {
> +			log_warning("- blkio bind %d failed (ret=%d)\n", i, ret);
> +			continue;
> +		}
> +	}
> +	if (ret)
> +		return log_msg_ret("prot", -ENOTSUPP);
> +
> +	return 0;
> +}
> +
> +int dm_scan_other(bool pre_reloc_only)
> +{
> +	if (gd->flags & GD_FLG_RELOC) {
> +		int ret;
> +
> +		/* Find all block devices and setup EFI devices for them */
> +		ret = setup_block();
> +		if (ret)
> +			return ret;
> +
> +		/* Not needed at present, but could be useful one day? */
> +		ret = setup_disks();
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> +
>   /**
>    * efi_main() - Start an EFI image
>    *
>

  reply	other threads:[~2021-09-08 18:14 UTC|newest]

Thread overview: 82+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-08 13:33 [PATCH 00/35] efi: Improvements to U-Boot running on top of UEFI Simon Glass
2021-09-08 13:33 ` [PATCH 01/35] x86: Keep symbol information in u-boot ELF file Simon Glass
2021-09-08 13:33 ` [PATCH 02/35] x86: Create a new header for EFI Simon Glass
2021-09-08 17:22   ` Heinrich Schuchardt
2021-09-09  8:57     ` Simon Glass
2021-09-09  9:25       ` Heinrich Schuchardt
2021-09-09 19:57         ` Simon Glass
2021-09-08 13:33 ` [PATCH 03/35] x86: Show some EFI info with the bdinfo command Simon Glass
2021-09-08 17:29   ` Heinrich Schuchardt
2021-09-09  8:57     ` Simon Glass
2021-09-09  9:29       ` Heinrich Schuchardt
2021-09-09 20:08         ` Simon Glass
2021-09-08 13:33 ` [PATCH 04/35] x86: Tidy up global_data pointer for 64-bit Simon Glass
2021-09-08 17:30   ` Heinrich Schuchardt
2021-09-08 13:33 ` [PATCH 05/35] efi: Add a script for building and testing U-Boot on UEFI Simon Glass
2021-09-08 13:33 ` [PATCH 06/35] x86: Create a 32/64-bit selection for the app Simon Glass
2021-09-08 17:35   ` Heinrich Schuchardt
2021-09-09  8:57     ` Simon Glass
2021-09-08 13:33 ` [PATCH 07/35] efi: Create a 64-bit app Simon Glass
2021-09-08 17:37   ` Heinrich Schuchardt
2021-09-08 13:33 ` [PATCH 08/35] x86: Don't duplicate global_ptr in 64-bit EFI app Simon Glass
2021-09-08 13:33 ` [PATCH 09/35] efi: Add a way to obtain boot services in the app Simon Glass
2021-09-08 13:33 ` [PATCH 10/35] efi: Add video support to " Simon Glass
2021-09-08 17:40   ` Heinrich Schuchardt
2021-09-09  8:57     ` Simon Glass
2021-09-08 13:33 ` [PATCH 11/35] RFC: efi: Drop code that doesn't work with driver model Simon Glass
2021-09-08 17:44   ` Heinrich Schuchardt
2021-09-09  8:57     ` Simon Glass
2021-09-09  9:21       ` Heinrich Schuchardt
2021-09-09 19:57         ` Simon Glass
2021-09-09 20:14           ` Tom Rini
2021-09-09 20:15           ` Mark Kettenis
2021-09-09 20:23             ` Tom Rini
2021-09-09 21:45               ` Mark Kettenis
2021-09-09 22:06                 ` Tom Rini
2021-09-24  2:48                 ` Simon Glass
2021-09-24 10:36                   ` Mark Kettenis
2021-09-24 12:32         ` Simon Glass
2021-09-08 13:33 ` [PATCH 12/35] efi: Add EFI uclass for media Simon Glass
2021-09-08 17:50   ` Heinrich Schuchardt
2021-09-09  8:57     ` Simon Glass
2021-09-08 13:33 ` [PATCH 13/35] efi: Add a media/block driver for EFI block devices Simon Glass
2021-09-08 17:59   ` Heinrich Schuchardt
2021-09-09  8:57     ` Simon Glass
2021-09-09 10:35       ` Heinrich Schuchardt
2021-09-09 19:58         ` Simon Glass
2021-09-08 13:33 ` [PATCH 14/35] efi: Locate all block devices in the app Simon Glass
2021-09-08 18:14   ` Heinrich Schuchardt [this message]
2021-09-09  1:11     ` AKASHI Takahiro
2021-09-09 20:09       ` Simon Glass
2021-09-10  0:50         ` AKASHI Takahiro
2021-09-09 20:09     ` Simon Glass
2021-09-08 13:33 ` [PATCH 15/35] patman: Use a ValueError exception if tools.Run() fails Simon Glass
2021-09-08 13:33 ` [PATCH 16/35] binman: Report an error if test files fail to compile Simon Glass
2021-09-08 13:33 ` [PATCH 17/35] binman: Support reading the offset of an ELF-file symbol Simon Glass
2021-09-08 13:33 ` [PATCH 18/35] binman: Allow timeout to occur in the image or its section Simon Glass
2021-09-08 13:33 ` [PATCH 19/35] binman: Tidy up comments on _DoTestFile() Simon Glass
2021-09-08 13:33 ` [PATCH 20/35] binman: Support updating the dtb in an ELF file Simon Glass
2021-09-08 13:33 ` [PATCH 21/35] efi: serial: Support arrow keys Simon Glass
2021-09-08 13:33 ` [PATCH 22/35] bloblist: Move to rST format Simon Glass
2021-09-08 18:18   ` Heinrich Schuchardt
2021-09-08 13:33 ` [PATCH 23/35] bloblist: Support allocating the bloblist Simon Glass
2021-09-08 13:33 ` [PATCH 24/35] x86: Allow booting a kernel from the EFI app Simon Glass
2021-09-08 18:22   ` Heinrich Schuchardt
2021-09-09  8:57     ` Simon Glass
2021-09-08 13:33 ` [PATCH 25/35] x86: Don't process the kernel command line unless enabled Simon Glass
2021-09-08 13:33 ` [PATCH 26/35] x86: efi: Add room for the binman definition in the dtb Simon Glass
2021-09-08 13:33 ` [PATCH 27/35] efi: Add comments to struct efi_priv Simon Glass
2021-09-08 13:33 ` [PATCH 28/35] efi: Fix ll_boot_init() operation with the app Simon Glass
2021-09-08 13:33 ` [PATCH 29/35] efi: Add a few comments to the stub Simon Glass
2021-09-08 13:34 ` [PATCH 30/35] efi: Share struct efi_priv between the app and stub code Simon Glass
2021-09-08 13:34 ` [PATCH 31/35] efi: Move exit_boot_services into a function Simon Glass
2021-09-08 13:34 ` [PATCH 32/35] efi: Check for failure when initing the app Simon Glass
2021-09-08 13:34 ` [PATCH 33/35] efi: Mention that efi_info_get() is only used in the stub Simon Glass
2021-09-08 13:34 ` [PATCH 34/35] efi: Show when allocated pages are used Simon Glass
2021-09-08 18:25   ` Heinrich Schuchardt
2021-09-09  8:57     ` Simon Glass
2021-09-09 10:39       ` Heinrich Schuchardt
2021-09-09 19:58         ` Simon Glass
2021-09-08 13:34 ` [PATCH 35/35] efi: Allow easy selection of serial-only operation Simon Glass
2021-09-09 16:29 ` [PATCH 00/35] efi: Improvements to U-Boot running on top of UEFI Bin Meng
2021-09-09 16:34   ` Tom Rini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2924c018-6a5b-4261-cff3-0ad1a416ef98@gmx.de \
    --to=xypron.glpk@gmx.de \
    --cc=agraf@csgraf.de \
    --cc=bmeng.cn@gmail.com \
    --cc=christian.melki@t2data.com \
    --cc=ilias.apalodimas@linaro.org \
    --cc=sjg@chromium.org \
    --cc=trini@konsulko.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.