uboot/env/ubi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (c) Copyright 2012 by National Instruments,
   4 *        Joe Hershberger <joe.hershberger@ni.com>
   5 */
   6
   7#include <common.h>
   8
   9#include <command.h>
  10#include <env.h>
  11#include <env_internal.h>
  12#include <errno.h>
  13#include <malloc.h>
  14#include <memalign.h>
  15#include <search.h>
  16#include <ubi_uboot.h>
  17#undef crc32
  18
  19#define _QUOTE(x) #x
  20#define QUOTE(x) _QUOTE(x)
  21
  22#if (CONFIG_ENV_UBI_VID_OFFSET == 0)
  23 #define UBI_VID_OFFSET NULL
  24#else
  25 #define UBI_VID_OFFSET QUOTE(CONFIG_ENV_UBI_VID_OFFSET)
  26#endif
  27
  28DECLARE_GLOBAL_DATA_PTR;
  29
  30#ifdef CONFIG_CMD_SAVEENV
  31#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
  32static int env_ubi_save(void)
  33{
  34        ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
  35        int ret;
  36
  37        ret = env_export(env_new);
  38        if (ret)
  39                return ret;
  40
  41        if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
  42                printf("\n** Cannot find mtd partition \"%s\"\n",
  43                       CONFIG_ENV_UBI_PART);
  44                return 1;
  45        }
  46
  47        if (gd->env_valid == ENV_VALID) {
  48                puts("Writing to redundant UBI... ");
  49                if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME_REDUND,
  50                                     (void *)env_new, CONFIG_ENV_SIZE)) {
  51                        printf("\n** Unable to write env to %s:%s **\n",
  52                               CONFIG_ENV_UBI_PART,
  53                               CONFIG_ENV_UBI_VOLUME_REDUND);
  54                        return 1;
  55                }
  56        } else {
  57                puts("Writing to UBI... ");
  58                if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME,
  59                                     (void *)env_new, CONFIG_ENV_SIZE)) {
  60                        printf("\n** Unable to write env to %s:%s **\n",
  61                               CONFIG_ENV_UBI_PART,
  62                               CONFIG_ENV_UBI_VOLUME);
  63                        return 1;
  64                }
  65        }
  66
  67        puts("done\n");
  68
  69        gd->env_valid = gd->env_valid == ENV_REDUND ? ENV_VALID : ENV_REDUND;
  70
  71        return 0;
  72}
  73#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
  74static int env_ubi_save(void)
  75{
  76        ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
  77        int ret;
  78
  79        ret = env_export(env_new);
  80        if (ret)
  81                return ret;
  82
  83        if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
  84                printf("\n** Cannot find mtd partition \"%s\"\n",
  85                       CONFIG_ENV_UBI_PART);
  86                return 1;
  87        }
  88
  89        if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, (void *)env_new,
  90                             CONFIG_ENV_SIZE)) {
  91                printf("\n** Unable to write env to %s:%s **\n",
  92                       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
  93                return 1;
  94        }
  95
  96        puts("done\n");
  97        return 0;
  98}
  99#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
 100#endif /* CONFIG_CMD_SAVEENV */
 101
 102#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
 103static int env_ubi_load(void)
 104{
 105        ALLOC_CACHE_ALIGN_BUFFER(char, env1_buf, CONFIG_ENV_SIZE);
 106        ALLOC_CACHE_ALIGN_BUFFER(char, env2_buf, CONFIG_ENV_SIZE);
 107        int read1_fail, read2_fail;
 108        env_t *tmp_env1, *tmp_env2;
 109
 110        /*
 111         * In case we have restarted u-boot there is a chance that buffer
 112         * contains old environment (from the previous boot).
 113         * If UBI volume is zero size, ubi_volume_read() doesn't modify the
 114         * buffer.
 115         * We need to clear buffer manually here, so the invalid CRC will
 116         * cause setting default environment as expected.
 117         */
 118        memset(env1_buf, 0x0, CONFIG_ENV_SIZE);
 119        memset(env2_buf, 0x0, CONFIG_ENV_SIZE);
 120
 121        tmp_env1 = (env_t *)env1_buf;
 122        tmp_env2 = (env_t *)env2_buf;
 123
 124        if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
 125                printf("\n** Cannot find mtd partition \"%s\"\n",
 126                       CONFIG_ENV_UBI_PART);
 127                env_set_default(NULL, 0);
 128                return -EIO;
 129        }
 130
 131        read1_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)tmp_env1,
 132                                     CONFIG_ENV_SIZE);
 133        if (read1_fail)
 134                printf("\n** Unable to read env from %s:%s **\n",
 135                       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
 136
 137        read2_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND,
 138                                     (void *)tmp_env2, CONFIG_ENV_SIZE);
 139        if (read2_fail)
 140                printf("\n** Unable to read redundant env from %s:%s **\n",
 141                       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME_REDUND);
 142
 143        return env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2,
 144                                                         read2_fail);
 145}
 146#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
 147static int env_ubi_load(void)
 148{
 149        ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
 150
 151        /*
 152         * In case we have restarted u-boot there is a chance that buffer
 153         * contains old environment (from the previous boot).
 154         * If UBI volume is zero size, ubi_volume_read() doesn't modify the
 155         * buffer.
 156         * We need to clear buffer manually here, so the invalid CRC will
 157         * cause setting default environment as expected.
 158         */
 159        memset(buf, 0x0, CONFIG_ENV_SIZE);
 160
 161        if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
 162                printf("\n** Cannot find mtd partition \"%s\"\n",
 163                       CONFIG_ENV_UBI_PART);
 164                env_set_default(NULL, 0);
 165                return -EIO;
 166        }
 167
 168        if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, buf, CONFIG_ENV_SIZE)) {
 169                printf("\n** Unable to read env from %s:%s **\n",
 170                       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
 171                env_set_default(NULL, 0);
 172                return -EIO;
 173        }
 174
 175        return env_import(buf, 1);
 176}
 177#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
 178
 179U_BOOT_ENV_LOCATION(ubi) = {
 180        .location       = ENVL_UBI,
 181        ENV_NAME("UBI")
 182        .load           = env_ubi_load,
 183        .save           = env_save_ptr(env_ubi_save),
 184};
 185