aboutsummaryrefslogtreecommitdiffstats
path: root/roms/u-boot/env/ubi.c
diff options
context:
space:
mode:
Diffstat (limited to 'roms/u-boot/env/ubi.c')
-rw-r--r--roms/u-boot/env/ubi.c185
1 files changed, 185 insertions, 0 deletions
diff --git a/roms/u-boot/env/ubi.c b/roms/u-boot/env/ubi.c
new file mode 100644
index 000000000..eb21c4f38
--- /dev/null
+++ b/roms/u-boot/env/ubi.c
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (c) Copyright 2012 by National Instruments,
+ * Joe Hershberger <joe.hershberger@ni.com>
+ */
+
+#include <common.h>
+#include <asm/global_data.h>
+
+#include <command.h>
+#include <env.h>
+#include <env_internal.h>
+#include <errno.h>
+#include <malloc.h>
+#include <memalign.h>
+#include <search.h>
+#include <ubi_uboot.h>
+#undef crc32
+
+#define _QUOTE(x) #x
+#define QUOTE(x) _QUOTE(x)
+
+#if (CONFIG_ENV_UBI_VID_OFFSET == 0)
+ #define UBI_VID_OFFSET NULL
+#else
+ #define UBI_VID_OFFSET QUOTE(CONFIG_ENV_UBI_VID_OFFSET)
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_CMD_SAVEENV
+#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
+static int env_ubi_save(void)
+{
+ ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
+ int ret;
+
+ ret = env_export(env_new);
+ if (ret)
+ return ret;
+
+ if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
+ printf("\n** Cannot find mtd partition \"%s\"\n",
+ CONFIG_ENV_UBI_PART);
+ return 1;
+ }
+
+ if (gd->env_valid == ENV_VALID) {
+ puts("Writing to redundant UBI... ");
+ if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME_REDUND,
+ (void *)env_new, CONFIG_ENV_SIZE)) {
+ printf("\n** Unable to write env to %s:%s **\n",
+ CONFIG_ENV_UBI_PART,
+ CONFIG_ENV_UBI_VOLUME_REDUND);
+ return 1;
+ }
+ } else {
+ puts("Writing to UBI... ");
+ if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME,
+ (void *)env_new, CONFIG_ENV_SIZE)) {
+ printf("\n** Unable to write env to %s:%s **\n",
+ CONFIG_ENV_UBI_PART,
+ CONFIG_ENV_UBI_VOLUME);
+ return 1;
+ }
+ }
+
+ puts("done\n");
+
+ gd->env_valid = gd->env_valid == ENV_REDUND ? ENV_VALID : ENV_REDUND;
+
+ return 0;
+}
+#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
+static int env_ubi_save(void)
+{
+ ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
+ int ret;
+
+ ret = env_export(env_new);
+ if (ret)
+ return ret;
+
+ if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
+ printf("\n** Cannot find mtd partition \"%s\"\n",
+ CONFIG_ENV_UBI_PART);
+ return 1;
+ }
+
+ if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, (void *)env_new,
+ CONFIG_ENV_SIZE)) {
+ printf("\n** Unable to write env to %s:%s **\n",
+ CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
+ return 1;
+ }
+
+ puts("done\n");
+ return 0;
+}
+#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
+#endif /* CONFIG_CMD_SAVEENV */
+
+#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
+static int env_ubi_load(void)
+{
+ ALLOC_CACHE_ALIGN_BUFFER(char, env1_buf, CONFIG_ENV_SIZE);
+ ALLOC_CACHE_ALIGN_BUFFER(char, env2_buf, CONFIG_ENV_SIZE);
+ int read1_fail, read2_fail;
+ env_t *tmp_env1, *tmp_env2;
+
+ /*
+ * In case we have restarted u-boot there is a chance that buffer
+ * contains old environment (from the previous boot).
+ * If UBI volume is zero size, ubi_volume_read() doesn't modify the
+ * buffer.
+ * We need to clear buffer manually here, so the invalid CRC will
+ * cause setting default environment as expected.
+ */
+ memset(env1_buf, 0x0, CONFIG_ENV_SIZE);
+ memset(env2_buf, 0x0, CONFIG_ENV_SIZE);
+
+ tmp_env1 = (env_t *)env1_buf;
+ tmp_env2 = (env_t *)env2_buf;
+
+ if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
+ printf("\n** Cannot find mtd partition \"%s\"\n",
+ CONFIG_ENV_UBI_PART);
+ env_set_default(NULL, 0);
+ return -EIO;
+ }
+
+ read1_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)tmp_env1,
+ CONFIG_ENV_SIZE);
+ if (read1_fail)
+ printf("\n** Unable to read env from %s:%s **\n",
+ CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
+
+ read2_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND,
+ (void *)tmp_env2, CONFIG_ENV_SIZE);
+ if (read2_fail)
+ printf("\n** Unable to read redundant env from %s:%s **\n",
+ CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME_REDUND);
+
+ return env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2,
+ read2_fail, H_EXTERNAL);
+}
+#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
+static int env_ubi_load(void)
+{
+ ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
+
+ /*
+ * In case we have restarted u-boot there is a chance that buffer
+ * contains old environment (from the previous boot).
+ * If UBI volume is zero size, ubi_volume_read() doesn't modify the
+ * buffer.
+ * We need to clear buffer manually here, so the invalid CRC will
+ * cause setting default environment as expected.
+ */
+ memset(buf, 0x0, CONFIG_ENV_SIZE);
+
+ if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
+ printf("\n** Cannot find mtd partition \"%s\"\n",
+ CONFIG_ENV_UBI_PART);
+ env_set_default(NULL, 0);
+ return -EIO;
+ }
+
+ if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, buf, CONFIG_ENV_SIZE)) {
+ printf("\n** Unable to read env from %s:%s **\n",
+ CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
+ env_set_default(NULL, 0);
+ return -EIO;
+ }
+
+ return env_import(buf, 1, H_EXTERNAL);
+}
+#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
+
+U_BOOT_ENV_LOCATION(ubi) = {
+ .location = ENVL_UBI,
+ ENV_NAME("UBI")
+ .load = env_ubi_load,
+ .save = env_save_ptr(env_ubi_save),
+};