xref: /openbmc/u-boot/env/ubi.c (revision 203e94f6c9ca03e260175ce240f5856507395585)
1 /*
2  * (c) Copyright 2012 by National Instruments,
3  *        Joe Hershberger <joe.hershberger@ni.com>
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 
8 #include <common.h>
9 
10 #include <command.h>
11 #include <environment.h>
12 #include <errno.h>
13 #include <malloc.h>
14 #include <memalign.h>
15 #include <search.h>
16 #include <ubi_uboot.h>
17 #undef crc32
18 
19 char *env_name_spec = "UBI";
20 
21 env_t *env_ptr;
22 
23 DECLARE_GLOBAL_DATA_PTR;
24 
25 int env_init(void)
26 {
27 	/* use default */
28 	gd->env_addr = (ulong)&default_environment[0];
29 	gd->env_valid = ENV_VALID;
30 
31 	return 0;
32 }
33 
34 #ifdef CONFIG_CMD_SAVEENV
35 #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
36 int saveenv(void)
37 {
38 	ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
39 	int ret;
40 
41 	ret = env_export(env_new);
42 	if (ret)
43 		return ret;
44 
45 	if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
46 		printf("\n** Cannot find mtd partition \"%s\"\n",
47 		       CONFIG_ENV_UBI_PART);
48 		return 1;
49 	}
50 
51 	if (gd->env_valid == ENV_VALID) {
52 		puts("Writing to redundant UBI... ");
53 		if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME_REDUND,
54 				     (void *)env_new, CONFIG_ENV_SIZE)) {
55 			printf("\n** Unable to write env to %s:%s **\n",
56 			       CONFIG_ENV_UBI_PART,
57 			       CONFIG_ENV_UBI_VOLUME_REDUND);
58 			return 1;
59 		}
60 	} else {
61 		puts("Writing to UBI... ");
62 		if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME,
63 				     (void *)env_new, CONFIG_ENV_SIZE)) {
64 			printf("\n** Unable to write env to %s:%s **\n",
65 			       CONFIG_ENV_UBI_PART,
66 			       CONFIG_ENV_UBI_VOLUME);
67 			return 1;
68 		}
69 	}
70 
71 	puts("done\n");
72 
73 	gd->env_valid = gd->env_valid == ENV_REDUND ? ENV_VALID : ENV_REDUND;
74 
75 	return 0;
76 }
77 #else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
78 int saveenv(void)
79 {
80 	ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
81 	int ret;
82 
83 	ret = env_export(env_new);
84 	if (ret)
85 		return ret;
86 
87 	if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
88 		printf("\n** Cannot find mtd partition \"%s\"\n",
89 		       CONFIG_ENV_UBI_PART);
90 		return 1;
91 	}
92 
93 	if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, (void *)env_new,
94 			     CONFIG_ENV_SIZE)) {
95 		printf("\n** Unable to write env to %s:%s **\n",
96 		       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
97 		return 1;
98 	}
99 
100 	puts("done\n");
101 	return 0;
102 }
103 #endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
104 #endif /* CONFIG_CMD_SAVEENV */
105 
106 #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
107 void env_relocate_spec(void)
108 {
109 	ALLOC_CACHE_ALIGN_BUFFER(char, env1_buf, CONFIG_ENV_SIZE);
110 	ALLOC_CACHE_ALIGN_BUFFER(char, env2_buf, CONFIG_ENV_SIZE);
111 	env_t *tmp_env1, *tmp_env2;
112 
113 	/*
114 	 * In case we have restarted u-boot there is a chance that buffer
115 	 * contains old environment (from the previous boot).
116 	 * If UBI volume is zero size, ubi_volume_read() doesn't modify the
117 	 * buffer.
118 	 * We need to clear buffer manually here, so the invalid CRC will
119 	 * cause setting default environment as expected.
120 	 */
121 	memset(env1_buf, 0x0, CONFIG_ENV_SIZE);
122 	memset(env2_buf, 0x0, CONFIG_ENV_SIZE);
123 
124 	tmp_env1 = (env_t *)env1_buf;
125 	tmp_env2 = (env_t *)env2_buf;
126 
127 	if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
128 		printf("\n** Cannot find mtd partition \"%s\"\n",
129 		       CONFIG_ENV_UBI_PART);
130 		set_default_env(NULL);
131 		return;
132 	}
133 
134 	if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)tmp_env1,
135 			    CONFIG_ENV_SIZE)) {
136 		printf("\n** Unable to read env from %s:%s **\n",
137 		       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
138 	}
139 
140 	if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND, (void *)tmp_env2,
141 			    CONFIG_ENV_SIZE)) {
142 		printf("\n** Unable to read redundant env from %s:%s **\n",
143 		       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME_REDUND);
144 	}
145 
146 	env_import_redund((char *)tmp_env1, (char *)tmp_env2);
147 }
148 #else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */
149 void env_relocate_spec(void)
150 {
151 	ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
152 
153 	/*
154 	 * In case we have restarted u-boot there is a chance that buffer
155 	 * contains old environment (from the previous boot).
156 	 * If UBI volume is zero size, ubi_volume_read() doesn't modify the
157 	 * buffer.
158 	 * We need to clear buffer manually here, so the invalid CRC will
159 	 * cause setting default environment as expected.
160 	 */
161 	memset(buf, 0x0, CONFIG_ENV_SIZE);
162 
163 	if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
164 		printf("\n** Cannot find mtd partition \"%s\"\n",
165 		       CONFIG_ENV_UBI_PART);
166 		set_default_env(NULL);
167 		return;
168 	}
169 
170 	if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, buf, CONFIG_ENV_SIZE)) {
171 		printf("\n** Unable to read env from %s:%s **\n",
172 		       CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
173 		set_default_env(NULL);
174 		return;
175 	}
176 
177 	env_import(buf, 1);
178 }
179 #endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
180