]>
Commit | Line | Data |
---|---|---|
2b74433f JH |
1 | /* |
2 | * (c) Copyright 2012 by National Instruments, | |
3 | * Joe Hershberger <joe.hershberger@ni.com> | |
4 | * | |
5 | * See file CREDITS for list of people who contributed to this | |
6 | * project. | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU General Public License as | |
10 | * published by the Free Software Foundation; either version 2 of | |
11 | * the License, or (at your option) any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | * GNU General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with this program; if not, write to the Free Software | |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
21 | * MA 02111-1307 USA | |
22 | */ | |
23 | ||
24 | #include <common.h> | |
25 | ||
26 | #include <command.h> | |
27 | #include <environment.h> | |
28 | #include <errno.h> | |
29 | #include <malloc.h> | |
30 | #include <search.h> | |
31 | #include <ubi_uboot.h> | |
32 | #undef crc32 | |
33 | ||
34 | char *env_name_spec = "UBI"; | |
35 | ||
36 | env_t *env_ptr; | |
37 | ||
38 | DECLARE_GLOBAL_DATA_PTR; | |
39 | ||
40 | int env_init(void) | |
41 | { | |
42 | /* use default */ | |
43 | gd->env_addr = (ulong)&default_environment[0]; | |
44 | gd->env_valid = 1; | |
45 | ||
46 | return 0; | |
47 | } | |
48 | ||
49 | #ifdef CONFIG_CMD_SAVEENV | |
785881f7 JH |
50 | #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT |
51 | static unsigned char env_flags; | |
52 | ||
53 | int saveenv(void) | |
54 | { | |
55 | ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); | |
56 | ssize_t len; | |
57 | char *res; | |
58 | ||
59 | res = (char *)&env_new->data; | |
60 | len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); | |
61 | if (len < 0) { | |
62 | error("Cannot export environment: errno = %d\n", errno); | |
63 | return 1; | |
64 | } | |
65 | ||
66 | if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) { | |
67 | printf("\n** Cannot find mtd partition \"%s\"\n", | |
68 | CONFIG_ENV_UBI_PART); | |
69 | return 1; | |
70 | } | |
71 | ||
72 | env_new->crc = crc32(0, env_new->data, ENV_SIZE); | |
73 | env_new->flags = ++env_flags; /* increase the serial */ | |
74 | ||
75 | if (gd->env_valid == 1) { | |
76 | puts("Writing to redundant UBI... "); | |
77 | if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME_REDUND, | |
78 | (void *)env_new, CONFIG_ENV_SIZE)) { | |
79 | printf("\n** Unable to write env to %s:%s **\n", | |
80 | CONFIG_ENV_UBI_PART, | |
81 | CONFIG_ENV_UBI_VOLUME_REDUND); | |
82 | return 1; | |
83 | } | |
84 | } else { | |
85 | puts("Writing to UBI... "); | |
86 | if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, | |
87 | (void *)env_new, CONFIG_ENV_SIZE)) { | |
88 | printf("\n** Unable to write env to %s:%s **\n", | |
89 | CONFIG_ENV_UBI_PART, | |
90 | CONFIG_ENV_UBI_VOLUME); | |
91 | return 1; | |
92 | } | |
93 | } | |
94 | ||
95 | puts("done\n"); | |
96 | ||
97 | gd->env_valid = gd->env_valid == 2 ? 1 : 2; | |
98 | ||
99 | return 0; | |
100 | } | |
101 | #else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */ | |
2b74433f JH |
102 | int saveenv(void) |
103 | { | |
104 | ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); | |
105 | ssize_t len; | |
106 | char *res; | |
107 | ||
108 | res = (char *)&env_new->data; | |
109 | len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); | |
110 | if (len < 0) { | |
111 | error("Cannot export environment: errno = %d\n", errno); | |
112 | return 1; | |
113 | } | |
114 | ||
115 | if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) { | |
116 | printf("\n** Cannot find mtd partition \"%s\"\n", | |
117 | CONFIG_ENV_UBI_PART); | |
118 | return 1; | |
119 | } | |
120 | ||
121 | env_new->crc = crc32(0, env_new->data, ENV_SIZE); | |
122 | ||
123 | if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, (void *)env_new, | |
124 | CONFIG_ENV_SIZE)) { | |
125 | printf("\n** Unable to write env to %s:%s **\n", | |
126 | CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME); | |
127 | return 1; | |
128 | } | |
129 | ||
130 | puts("done\n"); | |
131 | return 0; | |
132 | } | |
785881f7 | 133 | #endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */ |
2b74433f JH |
134 | #endif /* CONFIG_CMD_SAVEENV */ |
135 | ||
785881f7 JH |
136 | #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT |
137 | void env_relocate_spec(void) | |
138 | { | |
139 | ALLOC_CACHE_ALIGN_BUFFER(char, env1_buf, CONFIG_ENV_SIZE); | |
140 | ALLOC_CACHE_ALIGN_BUFFER(char, env2_buf, CONFIG_ENV_SIZE); | |
141 | int crc1_ok = 0, crc2_ok = 0; | |
142 | env_t *ep, *tmp_env1, *tmp_env2; | |
143 | ||
144 | tmp_env1 = (env_t *)env1_buf; | |
145 | tmp_env2 = (env_t *)env2_buf; | |
146 | ||
147 | if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) { | |
148 | printf("\n** Cannot find mtd partition \"%s\"\n", | |
149 | CONFIG_ENV_UBI_PART); | |
150 | set_default_env(NULL); | |
151 | return; | |
152 | } | |
153 | ||
154 | if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)tmp_env1, | |
155 | CONFIG_ENV_SIZE)) { | |
156 | printf("\n** Unable to read env from %s:%s **\n", | |
157 | CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME); | |
158 | } | |
159 | ||
160 | if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND, (void *)tmp_env2, | |
161 | CONFIG_ENV_SIZE)) { | |
162 | printf("\n** Unable to read redundant env from %s:%s **\n", | |
163 | CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME_REDUND); | |
164 | } | |
165 | ||
166 | crc1_ok = crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc; | |
167 | crc2_ok = crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc; | |
168 | ||
169 | if (!crc1_ok && !crc2_ok) { | |
170 | set_default_env("!bad CRC"); | |
171 | return; | |
172 | } else if (crc1_ok && !crc2_ok) { | |
173 | gd->env_valid = 1; | |
174 | } else if (!crc1_ok && crc2_ok) { | |
175 | gd->env_valid = 2; | |
176 | } else { | |
177 | /* both ok - check serial */ | |
178 | if (tmp_env1->flags == 255 && tmp_env2->flags == 0) | |
179 | gd->env_valid = 2; | |
180 | else if (tmp_env2->flags == 255 && tmp_env1->flags == 0) | |
181 | gd->env_valid = 1; | |
182 | else if (tmp_env1->flags > tmp_env2->flags) | |
183 | gd->env_valid = 1; | |
184 | else if (tmp_env2->flags > tmp_env1->flags) | |
185 | gd->env_valid = 2; | |
186 | else /* flags are equal - almost impossible */ | |
187 | gd->env_valid = 1; | |
188 | } | |
189 | ||
190 | if (gd->env_valid == 1) | |
191 | ep = tmp_env1; | |
192 | else | |
193 | ep = tmp_env2; | |
194 | ||
195 | env_flags = ep->flags; | |
196 | env_import((char *)ep, 0); | |
197 | } | |
198 | #else /* ! CONFIG_SYS_REDUNDAND_ENVIRONMENT */ | |
2b74433f JH |
199 | void env_relocate_spec(void) |
200 | { | |
201 | ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE); | |
202 | ||
203 | if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) { | |
204 | printf("\n** Cannot find mtd partition \"%s\"\n", | |
205 | CONFIG_ENV_UBI_PART); | |
206 | set_default_env(NULL); | |
207 | return; | |
208 | } | |
209 | ||
210 | if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)&buf, | |
211 | CONFIG_ENV_SIZE)) { | |
212 | printf("\n** Unable to read env from %s:%s **\n", | |
213 | CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME); | |
214 | set_default_env(NULL); | |
215 | return; | |
216 | } | |
217 | ||
218 | env_import(buf, 1); | |
219 | } | |
785881f7 | 220 | #endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */ |