📄 cmd_nand.c
字号:
} blk = simple_strtoul(argv[1], NULL, 16); page = simple_strtoul(argv[2], NULL, 10); check_blk_range(blk); check_page_range(page); nandll_read_page((u8 *) page_buf, (blk * NAND_BLOCK_SIZE) + (page * NAND_PAGE_SIZE)); for (i = 0; i < 32; i++) { printf("%03x: %08x %08x %08x %08x\n", i << 4, page_buf[(i << 2) + 0], page_buf[(i << 2) + 1], page_buf[(i << 2) + 2], page_buf[(i << 2) + 3]); } nandll_read_oob((char *) oob_buf, (blk * NAND_BLOCK_SIZE) + (page * NAND_PAGE_SIZE)); printf("\nOOB: %08x %08x %08x %08x\n\n", oob_buf[0], oob_buf[1], oob_buf[2], oob_buf[3]); return 0;}int do_nandyw(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){ ulong startblk, size, memadr; int ecc_option; if (argc != 5) { printf("Usage:\n%s\n", cmdtp->usage); return 1; } startblk = simple_strtoul(argv[1], NULL, 16); check_blk_range(startblk); size = simple_strtoul(argv[2], NULL, 16); memadr = simple_strtoul(argv[3], NULL, 16); ecc_option = (argv[4][0] == 'y') ? NF_USE_ECC : NF_USE_MTD_ECC; // yaffs image don't use 1st block startblk++; NF_Reset(); s3c24x0_nand_write(startblk, size, memadr, NF_RW_YAFFS, ecc_option); return 0;}int do_nandyr(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){ ulong startblk, size, memadr; if (argc != 4) { printf("Usage:\n%s\n", cmdtp->usage); return 1; } startblk = simple_strtoul(argv[1], NULL, 16); size = simple_strtoul(argv[2], NULL, 16); memadr = simple_strtoul(argv[3], NULL, 16); // yaffs image don't use 1st block startblk++; NF_Reset(); s3c24x0_nand_read(startblk, size, memadr, NF_RW_YAFFS); return 0;}/* getfree added U_BOOT_CMD TABLE 2003.12.05 */U_BOOT_CMD(nandr, 4, 0, do_nandr, "nandr - read data from NAND (specific)\n", "blk# size memaddr\n" " - SMDK24XX NAND Flash Read Command\n" " - targetblock 0~0xfff(4095), targetsize memory addr\n");U_BOOT_CMD(nandw, 4, 0, do_nandw, "nandw - write data to NAND (specific)\n", "blk# size memaddr\n" " - SMDK24XX NAND Flash Write Command\n" " - targetblock 0~0xfff(4095), targetsize memory addr\n");/* add command (nande, bbmark, bbcheck) by jyj. (2004.8.10) */U_BOOT_CMD(nande, 3, 0, do_nande, "nande - erase NAND block (specific)\n", "startblk# endblk#\n" " - SMDK24XX NAND Flash Erase Command\n" " - block range : 0 ~ 0xfff(4095) in hex value\n");U_BOOT_CMD(bbmark, 3, 0, do_bbmark, "bbmark - mark NAND bad block (specific)\n", "blk# on/off\n" " - SMDK24XX NAND Flash Mark Bad Block Command\n" " - block range : 0 ~ 0xfff(4095) as hex value\n" " - on/off : mark/unmark bad block\n");U_BOOT_CMD(bbcheck, 3, 0, do_bbcheck, "bbcheck - show NAND bad block (specific)\n", " - SMDK24XX NAND Flash Show Bad Block Command");U_BOOT_CMD(nandv, 3, 0, do_nandv, "nandv - show NAND block data (specific)\n", "blk page\n" " - SMDK24XX NAND Flash Show Block Data Command\n" " - block range : 0 ~ 0xfff(4095) in hexa\n" " - page range : 0 ~ 31 in decimal\n");U_BOOT_CMD(nandyw, 5, 0, do_nandyw, "nandyw - write YAFFS block in NAND (specific)\n", "blk# size addr ecc_option\n" " - SMDK24XX NAND Flash Write Command for Yaffs\n" " - targetblock 0~0xfff(4095), targetsize memory addr\n" " - ecc_option : [y] use yaffs ecc / [m] use mtd ecc\n");U_BOOT_CMD(nandyr, 4, 0, do_nandyr, "nandyr - read YAFFS block in NAND (specific)\n", "blk# size addr\n" " - SMDK24XX NAND Flash Read Command for Yaffs\n" " - block 0~0xfff(4095)\n");U_BOOT_CMD(nandE, 4, 0, do_nandE, "nandE - erase block and OOB (specific)\n", "blk# size" " - delete all blocks in given range regardless Bad Blcok\n");/* * NF_MarkBadBlock : */static int NF_MarkBadBlock(u32 block, int mark_flag){ int i; u32 blockPage;#ifdef S3C24X0_16BIT_NAND u16 *Buf = (unsigned short *) seBuf;#endif blockPage = (block << 6); seBuf[0] = 0x44; seBuf[1] = 0xff; seBuf[40] = 0xff; seBuf[41] = 0xff; seBuf[42] = 0xff; seBuf[43] = 0xff; seBuf[44] = 0xff; seBuf[45] = 0xff; seBuf[46] = 0xff; seBuf[47] = 0xff; seBuf[48] = 0xff; seBuf[49] = 0xff; seBuf[50] = 0xff; seBuf[51] = 0xff; seBuf[52] = 0xff; seBuf[53] = 0xff; seBuf[54] = 0xff; seBuf[55] = 0xff; seBuf[56] = 0xff; seBuf[57] = 0xff; seBuf[58] = 0xff; seBuf[59] = 0xff; seBuf[60] = 0xff; seBuf[61] = 0xff; seBuf[62] = 0xff; seBuf[63] = 0xff; // seBuf[5] = 0x44; // 0xff is good block, else is bad block if (mark_flag == NF_BB_OFF) seBuf[0] = 0xff; NF_nFCE_L();// NFCMD_REG = NAND_CMD_READOOB;// NFCMD_REG = NAND_CMD_SEQIN; // Write 1st command NFCMD_REG = 0x80; NFADDR_REG = 0x00; // The mark of bad block is NFADDR_REG = 0x00; NFADDR_REG = blockPage & 0xff; // marked 5th spare array NFADDR_REG = (blockPage >>8) & 0xff; // in the 1st page. for (i = 0; i < NAND_OOB_SIZE; i++) { NFDATA8_REG = seBuf[i]; }// NFCMD_REG = NAND_CMD_PAGEPROG; NFCMD_REG = 0x10; for (i = 0; i < 10; i++); NF_TRANSRnB(); NFCMD_REG = NAND_CMD_STATUS; for (i = 0; i < 3; i++); if (NFDATA8_REG & 0x1) { // Spare arrray write error NF_nFCE_H(); printf("[Program error is occurred but ignored]\n"); } else { NF_nFCE_H(); } if (mark_flag == NF_BB_ON) { printf("[block 0x%x is marked as a bad block]\n", block); } else { printf("[block 0x%x is marked as a good block]\n", block); } return 1;}static int NF_WritePage(u32 block, u32 page, u8 * buffer){ int i; int j = 0; int loop = 0; u32 blockPage = (block * NAND_PAGES_IN_BLOCK) + page;#ifdef S3C24X0_16BIT_NAND u16 *Buf = (unsigned short) seBuf; u16 *ptr16 = buffer;#else u8 *ptr8 = buffer;#endif int ret = 1;#ifdef ECC_CHECK NF_RSTECC(); // Initialize ECC NF_MECC_UnLock(); NF_CLRRnB();#endif NAND_WP_OFF(); NF_nFCE_L(); // NFCMD_REG = NAND_CMD_READ0;// NFCMD_REG = NAND_CMD_SEQIN; NFCMD_REG = 0x80; NFADDR_REG = 0x00; NFADDR_REG = 0x00; NFADDR_REG = blockPage & 0xff; NFADDR_REG = ((blockPage >> 8) & 0xff);#ifndef ECC_CHECK for(i = 0;i<NAND_PAGE_SIZE;i++){ NFDATA8_REG = *ptr8++; }#else seBuf[0] = 0xff; seBuf[1] = 0xff; loop = 0; for(i = 0;i<NAND_PAGE_SIZE;){ for(j= 0; j <ECC_COUNT_BIT;j++){ NFDATA8_REG = *ptr8++; i++; } NF_MECC_Lock(); seBuf[40+loop] = (NFMECC0_REG & 0x0ff); seBuf[41+loop] = ((NFMECC0_REG >>8)&0xff); seBuf[42+loop] = ((NFMECC0_REG >>16)&0xff); seBuf[42+loop] |= 0x03; loop += 3; NF_RSTECC(); // Initialize ECC NF_MECC_UnLock(); NF_CLRRnB(); } #endif// NFCMD_REG = NAND_CMD_PAGEPROG; NFCMD_REG = 0x10; for (i = 0; i < 10; i++); NF_TRANSRnB(); NFCMD_REG = 0x70;//NAND_CMD_STATUS; for (i = 0; i < 10; i++); if (NFDATA8_REG & 0x1) { /* Page Error */ printf("[PROGRAM_ERROR:block#=%d]\n", block); NF_MarkBadBlock(block, NF_BB_ON); ret = 0; } NF_nFCE_H(); NAND_WP_ON(); #ifdef ECC_CHECK NF_WriteOob(block,page,seBuf,-1);#endif return ret;}static int NF_WriteOob(u32 block, u32 page, u8 * buffer, int yaffs_option){ int i; u32 blockPage = (block * NAND_PAGES_IN_BLOCK) + page;#ifdef S3C24X0_16BIT_NAND u16 *ptr16 = buffer;#else u8 *ptr8 = buffer; u8 oobBuf[NAND_OOB_SIZE]; for (i = 0; i < NAND_OOB_SIZE; i++) { oobBuf[i] = (*ptr8++); } if (yaffs_option == NF_USE_MTD_ECC) { oobBuf[8] = 0xFF; oobBuf[9] = 0xFF; oobBuf[10] = 0xFF; oobBuf[13] = 0xFF; oobBuf[14] = 0xFF; oobBuf[15] = 0xFF; }#endif NF_nFCE_L(); // NFCMD_REG = NAND_CMD_READOOB;// NFCMD_REG = NAND_CMD_SEQIN; NFCMD_REG =0x80; NFADDR_REG = 0x00; NFADDR_REG = 0x08; NFADDR_REG = (blockPage & 0xff); NFADDR_REG = ((blockPage >> 8) & 0xff); for (i = 0; i < NAND_OOB_SIZE; i++) { NFDATA8_REG = oobBuf[i]; }// NFCMD_REG = NAND_CMD_PAGEPROG; NFCMD_REG = 0x10; for (i = 0; i < 10; i++); NF_TRANSRnB(); NFCMD_REG = NAND_CMD_STATUS; for (i = 0; i < 3; i++); if (NFDATA8_REG & 0x1) { /* Page Error */ printf("[Program error is occurred but ignored]\n"); } NF_nFCE_H();/* printf("\n ECC :" ); for(i = 0;i<5;i++) { printf(" %x ",oobBuf[i]); }*/ return 1;}static void NF_Reset(void){ int i; NF_CLRRnB(); NF_nFCE_L(); NFCMD_REG = NAND_CMD_RESET; for (i = 0; i < 80; i++); NF_TRANSRnB(); NF_nFCE_H();}/* * NF_EraseBlock */#if 0static int NF_EraseBlock (u32 block){ u32 blockPage; int i, ret = 1; NAND_WP_OFF(); blockPage = block * NAND_PAGES_IN_BLOCK; NF_CLRRnB(); NF_nFCE_L(); NFCMD_REG = 0x60//NAND_CMD_ERASE1; NFADDR_REG = blockPage & 0xff; NFADDR_REG = (blockPage >> 8) & 0xff; NFADDR_REG = (blockPage >> 16) & 0xff; NFCMD_REG = NAND_CMD_ERASE2; for (i = 0; i < 40; i++); NF_TRANSRnB(); NFCMD_REG = NAND_CMD_STATUS; if (NFDATA8_REG & 0x1) { /* we got Erase error */ printf("[ERASE_ERROR:block#=%d]\n", block); NF_MarkBadBlock(block, NF_BB_ON); ret = 0; } NF_nFCE_H(); NAND_WP_ON(); return ret;}#elsestatic int NF_EraseBlock (u32 block){ u32 blockPage; int i, ret = 1; NAND_WP_OFF(); blockPage = block * NAND_PAGES_IN_BLOCK; NF_CLRRnB(); NF_nFCE_L(); NFCMD_REG = 0x60;//NAND_CMD_ERASE1; // NFADDR_REG = blockPage & 0xff;// NFADDR_REG = (blockPage >> 8) & 0xff;// NFADDR_REG = (blockPage >> 16) & 0xff; NFADDR_REG = (blockPage & 0xff); NFADDR_REG = ((blockPage >> 8) & 0xff); NFCMD_REG = 0xD0;//NAND_CMD_ERASE2; for (i = 0; i < 40; i++); NF_TRANSRnB(); NFCMD_REG = NAND_CMD_STATUS; if (NFDATA8_REG & 0x1) { /* we got Erase error */ printf("[ERASE_ERROR:block#=%d]\n", block); NF_MarkBadBlock(block, NF_BB_ON); ret = 0; } NF_nFCE_H(); NAND_WP_ON(); return ret;}#endifstatic int NF_IsBadBlock(u32 block){ int i; int blockPage;#ifdef S3C24X0_16BIT_NAND u16 data;#else u8 data;#endif blockPage = block * NAND_PAGES_IN_BLOCK; NF_CLRRnB(); NF_nFCE_L();//Joe# if 0 NFCMD_REG = NAND_CMD_READOOB;#ifdef S3C24X0_16BIT_NAND NFADDR_REG = 512 & 0x7; /* X16 A0~A2 are valid */#else NFADDR_REG = 517 & 0xf; // Read the mark of bad block in spare array(M addr=5)#endif NFADDR_REG = blockPage & 0xff; // The mark of bad block is in 0 page NFADDR_REG = (blockPage >> 8) & 0xff; // For block number A[24:17]#ifdef NAND_3_ADDR_CYCLE#else NFADDR_REG = (blockPage >> 16) & 0xff; // For block number A[25]#endif#endif NFCMD_REG = 0x0; NFADDR_REG = 0x00; NFADDR_REG = 0x08; NFADDR_REG = (blockPage&0xff); NFADDR_REG =((blockPage>>8)&0xff); NFCMD_REG = 0x30; // data = NFDATA8_REG; for (i = 0; i < 10; i++); /* dummy check me */ NF_TRANSRnB(); data = NFDATA8_REG; NF_nFCE_H(); if (data != 0xff) { printf("[block 0x%x has been marked as a bad block(%x)]\n", block, data); return 1; } else { return 0; }}/*void nand_init(){ printf("64MB\n"); }*/#endif /* (CONFIG_COMMANDS & CFG_CMD_NAND) */#endif /* CONFIG_S3C24XX */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -