blob: d4a0e18c3d43b0e8d87156893049bddd992cad0c [file] [log] [blame]
wdenkc6097192002-11-03 00:24:07 +00001/*
Wolfgang Denkea882ba2010-06-20 23:33:59 +02002 * (C) Copyright 2000-2010
wdenkc6097192002-11-03 00:24:07 +00003 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 *
5 * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
6 * Andreas Heppel <aheppel@sysgo.de>
7
Wolfgang Denk1a459662013-07-08 09:37:19 +02008 * SPDX-License-Identifier: GPL-2.0+
wdenkc6097192002-11-03 00:24:07 +00009 */
10
11/* #define DEBUG */
12
13#include <common.h>
wdenkc6097192002-11-03 00:24:07 +000014#include <command.h>
15#include <environment.h>
wdenkc6097192002-11-03 00:24:07 +000016#include <linux/stddef.h>
wdenk47cd00f2003-03-06 13:39:27 +000017#include <malloc.h>
Wolfgang Denkea882ba2010-06-20 23:33:59 +020018#include <search.h>
19#include <errno.h>
wdenkc6097192002-11-03 00:24:07 +000020
Wolfgang Denkd87080b2006-03-31 18:32:53 +020021DECLARE_GLOBAL_DATA_PTR;
22
Mike Frysingerbdab39d2009-01-28 19:08:14 -050023#if defined(CONFIG_CMD_SAVEENV) && defined(CONFIG_CMD_FLASH)
wdenkc6097192002-11-03 00:24:07 +000024#define CMD_SAVEENV
Jean-Christophe PLAGNIOL-VILLARD0e8d1582008-09-10 22:48:06 +020025#elif defined(CONFIG_ENV_ADDR_REDUND)
Igor Grinberg82b54b92011-11-07 01:14:09 +000026#error CONFIG_ENV_ADDR_REDUND must have CONFIG_CMD_SAVEENV & CONFIG_CMD_FLASH
wdenkc6097192002-11-03 00:24:07 +000027#endif
28
Igor Grinberg82b54b92011-11-07 01:14:09 +000029#if defined(CONFIG_ENV_SIZE_REDUND) && \
30 (CONFIG_ENV_SIZE_REDUND < CONFIG_ENV_SIZE)
Jean-Christophe PLAGNIOL-VILLARD0e8d1582008-09-10 22:48:06 +020031#error CONFIG_ENV_SIZE_REDUND should not be less then CONFIG_ENV_SIZE
wdenkc6097192002-11-03 00:24:07 +000032#endif
33
Igor Grinberg82b54b92011-11-07 01:14:09 +000034char *env_name_spec = "Flash";
wdenkc6097192002-11-03 00:24:07 +000035
36#ifdef ENV_IS_EMBEDDED
Igor Grinberg994bc672011-11-17 06:07:23 +000037env_t *env_ptr = &environment;
wdenkc6097192002-11-03 00:24:07 +000038
Jean-Christophe PLAGNIOL-VILLARD0e8d1582008-09-10 22:48:06 +020039static env_t *flash_addr = (env_t *)CONFIG_ENV_ADDR;
wdenkc6097192002-11-03 00:24:07 +000040
41#else /* ! ENV_IS_EMBEDDED */
42
Jean-Christophe PLAGNIOL-VILLARD0e8d1582008-09-10 22:48:06 +020043env_t *env_ptr = (env_t *)CONFIG_ENV_ADDR;
Jean-Christophe PLAGNIOL-VILLARD0e8d1582008-09-10 22:48:06 +020044static env_t *flash_addr = (env_t *)CONFIG_ENV_ADDR;
wdenkc6097192002-11-03 00:24:07 +000045#endif /* ENV_IS_EMBEDDED */
46
Wolfgang Denkea882ba2010-06-20 23:33:59 +020047#if defined(CMD_SAVEENV) || defined(CONFIG_ENV_ADDR_REDUND)
48/* CONFIG_ENV_ADDR is supposed to be on sector boundary */
49static ulong end_addr = CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1;
50#endif
51
Jean-Christophe PLAGNIOL-VILLARD0e8d1582008-09-10 22:48:06 +020052#ifdef CONFIG_ENV_ADDR_REDUND
53static env_t *flash_addr_new = (env_t *)CONFIG_ENV_ADDR_REDUND;
wdenkc6097192002-11-03 00:24:07 +000054
Wolfgang Denkea882ba2010-06-20 23:33:59 +020055/* CONFIG_ENV_ADDR_REDUND is supposed to be on sector boundary */
Jean-Christophe PLAGNIOL-VILLARD0e8d1582008-09-10 22:48:06 +020056static ulong end_addr_new = CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SECT_SIZE - 1;
Jean-Christophe PLAGNIOL-VILLARD0e8d1582008-09-10 22:48:06 +020057#endif /* CONFIG_ENV_ADDR_REDUND */
wdenkc6097192002-11-03 00:24:07 +000058
wdenkc6097192002-11-03 00:24:07 +000059
Jean-Christophe PLAGNIOL-VILLARD0e8d1582008-09-10 22:48:06 +020060#ifdef CONFIG_ENV_ADDR_REDUND
Igor Grinberg82b54b92011-11-07 01:14:09 +000061int env_init(void)
wdenkc6097192002-11-03 00:24:07 +000062{
wdenk8ed96042005-01-09 23:16:25 +000063 int crc1_ok = 0, crc2_ok = 0;
wdenkc6097192002-11-03 00:24:07 +000064
65 uchar flag1 = flash_addr->flags;
66 uchar flag2 = flash_addr_new->flags;
67
68 ulong addr_default = (ulong)&default_environment[0];
69 ulong addr1 = (ulong)&(flash_addr->data);
70 ulong addr2 = (ulong)&(flash_addr_new->data);
71
Igor Grinberg82b54b92011-11-07 01:14:09 +000072 crc1_ok = crc32(0, flash_addr->data, ENV_SIZE) == flash_addr->crc;
73 crc2_ok =
74 crc32(0, flash_addr_new->data, ENV_SIZE) == flash_addr_new->crc;
wdenk8ed96042005-01-09 23:16:25 +000075
Igor Grinberg82b54b92011-11-07 01:14:09 +000076 if (crc1_ok && !crc2_ok) {
77 gd->env_addr = addr1;
78 gd->env_valid = 1;
79 } else if (!crc1_ok && crc2_ok) {
80 gd->env_addr = addr2;
81 gd->env_valid = 1;
82 } else if (!crc1_ok && !crc2_ok) {
83 gd->env_addr = addr_default;
84 gd->env_valid = 0;
wdenkc3f9d492004-03-14 00:59:59 +000085 } else if (flag1 == ACTIVE_FLAG && flag2 == OBSOLETE_FLAG) {
Igor Grinberg82b54b92011-11-07 01:14:09 +000086 gd->env_addr = addr1;
87 gd->env_valid = 1;
wdenkc3f9d492004-03-14 00:59:59 +000088 } else if (flag1 == OBSOLETE_FLAG && flag2 == ACTIVE_FLAG) {
Igor Grinberg82b54b92011-11-07 01:14:09 +000089 gd->env_addr = addr2;
90 gd->env_valid = 1;
wdenkc3f9d492004-03-14 00:59:59 +000091 } else if (flag1 == flag2) {
Igor Grinberg82b54b92011-11-07 01:14:09 +000092 gd->env_addr = addr1;
93 gd->env_valid = 2;
wdenkc3f9d492004-03-14 00:59:59 +000094 } else if (flag1 == 0xFF) {
Igor Grinberg82b54b92011-11-07 01:14:09 +000095 gd->env_addr = addr1;
96 gd->env_valid = 2;
wdenkc3f9d492004-03-14 00:59:59 +000097 } else if (flag2 == 0xFF) {
Igor Grinberg82b54b92011-11-07 01:14:09 +000098 gd->env_addr = addr2;
99 gd->env_valid = 2;
wdenkc6097192002-11-03 00:24:07 +0000100 }
101
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200102 return 0;
wdenkc6097192002-11-03 00:24:07 +0000103}
104
105#ifdef CMD_SAVEENV
106int saveenv(void)
107{
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200108 env_t env_new;
109 ssize_t len;
Igor Grinberg82b54b92011-11-07 01:14:09 +0000110 char *res, *saved_data = NULL;
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200111 char flag = OBSOLETE_FLAG, new_flag = ACTIVE_FLAG;
Igor Grinberg82b54b92011-11-07 01:14:09 +0000112 int rc = 1;
Jean-Christophe PLAGNIOL-VILLARD0e8d1582008-09-10 22:48:06 +0200113#if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200114 ulong up_data = 0;
wdenk500545c2003-03-06 14:23:06 +0000115#endif
wdenkc6097192002-11-03 00:24:07 +0000116
Igor Grinberg82b54b92011-11-07 01:14:09 +0000117 debug("Protect off %08lX ... %08lX\n", (ulong)flash_addr, end_addr);
wdenkc6097192002-11-03 00:24:07 +0000118
Igor Grinberg82b54b92011-11-07 01:14:09 +0000119 if (flash_sect_protect(0, (ulong)flash_addr, end_addr))
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200120 goto done;
wdenkc6097192002-11-03 00:24:07 +0000121
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200122 debug("Protect off %08lX ... %08lX\n",
wdenkc6097192002-11-03 00:24:07 +0000123 (ulong)flash_addr_new, end_addr_new);
124
Igor Grinberg82b54b92011-11-07 01:14:09 +0000125 if (flash_sect_protect(0, (ulong)flash_addr_new, end_addr_new))
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200126 goto done;
wdenkc6097192002-11-03 00:24:07 +0000127
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200128 res = (char *)&env_new.data;
Joe Hershbergerbe112352012-12-11 22:16:23 -0600129 len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200130 if (len < 0) {
131 error("Cannot export environment: errno = %d\n", errno);
132 goto done;
133 }
Igor Grinberg82b54b92011-11-07 01:14:09 +0000134 env_new.crc = crc32(0, env_new.data, ENV_SIZE);
135 env_new.flags = new_flag;
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200136
Jean-Christophe PLAGNIOL-VILLARD0e8d1582008-09-10 22:48:06 +0200137#if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE
Igor Grinberg82b54b92011-11-07 01:14:09 +0000138 up_data = end_addr_new + 1 - ((long)flash_addr_new + CONFIG_ENV_SIZE);
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200139 debug("Data to save 0x%lX\n", up_data);
wdenk47cd00f2003-03-06 13:39:27 +0000140 if (up_data) {
Igor Grinberg82b54b92011-11-07 01:14:09 +0000141 saved_data = malloc(up_data);
142 if (saved_data == NULL) {
wdenk8bde7f72003-06-27 21:31:46 +0000143 printf("Unable to save the rest of sector (%ld)\n",
wdenk47cd00f2003-03-06 13:39:27 +0000144 up_data);
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200145 goto done;
wdenk47cd00f2003-03-06 13:39:27 +0000146 }
wdenk8bde7f72003-06-27 21:31:46 +0000147 memcpy(saved_data,
Igor Grinberg82b54b92011-11-07 01:14:09 +0000148 (void *)((long)flash_addr_new + CONFIG_ENV_SIZE),
149 up_data);
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200150 debug("Data (start 0x%lX, len 0x%lX) saved at 0x%p\n",
151 (long)flash_addr_new + CONFIG_ENV_SIZE,
152 up_data, saved_data);
wdenk47cd00f2003-03-06 13:39:27 +0000153 }
154#endif
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200155 puts("Erasing Flash...");
Igor Grinberg82b54b92011-11-07 01:14:09 +0000156 debug(" %08lX ... %08lX ...", (ulong)flash_addr_new, end_addr_new);
wdenkc6097192002-11-03 00:24:07 +0000157
Igor Grinberg82b54b92011-11-07 01:14:09 +0000158 if (flash_sect_erase((ulong)flash_addr_new, end_addr_new))
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200159 goto done;
wdenkc6097192002-11-03 00:24:07 +0000160
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200161 puts("Writing to Flash... ");
162 debug(" %08lX ... %08lX ...",
wdenkc6097192002-11-03 00:24:07 +0000163 (ulong)&(flash_addr_new->data),
Igor Grinberg82b54b92011-11-07 01:14:09 +0000164 sizeof(env_ptr->data) + (ulong)&(flash_addr_new->data));
165 rc = flash_write((char *)&env_new, (ulong)flash_addr_new,
166 sizeof(env_new));
167 if (rc)
168 goto perror;
169
170 rc = flash_write(&flag, (ulong)&(flash_addr->flags),
171 sizeof(flash_addr->flags));
172 if (rc)
173 goto perror;
wdenkc6097192002-11-03 00:24:07 +0000174
Jean-Christophe PLAGNIOL-VILLARD0e8d1582008-09-10 22:48:06 +0200175#if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE
wdenk47cd00f2003-03-06 13:39:27 +0000176 if (up_data) { /* restore the rest of sector */
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200177 debug("Restoring the rest of data to 0x%lX len 0x%lX\n",
178 (long)flash_addr_new + CONFIG_ENV_SIZE, up_data);
wdenk8bde7f72003-06-27 21:31:46 +0000179 if (flash_write(saved_data,
Jean-Christophe PLAGNIOL-VILLARD0e8d1582008-09-10 22:48:06 +0200180 (long)flash_addr_new + CONFIG_ENV_SIZE,
Igor Grinberg82b54b92011-11-07 01:14:09 +0000181 up_data))
182 goto perror;
wdenk47cd00f2003-03-06 13:39:27 +0000183 }
184#endif
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200185 puts("done\n");
186
wdenkc6097192002-11-03 00:24:07 +0000187 {
Igor Grinberg82b54b92011-11-07 01:14:09 +0000188 env_t *etmp = flash_addr;
wdenkc6097192002-11-03 00:24:07 +0000189 ulong ltmp = end_addr;
190
191 flash_addr = flash_addr_new;
192 flash_addr_new = etmp;
193
194 end_addr = end_addr_new;
195 end_addr_new = ltmp;
196 }
197
198 rc = 0;
Igor Grinberg82b54b92011-11-07 01:14:09 +0000199 goto done;
200perror:
201 flash_perror(rc);
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200202done:
wdenk47cd00f2003-03-06 13:39:27 +0000203 if (saved_data)
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200204 free(saved_data);
wdenkc6097192002-11-03 00:24:07 +0000205 /* try to re-protect */
Igor Grinberg82b54b92011-11-07 01:14:09 +0000206 flash_sect_protect(1, (ulong)flash_addr, end_addr);
207 flash_sect_protect(1, (ulong)flash_addr_new, end_addr_new);
wdenkc6097192002-11-03 00:24:07 +0000208
209 return rc;
210}
211#endif /* CMD_SAVEENV */
212
Jean-Christophe PLAGNIOL-VILLARD0e8d1582008-09-10 22:48:06 +0200213#else /* ! CONFIG_ENV_ADDR_REDUND */
wdenkc6097192002-11-03 00:24:07 +0000214
Igor Grinberg82b54b92011-11-07 01:14:09 +0000215int env_init(void)
wdenkc6097192002-11-03 00:24:07 +0000216{
wdenkc6097192002-11-03 00:24:07 +0000217 if (crc32(0, env_ptr->data, ENV_SIZE) == env_ptr->crc) {
Igor Grinberg82b54b92011-11-07 01:14:09 +0000218 gd->env_addr = (ulong)&(env_ptr->data);
219 gd->env_valid = 1;
220 return 0;
wdenkc6097192002-11-03 00:24:07 +0000221 }
Dirk Behme9bb8b202007-08-20 07:09:05 +0200222
Igor Grinberg82b54b92011-11-07 01:14:09 +0000223 gd->env_addr = (ulong)&default_environment[0];
224 gd->env_valid = 0;
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200225 return 0;
wdenkc6097192002-11-03 00:24:07 +0000226}
227
228#ifdef CMD_SAVEENV
wdenkc6097192002-11-03 00:24:07 +0000229int saveenv(void)
230{
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200231 env_t env_new;
232 ssize_t len;
233 int rc = 1;
Igor Grinberg82b54b92011-11-07 01:14:09 +0000234 char *res, *saved_data = NULL;
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200235#if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE
236 ulong up_data = 0;
wdenkc6097192002-11-03 00:24:07 +0000237
Igor Grinberg82b54b92011-11-07 01:14:09 +0000238 up_data = end_addr + 1 - ((long)flash_addr + CONFIG_ENV_SIZE);
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200239 debug("Data to save 0x%lx\n", up_data);
240 if (up_data) {
Igor Grinberg82b54b92011-11-07 01:14:09 +0000241 saved_data = malloc(up_data);
242 if (saved_data == NULL) {
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200243 printf("Unable to save the rest of sector (%ld)\n",
244 up_data);
245 goto done;
246 }
247 memcpy(saved_data,
248 (void *)((long)flash_addr + CONFIG_ENV_SIZE), up_data);
249 debug("Data (start 0x%lx, len 0x%lx) saved at 0x%lx\n",
250 (ulong)flash_addr + CONFIG_ENV_SIZE,
251 up_data,
252 (ulong)saved_data);
wdenkc6097192002-11-03 00:24:07 +0000253 }
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200254#endif /* CONFIG_ENV_SECT_SIZE */
wdenkc6097192002-11-03 00:24:07 +0000255
Igor Grinberg82b54b92011-11-07 01:14:09 +0000256 debug("Protect off %08lX ... %08lX\n", (ulong)flash_addr, end_addr);
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200257
258 if (flash_sect_protect(0, (long)flash_addr, end_addr))
259 goto done;
260
261 res = (char *)&env_new.data;
Joe Hershbergerbe112352012-12-11 22:16:23 -0600262 len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200263 if (len < 0) {
264 error("Cannot export environment: errno = %d\n", errno);
265 goto done;
266 }
267 env_new.crc = crc32(0, env_new.data, ENV_SIZE);
268
269 puts("Erasing Flash...");
270 if (flash_sect_erase((long)flash_addr, end_addr))
271 goto done;
272
273 puts("Writing to Flash... ");
274 rc = flash_write((char *)&env_new, (long)flash_addr, CONFIG_ENV_SIZE);
Igor Grinberg82b54b92011-11-07 01:14:09 +0000275 if (rc != 0)
276 goto perror;
277
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200278#if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE
279 if (up_data) { /* restore the rest of sector */
280 debug("Restoring the rest of data to 0x%lx len 0x%lx\n",
281 (ulong)flash_addr + CONFIG_ENV_SIZE, up_data);
282 if (flash_write(saved_data,
283 (long)flash_addr + CONFIG_ENV_SIZE,
Igor Grinberg82b54b92011-11-07 01:14:09 +0000284 up_data))
285 goto perror;
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200286 }
287#endif
288 puts("done\n");
289 rc = 0;
Igor Grinberg82b54b92011-11-07 01:14:09 +0000290 goto done;
291perror:
292 flash_perror(rc);
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200293done:
294 if (saved_data)
295 free(saved_data);
wdenkc6097192002-11-03 00:24:07 +0000296 /* try to re-protect */
Igor Grinberg82b54b92011-11-07 01:14:09 +0000297 flash_sect_protect(1, (long)flash_addr, end_addr);
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200298 return rc;
wdenkc6097192002-11-03 00:24:07 +0000299}
wdenkc6097192002-11-03 00:24:07 +0000300#endif /* CMD_SAVEENV */
301
Jean-Christophe PLAGNIOL-VILLARD0e8d1582008-09-10 22:48:06 +0200302#endif /* CONFIG_ENV_ADDR_REDUND */
wdenkc6097192002-11-03 00:24:07 +0000303
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200304void env_relocate_spec(void)
wdenkc6097192002-11-03 00:24:07 +0000305{
Jean-Christophe PLAGNIOL-VILLARD0e8d1582008-09-10 22:48:06 +0200306#ifdef CONFIG_ENV_ADDR_REDUND
wdenkc3f9d492004-03-14 00:59:59 +0000307 if (gd->env_addr != (ulong)&(flash_addr->data)) {
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200308 env_t *etmp = flash_addr;
wdenkc6097192002-11-03 00:24:07 +0000309 ulong ltmp = end_addr;
310
311 flash_addr = flash_addr_new;
312 flash_addr_new = etmp;
313
314 end_addr = end_addr_new;
315 end_addr_new = ltmp;
316 }
317
wdenkc3f9d492004-03-14 00:59:59 +0000318 if (flash_addr_new->flags != OBSOLETE_FLAG &&
Igor Grinberg82b54b92011-11-07 01:14:09 +0000319 crc32(0, flash_addr_new->data, ENV_SIZE) == flash_addr_new->crc) {
wdenkc3f9d492004-03-14 00:59:59 +0000320 char flag = OBSOLETE_FLAG;
321
wdenkc6097192002-11-03 00:24:07 +0000322 gd->env_valid = 2;
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200323 flash_sect_protect(0, (ulong)flash_addr_new, end_addr_new);
wdenkc3f9d492004-03-14 00:59:59 +0000324 flash_write(&flag,
wdenk8bde7f72003-06-27 21:31:46 +0000325 (ulong)&(flash_addr_new->flags),
326 sizeof(flash_addr_new->flags));
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200327 flash_sect_protect(1, (ulong)flash_addr_new, end_addr_new);
wdenkc6097192002-11-03 00:24:07 +0000328 }
329
wdenkc3f9d492004-03-14 00:59:59 +0000330 if (flash_addr->flags != ACTIVE_FLAG &&
331 (flash_addr->flags & ACTIVE_FLAG) == ACTIVE_FLAG) {
332 char flag = ACTIVE_FLAG;
333
wdenkc6097192002-11-03 00:24:07 +0000334 gd->env_valid = 2;
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200335 flash_sect_protect(0, (ulong)flash_addr, end_addr);
wdenkc3f9d492004-03-14 00:59:59 +0000336 flash_write(&flag,
wdenk8bde7f72003-06-27 21:31:46 +0000337 (ulong)&(flash_addr->flags),
338 sizeof(flash_addr->flags));
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200339 flash_sect_protect(1, (ulong)flash_addr, end_addr);
wdenkc6097192002-11-03 00:24:07 +0000340 }
341
342 if (gd->env_valid == 2)
Igor Grinberg82b54b92011-11-07 01:14:09 +0000343 puts("*** Warning - some problems detected "
344 "reading environment; recovered successfully\n\n");
Jean-Christophe PLAGNIOL-VILLARD0e8d1582008-09-10 22:48:06 +0200345#endif /* CONFIG_ENV_ADDR_REDUND */
Wolfgang Denkea882ba2010-06-20 23:33:59 +0200346
347 env_import((char *)flash_addr, 1);
wdenkc6097192002-11-03 00:24:07 +0000348}