Blame view
cmd/nand.c
24.2 KB
dc7c9a1a5 * Patch by Rick B... |
1 2 3 4 5 |
/* * Driver for NAND support, Rick Bronson * borrowed heavily from: * (c) 1999 Machine Vision Holdings, Inc. * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> |
384cc6874 Patches by Josef ... |
6 |
* |
c9f7351b5 NAND: environment... |
7 8 9 10 |
* Ported 'dynenv' to 'nand env.oob' command * (C) 2010 Nanometrics, Inc. * 'dynenv' -- Dynamic environment offset in NAND OOB * (C) Copyright 2006-2007 OpenMoko, Inc. |
384cc6874 Patches by Josef ... |
11 12 |
* Added 16-bit nand support * (C) 2004 Texas Instruments |
ea533c260 cmd_nand: some in... |
13 |
* |
418396e21 nand: extend .raw... |
14 |
* Copyright 2010, 2012 Freescale Semiconductor |
ea533c260 cmd_nand: some in... |
15 16 17 18 19 |
* The portions of this file whose copyright is held by Freescale and which * are not considered a derived work of GPL v2-only code may be distributed * and/or modified under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. |
dc7c9a1a5 * Patch by Rick B... |
20 21 22 |
*/ #include <common.h> |
cfa460adf Update MTD to tha... |
23 |
#include <linux/mtd/mtd.h> |
addb2e165 Re-factoring the ... |
24 |
#include <command.h> |
24b852a7a Move console defi... |
25 |
#include <console.h> |
addb2e165 Re-factoring the ... |
26 27 28 |
#include <watchdog.h> #include <malloc.h> #include <asm/byteorder.h> |
addb2e165 Re-factoring the ... |
29 30 |
#include <jffs2/jffs2.h> #include <nand.h> |
0c8a84916 Separate mtdparts... |
31 |
#if defined(CONFIG_CMD_MTDPARTS) |
856f05441 [PATCH] NAND: Par... |
32 |
|
445093d17 Fix "par[t]ition"... |
33 |
/* partition handling routines */ |
856f05441 [PATCH] NAND: Par... |
34 35 36 |
int mtdparts_init(void); int id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num); int find_dev_and_part(const char *id, struct mtd_device **dev, |
4b0708093 Coding Style clea... |
37 |
u8 *part_num, struct part_info **part); |
856f05441 [PATCH] NAND: Par... |
38 |
#endif |
151c06ec6 mtd: nand: Remove... |
39 40 |
static int nand_dump(struct mtd_info *mtd, ulong off, int only_oob, int repeat) |
addb2e165 Re-factoring the ... |
41 42 |
{ int i; |
9ad754fef make nand dump an... |
43 |
u_char *datbuf, *oobbuf, *p; |
8c5659a6d nand commands: ma... |
44 |
static loff_t last; |
e40520b5b cmd_nand: fix a m... |
45 |
int ret = 0; |
8c5659a6d nand commands: ma... |
46 47 |
if (repeat) |
151c06ec6 mtd: nand: Remove... |
48 |
off = last + mtd->writesize; |
8c5659a6d nand commands: ma... |
49 50 |
last = off; |
addb2e165 Re-factoring the ... |
51 |
|
151c06ec6 mtd: nand: Remove... |
52 |
datbuf = memalign(ARCH_DMA_MINALIGN, mtd->writesize); |
e40520b5b cmd_nand: fix a m... |
53 |
if (!datbuf) { |
addb2e165 Re-factoring the ... |
54 55 56 57 |
puts("No memory for page buffer "); return 1; } |
e40520b5b cmd_nand: fix a m... |
58 |
|
151c06ec6 mtd: nand: Remove... |
59 |
oobbuf = memalign(ARCH_DMA_MINALIGN, mtd->oobsize); |
e40520b5b cmd_nand: fix a m... |
60 61 62 63 64 65 |
if (!oobbuf) { puts("No memory for page buffer "); ret = 1; goto free_dat; } |
151c06ec6 mtd: nand: Remove... |
66 |
off &= ~(mtd->writesize - 1); |
cfa460adf Update MTD to tha... |
67 |
loff_t addr = (loff_t) off; |
9ad754fef make nand dump an... |
68 69 70 |
struct mtd_oob_ops ops; memset(&ops, 0, sizeof(ops)); ops.datbuf = datbuf; |
cfdae12f3 cmd_nand.c: Fix '... |
71 |
ops.oobbuf = oobbuf; |
151c06ec6 mtd: nand: Remove... |
72 73 |
ops.len = mtd->writesize; ops.ooblen = mtd->oobsize; |
dfe64e2c8 mtd: resync with ... |
74 |
ops.mode = MTD_OPS_RAW; |
151c06ec6 mtd: nand: Remove... |
75 |
i = mtd_read_oob(mtd, addr, &ops); |
addb2e165 Re-factoring the ... |
76 |
if (i < 0) { |
e870690bd MTD/NAND: Fix pri... |
77 78 |
printf("Error (%d) reading page %08lx ", i, off); |
e40520b5b cmd_nand: fix a m... |
79 80 |
ret = 1; goto free_all; |
addb2e165 Re-factoring the ... |
81 |
} |
e870690bd MTD/NAND: Fix pri... |
82 83 |
printf("Page %08lx dump: ", off); |
4b0708093 Coding Style clea... |
84 |
|
7d25cd34e cmd_nand: slight ... |
85 |
if (!only_oob) { |
151c06ec6 mtd: nand: Remove... |
86 |
i = mtd->writesize >> 4; |
7d25cd34e cmd_nand: slight ... |
87 88 89 |
p = datbuf; while (i--) { |
9ad754fef make nand dump an... |
90 91 92 93 |
printf("\t%02x %02x %02x %02x %02x %02x %02x %02x" " %02x %02x %02x %02x %02x %02x %02x %02x ", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], |
dfbf617ff NAND read/write fix |
94 95 |
p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); |
7d25cd34e cmd_nand: slight ... |
96 97 |
p += 16; } |
addb2e165 Re-factoring the ... |
98 |
} |
7d25cd34e cmd_nand: slight ... |
99 |
|
addb2e165 Re-factoring the ... |
100 101 |
puts("OOB: "); |
151c06ec6 mtd: nand: Remove... |
102 |
i = mtd->oobsize >> 3; |
cfdae12f3 cmd_nand.c: Fix '... |
103 |
p = oobbuf; |
addb2e165 Re-factoring the ... |
104 |
while (i--) { |
cfa460adf Update MTD to tha... |
105 106 107 |
printf("\t%02x %02x %02x %02x %02x %02x %02x %02x ", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); |
addb2e165 Re-factoring the ... |
108 109 |
p += 8; } |
e40520b5b cmd_nand: fix a m... |
110 111 |
free_all: |
9ad754fef make nand dump an... |
112 |
free(oobbuf); |
e40520b5b cmd_nand: fix a m... |
113 114 |
free_dat: free(datbuf); |
addb2e165 Re-factoring the ... |
115 |
|
e40520b5b cmd_nand: fix a m... |
116 |
return ret; |
addb2e165 Re-factoring the ... |
117 118 119 |
} /* ------------------------------------------------------------------------- */ |
ea533c260 cmd_nand: some in... |
120 121 |
static int set_dev(int dev) { |
ad92dff28 cmd: nand: abstra... |
122 123 124 125 |
struct mtd_info *mtd = get_nand_dev_by_index(dev); if (!mtd) return -ENODEV; |
ea533c260 cmd_nand: some in... |
126 127 128 |
if (nand_curr_device == dev) return 0; |
ad92dff28 cmd: nand: abstra... |
129 |
printf("Device %d: %s", dev, mtd->name); |
ea533c260 cmd_nand: some in... |
130 131 132 133 134 |
puts("... is now current device "); nand_curr_device = dev; #ifdef CONFIG_SYS_NAND_SELECT_DEVICE |
6308e71be cmd: nand: remove... |
135 |
board_nand_select_device(mtd_to_nand(mtd), dev); |
ea533c260 cmd_nand: some in... |
136 137 138 139 |
#endif return 0; } |
50657c273 NAND: Enable nand... |
140 141 142 |
#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK static void print_status(ulong start, ulong end, ulong erasesize, int status) { |
e70bfa298 nand: Make NAND l... |
143 144 145 146 147 148 |
/* * Micron NAND flash (e.g. MT29F4G08ABADAH4) BLOCK LOCK READ STATUS is * not the same as others. Instead of bit 1 being lock, it is * #lock_tight. To make the driver support either format, ignore bit 1 * and use only bit 0 and bit 2. */ |
50657c273 NAND: Enable nand... |
149 150 151 152 153 154 |
printf("%08lx - %08lx: %08lx blocks %s%s%s ", start, end - 1, (end - start) / erasesize, ((status & NAND_LOCK_STATUS_TIGHT) ? "TIGHT " : ""), |
e70bfa298 nand: Make NAND l... |
155 |
(!(status & NAND_LOCK_STATUS_UNLOCK) ? "LOCK " : ""), |
50657c273 NAND: Enable nand... |
156 157 |
((status & NAND_LOCK_STATUS_UNLOCK) ? "UNLOCK " : "")); } |
151c06ec6 mtd: nand: Remove... |
158 |
static void do_nand_status(struct mtd_info *mtd) |
50657c273 NAND: Enable nand... |
159 160 161 162 |
{ ulong block_start = 0; ulong off; int last_status = -1; |
17cb4b8f3 mtd: nand: Add+us... |
163 |
struct nand_chip *nand_chip = mtd_to_nand(mtd); |
50657c273 NAND: Enable nand... |
164 |
/* check the WP bit */ |
151c06ec6 mtd: nand: Remove... |
165 |
nand_chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); |
50657c273 NAND: Enable nand... |
166 167 |
printf("device is %swrite protected ", |
151c06ec6 mtd: nand: Remove... |
168 169 |
(nand_chip->read_byte(mtd) & 0x80 ? "NOT " : "")); |
50657c273 NAND: Enable nand... |
170 |
|
151c06ec6 mtd: nand: Remove... |
171 172 |
for (off = 0; off < mtd->size; off += mtd->erasesize) { int s = nand_get_lock_status(mtd, off); |
50657c273 NAND: Enable nand... |
173 174 175 |
/* print message only if status has changed */ if (s != last_status && off != 0) { |
151c06ec6 mtd: nand: Remove... |
176 |
print_status(block_start, off, mtd->erasesize, |
50657c273 NAND: Enable nand... |
177 178 179 180 181 182 |
last_status); block_start = off; } last_status = s; } /* Print the last block info */ |
151c06ec6 mtd: nand: Remove... |
183 |
print_status(block_start, off, mtd->erasesize, last_status); |
50657c273 NAND: Enable nand... |
184 185 |
} #endif |
c9f7351b5 NAND: environment... |
186 187 |
#ifdef CONFIG_ENV_OFFSET_OOB unsigned long nand_env_oob_offset; |
ea533c260 cmd_nand: some in... |
188 |
int do_nand_env_oob(cmd_tbl_t *cmdtp, int argc, char *const argv[]) |
c9f7351b5 NAND: environment... |
189 190 191 |
{ int ret; uint32_t oob_buf[ENV_OFFSET_SIZE/sizeof(uint32_t)]; |
ad92dff28 cmd: nand: abstra... |
192 |
struct mtd_info *mtd = get_nand_dev_by_index(0); |
c9f7351b5 NAND: environment... |
193 |
char *cmd = argv[1]; |
8b7d51249 nand: Fix some mo... |
194 |
if (CONFIG_SYS_MAX_NAND_DEVICE == 0 || !mtd) { |
ea533c260 cmd_nand: some in... |
195 196 197 198 199 200 |
puts("no devices available "); return 1; } set_dev(0); |
c9f7351b5 NAND: environment... |
201 |
if (!strcmp(cmd, "get")) { |
151c06ec6 mtd: nand: Remove... |
202 |
ret = get_nand_env_oob(mtd, &nand_env_oob_offset); |
53504a278 NAND: formatting ... |
203 |
if (ret) |
c9f7351b5 NAND: environment... |
204 |
return 1; |
53504a278 NAND: formatting ... |
205 206 207 |
printf("0x%08lx ", nand_env_oob_offset); |
c9f7351b5 NAND: environment... |
208 |
} else if (!strcmp(cmd, "set")) { |
ea533c260 cmd_nand: some in... |
209 210 |
loff_t addr; loff_t maxsize; |
c9f7351b5 NAND: environment... |
211 |
struct mtd_oob_ops ops; |
ea533c260 cmd_nand: some in... |
212 |
int idx = 0; |
c9f7351b5 NAND: environment... |
213 214 215 |
if (argc < 3) goto usage; |
ad92dff28 cmd: nand: abstra... |
216 |
mtd = get_nand_dev_by_index(idx); |
c39d6a0ea nand: Extend nand... |
217 |
/* We don't care about size, or maxsize. */ |
09c328075 mtd, nand: Move c... |
218 |
if (mtd_arg_off(argv[2], &idx, &addr, &maxsize, &maxsize, |
ad92dff28 cmd: nand: abstra... |
219 |
MTD_DEV_TYPE_NAND, mtd->size)) { |
09c328075 mtd, nand: Move c... |
220 221 222 223 224 |
puts("Offset or partition name expected "); return 1; } if (set_dev(idx)) { |
ea533c260 cmd_nand: some in... |
225 226 227 228 229 230 231 232 |
puts("Offset or partition name expected "); return 1; } if (idx != 0) { puts("Partition not on first NAND device "); |
c9f7351b5 NAND: environment... |
233 234 |
return 1; } |
151c06ec6 mtd: nand: Remove... |
235 |
if (mtd->oobavail < ENV_OFFSET_SIZE) { |
53504a278 NAND: formatting ... |
236 237 238 239 240 |
printf("Insufficient available OOB bytes: " "%d OOB bytes available but %d required for " "env.oob support ", |
151c06ec6 mtd: nand: Remove... |
241 |
mtd->oobavail, ENV_OFFSET_SIZE); |
c9f7351b5 NAND: environment... |
242 243 |
return 1; } |
151c06ec6 mtd: nand: Remove... |
244 |
if ((addr & (mtd->erasesize - 1)) != 0) { |
c9f7351b5 NAND: environment... |
245 246 247 248 249 250 251 252 253 254 255 256 |
printf("Environment offset must be block-aligned "); return 1; } ops.datbuf = NULL; ops.mode = MTD_OOB_AUTO; ops.ooboffs = 0; ops.ooblen = ENV_OFFSET_SIZE; ops.oobbuf = (void *) oob_buf; oob_buf[0] = ENV_OOB_MARKER; |
151c06ec6 mtd: nand: Remove... |
257 |
oob_buf[1] = addr / mtd->erasesize; |
c9f7351b5 NAND: environment... |
258 |
|
151c06ec6 mtd: nand: Remove... |
259 |
ret = mtd->write_oob(mtd, ENV_OFFSET_SIZE, &ops); |
53504a278 NAND: formatting ... |
260 |
if (ret) { |
c9f7351b5 NAND: environment... |
261 262 263 264 |
printf("Error writing OOB block 0 "); return ret; } |
53504a278 NAND: formatting ... |
265 |
|
151c06ec6 mtd: nand: Remove... |
266 |
ret = get_nand_env_oob(mtd, &nand_env_oob_offset); |
53504a278 NAND: formatting ... |
267 268 269 270 271 272 273 274 |
if (ret) { printf("Error reading env offset in OOB "); return ret; } if (addr != nand_env_oob_offset) { printf("Verification of env offset in OOB failed: " |
ea533c260 cmd_nand: some in... |
275 276 277 |
"0x%08llx expected but got 0x%08lx ", (unsigned long long)addr, nand_env_oob_offset); |
53504a278 NAND: formatting ... |
278 279 |
return 1; } |
c9f7351b5 NAND: environment... |
280 281 282 283 284 285 286 |
} else { goto usage; } return ret; usage: |
4c12eeb8b Convert cmd_usage... |
287 |
return CMD_RET_USAGE; |
c9f7351b5 NAND: environment... |
288 289 290 |
} #endif |
ce80ddc18 NAND: Make page, ... |
291 |
static void nand_print_and_set_info(int idx) |
672ed2aee Enable multi chip... |
292 |
{ |
ad92dff28 cmd: nand: abstra... |
293 294 295 296 297 298 |
struct mtd_info *mtd; struct nand_chip *chip; mtd = get_nand_dev_by_index(idx); if (!mtd) return; |
ce80ddc18 NAND: Make page, ... |
299 |
|
ad92dff28 cmd: nand: abstra... |
300 |
chip = mtd_to_nand(mtd); |
672ed2aee Enable multi chip... |
301 302 303 304 305 |
printf("Device %d: ", idx); if (chip->numchips > 1) printf("%dx ", chip->numchips); printf("%s, sector size %u KiB ", |
151c06ec6 mtd: nand: Remove... |
306 307 308 309 310 311 312 |
mtd->name, mtd->erasesize >> 10); printf(" Page size %8d b ", mtd->writesize); printf(" OOB size %8d b ", mtd->oobsize); printf(" Erase size %8d b ", mtd->erasesize); |
5db73feb1 cmd, nand: add mo... |
313 314 |
printf(" subpagesize %8d b ", chip->subpagesize); |
66dc09c55 cmd, nand: fix br... |
315 316 317 318 |
printf(" options 0x%08x ", chip->options); printf(" bbt options 0x%08x ", chip->bbt_options); |
ce80ddc18 NAND: Make page, ... |
319 320 |
/* Set geometry info */ |
018f53032 env: Rename commo... |
321 322 323 |
env_set_hex("nand_writesize", mtd->writesize); env_set_hex("nand_oobsize", mtd->oobsize); env_set_hex("nand_erasesize", mtd->erasesize); |
672ed2aee Enable multi chip... |
324 |
} |
151c06ec6 mtd: nand: Remove... |
325 |
static int raw_access(struct mtd_info *mtd, ulong addr, loff_t off, |
2dc3c483a cmd, nand: add an... |
326 |
ulong count, int read, int no_verify) |
418396e21 nand: extend .raw... |
327 328 |
{ int ret = 0; |
418396e21 nand: extend .raw... |
329 330 331 332 333 |
while (count--) { /* Raw access */ mtd_oob_ops_t ops = { .datbuf = (u8 *)addr, |
151c06ec6 mtd: nand: Remove... |
334 335 336 |
.oobbuf = ((u8 *)addr) + mtd->writesize, .len = mtd->writesize, .ooblen = mtd->oobsize, |
dfe64e2c8 mtd: resync with ... |
337 |
.mode = MTD_OPS_RAW |
418396e21 nand: extend .raw... |
338 |
}; |
6b94f118a cmd_nand: Verify ... |
339 |
if (read) { |
151c06ec6 mtd: nand: Remove... |
340 |
ret = mtd_read_oob(mtd, off, &ops); |
6b94f118a cmd_nand: Verify ... |
341 |
} else { |
151c06ec6 mtd: nand: Remove... |
342 |
ret = mtd_write_oob(mtd, off, &ops); |
2dc3c483a cmd, nand: add an... |
343 |
if (!ret && !no_verify) |
151c06ec6 mtd: nand: Remove... |
344 |
ret = nand_verify_page_oob(mtd, &ops, off); |
6b94f118a cmd_nand: Verify ... |
345 |
} |
418396e21 nand: extend .raw... |
346 347 348 349 350 351 352 |
if (ret) { printf("%s: error at offset %llx, ret %d ", __func__, (long long)off, ret); break; } |
151c06ec6 mtd: nand: Remove... |
353 354 |
addr += mtd->writesize + mtd->oobsize; off += mtd->writesize; |
418396e21 nand: extend .raw... |
355 356 357 358 |
} return ret; } |
e834402fa nand: adjust eras... |
359 |
/* Adjust a chip/partition size down for bad blocks so we don't |
9b80aa8ec nand: Don't call ... |
360 |
* read/write past the end of a chip/partition by accident. |
e834402fa nand: adjust eras... |
361 362 363 364 365 366 |
*/ static void adjust_size_for_badblocks(loff_t *size, loff_t offset, int dev) { /* We grab the nand info object here fresh because this is usually * called after arg_off_size() which can change the value of dev. */ |
ad92dff28 cmd: nand: abstra... |
367 |
struct mtd_info *mtd = get_nand_dev_by_index(dev); |
e834402fa nand: adjust eras... |
368 369 370 371 |
loff_t maxoffset = offset + *size; int badblocks = 0; /* count badblocks in NAND from offset to offset + size */ |
151c06ec6 mtd: nand: Remove... |
372 373 |
for (; offset < maxoffset; offset += mtd->erasesize) { if (nand_block_isbad(mtd, offset)) |
e834402fa nand: adjust eras... |
374 375 376 377 |
badblocks++; } /* adjust size if any bad blocks found */ if (badblocks) { |
151c06ec6 mtd: nand: Remove... |
378 |
*size -= badblocks * mtd->erasesize; |
e834402fa nand: adjust eras... |
379 380 381 382 383 |
printf("size adjusted to 0x%llx (%d bad blocks) ", (unsigned long long)*size, badblocks); } } |
088f1b199 common/cmd_*.c: s... |
384 |
static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
addb2e165 Re-factoring the ... |
385 |
{ |
ea533c260 cmd_nand: some in... |
386 387 |
int i, ret = 0; ulong addr; |
c39d6a0ea nand: Extend nand... |
388 |
loff_t off, size, maxsize; |
addb2e165 Re-factoring the ... |
389 |
char *cmd, *s; |
151c06ec6 mtd: nand: Remove... |
390 |
struct mtd_info *mtd; |
6d0f6bcf3 rename CFG_ macro... |
391 392 |
#ifdef CONFIG_SYS_NAND_QUIET int quiet = CONFIG_SYS_NAND_QUIET; |
c750d2e66 NAND: Add CFG_NAN... |
393 |
#else |
2255b2d20 * Several improve... |
394 |
int quiet = 0; |
c750d2e66 NAND: Add CFG_NAN... |
395 |
#endif |
00caae6d4 env: Rename geten... |
396 |
const char *quiet_str = env_get("quiet"); |
ea533c260 cmd_nand: some in... |
397 |
int dev = nand_curr_device; |
8c5659a6d nand commands: ma... |
398 |
int repeat = flag & CMD_FLAG_REPEAT; |
addb2e165 Re-factoring the ... |
399 400 401 402 |
/* at least two arguments please */ if (argc < 2) goto usage; |
2255b2d20 * Several improve... |
403 404 |
if (quiet_str) quiet = simple_strtoul(quiet_str, NULL, 0) != 0; |
addb2e165 Re-factoring the ... |
405 |
cmd = argv[1]; |
8c5659a6d nand commands: ma... |
406 407 408 |
/* Only "dump" is repeatable. */ if (repeat && strcmp(cmd, "dump")) return 0; |
addb2e165 Re-factoring the ... |
409 410 411 412 |
if (strcmp(cmd, "info") == 0) { putc(' '); |
ad92dff28 cmd: nand: abstra... |
413 414 |
for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++) nand_print_and_set_info(i); |
addb2e165 Re-factoring the ... |
415 416 417 418 |
return 0; } if (strcmp(cmd, "device") == 0) { |
addb2e165 Re-factoring the ... |
419 |
if (argc < 3) { |
672ed2aee Enable multi chip... |
420 421 |
putc(' '); |
ea533c260 cmd_nand: some in... |
422 |
if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE) |
672ed2aee Enable multi chip... |
423 424 |
puts("no devices available "); |
addb2e165 Re-factoring the ... |
425 |
else |
ce80ddc18 NAND: Make page, ... |
426 |
nand_print_and_set_info(dev); |
addb2e165 Re-factoring the ... |
427 428 |
return 0; } |
43a2b0e76 Add board/cpu spe... |
429 |
|
ea533c260 cmd_nand: some in... |
430 431 |
dev = (int)simple_strtoul(argv[2], NULL, 10); set_dev(dev); |
43a2b0e76 Add board/cpu spe... |
432 |
|
addb2e165 Re-factoring the ... |
433 434 |
return 0; } |
c9f7351b5 NAND: environment... |
435 436 |
#ifdef CONFIG_ENV_OFFSET_OOB /* this command operates only on the first nand device */ |
ea533c260 cmd_nand: some in... |
437 438 |
if (strcmp(cmd, "env.oob") == 0) return do_nand_env_oob(cmdtp, argc - 1, argv + 1); |
c9f7351b5 NAND: environment... |
439 |
#endif |
ea533c260 cmd_nand: some in... |
440 441 442 443 444 445 |
/* The following commands operate on the current device, unless * overridden by a partition specifier. Note that if somehow the * current device is invalid, it will have to be changed to a valid * one before these commands can run, even if a partition specifier * for another device is to be used. */ |
ad92dff28 cmd: nand: abstra... |
446 447 |
mtd = get_nand_dev_by_index(dev); if (!mtd) { |
addb2e165 Re-factoring the ... |
448 449 450 451 452 |
puts(" no devices available "); return 1; } |
addb2e165 Re-factoring the ... |
453 454 |
if (strcmp(cmd, "bad") == 0) { |
ea533c260 cmd_nand: some in... |
455 456 457 |
printf(" Device %d bad blocks: ", dev); |
151c06ec6 mtd: nand: Remove... |
458 459 |
for (off = 0; off < mtd->size; off += mtd->erasesize) if (nand_block_isbad(mtd, off)) |
ea533c260 cmd_nand: some in... |
460 461 |
printf(" %08llx ", (unsigned long long)off); |
addb2e165 Re-factoring the ... |
462 463 |
return 0; } |
856f05441 [PATCH] NAND: Par... |
464 465 466 467 468 |
/* * Syntax is: * 0 1 2 3 4 * nand erase [clean] [off size] */ |
304863225 nand erase: .spre... |
469 |
if (strncmp(cmd, "erase", 5) == 0 || strncmp(cmd, "scrub", 5) == 0) { |
2255b2d20 * Several improve... |
470 |
nand_erase_options_t opts; |
856f05441 [PATCH] NAND: Par... |
471 |
/* "clean" at index 2 means request to write cleanmarker */ |
3043c045d Whitespace cleanu... |
472 |
int clean = argc > 2 && !strcmp("clean", argv[2]); |
608998166 NAND: Add -y opti... |
473 474 |
int scrub_yes = argc > 2 && !strcmp("-y", argv[2]); int o = (clean || scrub_yes) ? 3 : 2; |
304863225 nand erase: .spre... |
475 |
int scrub = !strncmp(cmd, "scrub", 5); |
304863225 nand erase: .spre... |
476 477 |
int spread = 0; int args = 2; |
608998166 NAND: Add -y opti... |
478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 |
const char *scrub_warn = "Warning: " "scrub option will erase all factory set bad blocks! " " " "There is no reliable way to recover them. " " " "Use this command only for testing purposes if you " " " "are sure of what you are doing! " " Really scrub this NAND flash? <y/N> "; |
304863225 nand erase: .spre... |
494 495 496 497 498 |
if (cmd[5] != 0) { if (!strcmp(&cmd[5], ".spread")) { spread = 1; } else if (!strcmp(&cmd[5], ".part")) { |
304863225 nand erase: .spre... |
499 500 |
args = 1; } else if (!strcmp(&cmd[5], ".chip")) { |
304863225 nand erase: .spre... |
501 502 503 504 505 506 507 508 509 510 511 512 513 |
args = 0; } else { goto usage; } } /* * Don't allow missing arguments to cause full chip/partition * erases -- easy to do accidentally, e.g. with a misspelled * variable name. */ if (argc != o + args) goto usage; |
2255b2d20 * Several improve... |
514 |
|
304863225 nand erase: .spre... |
515 516 |
printf(" NAND %s: ", cmd); |
856f05441 [PATCH] NAND: Par... |
517 |
/* skip first two or three arguments, look for offset and size */ |
09c328075 mtd, nand: Move c... |
518 519 |
if (mtd_arg_off_size(argc - o, argv + o, &dev, &off, &size, &maxsize, MTD_DEV_TYPE_NAND, |
ad92dff28 cmd: nand: abstra... |
520 |
mtd->size) != 0) |
09c328075 mtd, nand: Move c... |
521 522 523 |
return 1; if (set_dev(dev)) |
856f05441 [PATCH] NAND: Par... |
524 |
return 1; |
2255b2d20 * Several improve... |
525 |
|
ad92dff28 cmd: nand: abstra... |
526 |
mtd = get_nand_dev_by_index(dev); |
ea533c260 cmd_nand: some in... |
527 |
|
2255b2d20 * Several improve... |
528 529 530 531 532 |
memset(&opts, 0, sizeof(opts)); opts.offset = off; opts.length = size; opts.jffs2 = clean; opts.quiet = quiet; |
304863225 nand erase: .spre... |
533 |
opts.spread = spread; |
2255b2d20 * Several improve... |
534 535 |
if (scrub) { |
a5dffa4b6 Add the function ... |
536 |
if (scrub_yes) { |
608998166 NAND: Add -y opti... |
537 |
opts.scrub = 1; |
a5dffa4b6 Add the function ... |
538 539 540 |
} else { puts(scrub_warn); if (confirm_yesno()) { |
6b94b4962 cmd_nand: show na... |
541 |
opts.scrub = 1; |
a5dffa4b6 Add the function ... |
542 |
} else { |
6b94b4962 cmd_nand: show na... |
543 544 |
puts("scrub aborted "); |
46aabcc44 cmd_nand: Do not ... |
545 |
return 1; |
6b94b4962 cmd_nand: show na... |
546 |
} |
2255b2d20 * Several improve... |
547 548 |
} } |
151c06ec6 mtd: nand: Remove... |
549 |
ret = nand_erase_opts(mtd, &opts); |
addb2e165 Re-factoring the ... |
550 551 552 553 554 555 556 557 558 |
printf("%s ", ret ? "ERROR" : "OK"); return ret == 0 ? 0 : 1; } if (strncmp(cmd, "dump", 4) == 0) { if (argc < 3) goto usage; |
addb2e165 Re-factoring the ... |
559 |
off = (int)simple_strtoul(argv[2], NULL, 16); |
151c06ec6 mtd: nand: Remove... |
560 |
ret = nand_dump(mtd, off, !strcmp(&cmd[4], ".oob"), repeat); |
addb2e165 Re-factoring the ... |
561 562 |
return ret == 0 ? 1 : 0; |
addb2e165 Re-factoring the ... |
563 |
} |
addb2e165 Re-factoring the ... |
564 |
if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) { |
ea533c260 cmd_nand: some in... |
565 |
size_t rwsize; |
418396e21 nand: extend .raw... |
566 |
ulong pagecount = 1; |
2255b2d20 * Several improve... |
567 |
int read; |
ced199dc8 nand: fix nand re... |
568 |
int raw = 0; |
2dc3c483a cmd, nand: add an... |
569 |
int no_verify = 0; |
2255b2d20 * Several improve... |
570 |
|
addb2e165 Re-factoring the ... |
571 572 |
if (argc < 4) goto usage; |
2255b2d20 * Several improve... |
573 |
|
addb2e165 Re-factoring the ... |
574 |
addr = (ulong)simple_strtoul(argv[2], NULL, 16); |
2255b2d20 * Several improve... |
575 |
read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */ |
856f05441 [PATCH] NAND: Par... |
576 577 |
printf(" NAND %s: ", read ? "read" : "write"); |
4cbb651b2 Remove white spac... |
578 |
|
2255b2d20 * Several improve... |
579 |
s = strchr(cmd, '.'); |
418396e21 nand: extend .raw... |
580 |
|
2dc3c483a cmd, nand: add an... |
581 |
if (s && !strncmp(s, ".raw", 4)) { |
418396e21 nand: extend .raw... |
582 |
raw = 1; |
2dc3c483a cmd, nand: add an... |
583 584 |
if (!strcmp(s, ".raw.noverify")) no_verify = 1; |
09c328075 mtd, nand: Move c... |
585 586 |
if (mtd_arg_off(argv[3], &dev, &off, &size, &maxsize, MTD_DEV_TYPE_NAND, |
ad92dff28 cmd: nand: abstra... |
587 |
mtd->size)) |
09c328075 mtd, nand: Move c... |
588 589 590 |
return 1; if (set_dev(dev)) |
418396e21 nand: extend .raw... |
591 |
return 1; |
ad92dff28 cmd: nand: abstra... |
592 |
mtd = get_nand_dev_by_index(dev); |
93d3232d9 cmd_nand: Update ... |
593 |
|
418396e21 nand: extend .raw... |
594 595 596 597 598 |
if (argc > 4 && !str2long(argv[4], &pagecount)) { printf("'%s' is not a number ", argv[4]); return 1; } |
151c06ec6 mtd: nand: Remove... |
599 |
if (pagecount * mtd->writesize > size) { |
418396e21 nand: extend .raw... |
600 601 602 603 |
puts("Size exceeds partition or device limit "); return -1; } |
151c06ec6 mtd: nand: Remove... |
604 |
rwsize = pagecount * (mtd->writesize + mtd->oobsize); |
418396e21 nand: extend .raw... |
605 |
} else { |
09c328075 mtd, nand: Move c... |
606 607 608 |
if (mtd_arg_off_size(argc - 3, argv + 3, &dev, &off, &size, &maxsize, MTD_DEV_TYPE_NAND, |
ad92dff28 cmd: nand: abstra... |
609 |
mtd->size) != 0) |
09c328075 mtd, nand: Move c... |
610 611 612 |
return 1; if (set_dev(dev)) |
418396e21 nand: extend .raw... |
613 |
return 1; |
e834402fa nand: adjust eras... |
614 615 616 |
/* size is unspecified */ if (argc < 5) adjust_size_for_badblocks(&size, off, dev); |
418396e21 nand: extend .raw... |
617 618 |
rwsize = size; } |
ad92dff28 cmd: nand: abstra... |
619 |
mtd = get_nand_dev_by_index(dev); |
93d3232d9 cmd_nand: Update ... |
620 |
|
984e03cdf NAND: Always skip... |
621 622 |
if (!s || !strcmp(s, ".jffs2") || !strcmp(s, ".e") || !strcmp(s, ".i")) { |
dfbf617ff NAND read/write fix |
623 |
if (read) |
151c06ec6 mtd: nand: Remove... |
624 |
ret = nand_read_skip_bad(mtd, off, &rwsize, |
c39d6a0ea nand: Extend nand... |
625 |
NULL, maxsize, |
4b0708093 Coding Style clea... |
626 |
(u_char *)addr); |
dfbf617ff NAND read/write fix |
627 |
else |
151c06ec6 mtd: nand: Remove... |
628 |
ret = nand_write_skip_bad(mtd, off, &rwsize, |
c39d6a0ea nand: Extend nand... |
629 |
NULL, maxsize, |
6b94f118a cmd_nand: Verify ... |
630 631 |
(u_char *)addr, WITH_WR_VERIFY); |
c9494866d cmd_nand: add nan... |
632 633 634 635 636 637 638 |
#ifdef CONFIG_CMD_NAND_TRIMFFS } else if (!strcmp(s, ".trimffs")) { if (read) { printf("Unknown nand command suffix '%s' ", s); return 1; } |
151c06ec6 mtd: nand: Remove... |
639 |
ret = nand_write_skip_bad(mtd, off, &rwsize, NULL, |
c39d6a0ea nand: Extend nand... |
640 |
maxsize, (u_char *)addr, |
6b94f118a cmd_nand: Verify ... |
641 |
WITH_DROP_FFS | WITH_WR_VERIFY); |
c9494866d cmd_nand: add nan... |
642 |
#endif |
dfc99e143 cmd_nand: drop du... |
643 |
} else if (!strcmp(s, ".oob")) { |
cfa460adf Update MTD to tha... |
644 645 646 |
/* out-of-band data */ mtd_oob_ops_t ops = { .oobbuf = (u8 *)addr, |
ea533c260 cmd_nand: some in... |
647 |
.ooblen = rwsize, |
dfe64e2c8 mtd: resync with ... |
648 |
.mode = MTD_OPS_RAW |
cfa460adf Update MTD to tha... |
649 |
}; |
62d4f4365 Re-introduce the ... |
650 |
if (read) |
151c06ec6 mtd: nand: Remove... |
651 |
ret = mtd_read_oob(mtd, off, &ops); |
62d4f4365 Re-introduce the ... |
652 |
else |
151c06ec6 mtd: nand: Remove... |
653 |
ret = mtd_write_oob(mtd, off, &ops); |
418396e21 nand: extend .raw... |
654 |
} else if (raw) { |
2dc3c483a cmd, nand: add an... |
655 656 |
ret = raw_access(mtd, addr, off, pagecount, read, no_verify); |
856f05441 [PATCH] NAND: Par... |
657 |
} else { |
984e03cdf NAND: Always skip... |
658 659 660 |
printf("Unknown nand command suffix '%s'. ", s); return 1; |
2255b2d20 * Several improve... |
661 |
} |
ea533c260 cmd_nand: some in... |
662 663 |
printf(" %zu bytes %s: %s ", rwsize, |
2255b2d20 * Several improve... |
664 |
read ? "read" : "written", ret ? "ERROR" : "OK"); |
addb2e165 Re-factoring the ... |
665 666 667 |
return ret == 0 ? 0 : 1; } |
2255b2d20 * Several improve... |
668 |
|
3287f6d38 nand: Add torture... |
669 670 |
#ifdef CONFIG_CMD_NAND_TORTURE if (strcmp(cmd, "torture") == 0) { |
1866be7d2 nand: extend nand... |
671 672 |
loff_t endoff; unsigned int failed = 0, passed = 0; |
3287f6d38 nand: Add torture... |
673 674 675 676 677 678 679 680 |
if (argc < 3) goto usage; if (!str2off(argv[2], &off)) { puts("Offset is not a valid number "); return 1; } |
1866be7d2 nand: extend nand... |
681 682 683 684 685 686 687 688 |
size = mtd->erasesize; if (argc > 3) { if (!str2off(argv[3], &size)) { puts("Size is not a valid number "); return 1; } } |
3287f6d38 nand: Add torture... |
689 |
|
1866be7d2 nand: extend nand... |
690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 |
endoff = off + size; if (endoff > mtd->size) { puts("Arguments beyond end of NAND "); return 1; } off = round_down(off, mtd->erasesize); endoff = round_up(endoff, mtd->erasesize); size = endoff - off; printf(" NAND torture: device %d offset 0x%llx size 0x%llx (block size 0x%x) ", dev, off, size, mtd->erasesize); while (off < endoff) { ret = nand_torture(mtd, off); if (ret) { failed++; printf(" block at 0x%llx failed ", off); } else { passed++; } off += mtd->erasesize; } printf(" Passed: %u, failed: %u ", passed, failed); return failed != 0; |
3287f6d38 nand: Add torture... |
718 719 |
} #endif |
2255b2d20 * Several improve... |
720 |
if (strcmp(cmd, "markbad") == 0) { |
8360b66ba nand/onenand: Fix... |
721 722 |
argc -= 2; argv += 2; |
2255b2d20 * Several improve... |
723 |
|
8360b66ba nand/onenand: Fix... |
724 725 726 727 728 |
if (argc <= 0) goto usage; while (argc > 0) { addr = simple_strtoul(*argv, NULL, 16); |
151c06ec6 mtd: nand: Remove... |
729 |
if (mtd_block_markbad(mtd, addr)) { |
8360b66ba nand/onenand: Fix... |
730 731 732 733 734 735 736 737 738 739 740 741 742 |
printf("block 0x%08lx NOT marked " "as bad! ERROR %d ", addr, ret); ret = 1; } else { printf("block 0x%08lx successfully " "marked as bad ", addr); } --argc; ++argv; |
2255b2d20 * Several improve... |
743 |
} |
8360b66ba nand/onenand: Fix... |
744 |
return ret; |
2255b2d20 * Several improve... |
745 |
} |
dfbf617ff NAND read/write fix |
746 |
|
2255b2d20 * Several improve... |
747 748 749 750 |
if (strcmp(cmd, "biterr") == 0) { /* todo */ return 1; } |
50657c273 NAND: Enable nand... |
751 |
#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK |
2255b2d20 * Several improve... |
752 |
if (strcmp(cmd, "lock") == 0) { |
50657c273 NAND: Enable nand... |
753 |
int tight = 0; |
2255b2d20 * Several improve... |
754 755 756 757 758 759 760 |
int status = 0; if (argc == 3) { if (!strcmp("tight", argv[2])) tight = 1; if (!strcmp("status", argv[2])) status = 1; } |
2255b2d20 * Several improve... |
761 |
if (status) { |
151c06ec6 mtd: nand: Remove... |
762 |
do_nand_status(mtd); |
cfa460adf Update MTD to tha... |
763 |
} else { |
151c06ec6 mtd: nand: Remove... |
764 |
if (!nand_lock(mtd, tight)) { |
5e1dae5c3 Fixing coding sty... |
765 766 767 768 769 770 771 |
puts("NAND flash successfully locked "); } else { puts("Error locking NAND flash "); return 1; } |
2255b2d20 * Several improve... |
772 773 774 |
} return 0; } |
eee623a50 nand: Add support... |
775 776 777 778 779 780 781 |
if (strncmp(cmd, "unlock", 5) == 0) { int allexcept = 0; s = strchr(cmd, '.'); if (s && !strcmp(s, ".allexcept")) allexcept = 1; |
09c328075 mtd, nand: Move c... |
782 783 |
if (mtd_arg_off_size(argc - 2, argv + 2, &dev, &off, &size, &maxsize, MTD_DEV_TYPE_NAND, |
ad92dff28 cmd: nand: abstra... |
784 |
mtd->size) < 0) |
09c328075 mtd, nand: Move c... |
785 786 787 |
return 1; if (set_dev(dev)) |
856f05441 [PATCH] NAND: Par... |
788 |
return 1; |
2255b2d20 * Several improve... |
789 |
|
ad92dff28 cmd: nand: abstra... |
790 791 792 |
mtd = get_nand_dev_by_index(dev); if (!nand_unlock(mtd, off, size, allexcept)) { |
5e1dae5c3 Fixing coding sty... |
793 794 795 796 |
puts("NAND flash successfully unlocked "); } else { puts("Error unlocking NAND flash, " |
3043c045d Whitespace cleanu... |
797 798 |
"write and erase will probably fail "); |
5e1dae5c3 Fixing coding sty... |
799 800 |
return 1; } |
2255b2d20 * Several improve... |
801 802 |
return 0; } |
50657c273 NAND: Enable nand... |
803 |
#endif |
2255b2d20 * Several improve... |
804 |
|
addb2e165 Re-factoring the ... |
805 |
usage: |
4c12eeb8b Convert cmd_usage... |
806 |
return CMD_RET_USAGE; |
addb2e165 Re-factoring the ... |
807 |
} |
088f1b199 common/cmd_*.c: s... |
808 809 |
#ifdef CONFIG_SYS_LONGHELP static char nand_help_text[] = |
a89c33db9 General help mess... |
810 811 812 813 814 815 816 817 818 819 820 821 |
"info - show available NAND devices " "nand device [dev] - show or set current device " "nand read - addr off|partition size " "nand write - addr off|partition size " " read/write 'size' bytes starting at offset 'off' " " to/from memory address 'addr', skipping bad blocks. " |
418396e21 nand: extend .raw... |
822 823 |
"nand read.raw - addr off|partition [count] " |
2dc3c483a cmd, nand: add an... |
824 825 |
"nand write.raw[.noverify] - addr off|partition [count] " |
418396e21 nand: extend .raw... |
826 827 |
" Use read.raw/write.raw to avoid ECC and access the flash as-is. " |
c9494866d cmd_nand: add nan... |
828 829 830 831 832 833 834 835 836 837 |
#ifdef CONFIG_CMD_NAND_TRIMFFS "nand write.trimffs - addr off|partition size " " write 'size' bytes starting at offset 'off' from memory address " " 'addr', skipping bad blocks and dropping any pages at the end " " of eraseblocks that contain only 0xFF " #endif |
eb3abce89 cmd_nand: fix hel... |
838 |
"nand erase[.spread] [clean] off size - erase 'size' bytes " |
304863225 nand erase: .spre... |
839 840 841 842 843 844 845 846 847 848 |
"from offset 'off' " " With '.spread', erase enough for given file size, otherwise, " " 'size' includes skipped bad blocks. " "nand erase.part [clean] partition - erase entire mtd partition' " "nand erase.chip [clean] - erase entire chip' " |
a89c33db9 General help mess... |
849 850 851 852 |
"nand bad - show bad blocks " "nand dump[.oob] off - dump page " |
3287f6d38 nand: Add torture... |
853 |
#ifdef CONFIG_CMD_NAND_TORTURE |
1866be7d2 nand: extend nand... |
854 855 856 857 |
"nand torture off - torture one block at offset " "nand torture off [size] - torture blocks from off to off+size " |
3287f6d38 nand: Add torture... |
858 |
#endif |
608998166 NAND: Add -y opti... |
859 860 |
"nand scrub [-y] off size | scrub.part partition | scrub.chip " |
304863225 nand erase: .spre... |
861 862 |
" really clean NAND erasing bad blocks (UNSAFE) " |
a89c33db9 General help mess... |
863 864 865 |
"nand markbad off [...] - mark bad block(s) at offset (UNSAFE) " "nand biterr off - make a bit error at offset (UNSAFE)" |
50657c273 NAND: Enable nand... |
866 |
#ifdef CONFIG_CMD_NAND_LOCK_UNLOCK |
a89c33db9 General help mess... |
867 868 869 870 871 872 |
" " "nand lock [tight] [status] " " bring nand to lock state or display locked pages " |
eee623a50 nand: Add support... |
873 |
"nand unlock[.allexcept] [offset] [size] - unlock section" |
50657c273 NAND: Enable nand... |
874 |
#endif |
c9f7351b5 NAND: environment... |
875 876 877 878 879 880 881 882 883 884 |
#ifdef CONFIG_ENV_OFFSET_OOB " " "nand env.oob - environment offset in OOB of block 0 of" " first device. " "nand env.oob set off|partition - set enviromnent offset " "nand env.oob get - get environment offset" #endif |
088f1b199 common/cmd_*.c: s... |
885 886 887 888 889 890 |
""; #endif U_BOOT_CMD( nand, CONFIG_SYS_MAXARGS, 1, do_nand, "NAND sub-system", nand_help_text |
50657c273 NAND: Enable nand... |
891 |
); |
addb2e165 Re-factoring the ... |
892 |
|
151c06ec6 mtd: nand: Remove... |
893 |
static int nand_load_image(cmd_tbl_t *cmdtp, struct mtd_info *mtd, |
4b0708093 Coding Style clea... |
894 |
ulong offset, ulong addr, char *cmd) |
addb2e165 Re-factoring the ... |
895 |
{ |
addb2e165 Re-factoring the ... |
896 |
int r; |
67d668bf9 autostart: unify ... |
897 |
char *s; |
4ca79f477 NAND: fix some st... |
898 |
size_t cnt; |
21d29f7f9 bootm: make use o... |
899 |
#if defined(CONFIG_IMAGE_FORMAT_LEGACY) |
addb2e165 Re-factoring the ... |
900 |
image_header_t *hdr; |
21d29f7f9 bootm: make use o... |
901 |
#endif |
09475f752 [new uImage] Add ... |
902 |
#if defined(CONFIG_FIT) |
3bab76a26 Delay FIT format ... |
903 |
const void *fit_hdr = NULL; |
09475f752 [new uImage] Add ... |
904 |
#endif |
10e038932 [NAND] Bad block ... |
905 906 907 |
s = strchr(cmd, '.'); if (s != NULL && |
65d8bc94d NAND: Have nboot ... |
908 |
(strcmp(s, ".jffs2") && strcmp(s, ".e") && strcmp(s, ".i"))) { |
984e03cdf NAND: Always skip... |
909 910 |
printf("Unknown nand load suffix '%s' ", s); |
770605e4f bootstage: Replac... |
911 |
bootstage_error(BOOTSTAGE_ID_NAND_SUFFIX); |
984e03cdf NAND: Always skip... |
912 913 |
return 1; } |
addb2e165 Re-factoring the ... |
914 |
|
151c06ec6 mtd: nand: Remove... |
915 916 917 |
printf(" Loading from %s, offset 0x%lx ", mtd->name, offset); |
addb2e165 Re-factoring the ... |
918 |
|
151c06ec6 mtd: nand: Remove... |
919 920 921 |
cnt = mtd->writesize; r = nand_read_skip_bad(mtd, offset, &cnt, NULL, mtd->size, (u_char *)addr); |
addb2e165 Re-factoring the ... |
922 |
if (r) { |
856f05441 [PATCH] NAND: Par... |
923 924 |
puts("** Read error "); |
770605e4f bootstage: Replac... |
925 |
bootstage_error(BOOTSTAGE_ID_NAND_HDR_READ); |
addb2e165 Re-factoring the ... |
926 927 |
return 1; } |
770605e4f bootstage: Replac... |
928 |
bootstage_mark(BOOTSTAGE_ID_NAND_HDR_READ); |
addb2e165 Re-factoring the ... |
929 |
|
9a4daad0a [new uImage] Upda... |
930 |
switch (genimg_get_format ((void *)addr)) { |
21d29f7f9 bootm: make use o... |
931 |
#if defined(CONFIG_IMAGE_FORMAT_LEGACY) |
d5934ad77 [new uImage] Add ... |
932 933 |
case IMAGE_FORMAT_LEGACY: hdr = (image_header_t *)addr; |
770605e4f bootstage: Replac... |
934 |
bootstage_mark(BOOTSTAGE_ID_NAND_TYPE); |
d5934ad77 [new uImage] Add ... |
935 |
image_print_contents (hdr); |
addb2e165 Re-factoring the ... |
936 |
|
d5934ad77 [new uImage] Add ... |
937 938 |
cnt = image_get_image_size (hdr); break; |
21d29f7f9 bootm: make use o... |
939 |
#endif |
d5934ad77 [new uImage] Add ... |
940 941 |
#if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: |
09475f752 [new uImage] Add ... |
942 |
fit_hdr = (const void *)addr; |
09475f752 [new uImage] Add ... |
943 944 945 946 947 |
puts ("Fit image detected... "); cnt = fit_get_size (fit_hdr); break; |
d5934ad77 [new uImage] Add ... |
948 949 |
#endif default: |
770605e4f bootstage: Replac... |
950 |
bootstage_error(BOOTSTAGE_ID_NAND_TYPE); |
d5934ad77 [new uImage] Add ... |
951 952 |
puts ("** Unknown image type "); |
addb2e165 Re-factoring the ... |
953 954 |
return 1; } |
770605e4f bootstage: Replac... |
955 |
bootstage_mark(BOOTSTAGE_ID_NAND_TYPE); |
addb2e165 Re-factoring the ... |
956 |
|
151c06ec6 mtd: nand: Remove... |
957 958 |
r = nand_read_skip_bad(mtd, offset, &cnt, NULL, mtd->size, (u_char *)addr); |
addb2e165 Re-factoring the ... |
959 |
if (r) { |
856f05441 [PATCH] NAND: Par... |
960 961 |
puts("** Read error "); |
770605e4f bootstage: Replac... |
962 |
bootstage_error(BOOTSTAGE_ID_NAND_READ); |
addb2e165 Re-factoring the ... |
963 964 |
return 1; } |
770605e4f bootstage: Replac... |
965 |
bootstage_mark(BOOTSTAGE_ID_NAND_READ); |
addb2e165 Re-factoring the ... |
966 |
|
09475f752 [new uImage] Add ... |
967 968 |
#if defined(CONFIG_FIT) /* This cannot be done earlier, we need complete FIT image in RAM first */ |
3bab76a26 Delay FIT format ... |
969 970 |
if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) { if (!fit_check_format (fit_hdr)) { |
770605e4f bootstage: Replac... |
971 |
bootstage_error(BOOTSTAGE_ID_NAND_FIT_READ); |
3bab76a26 Delay FIT format ... |
972 973 974 975 |
puts ("** Bad FIT image format "); return 1; } |
770605e4f bootstage: Replac... |
976 |
bootstage_mark(BOOTSTAGE_ID_NAND_FIT_READ_OK); |
3bab76a26 Delay FIT format ... |
977 978 |
fit_print_contents (fit_hdr); } |
09475f752 [new uImage] Add ... |
979 |
#endif |
addb2e165 Re-factoring the ... |
980 981 982 |
/* Loading ok, update default load address */ load_addr = addr; |
67d668bf9 autostart: unify ... |
983 |
return bootm_maybe_autostart(cmdtp, cmd); |
addb2e165 Re-factoring the ... |
984 |
} |
088f1b199 common/cmd_*.c: s... |
985 986 |
static int do_nandboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
856f05441 [PATCH] NAND: Par... |
987 988 989 990 |
{ char *boot_device = NULL; int idx; ulong addr, offset = 0; |
ad92dff28 cmd: nand: abstra... |
991 |
struct mtd_info *mtd; |
0c8a84916 Separate mtdparts... |
992 |
#if defined(CONFIG_CMD_MTDPARTS) |
856f05441 [PATCH] NAND: Par... |
993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 |
struct mtd_device *dev; struct part_info *part; u8 pnum; if (argc >= 2) { char *p = (argc == 2) ? argv[1] : argv[2]; if (!(str2long(p, &addr)) && (mtdparts_init() == 0) && (find_dev_and_part(p, &dev, &pnum, &part) == 0)) { if (dev->id->type != MTD_DEV_TYPE_NAND) { puts("Not a NAND device "); return 1; } if (argc > 3) goto usage; if (argc == 3) |
10e038932 [NAND] Bad block ... |
1009 |
addr = simple_strtoul(argv[1], NULL, 16); |
856f05441 [PATCH] NAND: Par... |
1010 |
else |
6d0f6bcf3 rename CFG_ macro... |
1011 |
addr = CONFIG_SYS_LOAD_ADDR; |
ad92dff28 cmd: nand: abstra... |
1012 1013 1014 1015 |
mtd = get_nand_dev_by_index(dev->id->num); return nand_load_image(cmdtp, mtd, part->offset, addr, argv[0]); |
856f05441 [PATCH] NAND: Par... |
1016 1017 1018 |
} } #endif |
770605e4f bootstage: Replac... |
1019 |
bootstage_mark(BOOTSTAGE_ID_NAND_PART); |
856f05441 [PATCH] NAND: Par... |
1020 1021 |
switch (argc) { case 1: |
6d0f6bcf3 rename CFG_ macro... |
1022 |
addr = CONFIG_SYS_LOAD_ADDR; |
00caae6d4 env: Rename geten... |
1023 |
boot_device = env_get("bootdevice"); |
856f05441 [PATCH] NAND: Par... |
1024 1025 1026 |
break; case 2: addr = simple_strtoul(argv[1], NULL, 16); |
00caae6d4 env: Rename geten... |
1027 |
boot_device = env_get("bootdevice"); |
856f05441 [PATCH] NAND: Par... |
1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 |
break; case 3: addr = simple_strtoul(argv[1], NULL, 16); boot_device = argv[2]; break; case 4: addr = simple_strtoul(argv[1], NULL, 16); boot_device = argv[2]; offset = simple_strtoul(argv[3], NULL, 16); break; default: |
0c8a84916 Separate mtdparts... |
1039 |
#if defined(CONFIG_CMD_MTDPARTS) |
856f05441 [PATCH] NAND: Par... |
1040 1041 |
usage: #endif |
770605e4f bootstage: Replac... |
1042 |
bootstage_error(BOOTSTAGE_ID_NAND_SUFFIX); |
4c12eeb8b Convert cmd_usage... |
1043 |
return CMD_RET_USAGE; |
856f05441 [PATCH] NAND: Par... |
1044 |
} |
770605e4f bootstage: Replac... |
1045 |
bootstage_mark(BOOTSTAGE_ID_NAND_SUFFIX); |
856f05441 [PATCH] NAND: Par... |
1046 1047 1048 1049 1050 |
if (!boot_device) { puts(" ** No boot device ** "); |
770605e4f bootstage: Replac... |
1051 |
bootstage_error(BOOTSTAGE_ID_NAND_BOOT_DEVICE); |
856f05441 [PATCH] NAND: Par... |
1052 1053 |
return 1; } |
770605e4f bootstage: Replac... |
1054 |
bootstage_mark(BOOTSTAGE_ID_NAND_BOOT_DEVICE); |
addb2e165 Re-factoring the ... |
1055 |
|
856f05441 [PATCH] NAND: Par... |
1056 |
idx = simple_strtoul(boot_device, NULL, 16); |
ad92dff28 cmd: nand: abstra... |
1057 1058 |
mtd = get_nand_dev_by_index(idx); if (!mtd) { |
856f05441 [PATCH] NAND: Par... |
1059 1060 1061 |
printf(" ** Device %d not available ", idx); |
770605e4f bootstage: Replac... |
1062 |
bootstage_error(BOOTSTAGE_ID_NAND_AVAILABLE); |
856f05441 [PATCH] NAND: Par... |
1063 1064 |
return 1; } |
770605e4f bootstage: Replac... |
1065 |
bootstage_mark(BOOTSTAGE_ID_NAND_AVAILABLE); |
856f05441 [PATCH] NAND: Par... |
1066 |
|
ad92dff28 cmd: nand: abstra... |
1067 |
return nand_load_image(cmdtp, mtd, offset, addr, argv[0]); |
856f05441 [PATCH] NAND: Par... |
1068 1069 1070 |
} U_BOOT_CMD(nboot, 4, 1, do_nandboot, |
2fb2604d5 Command usage cle... |
1071 |
"boot from NAND device", |
a89c33db9 General help mess... |
1072 1073 |
"[partition] | [[[loadAddr] dev] offset]" ); |