blkmap: add an attribute to preserve the mem mapping
authorSughosh Ganu <sughosh.ganu@linaro.org>
Mon, 17 Mar 2025 08:34:01 +0000 (14:04 +0530)
committerIlias Apalodimas <ilias.apalodimas@linaro.org>
Wed, 26 Mar 2025 11:28:08 +0000 (13:28 +0200)
Some blkmap memory mapped devices might have to be relevant even
after U-Boot passes control to the next image as part of the platform
boot. An example of such a mapping would be an OS installer ISO image,
information for which has to be provided to the OS kernel. Use the
'preserve' attribute for such mappings. The code for adding a pmem
node to the device-tree then checks if this attribute is set, and adds
a node only for mappings which have this attribute.

Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org>
Reviewed-by: Tobias Waldekranz <tobias@waldekranz.com>
Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
cmd/blkmap.c
drivers/block/blkmap.c
drivers/block/blkmap_helper.c
include/blkmap.h

index 164f80f..86a123b 100644 (file)
@@ -62,13 +62,18 @@ static int do_blkmap_map_mem(struct map_ctx *ctx, int argc, char *const argv[])
 {
        phys_addr_t addr;
        int err;
+       bool preserve = false;
 
        if (argc < 2)
                return CMD_RET_USAGE;
 
        addr = hextoul(argv[1], NULL);
 
-       err = blkmap_map_pmem(ctx->dev, ctx->blknr, ctx->blkcnt, addr);
+       if (argc == 3 && !strcmp(argv[2], "preserve"))
+               preserve = true;
+
+       err = blkmap_map_pmem(ctx->dev, ctx->blknr, ctx->blkcnt, addr,
+                             preserve);
        if (err) {
                printf("Unable to map %#llx at block 0x" LBAF ": %d\n",
                       (unsigned long long)addr, ctx->blknr, err);
@@ -221,7 +226,7 @@ U_BOOT_CMD_WITH_SUBCMDS(
        "blkmap create <label> - create device\n"
        "blkmap destroy <label> - destroy device\n"
        "blkmap map <label> <blk#> <cnt> linear <interface> <dev> <blk#> - device mapping\n"
-       "blkmap map <label> <blk#> <cnt> mem <addr> - memory mapping\n",
+       "blkmap map <label> <blk#> <cnt> mem <addr> [preserve] - memory mapping\n",
        U_BOOT_SUBCMD_MKENT(info, 2, 1, do_blkmap_common),
        U_BOOT_SUBCMD_MKENT(part, 2, 1, do_blkmap_common),
        U_BOOT_SUBCMD_MKENT(dev, 4, 1, do_blkmap_common),
index 08f6857..1b161bd 100644 (file)
@@ -32,6 +32,14 @@ struct blkmap;
  */
 #define BLKMAP_SLICE_MEM       BIT(1)
 
+/**
+ * define BLKMAP_SLICE_PRESERVE - Preserved blkmap slice
+ *
+ * This blkmap slice is intended to be preserved, and it's
+ * information passed on to a later stage, like OS.
+ */
+#define BLKMAP_SLICE_PRESERVE  BIT(2)
+
 /**
  * struct blkmap_slice - Region mapped to a blkmap
  *
@@ -253,7 +261,7 @@ static void blkmap_mem_destroy(struct blkmap *bm, struct blkmap_slice *bms)
 }
 
 int __blkmap_map_mem(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
-                    void *addr, bool remapped)
+                    void *addr, bool remapped, bool preserve)
 {
        struct blkmap *bm = dev_get_plat(dev);
        struct blkmap_mem *bmm;
@@ -278,6 +286,9 @@ int __blkmap_map_mem(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
                .remapped = remapped,
        };
 
+       if (preserve)
+               bmm->slice.attr |= BLKMAP_SLICE_PRESERVE;
+
        err = blkmap_slice_add(bm, &bmm->slice);
        if (err)
                free(bmm);
@@ -288,11 +299,11 @@ int __blkmap_map_mem(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
 int blkmap_map_mem(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
                   void *addr)
 {
-       return __blkmap_map_mem(dev, blknr, blkcnt, addr, false);
+       return __blkmap_map_mem(dev, blknr, blkcnt, addr, false, false);
 }
 
 int blkmap_map_pmem(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
-                   phys_addr_t paddr)
+                   phys_addr_t paddr, bool preserve)
 {
        struct blkmap *bm = dev_get_plat(dev);
        struct blk_desc *bd = dev_get_uclass_plat(bm->blk);
@@ -303,7 +314,7 @@ int blkmap_map_pmem(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
        if (!addr)
                return -ENOMEM;
 
-       err = __blkmap_map_mem(dev, blknr, blkcnt, addr, true);
+       err = __blkmap_map_mem(dev, blknr, blkcnt, addr, true, preserve);
        if (err)
                unmap_sysmem(addr);
 
index bfba141..2f1bc28 100644 (file)
@@ -28,7 +28,7 @@ int blkmap_create_ramdisk(const char *label, ulong image_addr, ulong image_size,
        bm = dev_get_plat(bm_dev);
        desc = dev_get_uclass_plat(bm->blk);
        blknum = image_size >> desc->log2blksz;
-       ret = blkmap_map_pmem(bm_dev, 0, blknum, image_addr);
+       ret = blkmap_map_pmem(bm_dev, 0, blknum, image_addr, true);
        if (ret) {
                log_err("Unable to map %#llx at block %d : %d\n",
                        (unsigned long long)image_addr, 0, ret);
index d530954..754d867 100644 (file)
@@ -60,10 +60,12 @@ int blkmap_map_mem(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
  * @blknr: Start block number of the mapping
  * @blkcnt: Number of blocks to map
  * @paddr: The target physical memory address of the mapping
+ * @preserve: Mapping intended to be preserved for subsequent stages,
+ *             like the OS (e.g. ISO installer)
  * Returns: 0 on success, negative error code on failure
  */
 int blkmap_map_pmem(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
-                   phys_addr_t paddr);
+                   phys_addr_t paddr, bool preserve);
 
 /**
  * blkmap_from_label() - Find blkmap from label