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#include <asm/global_data.h>
   9
  10#include <command.h>
  11#include <env.h>
  12#include <env_internal.h>
  13#include <errno.h>
  14#include <malloc.h>
  15#include <memalign.h>
  16#include <search.h>
  17#include <ubi_uboot.h>
  18#undef crc32
  19
  20#define _QUOTE(x) #x
  21#define QUOTE(x) _QUOTE(x)
  22
  23#if (CONFIG_ENV_UBI_VID_OFFSET == 0)
  24 #define UBI_VID_OFFSET NULL
  25#else
  26 #define UBI_VID_OFFSET QUOTE(CONFIG_ENV_UBI_VID_OFFSET)
  27#endif
  28
  29DECLARE_GLOBAL_DATA_PTR;
  30
  31#if CONFIG_SYS_REDUNDAND_ENVIRONMENT
  32#define ENV_UBI_VOLUME_REDUND CONFIG_ENV_UBI_VOLUME_REDUND
  33#else
  34#define ENV_UBI_VOLUME_REDUND "invalid"
  35#endif
  36
  37#ifdef CONFIG_CMD_SAVEENV
  38#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
  39static int env_ubi_save(void)
  40{
  41        ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
  42        int ret;
  43
  44        ret = env_export(env_new);
  45        if (ret)
  46                return ret;
  47
  48        if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
  49                printf("\n** Cannot find mtd partition \"%s\"\n",
  50                       CONFIG_ENV_UBI_PART);
  51                return 1;
  52        }
  53
  54        if (gd->env_valid == ENV_VALID) {
  55                puts("Writing to redundant UBI... ");
  56                if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME_REDUND,
  57                                     (void *)env_new, CONFIG_ENV_SIZE)) {
  58                        printf("\n** Unable to write env to %s:%s **\n",
  59                               CONFIG_ENV_UBI_PART,
  60                               CONFIG_ENV_UBI_VOLUME_REDUND);
  61                        return 1;
  62                }
  63        } else {
  64                puts("Writing to UBI... ");
  65                if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME,
  66                                     (void *)env_new, CONFIG_ENV_SIZE)) {
  67                        printf("\n** Unable to write env to %s:%s **\n",
  68                               CONFIG_ENV_UBI_PART,
  69                               CONFIG_ENV_UBI_VOLUME);
  70                        return 1;
  71                }
  72        }
  73
  74        puts("done\n");
  75
  76        gd->env_valid = gd->env_valid == ENV_REDUND ? ENV_VALID : ENV_REDUND;
  77
  78        return 0;
  79}
  80#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
  81static int env_ubi_save(void)
  82{
  83        ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
  84        int ret;
  85
  86        ret = env_export(env_new);
  87        if (ret)
  88                return ret;
  89
  90        if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
  91                printf("\n** Cannot find mtd partition \"%s\"\n",
  92                       CONFIG_ENV_UBI_PART);
  93                return 1;
  94        }
  95
  96        if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, (void *)env_new,
  97                             CONFIG_ENV_SIZE)) {
  98                printf("\n** Unable to write env to %s:%s **\n",
  99                       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
 100                return 1;
 101        }
 102
 103        puts("done\n");
 104        return 0;
 105}
 106#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
 107#endif /* CONFIG_CMD_SAVEENV */
 108
 109#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
 110static int env_ubi_load(void)
 111{
 112        ALLOC_CACHE_ALIGN_BUFFER(char, env1_buf, CONFIG_ENV_SIZE);
 113        ALLOC_CACHE_ALIGN_BUFFER(char, env2_buf, CONFIG_ENV_SIZE);
 114        int read1_fail, read2_fail;
 115        env_t *tmp_env1, *tmp_env2;
 116
 117        /*
 118         * In case we have restarted u-boot there is a chance that buffer
 119         * contains old environment (from the previous boot).
 120         * If UBI volume is zero size, ubi_volume_read() doesn't modify the
 121         * buffer.
 122         * We need to clear buffer manually here, so the invalid CRC will
 123         * cause setting default environment as expected.
 124         */
 125        memset(env1_buf, 0x0, CONFIG_ENV_SIZE);
 126        memset(env2_buf, 0x0, CONFIG_ENV_SIZE);
 127
 128        tmp_env1 = (env_t *)env1_buf;
 129        tmp_env2 = (env_t *)env2_buf;
 130
 131        if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
 132                printf("\n** Cannot find mtd partition \"%s\"\n",
 133                       CONFIG_ENV_UBI_PART);
 134                env_set_default(NULL, 0);
 135                return -EIO;
 136        }
 137
 138        read1_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)tmp_env1,
 139                                     CONFIG_ENV_SIZE);
 140        if (read1_fail)
 141                printf("\n** Unable to read env from %s:%s **\n",
 142                       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
 143
 144        read2_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND,
 145                                     (void *)tmp_env2, CONFIG_ENV_SIZE);
 146        if (read2_fail)
 147                printf("\n** Unable to read redundant env from %s:%s **\n",
 148                       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME_REDUND);
 149
 150        return env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2,
 151                                 read2_fail, H_EXTERNAL);
 152}
 153#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
 154static int env_ubi_load(void)
 155{
 156        ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
 157
 158        /*
 159         * In case we have restarted u-boot there is a chance that buffer
 160         * contains old environment (from the previous boot).
 161         * If UBI volume is zero size, ubi_volume_read() doesn't modify the
 162         * buffer.
 163         * We need to clear buffer manually here, so the invalid CRC will
 164         * cause setting default environment as expected.
 165         */
 166        memset(buf, 0x0, CONFIG_ENV_SIZE);
 167
 168        if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
 169                printf("\n** Cannot find mtd partition \"%s\"\n",
 170                       CONFIG_ENV_UBI_PART);
 171                env_set_default(NULL, 0);
 172                return -EIO;
 173        }
 174
 175        if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, buf, CONFIG_ENV_SIZE)) {
 176                printf("\n** Unable to read env from %s:%s **\n",
 177                       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
 178                env_set_default(NULL, 0);
 179                return -EIO;
 180        }
 181
 182        return env_import(buf, 1, H_EXTERNAL);
 183}
 184#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
 185
 186static int env_ubi_erase(void)
 187{
 188        ALLOC_CACHE_ALIGN_BUFFER(char, env_buf, CONFIG_ENV_SIZE);
 189        int ret = 0;
 190
 191        if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
 192                printf("\n** Cannot find mtd partition \"%s\"\n",
 193                       CONFIG_ENV_UBI_PART);
 194                return 1;
 195        }
 196
 197        memset(env_buf, 0x0, CONFIG_ENV_SIZE);
 198
 199        if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME,
 200                             (void *)env_buf, CONFIG_ENV_SIZE)) {
 201                printf("\n** Unable to erase env to %s:%s **\n",
 202                       CONFIG_ENV_UBI_PART,
 203                       CONFIG_ENV_UBI_VOLUME);
 204                ret = 1;
 205        }
 206        if (IS_ENABLED(CONFIG_SYS_REDUNDAND_ENVIRONMENT)) {
 207                if (ubi_volume_write(ENV_UBI_VOLUME_REDUND,
 208                                     (void *)env_buf, CONFIG_ENV_SIZE)) {
 209                        printf("\n** Unable to erase env to %s:%s **\n",
 210                               CONFIG_ENV_UBI_PART,
 211                               ENV_UBI_VOLUME_REDUND);
 212                        ret = 1;
 213                }
 214        }
 215
 216        return ret;
 217}
 218
 219U_BOOT_ENV_LOCATION(ubi) = {
 220        .location       = ENVL_UBI,
 221        ENV_NAME("UBI")
 222        .load           = env_ubi_load,
 223        .save           = env_save_ptr(env_ubi_save),
 224        .erase          = ENV_ERASE_PTR(env_ubi_erase),
 225};
 226