1 // SPDX-License-Identifier: GPL-2.0+
3 * (c) Copyright 2012 by National Instruments,
8 #include <asm/global_data.h>
12 #include <env_internal.h>
17 #include <ubi_uboot.h>
21 #define QUOTE(x) _QUOTE(x)
23 #if (CONFIG_ENV_UBI_VID_OFFSET == 0)
24 #define UBI_VID_OFFSET NULL
26 #define UBI_VID_OFFSET QUOTE(CONFIG_ENV_UBI_VID_OFFSET)
29 DECLARE_GLOBAL_DATA_PTR;
31 #if CONFIG_SYS_REDUNDAND_ENVIRONMENT
32 #define ENV_UBI_VOLUME_REDUND CONFIG_ENV_UBI_VOLUME_REDUND
34 #define ENV_UBI_VOLUME_REDUND "invalid"
37 #ifdef CONFIG_CMD_SAVEENV
38 #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
39 static int env_ubi_save(void)
41 ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
44 ret = env_export(env_new);
48 if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
49 printf("\n** Cannot find mtd partition \"%s\"\n",
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",
60 CONFIG_ENV_UBI_VOLUME_REDUND);
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",
69 CONFIG_ENV_UBI_VOLUME);
76 gd->env_valid = gd->env_valid == ENV_REDUND ? ENV_VALID : ENV_REDUND;
80 #else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
81 static int env_ubi_save(void)
83 ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
86 ret = env_export(env_new);
90 if (ubi_part(CONFIG_ENV_UBI_PART, UBI_VID_OFFSET)) {
91 printf("\n** Cannot find mtd partition \"%s\"\n",
96 if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, (void *)env_new,
98 printf("\n** Unable to write env to %s:%s **\n",
99 CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
106 #endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
107 #endif /* CONFIG_CMD_SAVEENV */
109 #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
110 static int env_ubi_load(void)
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;
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
122 * We need to clear buffer manually here, so the invalid CRC will
123 * cause setting default environment as expected.
125 memset(env1_buf, 0x0, CONFIG_ENV_SIZE);
126 memset(env2_buf, 0x0, CONFIG_ENV_SIZE);
128 tmp_env1 = (env_t *)env1_buf;
129 tmp_env2 = (env_t *)env2_buf;
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);
138 read1_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)tmp_env1,
141 printf("\n** Unable to read env from %s:%s **\n",
142 CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
144 read2_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND,
145 (void *)tmp_env2, CONFIG_ENV_SIZE);
147 printf("\n** Unable to read redundant env from %s:%s **\n",
148 CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME_REDUND);
150 return env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2,
151 read2_fail, H_EXTERNAL);
153 #else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
154 static int env_ubi_load(void)
156 ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
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
163 * We need to clear buffer manually here, so the invalid CRC will
164 * cause setting default environment as expected.
166 memset(buf, 0x0, CONFIG_ENV_SIZE);
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);
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);
182 return env_import(buf, 1, H_EXTERNAL);
184 #endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
186 static int env_ubi_erase(void)
188 ALLOC_CACHE_ALIGN_BUFFER(char, env_buf, CONFIG_ENV_SIZE);
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);
197 memset(env_buf, 0x0, CONFIG_ENV_SIZE);
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",
203 CONFIG_ENV_UBI_VOLUME);
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",
211 ENV_UBI_VOLUME_REDUND);
219 U_BOOT_ENV_LOCATION(ubi) = {
220 .location = ENVL_UBI,
222 .load = env_ubi_load,
223 .save = env_save_ptr(env_ubi_save),
224 .erase = ENV_ERASE_PTR(env_ubi_erase),