From patchwork Fri Jul 14 05:44:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahisa Kojima X-Patchwork-Id: 702716 Delivered-To: patch@linaro.org Received: by 2002:adf:db4e:0:b0:314:25da:8dc4 with SMTP id f14csp906548wrj; Thu, 13 Jul 2023 22:47:35 -0700 (PDT) X-Google-Smtp-Source: APBJJlGiQ1/N3Z2EDC8xcPHVwUgeofbSfLKfOHa5k9BvDeLmPIr8oDaEPqV70a/NCKITSK5T3DQL X-Received: by 2002:a05:6402:74a:b0:51e:2525:68a3 with SMTP id p10-20020a056402074a00b0051e252568a3mr3189454edy.25.1689313655318; Thu, 13 Jul 2023 22:47:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689313655; cv=none; d=google.com; s=arc-20160816; b=vHj1X9kXHivhlhLVJmIlAj6UEjisyZLZUR40LfAc6xrcSP5mZz6Bm3YjX6jZ1DvLm2 2YO69nGhVnmg6jwv46qRUEdCkdTdPwPdcZYIGmD/hTk5WTrRqLIzxf3B/gol0UolxWs3 3/59rrYgXTznt9elRTi7x7QOoMk6pdWZ+9Vv/iT+ynN4VaZ1IfRBoGX6IfSGbam1fosE lRMn4KgF66Fndcx/EjD2VuyncyZHgnBpmubKQnMs99l85n4r2QA5d4tECqPtJNi4elgt jsif0SMSvHLo5eam9jgL0IgTjy39E9Le4k8RrSCuLRwx5UIl6u6DOwa7f7c4SEiwHPrs 0N3Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=hmx1rMHVzdbCstJRGar5e3Y8ZRpsgZDh/0wT1sTHdOM=; fh=k9uRNNo8VKxGprAjZaZf0XqLyq3c3E+oTj31oN2BOMo=; b=sLwRu6kVwPQzyk1Vqj9uR6GMm7vWhGn3MYBWxoGTqk0moMoO1qL11ivluTtWflHiJe xzu6463EfqLEvkTxIrhTvb4x0WIjriodS8ZV/67mVR6vECqkFahHIHWQaIYoIhQXpqLH dhvHIZWAydMW5kcG7TctTetKoaC7FhVNvMdVchA9CRneXb5rvLANE/Pupbbu8C1mM17O CDUkFnBkjQ1fQBIn3BHNz2K6yPXEhdm5cwA3/nmYSLnVCFRzmZw06w/eLjHe3U805Awp zhROC/gw1dwzrhQNqVo0RJPJLFxVu4CFhJU9964aa54VhHQgC7KQwj7RlC/vyNMuQKSO 2pcA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=VkDxpccj; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id u18-20020aa7d892000000b0051e2cab35b7si8316135edq.369.2023.07.13.22.47.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Jul 2023 22:47:35 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=VkDxpccj; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 50B6986D24; Fri, 14 Jul 2023 07:47:25 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="VkDxpccj"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 1F91E86D24; Fri, 14 Jul 2023 07:47:24 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-oi1-x230.google.com (mail-oi1-x230.google.com [IPv6:2607:f8b0:4864:20::230]) (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 B67F086D2C for ; Fri, 14 Jul 2023 07:47:20 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=masahisa.kojima@linaro.org Received: by mail-oi1-x230.google.com with SMTP id 5614622812f47-3a38953c928so1238753b6e.1 for ; Thu, 13 Jul 2023 22:47:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1689313639; x=1691905639; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=hmx1rMHVzdbCstJRGar5e3Y8ZRpsgZDh/0wT1sTHdOM=; b=VkDxpccjSesmX1bkfldUPofHEDChxkOFLke/sbYO0GHnK6F3zr/Mj/f7W6Ydp2ZoNA 9U1l9xn9OweasjxthB3wrRX2/bmip2a1A8/METVJDEk3Gm8TyPVrNslUURAzgcMkx423 E/Ejmk4aCsSR49BL/zvpxnnXEs64dbB1o1ncUSontDLOPHv8RieADvh8b6WZQ9r5hXww HcqjDuCBwtQWJpclipIqYvB7FRWtXVkLc4Rt+cXTO+GBKQ01Av69AXYVkR5mV7iZkrD6 rOP6fZBOR6A4hNJaNAs1oZ2zQVd6Xiswn0iTVt3/zcYUbHS4hFHf82QpfUfb+IooHGws IFAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1689313639; x=1691905639; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=hmx1rMHVzdbCstJRGar5e3Y8ZRpsgZDh/0wT1sTHdOM=; b=UKKCAoHRo1oSjwM02h1UgxUAWSmH+BrhBjgeEuye8JUgNgw6UN7+g+7K7BXWHZEd0U v7dr+AnRqQJZ2ALhEkjaRBjz5nx5cphbZbWmt0Ocn9vUPk8l56Omp4rsPMNL5gdxN/qU BcbHmLBj8iJYd5RKFs2wo+POv9RbjZno0eznMqp8vKi9X2nOhYnUy7n5Us0L1RZrLeKB o8K9mdoYalZ+Or4PhI75xWoXuIS7/sMiqqZni7ZGNYARLc0oroZwRvHHWq7BQ4tjoH0R djbCPKkG5Ar+OHmiJgWyR2JVDDOot87qnWqhacqLT1+9uNnYnbejcNJsY2NoN5SeG/OQ M9Gg== X-Gm-Message-State: ABy/qLac0mSpTz5FaRIz1pZYJUJqcgGL4LI5ZEMVcjkTPoc/4ZIGxhIi 6QXDU99U7m/4flCF20uUJFhlCRSvnzthOGlxEDo= X-Received: by 2002:aca:b9c6:0:b0:3a3:dda9:b90d with SMTP id j189-20020acab9c6000000b003a3dda9b90dmr3875458oif.45.1689313639031; Thu, 13 Jul 2023 22:47:19 -0700 (PDT) Received: from localhost ([164.70.16.189]) by smtp.gmail.com with ESMTPSA id f13-20020a63380d000000b0052858b41008sm6530003pga.87.2023.07.13.22.47.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 13 Jul 2023 22:47:18 -0700 (PDT) From: Masahisa Kojima To: u-boot@lists.denx.de Cc: Heinrich Schuchardt , Ilias Apalodimas , Simon Glass , Takahiro Akashi , Masahisa Kojima , Tobias Waldekranz , Heiko Schocher , Stefan Herbrechtsmeier , Jaehoon Chung , Michal Suchanek , Abdellatif El Khlifi Subject: [PATCH v2 2/6] ramdisk: add ramdisk uclass and driver Date: Fri, 14 Jul 2023 14:44:02 +0900 Message-Id: <20230714054406.761508-3-masahisa.kojima@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230714054406.761508-1-masahisa.kojima@linaro.org> References: <20230714054406.761508-1-masahisa.kojima@linaro.org> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 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.8 at phobos.denx.de X-Virus-Status: Clean This introcudes the ramdisk uclass and driver. Signed-off-by: Masahisa Kojima --- Newly introcuded in v2 disk/part.c | 3 + drivers/block/Kconfig | 7 +- drivers/block/Makefile | 2 + drivers/block/blk-uclass.c | 1 + drivers/block/blk_ramdisk.c | 187 +++++++++++++++++++++++++++++++ drivers/block/ramdisk-uclass.c | 14 +++ include/dm/uclass-id.h | 1 + include/ramdisk.h | 32 ++++++ lib/efi_loader/efi_device_path.c | 25 +++++ 9 files changed, 271 insertions(+), 1 deletion(-) create mode 100644 drivers/block/blk_ramdisk.c create mode 100644 drivers/block/ramdisk-uclass.c create mode 100644 include/ramdisk.h diff --git a/disk/part.c b/disk/part.c index 35300df590..d0cee3cc03 100644 --- a/disk/part.c +++ b/disk/part.c @@ -152,6 +152,9 @@ void dev_print(struct blk_desc *dev_desc) case UCLASS_EFI_MEDIA: printf("EFI media Block Device %d\n", dev_desc->devnum); break; + case UCLASS_RAM_DISK: + printf("RAM Disk Block Device %d\n", dev_desc->devnum); + break; case UCLASS_INVALID: puts("device type unknown\n"); return; diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 5a1aeb3d2b..ab56ef3406 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -2,7 +2,7 @@ config BLK bool # "Support block devices" depends on DM default y if MMC || USB || SCSI || NVME || IDE || AHCI || SATA - default y if EFI_MEDIA || VIRTIO_BLK || PVBLOCK + default y if EFI_MEDIA || VIRTIO_BLK || PVBLOCK || RAM_DISK help Enable support for block devices, such as SCSI, MMC and USB flash sticks. These provide a block-level interface which permits @@ -255,3 +255,8 @@ config SYS_64BIT_LBA help Make the block subsystem use 64bit sector addresses, rather than the default of 32bit. + +config RAM_DISK + bool "Enable RAM disk" + help + This option enables to mount the RAM disk. diff --git a/drivers/block/Makefile b/drivers/block/Makefile index a161d145fd..e867c7a126 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -19,3 +19,5 @@ obj-$(CONFIG_BLKMAP) += blkmap.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 +obj-$(CONFIG_RAM_DISK) += blk_ramdisk.o +obj-$(CONFIG_RAM_DISK) += ramdisk-uclass.o diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index 614b975e25..ea411fe674 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -34,6 +34,7 @@ static struct { { UCLASS_VIRTIO, "virtio" }, { UCLASS_PVBLOCK, "pvblock" }, { UCLASS_BLKMAP, "blkmap" }, + { UCLASS_RAM_DISK, "ramdisk" }, }; static enum uclass_id uclass_name_to_iftype(const char *uclass_idname) diff --git a/drivers/block/blk_ramdisk.c b/drivers/block/blk_ramdisk.c new file mode 100644 index 0000000000..8016837a80 --- /dev/null +++ b/drivers/block/blk_ramdisk.c @@ -0,0 +1,187 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * RAM Disk block device driver + * + * Copyright (c) 2023, Linaro Limited + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#if (IS_ENABLED(CONFIG_EFI_LOADER)) +#include +#endif + +#define MEM_BLOCK_SIZE_SHIFT 9 /* 512 bytes */ + +/** + * ramdisk_read() - 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 ramdisk_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt, + void *buffer) +{ + u8 *start; + struct ramdisk_blk_plat *plat = dev_get_plat(dev); + + log_debug("read buf=%p, block=%lx, count=%lx: ", buffer, (ulong)blknr, + (ulong)blkcnt); + + if (!buffer) + return 0; + + if (blknr + blkcnt > (plat->size >> MEM_BLOCK_SIZE_SHIFT)) + return 0; + + start = plat->start + (blknr << MEM_BLOCK_SIZE_SHIFT); + memmove(buffer, start, blkcnt << MEM_BLOCK_SIZE_SHIFT); + + return blkcnt; +} + +/** + * ramdisk_write() - 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 ramdisk_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt, + const void *buffer) +{ + u8 *start; + struct ramdisk_blk_plat *plat = dev_get_plat(dev); + + log_debug("write buf=%p, block=%lx, count=%lx: ", buffer, (ulong)blknr, + (ulong)blkcnt); + + if (!buffer) + return 0; + + if (blknr + blkcnt > (plat->size >> MEM_BLOCK_SIZE_SHIFT)) + return 0; + + start = plat->start + (blknr << MEM_BLOCK_SIZE_SHIFT); + memmove(start, buffer, blkcnt << MEM_BLOCK_SIZE_SHIFT); + + return blkcnt; +} + +static const struct blk_ops ramdisk_blk_ops = { + .read = ramdisk_read, + .write = ramdisk_write, +}; + +U_BOOT_DRIVER(ramdisk_blk) = { + .name = "ramdisk_blk", + .id = UCLASS_BLK, + .ops = &ramdisk_blk_ops, + .plat_auto = sizeof(struct ramdisk_blk_plat), +}; + +/* + * ramdisk_mount - mount ramdisk + * + * @start_address: The base address of registered RAM disk + * @size: The size of registered RAM disk + * @guid: The type of registered RAM disk + * Return: Pointer to the udevice strucure, return NULL if failed + */ +struct udevice *ramdisk_mount(u64 start_address, u64 size, void *guid) +{ + int ret; + char name[20]; + struct udevice *parent, *bdev; + static struct ramdisk_blk_plat *plat; + + if (!start_address || !size) + return NULL; + + ret = device_bind(dm_root(), DM_DRIVER_GET(ramdisk), "ramdisk", NULL, + ofnode_null(), &parent); + if (ret) { + log_err("bind ramdisk error\n"); + return NULL; + } + snprintf(name, sizeof(name), "ramdisk%d", dev_seq(parent)); + device_set_name(parent, name); + + ret = blk_create_device(parent, "ramdisk_blk", "ramdisk_blk", + UCLASS_RAM_DISK, dev_seq(parent), + 1 << MEM_BLOCK_SIZE_SHIFT, + (size >> MEM_BLOCK_SIZE_SHIFT) - 1, &bdev); + if (ret) { + log_err("ramdisk create block device failed\n"); + goto err; + } + snprintf(name, sizeof(name), "ramdisk_blk#%d", dev_seq(parent)); + device_set_name(bdev, name); + + plat = dev_get_plat(bdev); + plat->start = (u8 *)start_address; + plat->size = size; +#if (IS_ENABLED(CONFIG_EFI_LOADER)) + if (guid) + guidcpy(&plat->disk_type_guid, guid); +#endif + ret = blk_probe_or_unbind(bdev); + if (ret) { + log_err("ramdisk probe error\n"); + goto err; + } + + return bdev; + +err: + if (parent) { + ret = device_remove(parent, DM_REMOVE_NORMAL); + if (ret) + return NULL; + + ret = device_unbind(parent); + } + + return NULL; +} + +/* + * ramdisk_unmount - unmount ramdisk + * + * @dev: The device to be unmounted + * Return: 0 if success, negative value if error + */ +int ramdisk_unmount(struct udevice *dev) +{ + int ret; + struct udevice *parent; + + if (!dev) + return -EINVAL; + + parent = dev->parent; + ret = device_remove(parent, DM_REMOVE_NORMAL); + if (ret) + return ret; + + ret = device_unbind(parent); + + return ret; +} + +U_BOOT_DRIVER(ramdisk) = { + .name = "ramdisk", + .id = UCLASS_RAM_DISK, +}; diff --git a/drivers/block/ramdisk-uclass.c b/drivers/block/ramdisk-uclass.c new file mode 100644 index 0000000000..f1bf68f635 --- /dev/null +++ b/drivers/block/ramdisk-uclass.c @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * RAM Disk block device driver + * + * Copyright (c) 2023, Linaro Limited + */ + +#include +#include + +UCLASS_DRIVER(ramdisk) = { + .name = "ramdisk", + .id = UCLASS_RAM_DISK, +}; diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 307ad6931c..42b4907b1f 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -109,6 +109,7 @@ enum uclass_id { UCLASS_PWRSEQ, /* Power sequence device */ UCLASS_QFW, /* QEMU firmware config device */ UCLASS_RAM, /* RAM controller */ + UCLASS_RAM_DISK, /* RAM disk device */ UCLASS_REBOOT_MODE, /* Reboot mode */ UCLASS_REGULATOR, /* Regulator device */ UCLASS_REMOTEPROC, /* Remote Processor device */ diff --git a/include/ramdisk.h b/include/ramdisk.h new file mode 100644 index 0000000000..71383be5b8 --- /dev/null +++ b/include/ramdisk.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * ramdisk support + * + * Copyright (c) 2023, Linaro Limited + */ + +#ifndef _RAMDISK_H +#define _RAMDISK_H + +#ifdef CONFIG_EFI_LOADER +#include +#endif + +/** + * struct ramdisk_blk_plat - attributes of a block device + * + * @handle: handle of the controller on which this driver is installed + * @io: block io protocol proxied by this driver + */ +struct ramdisk_blk_plat { + u8 *start; + u64 size; +#if (IS_ENABLED(CONFIG_EFI_LOADER)) + efi_guid_t disk_type_guid; +#endif +}; + +struct udevice *ramdisk_mount(u64 start_address, u64 size, void *guid); +int ramdisk_unmount(struct udevice *dev); + +#endif diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index 04ebb449ca..1f16bda6ac 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include /* U16_MAX */ @@ -568,6 +569,11 @@ __maybe_unused static unsigned int dp_size(struct udevice *dev) */ return dp_size(dev->parent) + sizeof(struct efi_device_path_vendor) + 1; +#endif +#ifdef CONFIG_RAM_DISK + case UCLASS_RAM_DISK: + return dp_size(dev->parent) + + sizeof(struct efi_device_path_ram_disk_path) + 1; #endif default: return dp_size(dev->parent); @@ -766,6 +772,25 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev) dp->controller_number = desc->lun; return &dp[1]; } +#endif +#if defined(CONFIG_RAM_DISK) + case UCLASS_RAM_DISK: { + struct ramdisk_blk_plat *plat = dev_get_plat(dev); + struct efi_device_path_ram_disk_path *dp = + dp_fill(buf, dev->parent); + + dp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE; + dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_RAM_DISK_PATH; + dp->dp.length = + sizeof(struct efi_device_path_ram_disk_path); + put_unaligned_le64((u64)plat->start, + &dp->starting_address); + put_unaligned_le64((u64)(plat->start + plat->size - 1), + &dp->ending_address); + guidcpy(&dp->disk_type_guid, &plat->disk_type_guid); + dp->disk_instance = 0; + return &dp[1]; + } #endif default: debug("%s(%u) %s: unhandled parent class: %s (%u)\n",