From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D5864C433F5 for ; Sat, 25 Sep 2021 00:34:52 +0000 (UTC) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 48E5C6124B for ; Sat, 25 Sep 2021 00:34:52 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 48E5C6124B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=chromium.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=lists.denx.de Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 4D67C8351D; Sat, 25 Sep 2021 02:34:28 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="QJQdYkvS"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id D9D30834E5; Sat, 25 Sep 2021 02:31:59 +0200 (CEST) Received: from mail-ot1-x329.google.com (mail-ot1-x329.google.com [IPv6:2607:f8b0:4864:20::329]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id A775083509 for ; Sat, 25 Sep 2021 02:31:17 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-ot1-x329.google.com with SMTP id l16-20020a9d6a90000000b0053b71f7dc83so15447369otq.7 for ; Fri, 24 Sep 2021 17:31:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ePzKLVC+cKEf8seW3xKmhGxJCOx2kINQGlu2j5oi9jo=; b=QJQdYkvSMpO9B1VxGJ96inawQIX0b9AefaKIYRj0Gb4moLG2u8/U7NuqY8cmgzLGNc ASVGsScxRgXg4n46PRptbFdbL+NtS9TTqDNWsw1odtfl9FWDYOCtj2VVQ5xXzKirY/ax igYb0GNnCKRlPturiFI3lu6kQ+Y96XrORRYMc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ePzKLVC+cKEf8seW3xKmhGxJCOx2kINQGlu2j5oi9jo=; b=0T/4uaQLTYXVg24tI8QSgxQXj6woorGEjJVPnvVpjYXs6GxObVvDCVyjXR1dWhaCoj fLs2OAxxJbdPJusaW9uQGJdLbQqjqhMBoZY9VPiq5KtMKAiMlhV95fnyzNj198TcxWk+ OwRPpqQMxHCvuoy6Tn0q1j9J01Oi90o1L+AU7/IIMqLXDv6R0vkF4WY9wp1MrhgQefH5 Pz6xPS2up5DHv/hgkVEYT/pUIUX5Oo0EwIEDIFWGcC0VaIc1qVwRZQh6FwSV+z2ntK1B yBnu3FzmEvc0jbpvIKyZXcTgZSBTx2Bd1bAzFfZ2g2mxrm4cKS2pwdwBiu9AKmshvmTW cc1Q== X-Gm-Message-State: AOAM531rvXS6FMG5lhN0UAeu51a9MvxoJhjV9mN0QFaOtp6GyNSBVKnh 8ztLaL/ClWduLjSKIajB3kUebEbAvvO2nQ== X-Google-Smtp-Source: ABdhPJxc7HMGMuR69wM/GsOD4WJa5YtrhdWc0IHoLZFym1jBTlb3OhXz9zBHJjm+k0PFxj/KANnm4w== X-Received: by 2002:a05:6830:164b:: with SMTP id h11mr6463936otr.272.1632529876007; Fri, 24 Sep 2021 17:31:16 -0700 (PDT) Received: from kiwi.bld.corp.google.com (c-67-190-101-114.hsd1.co.comcast.net. [67.190.101.114]) by smtp.gmail.com with ESMTPSA id y83sm2491462oia.47.2021.09.24.17.31.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Sep 2021 17:31:15 -0700 (PDT) From: Simon Glass To: U-Boot Mailing List Cc: Heinrich Schuchardt , Bin Meng , Christian Melki , Tom Rini , Ilias Apalodimas , Simon Glass , Alexander Graf Subject: [PATCH v2 16/39] efi: Add a media/block driver for EFI block devices Date: Fri, 24 Sep 2021 18:30:32 -0600 Message-Id: <20210924183029.v2.16.I9b48fe5f6b8c61348f16a1b5df114282240238c0@changeid> X-Mailer: git-send-email 2.33.0.685.g46640cef36-goog In-Reply-To: <20210925003055.759305-1-sjg@chromium.org> References: <20210925003055.759305-1-sjg@chromium.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean Add a block driver which handles read/write for EFI block devices. This driver actually already exists ('efi_block') but is not really suitable for use as a real U-Boot driver: - The operations do not provide a udevice - The code is designed for running as part of EFI loader, so uses EFI_PRINT() and EFI_CALL(). - The bind method probes the device, which is not permitted - It uses 'EFI' as its parent device The new driver is more 'normal', just requiring its platform data be set up in advance. Signed-off-by: Simon Glass --- Changes in v2: - Drop mention of partitions from the commit message drivers/block/Kconfig | 10 ++++ drivers/block/Makefile | 1 + drivers/block/efi_blk.c | 115 ++++++++++++++++++++++++++++++++++++++++ include/efi.h | 11 ++++ 4 files changed, 137 insertions(+) create mode 100644 drivers/block/efi_blk.c diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 755fdccb574..8235430497d 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -82,6 +82,16 @@ config EFI_MEDIA_SANDBOX 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 diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 3778633da1d..b221a7c6eea 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -17,3 +17,4 @@ 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 diff --git a/drivers/block/efi_blk.c b/drivers/block/efi_blk.c new file mode 100644 index 00000000000..c00b0cc0b1c --- /dev/null +++ b/drivers/block/efi_blk.c @@ -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 +#include +#include +#include +#include + +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, + 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), +}; diff --git a/include/efi.h b/include/efi.h index b5835422b95..0ec5913ddd1 100644 --- a/include/efi.h +++ b/include/efi.h @@ -414,6 +414,17 @@ struct efi_priv { 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 */ extern char image_base[]; -- 2.33.0.685.g46640cef36-goog