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