blob: 0c3e93c2bf2d6397c1a7fac4c7672c4f2b548c2d [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Joe Hershberger2b744332013-04-08 10:32:51 +00002/*
3 * (c) Copyright 2012 by National Instruments,
4 * Joe Hershberger <joe.hershberger@ni.com>
Joe Hershberger2b744332013-04-08 10:32:51 +00005 */
6
Simon Glass401d1c42020-10-30 21:38:53 -06007#include <asm/global_data.h>
Joe Hershberger2b744332013-04-08 10:32:51 +00008
9#include <command.h>
Simon Glass0ac7d722019-08-01 09:47:00 -060010#include <env.h>
Simon Glassf3998fd2019-08-02 09:44:25 -060011#include <env_internal.h>
Joe Hershberger2b744332013-04-08 10:32:51 +000012#include <errno.h>
13#include <malloc.h>
Simon Glasscf92e052015-09-02 17:24:58 -060014#include <memalign.h>
Joe Hershberger2b744332013-04-08 10:32:51 +000015#include <search.h>
16#include <ubi_uboot.h>
17#undef crc32
18
Hamish Guthrie985186d2019-05-15 15:15:55 +020019#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
Joe Hershberger2b744332013-04-08 10:32:51 +000028DECLARE_GLOBAL_DATA_PTR;
29
Patrick Delaunay91fc7852022-12-14 16:51:31 +010030#if CONFIG_SYS_REDUNDAND_ENVIRONMENT
31#define ENV_UBI_VOLUME_REDUND CONFIG_ENV_UBI_VOLUME_REDUND
32#else
33#define ENV_UBI_VOLUME_REDUND "invalid"
34#endif
35
Joe Hershberger2b744332013-04-08 10:32:51 +000036#ifdef CONFIG_CMD_SAVEENV
Joe Hershberger785881f2013-04-08 10:32:52 +000037#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
Simon Glasse5bce242017-08-03 12:22:01 -060038static int env_ubi_save(void)
Joe Hershberger785881f2013-04-08 10:32:52 +000039{
40 ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
Marek Vasut7ce15262014-03-05 19:59:50 +010041 int ret;
Joe Hershberger785881f2013-04-08 10:32:52 +000042
Marek Vasut7ce15262014-03-05 19:59:50 +010043 ret = env_export(env_new);
44 if (ret)
45 return ret;
Joe Hershberger785881f2013-04-08 10:32:52 +000046
Hamish Guthrie985186d2019-05-15 15:15:55 +020047 if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
Joe Hershberger785881f2013-04-08 10:32:52 +000048 printf("\n** Cannot find mtd partition \"%s\"\n",
49 CONFIG_ENV_UBI_PART);
50 return 1;
51 }
52
Simon Glass203e94f2017-08-03 12:21:56 -060053 if (gd->env_valid == ENV_VALID) {
Joe Hershberger785881f2013-04-08 10:32:52 +000054 puts("Writing to redundant UBI... ");
55 if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME_REDUND,
56 (void *)env_new, CONFIG_ENV_SIZE)) {
57 printf("\n** Unable to write env to %s:%s **\n",
58 CONFIG_ENV_UBI_PART,
59 CONFIG_ENV_UBI_VOLUME_REDUND);
60 return 1;
61 }
62 } else {
63 puts("Writing to UBI... ");
64 if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME,
65 (void *)env_new, CONFIG_ENV_SIZE)) {
66 printf("\n** Unable to write env to %s:%s **\n",
67 CONFIG_ENV_UBI_PART,
68 CONFIG_ENV_UBI_VOLUME);
69 return 1;
70 }
71 }
72
73 puts("done\n");
74
Simon Glass203e94f2017-08-03 12:21:56 -060075 gd->env_valid = gd->env_valid == ENV_REDUND ? ENV_VALID : ENV_REDUND;
Joe Hershberger785881f2013-04-08 10:32:52 +000076
77 return 0;
78}
79#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
Simon Glasse5bce242017-08-03 12:22:01 -060080static int env_ubi_save(void)
Joe Hershberger2b744332013-04-08 10:32:51 +000081{
82 ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
Marek Vasut7ce15262014-03-05 19:59:50 +010083 int ret;
Joe Hershberger2b744332013-04-08 10:32:51 +000084
Marek Vasut7ce15262014-03-05 19:59:50 +010085 ret = env_export(env_new);
86 if (ret)
87 return ret;
Joe Hershberger2b744332013-04-08 10:32:51 +000088
Hamish Guthrie985186d2019-05-15 15:15:55 +020089 if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
Joe Hershberger2b744332013-04-08 10:32:51 +000090 printf("\n** Cannot find mtd partition \"%s\"\n",
91 CONFIG_ENV_UBI_PART);
92 return 1;
93 }
94
Joe Hershberger2b744332013-04-08 10:32:51 +000095 if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, (void *)env_new,
96 CONFIG_ENV_SIZE)) {
97 printf("\n** Unable to write env to %s:%s **\n",
98 CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
99 return 1;
100 }
101
102 puts("done\n");
103 return 0;
104}
Joe Hershberger785881f2013-04-08 10:32:52 +0000105#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
Joe Hershberger2b744332013-04-08 10:32:51 +0000106#endif /* CONFIG_CMD_SAVEENV */
107
Joe Hershberger785881f2013-04-08 10:32:52 +0000108#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
Simon Glassc5951992017-08-03 12:22:17 -0600109static int env_ubi_load(void)
Joe Hershberger785881f2013-04-08 10:32:52 +0000110{
111 ALLOC_CACHE_ALIGN_BUFFER(char, env1_buf, CONFIG_ENV_SIZE);
112 ALLOC_CACHE_ALIGN_BUFFER(char, env2_buf, CONFIG_ENV_SIZE);
Simon Goldschmidt31f044b2018-01-31 14:47:11 +0100113 int read1_fail, read2_fail;
Fiach Antaw9d364af2017-01-25 18:53:12 +1000114 env_t *tmp_env1, *tmp_env2;
Joe Hershberger785881f2013-04-08 10:32:52 +0000115
Marcin Niestrojc1f51e02016-05-24 14:59:55 +0200116 /*
117 * In case we have restarted u-boot there is a chance that buffer
118 * contains old environment (from the previous boot).
119 * If UBI volume is zero size, ubi_volume_read() doesn't modify the
120 * buffer.
121 * We need to clear buffer manually here, so the invalid CRC will
122 * cause setting default environment as expected.
123 */
124 memset(env1_buf, 0x0, CONFIG_ENV_SIZE);
125 memset(env2_buf, 0x0, CONFIG_ENV_SIZE);
126
Joe Hershberger785881f2013-04-08 10:32:52 +0000127 tmp_env1 = (env_t *)env1_buf;
128 tmp_env2 = (env_t *)env2_buf;
129
Hamish Guthrie985186d2019-05-15 15:15:55 +0200130 if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
Joe Hershberger785881f2013-04-08 10:32:52 +0000131 printf("\n** Cannot find mtd partition \"%s\"\n",
132 CONFIG_ENV_UBI_PART);
Simon Glass0ac7d722019-08-01 09:47:00 -0600133 env_set_default(NULL, 0);
Simon Glassc5951992017-08-03 12:22:17 -0600134 return -EIO;
Joe Hershberger785881f2013-04-08 10:32:52 +0000135 }
136
Simon Goldschmidt31f044b2018-01-31 14:47:11 +0100137 read1_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)tmp_env1,
138 CONFIG_ENV_SIZE);
139 if (read1_fail)
Joe Hershberger785881f2013-04-08 10:32:52 +0000140 printf("\n** Unable to read env from %s:%s **\n",
141 CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
Joe Hershberger785881f2013-04-08 10:32:52 +0000142
Simon Goldschmidt31f044b2018-01-31 14:47:11 +0100143 read2_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND,
144 (void *)tmp_env2, CONFIG_ENV_SIZE);
145 if (read2_fail)
Joe Hershberger785881f2013-04-08 10:32:52 +0000146 printf("\n** Unable to read redundant env from %s:%s **\n",
147 CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME_REDUND);
Joe Hershberger785881f2013-04-08 10:32:52 +0000148
Simon Goldschmidt31f044b2018-01-31 14:47:11 +0100149 return env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2,
Marek Vasut890feec2020-07-07 20:51:35 +0200150 read2_fail, H_EXTERNAL);
Joe Hershberger785881f2013-04-08 10:32:52 +0000151}
152#else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
Simon Glassc5951992017-08-03 12:22:17 -0600153static int env_ubi_load(void)
Joe Hershberger2b744332013-04-08 10:32:51 +0000154{
155 ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
156
Marcin Niestrojc1f51e02016-05-24 14:59:55 +0200157 /*
158 * In case we have restarted u-boot there is a chance that buffer
159 * contains old environment (from the previous boot).
160 * If UBI volume is zero size, ubi_volume_read() doesn't modify the
161 * buffer.
162 * We need to clear buffer manually here, so the invalid CRC will
163 * cause setting default environment as expected.
164 */
165 memset(buf, 0x0, CONFIG_ENV_SIZE);
166
Hamish Guthrie985186d2019-05-15 15:15:55 +0200167 if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
Joe Hershberger2b744332013-04-08 10:32:51 +0000168 printf("\n** Cannot find mtd partition \"%s\"\n",
169 CONFIG_ENV_UBI_PART);
Simon Glass0ac7d722019-08-01 09:47:00 -0600170 env_set_default(NULL, 0);
Simon Glassc5951992017-08-03 12:22:17 -0600171 return -EIO;
Joe Hershberger2b744332013-04-08 10:32:51 +0000172 }
173
Kevin Smitha7c06cd2015-10-23 17:51:47 +0000174 if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, buf, CONFIG_ENV_SIZE)) {
Joe Hershberger2b744332013-04-08 10:32:51 +0000175 printf("\n** Unable to read env from %s:%s **\n",
176 CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
Simon Glass0ac7d722019-08-01 09:47:00 -0600177 env_set_default(NULL, 0);
Simon Glassc5951992017-08-03 12:22:17 -0600178 return -EIO;
Joe Hershberger2b744332013-04-08 10:32:51 +0000179 }
180
Marek Vasut890feec2020-07-07 20:51:35 +0200181 return env_import(buf, 1, H_EXTERNAL);
Joe Hershberger2b744332013-04-08 10:32:51 +0000182}
Joe Hershberger785881f2013-04-08 10:32:52 +0000183#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
Simon Glass4415f1d2017-08-03 12:21:58 -0600184
Patrick Delaunay91fc7852022-12-14 16:51:31 +0100185static int env_ubi_erase(void)
186{
187 ALLOC_CACHE_ALIGN_BUFFER(char, env_buf, CONFIG_ENV_SIZE);
188 int ret = 0;
189
190 if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
191 printf("\n** Cannot find mtd partition \"%s\"\n",
192 CONFIG_ENV_UBI_PART);
193 return 1;
194 }
195
196 memset(env_buf, 0x0, CONFIG_ENV_SIZE);
197
198 if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME,
199 (void *)env_buf, CONFIG_ENV_SIZE)) {
200 printf("\n** Unable to erase env to %s:%s **\n",
201 CONFIG_ENV_UBI_PART,
202 CONFIG_ENV_UBI_VOLUME);
203 ret = 1;
204 }
205 if (IS_ENABLED(CONFIG_SYS_REDUNDAND_ENVIRONMENT)) {
206 if (ubi_volume_write(ENV_UBI_VOLUME_REDUND,
207 (void *)env_buf, CONFIG_ENV_SIZE)) {
208 printf("\n** Unable to erase env to %s:%s **\n",
209 CONFIG_ENV_UBI_PART,
210 ENV_UBI_VOLUME_REDUND);
211 ret = 1;
212 }
213 }
214
215 return ret;
216}
217
Simon Glass4415f1d2017-08-03 12:21:58 -0600218U_BOOT_ENV_LOCATION(ubi) = {
219 .location = ENVL_UBI,
Marek Vasut344ca792018-08-21 15:53:33 +0200220 ENV_NAME("UBI")
Simon Glasse5bce242017-08-03 12:22:01 -0600221 .load = env_ubi_load,
222 .save = env_save_ptr(env_ubi_save),
Patrick Delaunay91fc7852022-12-14 16:51:31 +0100223 .erase = ENV_ERASE_PTR(env_ubi_erase),
Simon Glass4415f1d2017-08-03 12:21:58 -0600224};