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#ifdef CONFIG_CMD_SAVEENV
  32#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
  33static int env_ubi_save(void)
  34{
  35        ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
  36        int ret;
  37
  38        ret = env_export(env_new);
  39        if (ret)
  40                return ret;
  41
  42        if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
  43                printf("\n** Cannot find mtd partition \"%s\"\n",
  44                       CONFIG_ENV_UBI_PART);
  45                return 1;
  46        }
  47
  48        if (gd->env_valid == ENV_VALID) {
  49                puts("Writing to redundant UBI... ");
  50                if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME_REDUND,
  51                                     (void *)env_new, CONFIG_ENV_SIZE)) {
  52                        printf("\n** Unable to write env to %s:%s **\n",
  53                               CONFIG_ENV_UBI_PART,
  54                               CONFIG_ENV_UBI_VOLUME_REDUND);
  55                        return 1;
  56                }
  57        } else {
  58                puts("Writing to UBI... ");
  59                if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME,
  60                                     (void *)env_new, CONFIG_ENV_SIZE)) {
  61                        printf("\n** Unable to write env to %s:%s **\n",
  62                               CONFIG_ENV_UBI_PART,
  63                               CONFIG_ENV_UBI_VOLUME);
  64                        return 1;
  65                }
  66        }
  67
  68        puts("done\n");
  69
  70        gd->env_valid = gd->env_valid == ENV_REDUND ? ENV_VALID : ENV_REDUND;
  71
  72        return 0;
  73}
  74#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
  75static int env_ubi_save(void)
  76{
  77        ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
  78        int ret;
  79
  80        ret = env_export(env_new);
  81        if (ret)
  82                return ret;
  83
  84        if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
  85                printf("\n** Cannot find mtd partition \"%s\"\n",
  86                       CONFIG_ENV_UBI_PART);
  87                return 1;
  88        }
  89
  90        if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, (void *)env_new,
  91                             CONFIG_ENV_SIZE)) {
  92                printf("\n** Unable to write env to %s:%s **\n",
  93                       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
  94                return 1;
  95        }
  96
  97        puts("done\n");
  98        return 0;
  99}
 100#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
 101#endif /* CONFIG_CMD_SAVEENV */
 102
 103#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
 104static int env_ubi_load(void)
 105{
 106        ALLOC_CACHE_ALIGN_BUFFER(char, env1_buf, CONFIG_ENV_SIZE);
 107        ALLOC_CACHE_ALIGN_BUFFER(char, env2_buf, CONFIG_ENV_SIZE);
 108        int read1_fail, read2_fail;
 109        env_t *tmp_env1, *tmp_env2;
 110
 111        /*
 112         * In case we have restarted u-boot there is a chance that buffer
 113         * contains old environment (from the previous boot).
 114         * If UBI volume is zero size, ubi_volume_read() doesn't modify the
 115         * buffer.
 116         * We need to clear buffer manually here, so the invalid CRC will
 117         * cause setting default environment as expected.
 118         */
 119        memset(env1_buf, 0x0, CONFIG_ENV_SIZE);
 120        memset(env2_buf, 0x0, CONFIG_ENV_SIZE);
 121
 122        tmp_env1 = (env_t *)env1_buf;
 123        tmp_env2 = (env_t *)env2_buf;
 124
 125        if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
 126                printf("\n** Cannot find mtd partition \"%s\"\n",
 127                       CONFIG_ENV_UBI_PART);
 128                env_set_default(NULL, 0);
 129                return -EIO;
 130        }
 131
 132        read1_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)tmp_env1,
 133                                     CONFIG_ENV_SIZE);
 134        if (read1_fail)
 135                printf("\n** Unable to read env from %s:%s **\n",
 136                       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
 137
 138        read2_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND,
 139                                     (void *)tmp_env2, CONFIG_ENV_SIZE);
 140        if (read2_fail)
 141                printf("\n** Unable to read redundant env from %s:%s **\n",
 142                       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME_REDUND);
 143
 144        return env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2,
 145                                 read2_fail, H_EXTERNAL);
 146}
 147#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
 148static int env_ubi_load(void)
 149{
 150        ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
 151
 152        /*
 153         * In case we have restarted u-boot there is a chance that buffer
 154         * contains old environment (from the previous boot).
 155         * If UBI volume is zero size, ubi_volume_read() doesn't modify the
 156         * buffer.
 157         * We need to clear buffer manually here, so the invalid CRC will
 158         * cause setting default environment as expected.
 159         */
 160        memset(buf, 0x0, CONFIG_ENV_SIZE);
 161
 162        if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
 163                printf("\n** Cannot find mtd partition \"%s\"\n",
 164                       CONFIG_ENV_UBI_PART);
 165                env_set_default(NULL, 0);
 166                return -EIO;
 167        }
 168
 169        if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, buf, CONFIG_ENV_SIZE)) {
 170                printf("\n** Unable to read env from %s:%s **\n",
 171                       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
 172                env_set_default(NULL, 0);
 173                return -EIO;
 174        }
 175
 176        return env_import(buf, 1, H_EXTERNAL);
 177}
 178#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
 179
 180U_BOOT_ENV_LOCATION(ubi) = {
 181        .location       = ENVL_UBI,
 182        ENV_NAME("UBI")
 183        .load           = env_ubi_load,
 184        .save           = env_save_ptr(env_ubi_save),
 185};
 186