int saveenv(void) { ulong total; int ret = 0; env_ptr->flags++; total = CFG_ENV_SIZE; if(gd->env_valid == 1) { puts ("Erasing redundant Nand..."); if (nand_erase(&nand_info[0], CFG_ENV_OFFSET_REDUND, CFG_ENV_SIZE)) return 1; puts ("Writing to redundant Nand... "); ret = nand_write(&nand_info[0], CFG_ENV_OFFSET_REDUND, &total, (u_char*) env_ptr); } else { puts ("Erasing Nand..."); if (nand_erase(&nand_info[0], CFG_ENV_OFFSET, CFG_ENV_SIZE)) return 1; puts ("Writing to Nand... "); ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*) env_ptr); } if (ret || total != CFG_ENV_SIZE) return 1; puts ("done\n"); gd->env_valid = (gd->env_valid == 2 ? 1 : 2); return ret; }
void sdram_to_nand_test() { unsigned long sdram_addr,nand_addr,len; printf("sdram addr,nand addr,len:"); scanf("%d %d %d",&sdram_addr,&nand_addr,&len); nand_erase(0);/* 1块 128k */ printf("Erase block 0 ok\r\n"); nand_erase(1); printf("Erase block 0 ok\r\n"); nand_erase(2); printf("Erase block 0 ok\r\n"); copy_sdram_to_nand((unsigned long *)sdram_addr,(unsigned long)nand_addr,len); }
void write_test() { char c; int count = 0; unsigned char buffer[128]; printf("Enter a string:\r\n"); // 接收字符串,回车时表示结束 while(1) { c = getc(); putc(c); if(c == '\r') { buffer[count] = '\0'; break; } else { buffer[count++] = c; } } printf("\r\n"); // 擦除第0个块 nand_erase(0); printf("Erase block 0 ok\r\n"); // 写第0个块 copy_sdram_to_nand(buffer, (unsigned long)0, strlen((char *)buffer)+1); printf("Write %s ok\r\n",buffer); }
int do_insAndroidUserImage(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { int ret = 0; nand_write_options_t opts; memset(&opts, 0, sizeof(opts)); //------------------------------------------------------------------ opts.pad = 0; opts.blockalign = 1; opts.writeoob = 1; opts.autoplace = 1; opts.offset = 0x9000000; opts.length = readl(0x27FFFFE8); opts.buffer = readl(0x27FFFFE0); if(opts.length > 0x500000) opts.quiet = 0; else opts.quiet = 1; printf("Start Addr : %X, Size : %X \n",opts.buffer,opts.length); nand_erase(&nand_info[0], opts.buffer, &opts.length); ret = nand_write_opts(&nand_info[0], &opts); printf("Writed User Data \n"); printf("Installed Android UserData Image image. \n"); return ret == 0 ? 0 : 1; return 1; }
/** * 作用:对nand标强制擦除 * * 参数: * @blockid ---block块的字符串 * * * 描述:nand强制擦除功能,当如果有软件坏块时也可以用此函数来强制擦除 */ void bsp_nand_erase_force(char *blockid) { int ret = NANDC_ERROR; unsigned int id; char *blk_id = bsp_nand_argument_check(blockid); /* string to int */ ret= str2ul(blk_id, &id); if(ret) { NAND_TRACE(("[%s]ERROR: string to integer failed, ret = 0x%x.\n", __FUNCTION__, ret)); goto ERRO; } /*直接擦除*/ ret = nand_erase(id); if(ret) { NAND_TRACE(("[%s]ERROR: nand check bad failed, ret = 0x%x.\n", __FUNCTION__, ret)); goto ERRO; } else { NAND_TRACE(("SUCCESS: erase block %x forcely.\n", id)); } return; ERRO: return; }
/* need transfer two para :blk_num ,start_blk */ int handle_nerase(void) { if (com_argc < 5) { printf(" Usage: nerase (1) (2) (3) (4)\n" " 1:start block number\n" " 2:block length\n" " 3:device index number\n" " 4:flash chip index number\n"); return -1; } init_nand_in(); nand_in.start = atoi(com_argv[1]); nand_in.length = atoi(com_argv[2]); nand_in.dev = atoi(com_argv[3]); if (atoi(com_argv[4]) >= MAX_DEV_NUM) { printf(" Flash index number overflow!\n"); return -1; } (nand_in.cs_map)[atoi(com_argv[4])] = 1; if (nand_erase(&nand_in) < 1) return -1; return 1; }
int VFL_Erase(u16 block) { u16 physicalBlock; int ret; int bank; int i; block = block + FTLData->field_4; for(bank = 0; bank < NANDGeometry->banksTotal; ++bank) { if(vfl_check_remap_scheduled(bank, block)) { vfl_remap_block(bank, block); vfl_mark_remap_done(bank, block); vfl_commit_cxt(bank); } physicalBlock = virtual_block_to_physical_block(bank, block); for(i = 0; i < 3; ++i) { ret = nand_erase(bank, physicalBlock); if(ret == 0) break; } if(ret) { LOG("ftl: block erase failed for bank %d, block %d\n", bank, block); // FIXME: properly handle this return ret; } } return 0; }
int do_insAndroidRamdisk(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { int ret = 0; nand_write_options_t opts; memset(&opts, 0, sizeof(opts)); opts.pad = 1; opts.blockalign = 1; opts.writeoob = 0; opts.autoplace = 1; //------------------------------------------------------------------ printf("Start android Ramdisk installation. \n"); opts.offset = 0x600000; opts.length = readl(0x27FFFFC8); opts.buffer = readl(0x27FFFFC0); if(opts.length > 0x500000) opts.quiet = 0; else opts.quiet = 1; nand_erase(&nand_info[0], opts.buffer, &opts.length); ret = nand_write_opts(&nand_info[0], &opts); printf("Writed Ramdisk \n"); printf("Installed Android Ramdisk image. \n"); return ret == 0 ? 0 : 1; return 1; }
void nand_test_erase(void) { nand_erase(0,1105); rt_kprintf("total block are erased \n"); nand_read_total(0,1105); rt_kprintf("total block are readed \n"); }
int do_insnand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { size_t total = CFG_ENV_OFFSET; ulong addr = PHYS_SDRAM_1; movi_read((uint) addr, ofsinfo.bl2, MOVI_BL2_BLKCNT); nand_erase(&nand_info[0], 0x0, CFG_ENV_OFFSET + CFG_ENV_SIZE); nand_write(&nand_info[0], 0x0, &total, (u_char *) addr); printf("Done\n"); return 1; }
void cmd_nand_erase(int argc, char** argv) { if(argc < 3) { bufferPrintf("Usage: %s <bank> <block> -- You probably don't want to do this.\r\n", argv[0]); return; } uint32_t bank = parseNumber(argv[1]); uint32_t block = parseNumber(argv[2]); bufferPrintf("Erasing bank %d, block %d...\r\n", bank, block); bufferPrintf("nand_erase: %d\r\n", nand_erase(bank, block)); }
int saveenv_nand_adv(void) { size_t total; int ret = 0; u_char *tmp; total = CFG_ENV_OFFSET; tmp = (u_char *) malloc(total); nand_read(&nand_info[0], 0x0, &total, (u_char *) tmp); puts("Erasing Nand..."); nand_erase(&nand_info[0], 0x0, CFG_ENV_OFFSET + CFG_ENV_SIZE); //#ifndef CONFIG_S5PC100_EVT1 if (nand_erase(&nand_info[0], 0x0, CFG_ENV_OFFSET + CFG_ENV_SIZE)) { free(tmp); return 1; } //#endif puts("Writing to Nand... "); ret = nand_write(&nand_info[0], 0x0, &total, (u_char *) tmp); total = CFG_ENV_SIZE; ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char *) env_ptr); //#ifndef CONFIG_S5PC100_EVT1 if (ret || total != CFG_ENV_SIZE) { free(tmp); return 1; } //#endif puts("done\n"); free(tmp); return ret; }
int saveenv_nand_adv(void) { #if defined(CONFIG_CMD_NAND) size_t total; int ret = 0; u_char *tmp; total = CONFIG_ENV_OFFSET; tmp = (u_char *) malloc(total); nand_read(&nand_info[0], 0x0, &total, (u_char *) tmp); puts("Erasing Nand..."); nand_erase(&nand_info[0], 0x0, CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE); if (nand_erase(&nand_info[0], 0x0, CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)) { free(tmp); return 1; } puts("Writing to Nand... "); ret = nand_write(&nand_info[0], 0x0, &total, (u_char *) tmp); total = CONFIG_ENV_SIZE; ret = nand_write(&nand_info[0], CONFIG_ENV_OFFSET, &total, (u_char *) env_ptr); if (ret || total != CONFIG_ENV_SIZE) { free(tmp); return 1; } puts("done\n"); free(tmp); return ret; #else return 0; #endif /* CONFIG_CMD_NAND */ }
/***************************************************************************** * name : flash_erase_force * * description : Erase nand block force, even if it's bad. * * input : char *partition_name: partition to be erase * * other : No *****************************************************************************/ void flash_erase_force(char *partition_name) { unsigned i = 0; unsigned ret = ERROR; unsigned block_start = 0; unsigned block_end= 0; struct nand_spec spec; struct ptentry *ptn = NULL; ret = nand_get_spec(&spec); if(ret) { cprintf("ERROR: nand get spec failed!\n"); goto EXIT; } partition_name = bsp_nand_argument_check(partition_name); if(NULL == partition_name) { cprintf("ERROR: no partition name!\n"); goto EXIT; } ptn = flash_find_ptn(partition_name); if(!ptn) { cprintf("ERROR: wrong partition name: %s\n", partition_name); goto EXIT; } /* coverity[uninit_use] */ block_start = (ptn->start + spec.blocksize- 1) / spec.blocksize; block_end = (ptn->start + ptn->length + spec.blocksize - 1) / spec.blocksize; for (i = block_start; i < block_end; i++) { ret = nand_erase(i); if(ret) { cprintf("ERROR: nand erase error, block id = %d, ret = %d.\n", i, ret); } } cprintf("Erase %s force finished!\n", partition_name); return; EXIT: cprintf("ret = 0x%x!\n", ret); return; }
int main() { nand_init(); nand_erase(0x600000, 0x100000); char *str = "jiangshen 123456789 haha"; nand_write((unsigned int)str, 0x600000, 2048); nand_read((unsigned int)0x41000000, 0x600000, 2048); return 0; }
static int fastboot_data_part_wipe() { int ret = B_OK; int err; int index; #ifdef MTK_NEW_COMBO_EMMC_SUPPORT unsigned int part_id; #endif unsigned long long ptn; unsigned long long size; index = partition_get_index("userdata"); if (index == -1 || !is_support_erase(index)) { ret = PART_GET_INDEX_FAIL; return ret; } #ifdef MTK_NEW_COMBO_EMMC_SUPPORT part_id = partition_get_region(index); #endif ptn = partition_get_offset(index); size = partition_get_size(index); set_env("unlock_erase", "start"); #ifdef MTK_EMMC_SUPPORT #ifdef MTK_NEW_COMBO_EMMC_SUPPORT err = emmc_erase(part_id, ptn, size); #else err = emmc_erase(ptn, size); #endif #else err = nand_erase(ptn,(u64)size); #endif if (err) { ret = PART_ERASE_FAIL; set_env("unlock_erase", "fail"); } else { ret = B_OK; set_env("unlock_erase", "pass"); } return ret; }
int erase_test() { int blocknum = 0; printf("Block # to erase: "); scanf("%d",&blocknum); printf("\r\n"); if(nand_erase(blocknum) == -1) return -1; printf("Block %d erase ok\r\n", blocknum); return 0; }
int sec_dev_write_wrapper(char *part_name, u64 offset, u8* data, u32 size) { part_dev_t *dev; long len; #ifdef MTK_EMMC_SUPPORT #ifdef MTK_NEW_COMBO_EMMC_SUPPORT part_t *part; #endif #endif dev = mt_part_get_device(); if (!dev) return PART_GET_DEV_FAIL; #ifndef MTK_EMMC_SUPPORT if(nand_erase(offset,(u64)size)!=0){ return PART_ERASE_FAIL; } #endif #ifdef MTK_EMMC_SUPPORT #ifdef MTK_NEW_COMBO_EMMC_SUPPORT part = mt_part_get_partition(part_name); if (!part){ dprintf(CRITICAL,"[write_wrapper] mt_part_get_partition error, name: %s\n", part_name); ASSERT(0); } len = dev->write(dev, (uchar *) data, offset, size, part->part_id); #else len = dev->write(dev, (uchar *) data, offset, size); #endif #else #ifdef MTK_NEW_COMBO_EMMC_SUPPORT len = dev->write(dev, (uchar *) data, offset, size, NAND_PART_USER); #else len = dev->write(dev, (uchar *) data, offset, size); #endif #endif if (len != (int)size) { return PART_WRITE_FAIL; } return B_OK; }
static u16 vfl_remap_block(int bank, u16 block) { u16 newBlock = 0; int newBlockIdx; int i; if(bank >= NANDGeometry->banksTotal || block >= NANDGeometry->blocksPerBank) return 0; LOG("ftl: attempting to remap bank %d, block %d\n", bank, block); return 0; // find a reserved block that is not being used for(i = 0; i < pstVFLCxt[bank].totalReservedBlocks; ++i) { if(pstVFLCxt[bank].reservedBlockPoolMap[i] == 0) { newBlock = pstVFLCxt[bank].reservedBlockPoolStart + i; newBlockIdx = i; break; } } // none found if(newBlock == 0) return 0; // try to erase newly allocated reserved block nine times for(i = 0; i < 9; ++i) { if(nand_erase(bank, newBlock) == 0) break; } for(i = 0; i < newBlockIdx; ++i) { // mark any reserved block previously remapped for this block as bad if(pstVFLCxt[bank].reservedBlockPoolMap[i] == block) pstVFLCxt[bank].reservedBlockPoolMap[i] = 0xFFFF; } pstVFLCxt[bank].reservedBlockPoolMap[newBlockIdx] = block; ++pstVFLCxt[bank].numReservedBlocks; vfl_set_good_block(bank, block, false); return newBlock; }
int saveenv(void) { int total, ret = 0; puts ("Erasing Nand..."); if (nand_erase(nand_dev_desc + 0, CFG_ENV_OFFSET, CFG_ENV_SIZE, 0)) return 1; puts ("Writing to Nand... "); ret = nand_rw(nand_dev_desc + 0, NANDRW_WRITE | NANDRW_JFFS2, CFG_ENV_OFFSET, CFG_ENV_SIZE, &total, (u_char*)env_ptr); if (ret || total != CFG_ENV_SIZE) return 1; puts ("done\n"); return ret; }
// for sequential void merge_switch(int log_pbn, int data_pbn) { //1. search & update pointers //2. update BMT int i; for(i = 0; i< total_blk_num; i++){ if( BMT[i] == data_pbn ){ BMT[i] = log_pbn; break; } } ASSERT(i != total_blk_num); //3. erase (data_pbn) nand_erase(data_pbn); }
/* * The legacy NAND code saved the environment in the first NAND device i.e., * nand_dev_desc + 0. This is also the behaviour using the new NAND code. */ #ifdef CFG_ENV_OFFSET_REDUND int saveenv(void) { ulong total; int ret = 0; env_ptr->flags++; total = CFG_ENV_SIZE; if(gd->env_valid == 1) { puts ("Erasing redundant Nand..."); if (nand_erase(&nand_info[0], CFG_ENV_OFFSET_REDUND, CFG_ENV_SIZE)) return 1; puts ("Writing to redundant Nand... "); ret = nand_write(&nand_info[0], CFG_ENV_OFFSET_REDUND, &total, (u_char*) env_ptr); } else { puts ("Erasing Nand..."); if (nand_erase(&nand_info[0], CFG_ENV_OFFSET, CFG_ENV_SIZE)) return 1; puts ("Writing to Nand... "); ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*) env_ptr); } if (ret || total != CFG_ENV_SIZE) return 1; puts ("done\n"); gd->env_valid = (gd->env_valid == 2 ? 1 : 2); return ret; } #else /* ! CFG_ENV_OFFSET_REDUND */ int saveenv(void) { ulong total; int ret = 0; puts ("Erasing Nand..."); if (nand_erase(&nand_info[0], CFG_ENV_OFFSET, CFG_ENV_SIZE)) return 1; puts ("Writing to Nand... "); total = CFG_ENV_SIZE; ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr); if (ret || total != CFG_ENV_SIZE) return 1; puts ("done\n"); return ret; }
void cmd_erase_nand(const char *arg, void *data, unsigned sz) { int index; u64 offset,size; char msg[256]; index = partition_get_index(arg); if(index == -1){ fastboot_fail_wrapper("partition get index fail"); return; } if(!is_support_erase(index)){ sprintf(msg,"partition '%s' not support erase\n",arg); fastboot_fail_wrapper(msg); return; } offset = partition_get_offset(index); if(offset == (u64)(-1)){ fastboot_fail_wrapper("partition get offset fail"); return; }else{ printf("get offset: 0x%llx\n",offset); } size = partition_get_size(index); if(size == (u64)(-1)){ fastboot_fail_wrapper("partition get size fail"); return; }else{ printf("get size: 0x%llx\n",size); } TIME_START; display_info("erase flash ...."); if(nand_erase(offset,size)!=0){ fastboot_fail_wrapper("failed to erase partition"); return; } fastboot_ok_wrapper("erase flash sucess",sz); return; }
/** * 作用:nandc模块按分区名和分区偏移地址来擦除flash操作 * * 参数: * @partition_name ---要擦除的分区名 * @partition_offset ---要擦除的相对偏移地址 * * * 描述:根据分区名和分区的偏移地址来确定Flash的地址,再来擦除一个block,注意是擦除一个block数据块 */ int bsp_nand_erase(const char *partition_name, u32 partition_offset) { u32 flash_addr; u32 block_id, bad_flag; u32 ret = NANDC_ERROR; struct nandc_host * host = NULL; struct ST_PART_TBL * ptable = find_partition_by_name(partition_name); /*参数不正确*/ if(!ptable) { goto ERRO; } /*得到flash的地址信息*/ flash_addr = ptable->offset + partition_offset; host = nandc_nand_host; if(!host) { NAND_TRACE(("ERROR: function %s, line %d\n", __FUNCTION__, __LINE__)); goto ERRO; } /*得到块号并判断是否是坏块*/ block_id = flash_addr / host->nandchip->spec.blocksize; ret = nand_isbad(block_id, &bad_flag); if(ret) { NAND_TRACE(("ERROR: nand quary bad failed, function %s, line %d\n", __FUNCTION__, __LINE__)); goto ERRO; } if(NANDC_BAD_BLOCK == bad_flag) { NAND_TRACE(("ERROR: try to erase a bad block, function %s, line %d\n", __FUNCTION__, __LINE__)); goto ERRO; } /*擦除flash操作*/ return nand_erase(block_id); ERRO: return ret; }
int main(int argc, char *argv[]) { int i = 0; char *p=(void *)0x52000000; char *buf=(void *)0x51000000; WTCON=0; clock_init(); uart_init(); ddr_init(); nand_init(); memcpy(buf,"helloworld\n",12); memset(p,0,12); nand_erase(0x200000,12); nand_write(buf,0x200000,12); nand_read(p,0x200000,12); uprintf(p); uprintf("\n"); return 0; }
static int warp_nand_bferase(int saveno) { int ret; unsigned long off, end; nand_info_t *nand = &nand_info[0]; off = warp_savearea[saveno].bootflag_area; end = off + warp_savearea[saveno].bootflag_size; printf("Warp!! bootflag clear NAND: 0x%08lx-0x%08lx\n", off, end - 1); while (off < end) { if (!nand_block_isbad(nand, off)) { if ((ret = nand_erase(nand, off, nand->erasesize)) != 0) { printf("bootflag erase error %d\n", ret); return ret; } } off += nand->erasesize; } return 0; }
static int vfl_commit_cxt(int bank) { u32 cur; u32 block; if((pstVFLCxt[bank].nextcxtpage + 8) <= NANDGeometry->pagesPerBlock) if(vfl_store_cxt(bank) == 0) return 0; cur = pstVFLCxt[bank].activecxtblock; block = cur; while(true) { int i; block = (block + 1) % 4; if(block == cur) break; // try to erase 4 times for(i = 0; i < 4; ++i) { if(nand_erase(bank, pstVFLCxt[bank].VFLCxtBlock[block]) == 0) break; } if(i == 4) continue; pstVFLCxt[bank].activecxtblock = block; pstVFLCxt[bank].nextcxtpage = 0; if(vfl_store_cxt(bank) == 0) return 0; } LOG("ftl: failed to commit VFL context!\n"); return -1; }
/***************************************************************************** * name : flash_erase * * description : Erase nand block * * input : ptentry *ptn: partition to be erase * * return : NANDF_OK: erase OK * NANDF_ERROR_INIT: Init failed * NANDF_ERROR_ARGS: Input error * NANDF_BAD_BLOCK: the block to be erase is a bad block * NANDF_ERROR_ERASE: erase failed, and mark the block as a bad block * NANDF_ERROR_ERASE_MARKBAD: erase failed, and mark bad block failed * NANDF_ERROR_SEMTAKE: apply semphore failed * NANDF_ERROR_SEMGIVE: release semphore failed * * other : No *****************************************************************************/ int flash_erase(ptentry *ptn) { int ret = ERROR; unsigned i = 0; unsigned block_start = 0; unsigned block_end= 0; unsigned bad_flag; struct nand_spec spec; ret = nand_get_spec(&spec); if(ret) { cprintf("ERROR: nand get spec failed!\n"); return ERROR; } /* coverity[uninit_use] */ block_start = (ptn->start + spec.blocksize- 1) / spec.blocksize; block_end = (ptn->start + ptn->length + spec.blocksize - 1) / spec.blocksize; for (i = block_start; i < block_end; i++) { ret = (s32)nand_isbad(i, &bad_flag); if(NANDC_OK != ret || NANDC_BAD_BLOCK == bad_flag) { cprintf("block %d is bad, not erase, ret=%x\n", i, ret); continue; } ret = (s32)nand_erase(i); if(ret) { cprintf("erase block %d failed, ret=%x\n", i, ret); } } return OK; }
static int nand_burn_image(size_t image_size) { int ret, block_size; nand_info_t *nand; int dev = nand_curr_device; if ((dev < 0) || (dev >= CONFIG_SYS_MAX_NAND_DEVICE) || (!nand_info[dev].name)) { puts("\nno devices available\n"); return -ENOMEDIUM; } nand = &nand_info[dev]; block_size = nand->erasesize; /* Align U-Boot size to currently used blocksize */ image_size = ((image_size + (block_size - 1)) & (~(block_size - 1))); /* Erase the U-BOOT image space */ printf("Erasing 0x%x - 0x%x:...", 0, (int)image_size); ret = nand_erase(nand, 0, image_size); if (ret) { printf("Error!\n"); goto error; } printf("Done!\n"); /* Write the image to flash */ printf("Writing image:..."); printf("&image_size = 0x%p\n", (void *)&image_size); ret = nand_write(nand, 0, &image_size, (void *)get_load_addr()); if (ret) printf("Error!\n"); else printf("Done!\n"); error: return ret; }
u32t nand_write(u32t mem_add, u32t nand_add, u32t length){ u32t write_c = 0, i; unsigned char *c = (unsigned char *)mem_add; nand_erase(nand_add, length); NAND_CHIP_ENABLE; while (write_c < length) { nand_reg->NFCMD = 0x80; send_addr(nand_add + write_c); for (i = 0; i < PAGE_SIZE && write_c < length;\ i++, write_c++) { *(unsigned char volatile *)&nand_reg->NFDATA = c[write_c]; } nand_reg->NFCMD = 0x10; NAND_STATE_READY; } NAND_CHIP_DISABLE; return write_c; }