2 * (c) Copyright 2012 by National Instruments,
3 * Joe Hershberger <joe.hershberger@ni.com>
5 * SPDX-License-Identifier: GPL-2.0+
11 #include <environment.h>
15 #include <ubi_uboot.h>
18 char *env_name_spec = "UBI";
22 DECLARE_GLOBAL_DATA_PTR;
27 gd->env_addr = (ulong)&default_environment[0];
33 #ifdef CONFIG_CMD_SAVEENV
34 #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
35 static unsigned char env_flags;
39 ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
43 res = (char *)&env_new->data;
44 len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
46 error("Cannot export environment: errno = %d\n", errno);
50 if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
51 printf("\n** Cannot find mtd partition \"%s\"\n",
56 env_new->crc = crc32(0, env_new->data, ENV_SIZE);
57 env_new->flags = ++env_flags; /* increase the serial */
59 if (gd->env_valid == 1) {
60 puts("Writing to redundant UBI... ");
61 if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME_REDUND,
62 (void *)env_new, CONFIG_ENV_SIZE)) {
63 printf("\n** Unable to write env to %s:%s **\n",
65 CONFIG_ENV_UBI_VOLUME_REDUND);
69 puts("Writing to UBI... ");
70 if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME,
71 (void *)env_new, CONFIG_ENV_SIZE)) {
72 printf("\n** Unable to write env to %s:%s **\n",
74 CONFIG_ENV_UBI_VOLUME);
81 gd->env_valid = gd->env_valid == 2 ? 1 : 2;
85 #else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
88 ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
92 res = (char *)&env_new->data;
93 len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
95 error("Cannot export environment: errno = %d\n", errno);
99 if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
100 printf("\n** Cannot find mtd partition \"%s\"\n",
101 CONFIG_ENV_UBI_PART);
105 env_new->crc = crc32(0, env_new->data, ENV_SIZE);
107 if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, (void *)env_new,
109 printf("\n** Unable to write env to %s:%s **\n",
110 CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
117 #endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
118 #endif /* CONFIG_CMD_SAVEENV */
120 #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
121 void env_relocate_spec(void)
123 ALLOC_CACHE_ALIGN_BUFFER(char, env1_buf, CONFIG_ENV_SIZE);
124 ALLOC_CACHE_ALIGN_BUFFER(char, env2_buf, CONFIG_ENV_SIZE);
125 int crc1_ok = 0, crc2_ok = 0;
126 env_t *ep, *tmp_env1, *tmp_env2;
128 tmp_env1 = (env_t *)env1_buf;
129 tmp_env2 = (env_t *)env2_buf;
131 if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
132 printf("\n** Cannot find mtd partition \"%s\"\n",
133 CONFIG_ENV_UBI_PART);
134 set_default_env(NULL);
138 if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)tmp_env1,
140 printf("\n** Unable to read env from %s:%s **\n",
141 CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
144 if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND, (void *)tmp_env2,
146 printf("\n** Unable to read redundant env from %s:%s **\n",
147 CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME_REDUND);
150 crc1_ok = crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc;
151 crc2_ok = crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc;
153 if (!crc1_ok && !crc2_ok) {
154 set_default_env("!bad CRC");
156 } else if (crc1_ok && !crc2_ok) {
158 } else if (!crc1_ok && crc2_ok) {
161 /* both ok - check serial */
162 if (tmp_env1->flags == 255 && tmp_env2->flags == 0)
164 else if (tmp_env2->flags == 255 && tmp_env1->flags == 0)
166 else if (tmp_env1->flags > tmp_env2->flags)
168 else if (tmp_env2->flags > tmp_env1->flags)
170 else /* flags are equal - almost impossible */
174 if (gd->env_valid == 1)
179 env_flags = ep->flags;
180 env_import((char *)ep, 0);
182 #else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
183 void env_relocate_spec(void)
185 ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
187 if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
188 printf("\n** Cannot find mtd partition \"%s\"\n",
189 CONFIG_ENV_UBI_PART);
190 set_default_env(NULL);
194 if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)&buf,
196 printf("\n** Unable to read env from %s:%s **\n",
197 CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
198 set_default_env(NULL);
204 #endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */