diff mbox series

[4/8] blk: blkmap: Add memory mapping support

Message ID 20230201181016.4145834-5-tobias@waldekranz.com
State Superseded
Delegated to: Tom Rini
Headers show
Series blk: blkmap: Composable virtual block devices | expand

Commit Message

Tobias Waldekranz Feb. 1, 2023, 6:10 p.m. UTC
Allow a slice of RAM to be mapped to a blkmap. This means that RAM can
now be accessed as if it was a block device, meaning that existing
filesystem drivers can now be used to access ramdisks.

Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
---
 drivers/block/blkmap.c | 106 +++++++++++++++++++++++++++++++++++++++++
 include/blkmap.h       |   4 ++
 2 files changed, 110 insertions(+)

Comments

Simon Glass Feb. 1, 2023, 8:21 p.m. UTC | #1
Hi Tobias,

On Wed, 1 Feb 2023 at 11:10, Tobias Waldekranz <tobias@waldekranz.com> wrote:
>
> Allow a slice of RAM to be mapped to a blkmap. This means that RAM can
> now be accessed as if it was a block device, meaning that existing
> filesystem drivers can now be used to access ramdisks.
>
> Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
> ---
>  drivers/block/blkmap.c | 106 +++++++++++++++++++++++++++++++++++++++++
>  include/blkmap.h       |   4 ++
>  2 files changed, 110 insertions(+)
>
> diff --git a/drivers/block/blkmap.c b/drivers/block/blkmap.c
> index a6ba07404c..c8c2dcac11 100644
> --- a/drivers/block/blkmap.c
> +++ b/drivers/block/blkmap.c
> @@ -12,6 +12,7 @@
>  #include <dm/lists.h>
>  #include <dm/root.h>
>  #include <malloc.h>
> +#include <mapmem.h>
>  #include <part.h>
>
>  struct blkmap;
> @@ -93,6 +94,111 @@ static int blkmap_add(struct blkmap *bm, struct blkmap_slice *new)
>         return 0;
>  }
>
> +struct blkmap_mem {
> +       struct blkmap_slice slice;
> +       void *addr;
> +       bool remapped;
> +};
> +
> +static ulong blkmap_mem_read(struct blkmap *bm, struct blkmap_slice *bms,
> +                            lbaint_t blknr, lbaint_t blkcnt, void *buffer)
> +{
> +       struct blkmap_mem *bmm = container_of(bms, struct blkmap_mem, slice);
> +       struct blk_desc *bd = dev_get_uclass_plat(bm->dev);
> +       char *src;
> +
> +       src = bmm->addr + (blknr << bd->log2blksz);
> +       memcpy(buffer, src, blkcnt << bd->log2blksz);
> +       return blkcnt;
> +}
> +
> +static ulong blkmap_mem_write(struct blkmap *bm, struct blkmap_slice *bms,
> +                             lbaint_t blknr, lbaint_t blkcnt,
> +                             const void *buffer)
> +{
> +       struct blkmap_mem *bmm = container_of(bms, struct blkmap_mem, slice);
> +       struct blk_desc *bd = dev_get_uclass_plat(bm->dev);
> +       char *dst;
> +
> +       dst = bmm->addr + (blknr << bd->log2blksz);
> +       memcpy(dst, buffer, blkcnt << bd->log2blksz);
> +       return blkcnt;
> +}
> +
> +static void blkmap_mem_destroy(struct blkmap *bm, struct blkmap_slice *bms)
> +{
> +       struct blkmap_mem *bmm = container_of(bms, struct blkmap_mem, slice);
> +
> +       if (bmm->remapped)
> +               unmap_sysmem(bmm->addr);
> +}
> +
> +int __blkmap_map_mem(int devnum, lbaint_t blknr, lbaint_t blkcnt, void *addr,
> +                    bool remapped)
> +{
> +       struct blkmap_mem *bmm;
> +       struct blkmap *bm;
> +       int err;
> +
> +       bm = blkmap_from_devnum(devnum);
> +       if (!bm)
> +               return -ENODEV;
> +
> +       bmm = malloc(sizeof(*bmm));
> +       if (!bmm)
> +               return -ENOMEM;
> +
> +       *bmm = (struct blkmap_mem) {
> +               .slice = {
> +                       .blknr = blknr,
> +                       .blkcnt = blkcnt,
> +
> +                       .read = blkmap_mem_read,
> +                       .write = blkmap_mem_write,
> +                       .destroy = blkmap_mem_destroy,
> +               },
> +
> +               .addr = addr,
> +               .remapped = remapped,
> +       };
> +
> +       err = blkmap_add(bm, &bmm->slice);
> +       if (err)
> +               free(bmm);
> +
> +       return err;
> +}
> +
> +int blkmap_map_mem(int devnum, lbaint_t blknr, lbaint_t blkcnt, void *addr)
> +{
> +       return __blkmap_map_mem(devnum, blknr, blkcnt, addr, false);
> +}
> +
> +int blkmap_map_pmem(int devnum, lbaint_t blknr, lbaint_t blkcnt,
> +                   phys_addr_t paddr)
> +{
> +       struct blk_desc *bd;
> +       struct blkmap *bm;
> +       void *addr;
> +       int err;
> +
> +       bm = blkmap_from_devnum(devnum);
> +       if (!bm)
> +               return -ENODEV;
> +
> +       bd = dev_get_uclass_plat(bm->dev);
> +
> +       addr = map_sysmem(paddr, blkcnt << bd->log2blksz);
> +       if (!addr)
> +               return -ENOMEM;
> +
> +       err = __blkmap_map_mem(devnum, blknr, blkcnt, addr, true);
> +       if (err)
> +               unmap_sysmem(addr);
> +
> +       return err;
> +}
> +
>  static struct udevice *blkmap_root(void)
>  {
>         static struct udevice *dev;
> diff --git a/include/blkmap.h b/include/blkmap.h
> index 37c0c31c3f..a93611ff62 100644
> --- a/include/blkmap.h
> +++ b/include/blkmap.h
> @@ -9,6 +9,10 @@
>
>  #include <stdbool.h>
>
> +int blkmap_map_mem(int devnum, lbaint_t blknr, lbaint_t blkcnt, void *addr);
> +int blkmap_map_pmem(int devnum, lbaint_t blknr, lbaint_t blkcnt,
> +                   phys_addr_t paddr);

Comments again.

> +
>  int blkmap_create(int devnum);
>  int blkmap_destroy(int devnum);
>
> --
> 2.34.1
>

Other than that and the devnum stuff, LGTM

Regards,
Simon
diff mbox series

Patch

diff --git a/drivers/block/blkmap.c b/drivers/block/blkmap.c
index a6ba07404c..c8c2dcac11 100644
--- a/drivers/block/blkmap.c
+++ b/drivers/block/blkmap.c
@@ -12,6 +12,7 @@ 
 #include <dm/lists.h>
 #include <dm/root.h>
 #include <malloc.h>
+#include <mapmem.h>
 #include <part.h>
 
 struct blkmap;
@@ -93,6 +94,111 @@  static int blkmap_add(struct blkmap *bm, struct blkmap_slice *new)
 	return 0;
 }
 
+struct blkmap_mem {
+	struct blkmap_slice slice;
+	void *addr;
+	bool remapped;
+};
+
+static ulong blkmap_mem_read(struct blkmap *bm, struct blkmap_slice *bms,
+			     lbaint_t blknr, lbaint_t blkcnt, void *buffer)
+{
+	struct blkmap_mem *bmm = container_of(bms, struct blkmap_mem, slice);
+	struct blk_desc *bd = dev_get_uclass_plat(bm->dev);
+	char *src;
+
+	src = bmm->addr + (blknr << bd->log2blksz);
+	memcpy(buffer, src, blkcnt << bd->log2blksz);
+	return blkcnt;
+}
+
+static ulong blkmap_mem_write(struct blkmap *bm, struct blkmap_slice *bms,
+			      lbaint_t blknr, lbaint_t blkcnt,
+			      const void *buffer)
+{
+	struct blkmap_mem *bmm = container_of(bms, struct blkmap_mem, slice);
+	struct blk_desc *bd = dev_get_uclass_plat(bm->dev);
+	char *dst;
+
+	dst = bmm->addr + (blknr << bd->log2blksz);
+	memcpy(dst, buffer, blkcnt << bd->log2blksz);
+	return blkcnt;
+}
+
+static void blkmap_mem_destroy(struct blkmap *bm, struct blkmap_slice *bms)
+{
+	struct blkmap_mem *bmm = container_of(bms, struct blkmap_mem, slice);
+
+	if (bmm->remapped)
+		unmap_sysmem(bmm->addr);
+}
+
+int __blkmap_map_mem(int devnum, lbaint_t blknr, lbaint_t blkcnt, void *addr,
+		     bool remapped)
+{
+	struct blkmap_mem *bmm;
+	struct blkmap *bm;
+	int err;
+
+	bm = blkmap_from_devnum(devnum);
+	if (!bm)
+		return -ENODEV;
+
+	bmm = malloc(sizeof(*bmm));
+	if (!bmm)
+		return -ENOMEM;
+
+	*bmm = (struct blkmap_mem) {
+		.slice = {
+			.blknr = blknr,
+			.blkcnt = blkcnt,
+
+			.read = blkmap_mem_read,
+			.write = blkmap_mem_write,
+			.destroy = blkmap_mem_destroy,
+		},
+
+		.addr = addr,
+		.remapped = remapped,
+	};
+
+	err = blkmap_add(bm, &bmm->slice);
+	if (err)
+		free(bmm);
+
+	return err;
+}
+
+int blkmap_map_mem(int devnum, lbaint_t blknr, lbaint_t blkcnt, void *addr)
+{
+	return __blkmap_map_mem(devnum, blknr, blkcnt, addr, false);
+}
+
+int blkmap_map_pmem(int devnum, lbaint_t blknr, lbaint_t blkcnt,
+		    phys_addr_t paddr)
+{
+	struct blk_desc *bd;
+	struct blkmap *bm;
+	void *addr;
+	int err;
+
+	bm = blkmap_from_devnum(devnum);
+	if (!bm)
+		return -ENODEV;
+
+	bd = dev_get_uclass_plat(bm->dev);
+
+	addr = map_sysmem(paddr, blkcnt << bd->log2blksz);
+	if (!addr)
+		return -ENOMEM;
+
+	err = __blkmap_map_mem(devnum, blknr, blkcnt, addr, true);
+	if (err)
+		unmap_sysmem(addr);
+
+	return err;
+}
+
 static struct udevice *blkmap_root(void)
 {
 	static struct udevice *dev;
diff --git a/include/blkmap.h b/include/blkmap.h
index 37c0c31c3f..a93611ff62 100644
--- a/include/blkmap.h
+++ b/include/blkmap.h
@@ -9,6 +9,10 @@ 
 
 #include <stdbool.h>
 
+int blkmap_map_mem(int devnum, lbaint_t blknr, lbaint_t blkcnt, void *addr);
+int blkmap_map_pmem(int devnum, lbaint_t blknr, lbaint_t blkcnt,
+		    phys_addr_t paddr);
+
 int blkmap_create(int devnum);
 int blkmap_destroy(int devnum);