Some blkmap memory mapped devices might have to be 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.g...@linaro.org>
Reviewed-by: Tobias Waldekranz <tob...@waldekranz.com>
Reviewed-by: Ilias Apalodimas <ilias.apalodi...@linaro.org>
---
Changes since V5: None

 cmd/blkmap.c                  |  9 +++++++--
 drivers/block/blkmap.c        | 12 ++++++++----
 drivers/block/blkmap_helper.c |  2 +-
 include/blkmap.h              |  4 +++-
 4 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/cmd/blkmap.c b/cmd/blkmap.c
index 164f80f1387..86a123b1cd3 100644
--- a/cmd/blkmap.c
+++ b/cmd/blkmap.c
@@ -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),
diff --git a/drivers/block/blkmap.c b/drivers/block/blkmap.c
index 453510cca62..eefed615998 100644
--- a/drivers/block/blkmap.c
+++ b/drivers/block/blkmap.c
@@ -19,6 +19,7 @@ struct blkmap;
 /* Attributes of blkmap slice */
 #define BLKMAP_SLICE_LINEAR    BIT(0)
 #define BLKMAP_SLICE_MEM       BIT(1)
+#define BLKMAP_SLICE_PRESERVE  BIT(2)
 
 /**
  * struct blkmap_slice - Region mapped to a blkmap
@@ -241,7 +242,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;
@@ -266,6 +267,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);
@@ -276,11 +280,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);
@@ -291,7 +295,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);
 
diff --git a/drivers/block/blkmap_helper.c b/drivers/block/blkmap_helper.c
index bfba14110d2..2f1bc28ee5d 100644
--- a/drivers/block/blkmap_helper.c
+++ b/drivers/block/blkmap_helper.c
@@ -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);
diff --git a/include/blkmap.h b/include/blkmap.h
index d53095437fa..754d8671b01 100644
--- a/include/blkmap.h
+++ b/include/blkmap.h
@@ -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
-- 
2.34.1

Reply via email to