]> git.ipfire.org Git - people/ms/u-boot.git/commitdiff
env: Save environment at the end of an MMC partition
authorJorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
Mon, 6 Nov 2017 13:16:37 +0000 (14:16 +0100)
committerTom Rini <trini@konsulko.com>
Fri, 17 Nov 2017 12:44:13 +0000 (07:44 -0500)
Allow the platform to define a partition by name at the end of which
the environment data will be located.

Signed-off-by: Jorge Ramirez-Ortiz <jorge.ramirez-ortiz@linaro.org>
doc/device-tree-bindings/config.txt
env/mmc.c

index fe0e04af92b8dc50335ccdd434f1254d032e58bf..15e4349c19ad29a407f6f6aeae621c1bcd62e1df 100644 (file)
@@ -21,6 +21,15 @@ u-boot,efi-partition-entries-offset
 
        This setting will override any values configured via Kconfig.
 
+u-boot,mmc-env-partition
+       if present, the environment shall be placed at the last
+       CONFIG_ENV_SIZE blocks of the partition on the
+       CONFIG_SYS_MMC_ENV_DEV.
+
+       if u-boot,mmc-env-offset* is present, this setting will take
+       precedence. In that case, only if the partition is not found,
+       mmc-env-offset* will be tried.
+
 u-boot,mmc-env-offset
 u-boot,mmc-env-offset-redundant
        If present, the values of the 'u-boot,mmc-env-offset' and/or
index 3f3092d975607a48161e3e74819d98a67a16ad64..3343f9e9f6c0742bc65105bc81ebc87aea23afd7 100644 (file)
--- a/env/mmc.c
+++ b/env/mmc.c
 #include <malloc.h>
 #include <memalign.h>
 #include <mmc.h>
+#include <part.h>
 #include <search.h>
 #include <errno.h>
 
+#define __STR(X) #X
+#define STR(X) __STR(X)
+
 #if defined(CONFIG_ENV_SIZE_REDUND) &&  \
        (CONFIG_ENV_SIZE_REDUND != CONFIG_ENV_SIZE)
 #error CONFIG_ENV_SIZE_REDUND should be the same as CONFIG_ENV_SIZE
@@ -30,18 +34,68 @@ DECLARE_GLOBAL_DATA_PTR;
 #endif
 
 #if CONFIG_IS_ENABLED(OF_CONTROL)
+static inline int mmc_offset_try_partition(const char *str, s64 *val)
+{
+       disk_partition_t info;
+       struct blk_desc *desc;
+       int len, i, ret;
+
+       ret = blk_get_device_by_str("mmc", STR(CONFIG_SYS_MMC_ENV_DEV), &desc);
+       if (ret < 0)
+               return (ret);
+
+       for (i = 1;;i++) {
+               ret = part_get_info(desc, i, &info);
+               if (ret < 0)
+                       return ret;
+
+               if (!strncmp((const char *)info.name, str, sizeof(str)))
+                       break;
+       }
+
+       /* round up to info.blksz */
+       len = (CONFIG_ENV_SIZE + info.blksz - 1) & ~(info.blksz - 1);
+
+       /* use the top of the partion for the environment */
+       *val = (info.start + info.size - 1) - len / info.blksz;
+
+       return 0;
+}
+
 static inline s64 mmc_offset(int copy)
 {
-       const char *propname = "u-boot,mmc-env-offset";
-       s64 defvalue = CONFIG_ENV_OFFSET;
+       const struct {
+               const char *offset_redund;
+               const char *partition;
+               const char *offset;
+       } dt_prop = {
+               .offset_redund = "u-boot,mmc-env-offset-redundant",
+               .partition = "u-boot,mmc-env-partition",
+               .offset = "u-boot,mmc-env-offset",
+       };
+       s64 val, defvalue;
+       const char *propname;
+       const char *str;
+       int err;
+
+       /* look for the partition in mmc CONFIG_SYS_MMC_ENV_DEV */
+       str = fdtdec_get_config_string(gd->fdt_blob, dt_prop.partition);
+       if (str) {
+               /* try to place the environment at end of the partition */
+               err = mmc_offset_try_partition(str, &val);
+               if (!err)
+                       return val;
+       }
+
+       defvalue = CONFIG_ENV_OFFSET;
+       propname = dt_prop.offset;
 
 #if defined(CONFIG_ENV_OFFSET_REDUND)
        if (copy) {
-               propname = "u-boot,mmc-env-offset-redundant";
                defvalue = CONFIG_ENV_OFFSET_REDUND;
+               propname = dt_prop.offset_redund;
        }
 #endif
-
        return fdtdec_get_config_int(gd->fdt_blob, propname, defvalue);
 }
 #else