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 */