Blame view
env/sf.c
6.9 KB
83d290c56 SPDX: Convert all... |
1 |
// SPDX-License-Identifier: GPL-2.0+ |
8c66497e0 Add support for e... |
2 |
/* |
ea882baf9 New implementatio... |
3 |
* (C) Copyright 2000-2010 |
8c66497e0 Add support for e... |
4 5 6 7 8 9 |
* Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com> * Andreas Heppel <aheppel@sysgo.de> * * (C) Copyright 2008 Atmel Corporation |
8c66497e0 Add support for e... |
10 11 |
*/ #include <common.h> |
9d922450a dm: Use dm.h head... |
12 |
#include <dm.h> |
8c66497e0 Add support for e... |
13 |
#include <environment.h> |
5b3375ac8 env_sf: support e... |
14 |
#include <malloc.h> |
843c9e879 dm: Add spi.h hea... |
15 |
#include <spi.h> |
8c66497e0 Add support for e... |
16 |
#include <spi_flash.h> |
ea882baf9 New implementatio... |
17 18 |
#include <search.h> #include <errno.h> |
19c31285a dm: env_sf: fix s... |
19 |
#include <dm/device-internal.h> |
8c66497e0 Add support for e... |
20 |
|
0e8d15866 rename CFG_ENV ma... |
21 |
#ifndef CONFIG_ENV_SPI_BUS |
2e4e5ad4c common: env_sf: U... |
22 |
# define CONFIG_ENV_SPI_BUS CONFIG_SF_DEFAULT_BUS |
8c66497e0 Add support for e... |
23 |
#endif |
0e8d15866 rename CFG_ENV ma... |
24 |
#ifndef CONFIG_ENV_SPI_CS |
2e4e5ad4c common: env_sf: U... |
25 |
# define CONFIG_ENV_SPI_CS CONFIG_SF_DEFAULT_CS |
8c66497e0 Add support for e... |
26 |
#endif |
0e8d15866 rename CFG_ENV ma... |
27 |
#ifndef CONFIG_ENV_SPI_MAX_HZ |
2e4e5ad4c common: env_sf: U... |
28 |
# define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED |
8c66497e0 Add support for e... |
29 |
#endif |
0e8d15866 rename CFG_ENV ma... |
30 |
#ifndef CONFIG_ENV_SPI_MODE |
2e4e5ad4c common: env_sf: U... |
31 |
# define CONFIG_ENV_SPI_MODE CONFIG_SF_DEFAULT_MODE |
8c66497e0 Add support for e... |
32 |
#endif |
4415f1d1f env: Create a loc... |
33 34 |
#ifndef CONFIG_SPL_BUILD #define CMD_SAVEENV |
b500c92b7 env: sf: Add supp... |
35 |
#define INITENV |
4415f1d1f env: Create a loc... |
36 |
#endif |
7319bcaf8 add redundant env... |
37 |
#ifdef CONFIG_ENV_OFFSET_REDUND |
4415f1d1f env: Create a loc... |
38 |
#ifdef CMD_SAVEENV |
eb58a7fc7 env: clean env_sf... |
39 40 |
static ulong env_offset = CONFIG_ENV_OFFSET; static ulong env_new_offset = CONFIG_ENV_OFFSET_REDUND; |
4415f1d1f env: Create a loc... |
41 |
#endif |
7319bcaf8 add redundant env... |
42 |
|
eb58a7fc7 env: clean env_sf... |
43 44 |
#define ACTIVE_FLAG 1 #define OBSOLETE_FLAG 0 |
a3110f01c env_sf: updated t... |
45 |
#endif /* CONFIG_ENV_OFFSET_REDUND */ |
7319bcaf8 add redundant env... |
46 |
|
8c66497e0 Add support for e... |
47 |
DECLARE_GLOBAL_DATA_PTR; |
8c66497e0 Add support for e... |
48 |
static struct spi_flash *env_flash; |
afa81a775 env_sf: factor ou... |
49 |
static int setup_flash_device(void) |
7319bcaf8 add redundant env... |
50 |
{ |
19c31285a dm: env_sf: fix s... |
51 52 |
#ifdef CONFIG_DM_SPI_FLASH struct udevice *new; |
afa81a775 env_sf: factor ou... |
53 |
int ret; |
19c31285a dm: env_sf: fix s... |
54 |
|
96907c0fe dm: spi: Read def... |
55 |
/* speed and mode will be read from DT */ |
19c31285a dm: env_sf: fix s... |
56 |
ret = spi_flash_probe_bus_cs(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS, |
25a17652c fix: env: Fix the... |
57 58 |
CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE, &new); |
19c31285a dm: env_sf: fix s... |
59 |
if (ret) { |
c5d548a9f env: common: acce... |
60 |
set_default_env("spi_flash_probe_bus_cs() failed", 0); |
c59519919 env: Adjust the l... |
61 |
return ret; |
19c31285a dm: env_sf: fix s... |
62 63 64 65 |
} env_flash = dev_get_uclass_priv(new); #else |
7319bcaf8 add redundant env... |
66 67 |
if (!env_flash) { |
a3110f01c env_sf: updated t... |
68 69 70 71 |
env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, CONFIG_ENV_SPI_CS, CONFIG_ENV_SPI_MAX_HZ, CONFIG_ENV_SPI_MODE); if (!env_flash) { |
c5d548a9f env: common: acce... |
72 |
set_default_env("spi_flash_probe() failed", 0); |
c59519919 env: Adjust the l... |
73 |
return -EIO; |
a3110f01c env_sf: updated t... |
74 |
} |
7319bcaf8 add redundant env... |
75 |
} |
19c31285a dm: env_sf: fix s... |
76 |
#endif |
afa81a775 env_sf: factor ou... |
77 78 79 80 |
return 0; } #if defined(CONFIG_ENV_OFFSET_REDUND) |
4415f1d1f env: Create a loc... |
81 |
#ifdef CMD_SAVEENV |
e5bce247b env: Switch over ... |
82 |
static int env_sf_save(void) |
afa81a775 env_sf: factor ou... |
83 84 85 |
{ env_t env_new; char *saved_buffer = NULL, flag = OBSOLETE_FLAG; |
0b2e5bbe6 env_sf: use DIV_R... |
86 |
u32 saved_size, saved_offset, sector; |
afa81a775 env_sf: factor ou... |
87 88 89 90 91 |
int ret; ret = setup_flash_device(); if (ret) return ret; |
7319bcaf8 add redundant env... |
92 |
|
7ce1526ed env: Add env_expo... |
93 94 |
ret = env_export(&env_new); if (ret) |
c59519919 env: Adjust the l... |
95 |
return -EIO; |
cd0f4fa1c Revert "env: fix ... |
96 |
env_new.flags = ACTIVE_FLAG; |
ea882baf9 New implementatio... |
97 |
|
203e94f6c env: Add an enum ... |
98 |
if (gd->env_valid == ENV_VALID) { |
a3110f01c env_sf: updated t... |
99 100 101 102 103 104 |
env_new_offset = CONFIG_ENV_OFFSET_REDUND; env_offset = CONFIG_ENV_OFFSET; } else { env_new_offset = CONFIG_ENV_OFFSET; env_offset = CONFIG_ENV_OFFSET_REDUND; } |
7319bcaf8 add redundant env... |
105 106 107 108 |
/* Is the sector larger than the env (i.e. embedded) */ if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { saved_size = CONFIG_ENV_SECT_SIZE - CONFIG_ENV_SIZE; saved_offset = env_new_offset + CONFIG_ENV_SIZE; |
7dd017446 env: use cache li... |
109 |
saved_buffer = memalign(ARCH_DMA_MINALIGN, saved_size); |
7319bcaf8 add redundant env... |
110 |
if (!saved_buffer) { |
c59519919 env: Adjust the l... |
111 |
ret = -ENOMEM; |
7319bcaf8 add redundant env... |
112 113 114 115 116 117 118 |
goto done; } ret = spi_flash_read(env_flash, saved_offset, saved_size, saved_buffer); if (ret) goto done; } |
0b2e5bbe6 env_sf: use DIV_R... |
119 |
sector = DIV_ROUND_UP(CONFIG_ENV_SIZE, CONFIG_ENV_SECT_SIZE); |
7319bcaf8 add redundant env... |
120 121 122 123 124 125 126 127 |
puts("Erasing SPI flash..."); ret = spi_flash_erase(env_flash, env_new_offset, sector * CONFIG_ENV_SECT_SIZE); if (ret) goto done; puts("Writing to SPI flash..."); |
7319bcaf8 add redundant env... |
128 |
|
a3110f01c env_sf: updated t... |
129 |
ret = spi_flash_write(env_flash, env_new_offset, |
cd0f4fa1c Revert "env: fix ... |
130 |
CONFIG_ENV_SIZE, &env_new); |
7319bcaf8 add redundant env... |
131 132 133 134 135 136 137 138 139 |
if (ret) goto done; if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { ret = spi_flash_write(env_flash, saved_offset, saved_size, saved_buffer); if (ret) goto done; } |
eb58a7fc7 env: clean env_sf... |
140 |
ret = spi_flash_write(env_flash, env_offset + offsetof(env_t, flags), |
cd0f4fa1c Revert "env: fix ... |
141 |
sizeof(env_new.flags), &flag); |
a3110f01c env_sf: updated t... |
142 143 |
if (ret) goto done; |
7319bcaf8 add redundant env... |
144 |
|
7319bcaf8 add redundant env... |
145 146 |
puts("done "); |
203e94f6c env: Add an enum ... |
147 |
gd->env_valid = gd->env_valid == ENV_REDUND ? ENV_VALID : ENV_REDUND; |
a3110f01c env_sf: updated t... |
148 |
|
2dc55d9ed fix redundant env... |
149 150 |
printf("Valid environment: %d ", (int)gd->env_valid); |
a3110f01c env_sf: updated t... |
151 |
|
7319bcaf8 add redundant env... |
152 153 154 |
done: if (saved_buffer) free(saved_buffer); |
eb58a7fc7 env: clean env_sf... |
155 |
|
7319bcaf8 add redundant env... |
156 157 |
return ret; } |
4415f1d1f env: Create a loc... |
158 |
#endif /* CMD_SAVEENV */ |
7319bcaf8 add redundant env... |
159 |
|
c59519919 env: Adjust the l... |
160 |
static int env_sf_load(void) |
7319bcaf8 add redundant env... |
161 162 |
{ int ret; |
80719938c env: sf: use env_... |
163 164 |
int read1_fail, read2_fail; env_t *tmp_env1, *tmp_env2; |
7319bcaf8 add redundant env... |
165 |
|
7dd017446 env: use cache li... |
166 167 168 169 |
tmp_env1 = (env_t *)memalign(ARCH_DMA_MINALIGN, CONFIG_ENV_SIZE); tmp_env2 = (env_t *)memalign(ARCH_DMA_MINALIGN, CONFIG_ENV_SIZE); |
ea882baf9 New implementatio... |
170 |
if (!tmp_env1 || !tmp_env2) { |
c5d548a9f env: common: acce... |
171 |
set_default_env("malloc() failed", 0); |
c59519919 env: Adjust the l... |
172 |
ret = -EIO; |
2dc55d9ed fix redundant env... |
173 |
goto out; |
7319bcaf8 add redundant env... |
174 |
} |
8fee8845e enf_sf: reuse set... |
175 176 |
ret = setup_flash_device(); if (ret) |
2dc55d9ed fix redundant env... |
177 |
goto out; |
7319bcaf8 add redundant env... |
178 |
|
80719938c env: sf: use env_... |
179 180 181 182 |
read1_fail = spi_flash_read(env_flash, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, tmp_env1); read2_fail = spi_flash_read(env_flash, CONFIG_ENV_OFFSET_REDUND, CONFIG_ENV_SIZE, tmp_env2); |
ea882baf9 New implementatio... |
183 |
|
80719938c env: sf: use env_... |
184 185 |
ret = env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2, read2_fail); |
7319bcaf8 add redundant env... |
186 |
|
7319bcaf8 add redundant env... |
187 188 |
spi_flash_free(env_flash); env_flash = NULL; |
7319bcaf8 add redundant env... |
189 |
out: |
ea882baf9 New implementatio... |
190 191 |
free(tmp_env1); free(tmp_env2); |
c59519919 env: Adjust the l... |
192 193 |
return ret; |
7319bcaf8 add redundant env... |
194 195 |
} #else |
4415f1d1f env: Create a loc... |
196 |
#ifdef CMD_SAVEENV |
e5bce247b env: Switch over ... |
197 |
static int env_sf_save(void) |
8c66497e0 Add support for e... |
198 |
{ |
0b2e5bbe6 env_sf: use DIV_R... |
199 |
u32 saved_size, saved_offset, sector; |
7ce1526ed env: Add env_expo... |
200 |
char *saved_buffer = NULL; |
eb58a7fc7 env: clean env_sf... |
201 |
int ret = 1; |
cd0f4fa1c Revert "env: fix ... |
202 |
env_t env_new; |
19c31285a dm: env_sf: fix s... |
203 |
|
afa81a775 env_sf: factor ou... |
204 205 206 |
ret = setup_flash_device(); if (ret) return ret; |
8c66497e0 Add support for e... |
207 |
|
5b3375ac8 env_sf: support e... |
208 209 210 211 212 |
/* Is the sector larger than the env (i.e. embedded) */ if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { saved_size = CONFIG_ENV_SECT_SIZE - CONFIG_ENV_SIZE; saved_offset = CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE; saved_buffer = malloc(saved_size); |
eb58a7fc7 env: clean env_sf... |
213 |
if (!saved_buffer) |
5b3375ac8 env_sf: support e... |
214 |
goto done; |
eb58a7fc7 env: clean env_sf... |
215 |
|
a3110f01c env_sf: updated t... |
216 217 |
ret = spi_flash_read(env_flash, saved_offset, saved_size, saved_buffer); |
5b3375ac8 env_sf: support e... |
218 219 220 |
if (ret) goto done; } |
7ce1526ed env: Add env_expo... |
221 222 |
ret = env_export(&env_new); if (ret) |
a3110f01c env_sf: updated t... |
223 |
goto done; |
a3110f01c env_sf: updated t... |
224 |
|
0b2e5bbe6 env_sf: use DIV_R... |
225 |
sector = DIV_ROUND_UP(CONFIG_ENV_SIZE, CONFIG_ENV_SECT_SIZE); |
8c66497e0 Add support for e... |
226 |
puts("Erasing SPI flash..."); |
a3110f01c env_sf: updated t... |
227 228 |
ret = spi_flash_erase(env_flash, CONFIG_ENV_OFFSET, sector * CONFIG_ENV_SECT_SIZE); |
5b3375ac8 env_sf: support e... |
229 230 |
if (ret) goto done; |
8c66497e0 Add support for e... |
231 232 |
puts("Writing to SPI flash..."); |
a3110f01c env_sf: updated t... |
233 |
ret = spi_flash_write(env_flash, CONFIG_ENV_OFFSET, |
cd0f4fa1c Revert "env: fix ... |
234 |
CONFIG_ENV_SIZE, &env_new); |
5b3375ac8 env_sf: support e... |
235 236 |
if (ret) goto done; |
8c66497e0 Add support for e... |
237 |
|
5b3375ac8 env_sf: support e... |
238 |
if (CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE) { |
a3110f01c env_sf: updated t... |
239 240 |
ret = spi_flash_write(env_flash, saved_offset, saved_size, saved_buffer); |
5b3375ac8 env_sf: support e... |
241 242 243 244 245 |
if (ret) goto done; } ret = 0; |
8c66497e0 Add support for e... |
246 247 |
puts("done "); |
5b3375ac8 env_sf: support e... |
248 249 250 251 |
done: if (saved_buffer) free(saved_buffer); |
eb58a7fc7 env: clean env_sf... |
252 |
|
5b3375ac8 env_sf: support e... |
253 |
return ret; |
8c66497e0 Add support for e... |
254 |
} |
4415f1d1f env: Create a loc... |
255 |
#endif /* CMD_SAVEENV */ |
8c66497e0 Add support for e... |
256 |
|
c59519919 env: Adjust the l... |
257 |
static int env_sf_load(void) |
8c66497e0 Add support for e... |
258 259 |
{ int ret; |
5a89fa927 SPL: P2020RDB: fi... |
260 |
char *buf = NULL; |
8c66497e0 Add support for e... |
261 |
|
7dd017446 env: use cache li... |
262 |
buf = (char *)memalign(ARCH_DMA_MINALIGN, CONFIG_ENV_SIZE); |
c041c60c6 env_sf: re-order ... |
263 |
if (!buf) { |
c5d548a9f env: common: acce... |
264 |
set_default_env("malloc() failed", 0); |
c59519919 env: Adjust the l... |
265 |
return -EIO; |
ea882baf9 New implementatio... |
266 |
} |
8c66497e0 Add support for e... |
267 |
|
c041c60c6 env_sf: re-order ... |
268 269 270 |
ret = setup_flash_device(); if (ret) goto out; |
ea882baf9 New implementatio... |
271 272 273 |
ret = spi_flash_read(env_flash, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, buf); if (ret) { |
c5d548a9f env: common: acce... |
274 |
set_default_env("spi_flash_read() failed", 0); |
c041c60c6 env_sf: re-order ... |
275 |
goto err_read; |
ea882baf9 New implementatio... |
276 |
} |
8c66497e0 Add support for e... |
277 |
|
ea882baf9 New implementatio... |
278 |
ret = env_import(buf, 1); |
42a1820bb env: make env_imp... |
279 |
if (!ret) |
203e94f6c env: Add an enum ... |
280 |
gd->env_valid = ENV_VALID; |
c041c60c6 env_sf: re-order ... |
281 282 |
err_read: |
8c66497e0 Add support for e... |
283 284 |
spi_flash_free(env_flash); env_flash = NULL; |
c041c60c6 env_sf: re-order ... |
285 286 |
out: free(buf); |
c59519919 env: Adjust the l... |
287 288 |
return ret; |
8c66497e0 Add support for e... |
289 |
} |
7319bcaf8 add redundant env... |
290 |
#endif |
8c66497e0 Add support for e... |
291 |
|
119c01c2a env: sf: define A... |
292 293 294 295 296 297 |
#ifdef CONFIG_ENV_ADDR __weak void *env_sf_get_env_addr(void) { return (void *)CONFIG_ENV_ADDR; } #endif |
b500c92b7 env: sf: Add supp... |
298 299 300 |
#if defined(INITENV) && defined(CONFIG_ENV_ADDR) static int env_sf_init(void) { |
119c01c2a env: sf: define A... |
301 |
env_t *env_ptr = (env_t *)env_sf_get_env_addr(); |
b500c92b7 env: sf: Add supp... |
302 303 304 305 306 307 308 309 310 311 312 313 |
if (crc32(0, env_ptr->data, ENV_SIZE) == env_ptr->crc) { gd->env_addr = (ulong)&(env_ptr->data); gd->env_valid = 1; } else { gd->env_addr = (ulong)&default_environment[0]; gd->env_valid = 1; } return 0; } #endif |
4415f1d1f env: Create a loc... |
314 315 |
U_BOOT_ENV_LOCATION(sf) = { .location = ENVL_SPI_FLASH, |
ac358beb8 env: Drop the env... |
316 |
ENV_NAME("SPI Flash") |
e5bce247b env: Switch over ... |
317 |
.load = env_sf_load, |
4415f1d1f env: Create a loc... |
318 |
#ifdef CMD_SAVEENV |
e5bce247b env: Switch over ... |
319 |
.save = env_save_ptr(env_sf_save), |
4415f1d1f env: Create a loc... |
320 |
#endif |
b500c92b7 env: sf: Add supp... |
321 322 323 |
#if defined(INITENV) && defined(CONFIG_ENV_ADDR) .init = env_sf_init, #endif |
4415f1d1f env: Create a loc... |
324 |
}; |