Hi Heinrich, On Thu, 20 Jul 2023 at 00:10, Heinrich Schuchardt <xypron.g...@gmx.de> wrote: > > On 14.07.23 07:44, Masahisa Kojima wrote: > > This introcudes the ramdisk uclass and driver. > > > > Signed-off-by: Masahisa Kojima <masahisa.koj...@linaro.org> > > --- > > 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 <blk.h> > > +#include <common.h> > > +#include <dm.h> > > +#include <log.h> > > +#include <part.h> > > +#include <ramdisk.h> > > +#include <dm/device-internal.h> > > +#include <dm/root.h> > > + > > +#if (IS_ENABLED(CONFIG_EFI_LOADER)) > > +#include <efi_loader.h> > > +#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 <common.h> > > +#include <dm.h> > > + > > +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 <efi.h> > > +#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 <nvme.h> > > #include <efi_loader.h> > > #include <part.h> > > +#include <ramdisk.h> > > #include <uuid.h> > > #include <asm-generic/unaligned.h> > > #include <linux/compat.h> /* 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: > > What is the difference to UCLASS_BLKMAP? > > [PATCH v2 0/9] blk: blkmap: Composable virtual block devices > https://lore.kernel.org/u-boot/20230216153355.448302-1-tob...@waldekranz.com/
I was not aware of the blkmap when I created this series. This patch is duplicated, please drop this series. Thanks, Masahisa Kojima > > Best regards > > Heinrich > > > + 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", >