to make u-boot work for fat32 filesystem
[jz_uboot.git] / common / cmd_nand.c
blobfd40e8577a0c9940f8bfe08787e5569c02b9c779
1 /*
2 * Driver for NAND support, Rick Bronson
3 * borrowed heavily from:
4 * (c) 1999 Machine Vision Holdings, Inc.
5 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
7 * Added 16-bit nand support
8 * (C) 2004 Texas Instruments
9 */
11 #include <common.h>
14 #ifndef CFG_NAND_LEGACY
17 * New NAND support
20 #include <common.h>
22 #if (CONFIG_COMMANDS & CFG_CMD_NAND)
24 #define CFG_NAND_WRITE_YAFFS
26 #include <command.h>
27 #include <watchdog.h>
28 #include <malloc.h>
29 #include <asm/byteorder.h>
31 #ifdef CONFIG_SHOW_BOOT_PROGRESS
32 # include <status_led.h>
33 # define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg)
34 #else
35 # define SHOW_BOOT_PROGRESS(arg)
36 #endif
38 #include <jffs2/jffs2.h>
39 #include <nand.h>
41 #if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
43 /* parition handling routines */
44 int mtdparts_init(void);
45 int id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num);
46 int find_dev_and_part(const char *id, struct mtd_device **dev,
47 u8 *part_num, struct part_info **part);
48 #endif
50 extern nand_info_t nand_info[]; /* info for NAND chips */
52 static int nand_dump_oob(nand_info_t *nand, ulong off)
54 return 0;
57 static int nand_dump(nand_info_t *nand, ulong off)
59 int i;
60 u_char *buf, *p;
62 buf = malloc(nand->oobblock + nand->oobsize);
63 if (!buf) {
64 puts("No memory for page buffer\n");
65 return 1;
67 off &= ~(nand->oobblock - 1);
68 i = nand_read_raw(nand, buf, off, nand->oobblock, nand->oobsize);
69 if (i < 0) {
70 printf("Error (%d) reading page %08x\n", i, off);
71 free(buf);
72 return 1;
74 printf("Page %08x dump:\n", off);
75 i = nand->oobblock >> 4; p = buf;
76 while (i--) {
77 printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x"
78 " %02x %02x %02x %02x %02x %02x %02x %02x\n",
79 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
80 p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
81 p += 16;
83 puts("OOB:\n");
84 i = nand->oobsize >> 3;
85 while (i--) {
86 printf( "\t%02x %02x %02x %02x %02x %02x %02x %02x\n",
87 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
88 p += 8;
90 free(buf);
92 return 0;
95 /* ------------------------------------------------------------------------- */
97 static inline int str2long(char *p, ulong *num)
99 char *endptr;
101 *num = simple_strtoul(p, &endptr, 16);
102 return (*p != '\0' && *endptr == '\0') ? 1 : 0;
105 static int
106 arg_off_size(int argc, char *argv[], nand_info_t *nand, ulong *off, ulong *size)
108 int idx = nand_curr_device;
109 #if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
110 struct mtd_device *dev;
111 struct part_info *part;
112 u8 pnum;
114 if (argc >= 1 && !(str2long(argv[0], off))) {
115 if ((mtdparts_init() == 0) &&
116 (find_dev_and_part(argv[0], &dev, &pnum, &part) == 0)) {
117 if (dev->id->type != MTD_DEV_TYPE_NAND) {
118 puts("not a NAND device\n");
119 return -1;
121 *off = part->offset;
122 if (argc >= 2) {
123 if (!(str2long(argv[1], size))) {
124 printf("'%s' is not a number\n", argv[1]);
125 return -1;
127 if (*size > part->size)
128 *size = part->size;
129 } else {
130 *size = part->size;
132 idx = dev->id->num;
133 *nand = nand_info[idx];
134 goto out;
137 #endif
139 if (argc >= 1) {
140 if (!(str2long(argv[0], off))) {
141 printf("'%s' is not a number\n", argv[0]);
142 return -1;
144 } else {
145 *off = 0;
148 if (argc >= 2) {
149 if (!(str2long(argv[1], size))) {
150 printf("'%s' is not a number\n", argv[1]);
151 return -1;
153 } else {
154 *size = nand->size - *off;
157 #if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
158 out:
159 #endif
160 printf("device %d ", idx);
161 if (*size == nand->size)
162 puts("whole chip\n");
163 else
164 printf("offset 0x%x, size 0x%x\n", *off, *size);
165 return 0;
168 #ifdef CFG_NAND_WRITE_YAFFS
171 * Write a yaffs filesystem image to NAND.
173 * If yaffs flag is 1, then the image is assumed to have been
174 * generated by yaffs2/utils/mkyaffsimage.c, and only
175 * 512B block + 16B OOB NAND is supported using the YAFFS1 OOB layout.
177 * Otherwise, the image is assumed to have been generated by
178 * yaffs2/utils/mkyaffs2image.c with Sergey Kubushyn's patch applied
179 * (see http://aleph1.co.uk/lurker/message/20060211.004601.77b55bf3.en.html)
180 * and supports larger 2KB block + 64B OOB NAND.
182 * Only MTD generated ECC is supported.
184 * Loosely based on mtd/util/nandwrite.c.
187 static struct nand_oobinfo yaffs1_oobinfo = {
188 .useecc = MTD_NANDECC_PLACE,
189 .eccbytes = 6,
190 .eccpos = { 8, 9, 10, 13, 14, 15 }
193 static struct nand_oobinfo yaffs2_oobinfo = {
194 .useecc = MTD_NANDECC_AUTOPLACE,
195 .eccbytes = 24,
196 .eccpos = {
197 40, 41, 42, 43, 44, 45, 46, 47,
198 48, 49, 50, 51, 52, 53, 54, 55,
199 56, 57, 58, 59, 60, 61, 62, 63},
200 .oobfree = { {2, 38} }
203 static int nand_write_yaffs(nand_info_t *nand, ulong off, ulong *size, u_char *image, int yaffs)
205 int imglen, pagelen;
206 u_char *imgptr, *oobptr;
207 int ret;
208 size_t retlen;
209 int i;
210 struct nand_oobinfo old_oobinfo;
212 imglen = *size;
213 imgptr = image;
214 *size = 0;
216 /* Make sure device page sizes are valid */
217 if ((yaffs == 1 && !(nand->oobsize == 16 && nand->oobblock == 512)) ||
218 (yaffs == 2 && !(nand->oobsize == 64 && nand->oobblock == 2048))) {
219 printf("Unsupported flash layout\n");
220 return 1;
223 /* update oobinfo for yaffs */
224 old_oobinfo = nand->oobinfo;
225 nand->oobinfo = yaffs == 1 ? yaffs1_oobinfo : yaffs2_oobinfo;
227 /* Check, if image is pagealigned */
228 pagelen = nand->oobblock + nand->oobsize;
229 if ((off % nand->erasesize) != 0 || (imglen % pagelen) != 0) {
230 printf ("Input image is not page aligned\n");
231 goto closeall;
234 /* Check, if length fits into device */
235 if ( ((imglen / pagelen) * nand->oobblock) > (nand->size - off)) {
236 printf ("Input image does not fit into device");
237 goto closeall;
240 /* Get data from input and write to the device */
241 while (imglen > 0 && (off < nand->size)) {
243 /* if start of eraseblock, check for bad block */
244 if (off % nand->erasesize == 0 && (nand->block_isbad)(nand, off)) {
245 printf ("Bad block at 0x%08lx, will be skipped\n", off);
247 off += nand->erasesize;
248 continue;
251 oobptr = imgptr + nand->oobblock;
253 /* set the ECC bytes to 0xff so MTD will calculate it */
254 for (i = 0; i < nand->oobinfo.eccbytes; i++)
255 oobptr[nand->oobinfo.eccpos[i]] = 0xff;
257 /* Write OOB data first, as ecc will be placed in there */
258 ret = (nand->write_oob)(nand, off, nand->oobsize, &retlen, oobptr);
259 if (ret != 0) {
260 printf("\nNAND OOB write error %d at block 0x%08lx\n", ret, off);
261 goto closeall;
264 /* Write out the Page data */
265 ret = (nand->write)(nand, off, nand->oobblock, &retlen, imgptr);
266 if (ret != 0) {
267 printf("\nNAND write error %d at block 0x%08lx\n", ret, off);
268 goto closeall;
271 imgptr += pagelen;
272 imglen -= pagelen;
273 off += nand->oobblock;
276 closeall:
277 nand->oobinfo = old_oobinfo;
279 *size = imgptr - image;
281 if (imglen > 0) {
282 printf("Data did not fit into device, due to bad blocks\n");
283 return 1;
286 return 0;
289 #endif /* CFG_NAND_WRITE_YAFFS */
292 int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
294 int i, dev, ret=0;
295 ulong addr, off, size;
296 char *cmd, *s;
297 nand_info_t *nand;
298 // int quiet = 0;
299 int quiet = 1;
300 const char *quiet_str = getenv("quiet");
302 #ifdef CFG_NAND_WRITE_YAFFS
303 int yaffs = 0; /* 1 = 512+64 NAND, 2 = 2048+64 NAND */
304 #endif
306 /* at least two arguments please */
307 if (argc < 2)
308 goto usage;
310 if (quiet_str)
311 quiet = simple_strtoul(quiet_str, NULL, 0) != 0;
313 cmd = argv[1];
315 if (strcmp(cmd, "info") == 0) {
317 putc('\n');
318 for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) {
319 if (nand_info[i].name)
320 printf("Device %d: %s, sector size %lu KiB\n",
321 i, nand_info[i].name,
322 nand_info[i].erasesize >> 10);
324 return 0;
327 if (strcmp(cmd, "device") == 0) {
329 if (argc < 3) {
330 if ((nand_curr_device < 0) ||
331 (nand_curr_device >= CFG_MAX_NAND_DEVICE))
332 puts("\nno devices available\n");
333 else
334 printf("\nDevice %d: %s\n", nand_curr_device,
335 nand_info[nand_curr_device].name);
336 return 0;
338 dev = (int)simple_strtoul(argv[2], NULL, 10);
339 if (dev < 0 || dev >= CFG_MAX_NAND_DEVICE || !nand_info[dev].name) {
340 puts("No such device\n");
341 return 1;
343 printf("Device %d: %s", dev, nand_info[dev].name);
344 puts("... is now current device\n");
345 nand_curr_device = dev;
347 #ifdef CFG_NAND_SELECT_DEVICE
349 * Select the chip in the board/cpu specific driver
351 board_nand_select_device(nand_info[dev].priv, dev);
352 #endif
354 return 0;
357 if (strcmp(cmd, "bad") != 0 && strcmp(cmd, "erase") != 0 &&
358 strncmp(cmd, "dump", 4) != 0 &&
359 strncmp(cmd, "read", 4) != 0 && strncmp(cmd, "write", 5) != 0 &&
360 strcmp(cmd, "scrub") != 0 && strcmp(cmd, "markbad") != 0 &&
361 strcmp(cmd, "biterr") != 0 &&
362 strcmp(cmd, "lock") != 0 && strcmp(cmd, "unlock") != 0 )
363 goto usage;
365 /* the following commands operate on the current device */
366 if (nand_curr_device < 0 || nand_curr_device >= CFG_MAX_NAND_DEVICE ||
367 !nand_info[nand_curr_device].name) {
368 puts("\nno devices available\n");
369 return 1;
371 nand = &nand_info[nand_curr_device];
373 if (strcmp(cmd, "bad") == 0) {
374 printf("\nDevice %d bad blocks:\n", nand_curr_device);
375 for (off = 0; off < nand->size; off += nand->erasesize)
376 if (nand_block_isbad(nand, off))
377 printf(" %08x\n", off);
378 return 0;
382 * Syntax is:
383 * 0 1 2 3 4
384 * nand erase [clean] [off size]
386 if (strcmp(cmd, "erase") == 0 || strcmp(cmd, "scrub") == 0) {
387 nand_erase_options_t opts;
388 /* "clean" at index 2 means request to write cleanmarker */
389 int clean = argc > 2 && !strcmp("clean", argv[2]);
390 int o = clean ? 3 : 2;
391 int scrub = !strcmp(cmd, "scrub");
393 printf("\nNAND %s: ", scrub ? "scrub" : "erase");
394 /* skip first two or three arguments, look for offset and size */
395 if (arg_off_size(argc - o, argv + o, nand, &off, &size) != 0)
396 return 1;
398 memset(&opts, 0, sizeof(opts));
399 opts.offset = off;
400 opts.length = size;
401 opts.jffs2 = clean;
402 opts.quiet = quiet;
404 if (scrub) {
405 puts("Warning: "
406 "scrub option will erase all factory set "
407 "bad blocks!\n"
409 "There is no reliable way to recover them.\n"
411 "Use this command only for testing purposes "
412 "if you\n"
414 "are sure of what you are doing!\n"
415 "\nReally scrub this NAND flash? <y/N>\n");
417 if (getc() == 'y' && getc() == '\r') {
418 opts.scrub = 1;
419 } else {
420 puts("scrub aborted\n");
421 return -1;
424 ret = nand_erase_opts(nand, &opts);
425 printf("%s\n", ret ? "ERROR" : "OK");
427 return ret == 0 ? 0 : 1;
430 if (strncmp(cmd, "dump", 4) == 0) {
431 if (argc < 3)
432 goto usage;
434 s = strchr(cmd, '.');
435 off = (int)simple_strtoul(argv[2], NULL, 16);
437 if (s != NULL && strcmp(s, ".oob") == 0)
438 ret = nand_dump_oob(nand, off);
439 else
440 ret = nand_dump(nand, off);
442 return ret == 0 ? 1 : 0;
446 /* read write */
447 if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) {
448 int read;
450 if (argc < 4)
451 goto usage;
453 addr = (ulong)simple_strtoul(argv[2], NULL, 16);
455 read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */
456 printf("\nNAND %s: ", read ? "read" : "write");
457 if (arg_off_size(argc - 3, argv + 3, nand, &off, &size) != 0)
458 return 1;
460 s = strchr(cmd, '.');
462 #ifdef CFG_NAND_WRITE_YAFFS
463 if (s != NULL && strncmp(s, ".yaffs", 6) == 0) {
464 if (s[6] == '1')
465 yaffs = 1;
466 else if (s[6] == '2' || s[6] == '\0')
467 yaffs = 2;
469 #endif
471 // if (s != NULL &&
472 if (s == NULL ||
473 (!strcmp(s, ".jffs2") || !strcmp(s, ".yaffs1")|| !strcmp(s, ".yaffs2")|| !strcmp(s, ".e") || !strcmp(s, ".i"))) {
474 if (read) {
475 /* read */
476 nand_read_options_t opts;
477 memset(&opts, 0, sizeof(opts));
478 opts.buffer = (u_char*) addr;
479 opts.length = size;
480 opts.offset = off;
481 opts.quiet = quiet;
482 ret = nand_read_opts(nand, &opts);
483 } else {
484 /* write */
485 nand_write_options_t opts;
486 memset(&opts, 0, sizeof(opts));
487 opts.buffer = (u_char*) addr;
488 opts.length = size;
489 opts.offset = off;
490 /* opts.forcejffs2 = 1; */
491 opts.pad = 1;
492 opts.blockalign = 1;
493 opts.quiet = quiet;
494 #ifdef CFG_NAND_WRITE_YAFFS
495 if(yaffs)
496 ret = nand_write_yaffs(nand, off, &size, (u_char *)addr, yaffs);
497 else
498 ret = nand_write_opts(nand, &opts);
499 #endif
500 #ifndef CFG_NAND_WRITE_YAFFS
501 ret = nand_write_opts(nand, &opts);
502 #endif
504 } else {
505 if (read)
506 ret = nand_read(nand, off, &size, (u_char *)addr);
507 else
508 ret = nand_write(nand, off, &size, (u_char *)addr);
511 printf(" %d bytes %s: %s\n", size,
512 read ? "read" : "written", ret ? "ERROR" : "OK");
514 return ret == 0 ? 0 : 1;
517 if (strcmp(cmd, "markbad") == 0) {
518 addr = (ulong)simple_strtoul(argv[2], NULL, 16);
520 int ret = nand->block_markbad(nand, addr);
521 if (ret == 0) {
522 printf("block 0x%08lx successfully marked as bad\n",
523 (ulong) addr);
524 return 0;
525 } else {
526 printf("block 0x%08lx NOT marked as bad! ERROR %d\n",
527 (ulong) addr, ret);
529 return 1;
531 if (strcmp(cmd, "biterr") == 0) {
532 /* todo */
533 return 1;
536 if (strcmp(cmd, "lock") == 0) {
537 int tight = 0;
538 int status = 0;
539 if (argc == 3) {
540 if (!strcmp("tight", argv[2]))
541 tight = 1;
542 if (!strcmp("status", argv[2]))
543 status = 1;
546 if (status) {
547 ulong block_start = 0;
548 ulong off;
549 int last_status = -1;
551 struct nand_chip *nand_chip = nand->priv;
552 /* check the WP bit */
553 nand_chip->cmdfunc (nand, NAND_CMD_STATUS, -1, -1);
554 printf("device is %swrite protected\n",
555 (nand_chip->read_byte(nand) & 0x80 ?
556 "NOT " : "" ) );
558 for (off = 0; off < nand->size; off += nand->oobblock) {
559 int s = nand_get_lock_status(nand, off);
561 /* print message only if status has changed
562 * or at end of chip
564 if (off == nand->size - nand->oobblock
565 || (s != last_status && off != 0)) {
567 printf("%08x - %08x: %8d pages %s%s%s\n",
568 block_start,
569 off-1,
570 (off-block_start)/nand->oobblock,
571 ((last_status & NAND_LOCK_STATUS_TIGHT) ? "TIGHT " : ""),
572 ((last_status & NAND_LOCK_STATUS_LOCK) ? "LOCK " : ""),
573 ((last_status & NAND_LOCK_STATUS_UNLOCK) ? "UNLOCK " : ""));
576 last_status = s;
578 } else {
579 if (!nand_lock(nand, tight)) {
580 puts("NAND flash successfully locked\n");
581 } else {
582 puts("Error locking NAND flash\n");
583 return 1;
586 return 0;
589 if (strcmp(cmd, "unlock") == 0) {
590 if (arg_off_size(argc - 2, argv + 2, nand, &off, &size) < 0)
591 return 1;
593 if (!nand_unlock(nand, off, size)) {
594 puts("NAND flash successfully unlocked\n");
595 } else {
596 puts("Error unlocking NAND flash, "
597 "write and erase will probably fail\n");
598 return 1;
600 return 0;
603 usage:
604 printf("Usage:\n%s\n", cmdtp->usage);
605 return 1;
608 U_BOOT_CMD(nand, 5, 1, do_nand,
609 "nand - NAND sub-system\n",
610 "info - show available NAND devices\n"
611 "nand device [dev] - show or set current device\n"
612 "nand read[.jffs2] - addr off|partition size\n"
613 "nand write[.jffs2] - addr off|partiton size - read/write `size' bytes starting\n"
614 " at offset `off' to/from memory address `addr'\n"
615 #ifdef CFG_NAND_WRITE_YAFFS
616 "nand write[.yaffs[1]] addr off size - read/write `size' bytes starting\n"
617 " at offset `off' to memory address `addr' [yaffs1 or yaffs2 format]\n"
618 #endif
619 "nand erase [clean] [off size] - erase `size' bytes from\n"
620 " offset `off' (entire device if not specified)\n"
621 "nand bad - show bad blocks\n"
622 "nand dump[.oob] off - dump page\n"
623 "nand scrub - really clean NAND erasing bad blocks (UNSAFE)\n"
624 "nand markbad off - mark bad block at offset (UNSAFE)\n"
625 "nand biterr off - make a bit error at offset (UNSAFE)\n"
626 "nand lock [tight] [status] - bring nand to lock state or display locked pages\n"
627 "nand unlock [offset] [size] - unlock section\n");
629 static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
630 ulong offset, ulong addr, char *cmd)
632 int r;
633 char *ep;
634 ulong cnt;
635 image_header_t *hdr;
637 printf("\nLoading from %s, offset 0x%lx\n", nand->name, offset);
639 cnt = nand->oobblock;
640 r = nand_read(nand, offset, &cnt, (u_char *) addr);
641 if (r) {
642 puts("** Read error\n");
643 SHOW_BOOT_PROGRESS(-1);
644 return 1;
647 hdr = (image_header_t *) addr;
649 if (ntohl(hdr->ih_magic) != IH_MAGIC) {
650 printf("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic);
651 SHOW_BOOT_PROGRESS(-1);
652 return 1;
655 print_image_hdr(hdr);
657 cnt = (ntohl(hdr->ih_size) + sizeof (image_header_t));
659 r = nand_read(nand, offset, &cnt, (u_char *) addr);
660 if (r) {
661 puts("** Read error\n");
662 SHOW_BOOT_PROGRESS(-1);
663 return 1;
666 /* Loading ok, update default load address */
668 load_addr = addr;
670 /* Check if we should attempt an auto-start */
671 if (((ep = getenv("autostart")) != NULL) && (strcmp(ep, "yes") == 0)) {
672 char *local_args[2];
673 extern int do_bootm(cmd_tbl_t *, int, int, char *[]);
675 local_args[0] = cmd;
676 local_args[1] = NULL;
678 printf("Automatic boot of image at addr 0x%08lx ...\n", addr);
680 do_bootm(cmdtp, 0, 1, local_args);
681 return 1;
683 return 0;
686 int do_nandboot(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
688 char *boot_device = NULL;
689 int idx;
690 ulong addr, offset = 0;
691 #if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
692 struct mtd_device *dev;
693 struct part_info *part;
694 u8 pnum;
696 if (argc >= 2) {
697 char *p = (argc == 2) ? argv[1] : argv[2];
698 if (!(str2long(p, &addr)) && (mtdparts_init() == 0) &&
699 (find_dev_and_part(p, &dev, &pnum, &part) == 0)) {
700 if (dev->id->type != MTD_DEV_TYPE_NAND) {
701 puts("Not a NAND device\n");
702 return 1;
704 if (argc > 3)
705 goto usage;
706 if (argc == 3)
707 addr = simple_strtoul(argv[2], NULL, 16);
708 else
709 addr = CFG_LOAD_ADDR;
710 return nand_load_image(cmdtp, &nand_info[dev->id->num],
711 part->offset, addr, argv[0]);
714 #endif
716 switch (argc) {
717 case 1:
718 addr = CFG_LOAD_ADDR;
719 boot_device = getenv("bootdevice");
720 break;
721 case 2:
722 addr = simple_strtoul(argv[1], NULL, 16);
723 boot_device = getenv("bootdevice");
724 break;
725 case 3:
726 addr = simple_strtoul(argv[1], NULL, 16);
727 boot_device = argv[2];
728 break;
729 case 4:
730 addr = simple_strtoul(argv[1], NULL, 16);
731 boot_device = argv[2];
732 offset = simple_strtoul(argv[3], NULL, 16);
733 break;
734 default:
735 #if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)
736 usage:
737 #endif
738 printf("Usage:\n%s\n", cmdtp->usage);
739 SHOW_BOOT_PROGRESS(-1);
740 return 1;
743 if (!boot_device) {
744 puts("\n** No boot device **\n");
745 SHOW_BOOT_PROGRESS(-1);
746 return 1;
749 idx = simple_strtoul(boot_device, NULL, 16);
751 if (idx < 0 || idx >= CFG_MAX_NAND_DEVICE || !nand_info[idx].name) {
752 printf("\n** Device %d not available\n", idx);
753 SHOW_BOOT_PROGRESS(-1);
754 return 1;
757 return nand_load_image(cmdtp, &nand_info[idx], offset, addr, argv[0]);
760 U_BOOT_CMD(nboot, 4, 1, do_nandboot,
761 "nboot - boot from NAND device\n",
762 "[partition] | [[[loadAddr] dev] offset]\n");
764 #endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */
766 #else /* CFG_NAND_LEGACY */
769 * Legacy NAND support - to be phased out
772 #include <command.h>
773 #include <malloc.h>
774 #include <asm/io.h>
775 #include <watchdog.h>
777 #ifdef CONFIG_SHOW_BOOT_PROGRESS
778 # include <status_led.h>
779 # define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg)
780 #else
781 # define SHOW_BOOT_PROGRESS(arg)
782 #endif
784 #if (CONFIG_COMMANDS & CFG_CMD_NAND)
785 #include <linux/mtd/nand_legacy.h>
786 #if 0
787 #include <linux/mtd/nand_ids.h>
788 #include <jffs2/jffs2.h>
789 #endif
791 #ifdef CONFIG_OMAP1510
792 void archflashwp(void *archdata, int wp);
793 #endif
795 #define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1)))
797 #undef NAND_DEBUG
798 #undef PSYCHO_DEBUG
800 /* ****************** WARNING *********************
801 * When ALLOW_ERASE_BAD_DEBUG is non-zero the erase command will
802 * erase (or at least attempt to erase) blocks that are marked
803 * bad. This can be very handy if you are _sure_ that the block
804 * is OK, say because you marked a good block bad to test bad
805 * block handling and you are done testing, or if you have
806 * accidentally marked blocks bad.
808 * Erasing factory marked bad blocks is a _bad_ idea. If the
809 * erase succeeds there is no reliable way to find them again,
810 * and attempting to program or erase bad blocks can affect
811 * the data in _other_ (good) blocks.
813 #define ALLOW_ERASE_BAD_DEBUG 0
815 #define CONFIG_MTD_NAND_ECC /* enable ECC */
816 #define CONFIG_MTD_NAND_ECC_JFFS2
818 /* bits for nand_legacy_rw() `cmd'; or together as needed */
819 #define NANDRW_READ 0x01
820 #define NANDRW_WRITE 0x00
821 #define NANDRW_JFFS2 0x02
822 #define NANDRW_JFFS2_SKIP 0x04
825 * Imports from nand_legacy.c
827 extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];
828 extern int curr_device;
829 extern int nand_legacy_erase(struct nand_chip *nand, size_t ofs,
830 size_t len, int clean);
831 extern int nand_legacy_rw(struct nand_chip *nand, int cmd, size_t start,
832 size_t len, size_t *retlen, u_char *buf);
833 extern void nand_print(struct nand_chip *nand);
834 extern void nand_print_bad(struct nand_chip *nand);
835 extern int nand_read_oob(struct nand_chip *nand, size_t ofs,
836 size_t len, size_t *retlen, u_char *buf);
837 extern int nand_write_oob(struct nand_chip *nand, size_t ofs,
838 size_t len, size_t *retlen, const u_char *buf);
841 int do_nand (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
843 int rcode = 0;
845 switch (argc) {
846 case 0:
847 case 1:
848 printf ("Usage:\n%s\n", cmdtp->usage);
849 return 1;
850 case 2:
851 if (strcmp(argv[1],"info") == 0) {
852 int i;
854 putc ('\n');
856 for (i=0; i<CFG_MAX_NAND_DEVICE; ++i) {
857 if(nand_dev_desc[i].ChipID == NAND_ChipID_UNKNOWN)
858 continue; /* list only known devices */
859 printf ("Device %d: ", i);
860 nand_print(&nand_dev_desc[i]);
862 return 0;
864 } else if (strcmp(argv[1],"device") == 0) {
865 if ((curr_device < 0) || (curr_device >= CFG_MAX_NAND_DEVICE)) {
866 puts ("\nno devices available\n");
867 return 1;
869 printf ("\nDevice %d: ", curr_device);
870 nand_print(&nand_dev_desc[curr_device]);
871 return 0;
873 } else if (strcmp(argv[1],"bad") == 0) {
874 if ((curr_device < 0) || (curr_device >= CFG_MAX_NAND_DEVICE)) {
875 puts ("\nno devices available\n");
876 return 1;
878 printf ("\nDevice %d bad blocks:\n", curr_device);
879 nand_print_bad(&nand_dev_desc[curr_device]);
880 return 0;
883 printf ("Usage:\n%s\n", cmdtp->usage);
884 return 1;
885 case 3:
886 if (strcmp(argv[1],"device") == 0) {
887 int dev = (int)simple_strtoul(argv[2], NULL, 10);
889 printf ("\nDevice %d: ", dev);
890 if (dev >= CFG_MAX_NAND_DEVICE) {
891 puts ("unknown device\n");
892 return 1;
894 nand_print(&nand_dev_desc[dev]);
895 /*nand_print (dev);*/
897 if (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN) {
898 return 1;
901 curr_device = dev;
903 puts ("... is now current device\n");
905 return 0;
907 else if (strcmp(argv[1],"erase") == 0 && strcmp(argv[2], "clean") == 0) {
908 struct nand_chip* nand = &nand_dev_desc[curr_device];
909 ulong off = 0;
910 ulong size = nand->totlen;
911 int ret;
913 printf ("\nNAND erase: device %d offset %ld, size %ld ... ",
914 curr_device, off, size);
916 ret = nand_legacy_erase (nand, off, size, 1);
918 printf("%s\n", ret ? "ERROR" : "OK");
920 return ret;
923 printf ("Usage:\n%s\n", cmdtp->usage);
924 return 1;
925 default:
926 /* at least 4 args */
928 if (strncmp(argv[1], "read", 4) == 0 ||
929 strncmp(argv[1], "write", 5) == 0) {
930 ulong addr = simple_strtoul(argv[2], NULL, 16);
931 ulong off = simple_strtoul(argv[3], NULL, 16);
932 ulong size = simple_strtoul(argv[4], NULL, 16);
933 int cmd = (strncmp(argv[1], "read", 4) == 0) ?
934 NANDRW_READ : NANDRW_WRITE;
935 int ret, total;
936 char* cmdtail = strchr(argv[1], '.');
938 if (cmdtail && !strncmp(cmdtail, ".oob", 2)) {
939 /* read out-of-band data */
940 if (cmd & NANDRW_READ) {
941 ret = nand_read_oob(nand_dev_desc + curr_device,
942 off, size, (size_t *)&total,
943 (u_char*)addr);
945 else {
946 ret = nand_write_oob(nand_dev_desc + curr_device,
947 off, size, (size_t *)&total,
948 (u_char*)addr);
950 return ret;
952 else if (cmdtail && !strncmp(cmdtail, ".jffs2", 2))
953 cmd |= NANDRW_JFFS2; /* skip bad blocks */
954 else if (cmdtail && !strncmp(cmdtail, ".jffs2s", 2)) {
955 cmd |= NANDRW_JFFS2; /* skip bad blocks (on read too) */
956 if (cmd & NANDRW_READ)
957 cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */
959 #ifdef SXNI855T
960 /* need ".e" same as ".j" for compatibility with older units */
961 else if (cmdtail && !strcmp(cmdtail, ".e"))
962 cmd |= NANDRW_JFFS2; /* skip bad blocks */
963 #endif
964 #ifdef CFG_NAND_SKIP_BAD_DOT_I
965 /* need ".i" same as ".jffs2s" for compatibility with older units (esd) */
966 /* ".i" for image -> read skips bad block (no 0xff) */
967 else if (cmdtail && !strcmp(cmdtail, ".i")) {
968 cmd |= NANDRW_JFFS2; /* skip bad blocks (on read too) */
969 if (cmd & NANDRW_READ)
970 cmd |= NANDRW_JFFS2_SKIP; /* skip bad blocks (on read too) */
972 #endif /* CFG_NAND_SKIP_BAD_DOT_I */
973 else if (cmdtail) {
974 printf ("Usage:\n%s\n", cmdtp->usage);
975 return 1;
978 printf ("\nNAND %s: device %d offset %ld, size %ld ...\n",
979 (cmd & NANDRW_READ) ? "read" : "write",
980 curr_device, off, size);
982 ret = nand_legacy_rw(nand_dev_desc + curr_device, cmd, off, size,
983 (size_t *)&total, (u_char*)addr);
985 printf (" %d bytes %s: %s\n", total,
986 (cmd & NANDRW_READ) ? "read" : "written",
987 ret ? "ERROR" : "OK");
989 return ret;
990 } else if (strcmp(argv[1],"erase") == 0 &&
991 (argc == 4 || strcmp("clean", argv[2]) == 0)) {
992 int clean = argc == 5;
993 ulong off = simple_strtoul(argv[2 + clean], NULL, 16);
994 ulong size = simple_strtoul(argv[3 + clean], NULL, 16);
995 int ret;
997 printf ("\nNAND erase: device %d offset %ld, size %ld ...\n",
998 curr_device, off, size);
1000 ret = nand_legacy_erase (nand_dev_desc + curr_device,
1001 off, size, clean);
1003 printf("%s\n", ret ? "ERROR" : "OK");
1005 return ret;
1006 } else {
1007 printf ("Usage:\n%s\n", cmdtp->usage);
1008 rcode = 1;
1011 return rcode;
1015 U_BOOT_CMD(
1016 nand, 5, 1, do_nand,
1017 "nand - legacy NAND sub-system\n",
1018 "info - show available NAND devices\n"
1019 "nand device [dev] - show or set current device\n"
1020 "nand read[.jffs2[s]] addr off size\n"
1021 "nand write[.jffs2] addr off size - read/write `size' bytes starting\n"
1022 " at offset `off' to/from memory address `addr'\n"
1023 "nand erase [clean] [off size] - erase `size' bytes from\n"
1024 " offset `off' (entire device if not specified)\n"
1025 "nand bad - show bad blocks\n"
1026 "nand read.oob addr off size - read out-of-band data\n"
1027 "nand write.oob addr off size - read out-of-band data\n"
1030 int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
1032 char *boot_device = NULL;
1033 char *ep;
1034 int dev;
1035 ulong cnt;
1036 ulong addr;
1037 ulong offset = 0;
1038 image_header_t *hdr;
1039 int rcode = 0;
1040 switch (argc) {
1041 case 1:
1042 addr = CFG_LOAD_ADDR;
1043 boot_device = getenv ("bootdevice");
1044 break;
1045 case 2:
1046 addr = simple_strtoul(argv[1], NULL, 16);
1047 boot_device = getenv ("bootdevice");
1048 break;
1049 case 3:
1050 addr = simple_strtoul(argv[1], NULL, 16);
1051 boot_device = argv[2];
1052 break;
1053 case 4:
1054 addr = simple_strtoul(argv[1], NULL, 16);
1055 boot_device = argv[2];
1056 offset = simple_strtoul(argv[3], NULL, 16);
1057 break;
1058 default:
1059 printf ("Usage:\n%s\n", cmdtp->usage);
1060 SHOW_BOOT_PROGRESS (-1);
1061 return 1;
1064 if (!boot_device) {
1065 puts ("\n** No boot device **\n");
1066 SHOW_BOOT_PROGRESS (-1);
1067 return 1;
1070 dev = simple_strtoul(boot_device, &ep, 16);
1072 if ((dev >= CFG_MAX_NAND_DEVICE) ||
1073 (nand_dev_desc[dev].ChipID == NAND_ChipID_UNKNOWN)) {
1074 printf ("\n** Device %d not available\n", dev);
1075 SHOW_BOOT_PROGRESS (-1);
1076 return 1;
1079 printf ("\nLoading from device %d: %s at 0x%lx (offset 0x%lx)\n",
1080 dev, nand_dev_desc[dev].name, nand_dev_desc[dev].IO_ADDR,
1081 offset);
1083 if (nand_legacy_rw (nand_dev_desc + dev, NANDRW_READ, offset,
1084 SECTORSIZE, NULL, (u_char *)addr)) {
1085 printf ("** Read error on %d\n", dev);
1086 SHOW_BOOT_PROGRESS (-1);
1087 return 1;
1090 hdr = (image_header_t *)addr;
1092 if (ntohl(hdr->ih_magic) == IH_MAGIC) {
1094 print_image_hdr (hdr);
1096 cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
1097 cnt -= SECTORSIZE;
1098 } else {
1099 printf ("\n** Bad Magic Number 0x%x **\n", ntohl(hdr->ih_magic));
1100 SHOW_BOOT_PROGRESS (-1);
1101 return 1;
1104 if (nand_legacy_rw (nand_dev_desc + dev, NANDRW_READ,
1105 offset + SECTORSIZE, cnt, NULL,
1106 (u_char *)(addr+SECTORSIZE))) {
1107 printf ("** Read error on %d\n", dev);
1108 SHOW_BOOT_PROGRESS (-1);
1109 return 1;
1112 /* Loading ok, update default load address */
1114 load_addr = addr;
1116 /* Check if we should attempt an auto-start */
1117 if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
1118 char *local_args[2];
1119 extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
1121 local_args[0] = argv[0];
1122 local_args[1] = NULL;
1124 printf ("Automatic boot of image at addr 0x%08lx ...\n", addr);
1126 do_bootm (cmdtp, 0, 1, local_args);
1127 rcode = 1;
1129 return rcode;
1132 U_BOOT_CMD(
1133 nboot, 4, 1, do_nandboot,
1134 "nboot - boot from NAND device\n",
1135 "loadAddr dev\n"
1138 #endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */
1140 #endif /* CFG_NAND_LEGACY */