static int warp_nand_drvload(void) { int ret; unsigned long size, off; nand_info_t *nand = &nand_info[0]; off = warp_nand_skipbad(nand, warp_drv_area, warp_drv_size); if (off == (unsigned long)-1) return 1; size = WARP_DRV_PRELOAD; if ((ret = nand_read(nand, off, &size, (void *)warp_drv_addr)) == 0) { if (*(int *)(warp_drv_addr + WARP_HEADER_ID) != WARP_ID_DRIVER) return 1; size = *(int *)(warp_drv_addr + WARP_HEADER_COPY_SIZE) - WARP_DRV_PRELOAD; if (size <= 0 || (ret = nand_read(nand, off + WARP_DRV_PRELOAD, &size, (void *)(warp_drv_addr + WARP_DRV_PRELOAD))) == 0) { size += WARP_DRV_PRELOAD; flush_cache(warp_drv_addr, size); return 0; } } printf("hibdrv read error %d\n", ret); return ret; }
int VFL_Read(uint32_t virtualPageNumber, uint8_t* buffer, uint8_t* spare, int empty_ok, int* refresh_page) { if(refresh_page) { *refresh_page = FALSE; } VFLData1.field_8++; VFLData1.field_20++; uint32_t dwVpn = virtualPageNumber + (Data->pagesPerSubBlk * Data2->field_4); if(dwVpn >= Data->pagesTotal) { bufferPrintf("ftl: dwVpn overflow: %d\r\n", dwVpn); return ERROR_ARG; } if(dwVpn < Data->pagesPerSubBlk) { bufferPrintf("ftl: dwVpn underflow: %d\r\n", dwVpn); } uint16_t virtualBank; uint16_t virtualBlock; uint16_t virtualPage; uint16_t physicalBlock; virtual_page_number_to_virtual_address(dwVpn, &virtualBank, &virtualBlock, &virtualPage); physicalBlock = virtual_block_to_physical_block(virtualBank, virtualBlock); int page = physicalBlock * Data->pagesPerBlock + virtualPage; int ret = nand_read(virtualBank, page, buffer, spare, TRUE, TRUE); if(!empty_ok && ret == ERROR_EMPTYBLOCK) { ret = ERROR_NAND; } if(refresh_page) { if((Data->field_2F <= 0 && ret == 0) || ret == ERROR_NAND) { bufferPrintf("ftl: setting refresh_page to TRUE due to the following factors: Data->field_2F = %x, ret = %d\r\n", Data->field_2F, ret); *refresh_page = TRUE; } } if(ret == ERROR_ARG || ret == ERROR_NAND) { nand_bank_reset(virtualBank, 100); ret = nand_read(virtualBank, page, buffer, spare, TRUE, TRUE); if(!empty_ok && ret == ERROR_EMPTYBLOCK) { return ERROR_NAND; } if(ret == ERROR_ARG || ret == ERROR_NAND) return ret; } if(ret == ERROR_EMPTYBLOCK) { if(spare) { memset(spare, 0xFF, sizeof(SpareData)); } } return ret; }
int K9F2G08_ReadChunk(u32 chunk, u8 *data, u8 *tags) { int i; nand_cs_en(); nand_write_cmd(NAND_CMD_READ0); nand_write_addr(0x00); nand_write_addr(0x00); nand_write_addr(chunk & 0xff); nand_write_addr((chunk >> 8) & 0xff); nand_write_addr((chunk >> 16) & 0xff); // /* nand_Init_ECC(); */ nand_write_cmd(NAND_CMD_READ30); nand_wait(); /* Wait tR(max 12us) */ for(i = 0; i < PAGE_DATA_SIZE; i++) { data[i] = nand_read(); /* Read page data */ } for(i = 0; i < PAGE_SPARE_SIZE; i++) { tags[i] = nand_read(); /* Read spare array */ } nand_cs_ds(); return 1; }
int VFL_Read(u32 virtualPageNumber, u8* buffer, u8* spare, bool empty_ok) { u16 virtualBank; u16 virtualBlock; u16 virtualPage; u16 physicalBlock; u32 dwVpn; int page; int ret; VFLData1.field_8++; VFLData1.field_20++; dwVpn = virtualPageNumber + (NANDGeometry->pagesPerSuBlk * FTLData->field_4); if(dwVpn >= NANDGeometry->pagesTotal) { LOG("ftl: dwVpn overflow: %d\n", dwVpn); return -EINVAL; } if(dwVpn < NANDGeometry->pagesPerSuBlk) { LOG("ftl: dwVpn underflow: %d\n", dwVpn); } virtual_page_number_to_virtual_address(dwVpn, &virtualBank, &virtualBlock, &virtualPage); physicalBlock = virtual_block_to_physical_block(virtualBank, virtualBlock); page = physicalBlock * NANDGeometry->pagesPerBlock + virtualPage; #ifdef IPHONE_DEBUG LOG("ftl: vfl_read: vpn: %u, bank %d, page %u\n", virtualPageNumber, virtualBank, page); #endif ret = nand_read(virtualBank, page, buffer, spare, true, true); if(!empty_ok && ret == ERROR_EMPTYBLOCK) { ret = -EIO; } if(ret == -EINVAL || ret == -EIO) { nand_bank_reset(virtualBank, 100); ret = nand_read(virtualBank, page, buffer, spare, true, true); if(!empty_ok && ret == ERROR_EMPTYBLOCK) { return -EIO; } if(ret == -EINVAL || ret == -EIO) return ret; } if(ret == ERROR_EMPTYBLOCK) { if(spare) { memset(spare, 0xFF, sizeof(SpareData)); } } return ret; }
static void nand_copy( UINT32 *dst, UINT32 address, int len ) { while( len > 0 ) { *( dst++ ) = nand_read( address ) | ( nand_read( address + 2 ) << 16 ); address += 4; len -= 4; } }
void env_relocate_spec (void) { #if !defined(ENV_IS_EMBEDDED) ulong total; int crc1_ok = 0, crc2_ok = 0; env_t *tmp_env1, *tmp_env2; total = CFG_ENV_SIZE; tmp_env1 = (env_t *) malloc(CFG_ENV_SIZE); tmp_env2 = (env_t *) malloc(CFG_ENV_SIZE); nand_read(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*) tmp_env1); nand_read(&nand_info[0], CFG_ENV_OFFSET_REDUND, &total, (u_char*) tmp_env2); crc1_ok = (crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc); crc2_ok = (crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc); if(!crc1_ok && !crc2_ok) return use_default(); else if(crc1_ok && !crc2_ok) gd->env_valid = 1; else if(!crc1_ok && crc2_ok) gd->env_valid = 2; else { /* both ok - check serial */ if(tmp_env1->flags == 255 && tmp_env2->flags == 0) gd->env_valid = 2; else if(tmp_env2->flags == 255 && tmp_env1->flags == 0) gd->env_valid = 1; else if(tmp_env1->flags > tmp_env2->flags) gd->env_valid = 1; else if(tmp_env2->flags > tmp_env1->flags) gd->env_valid = 2; else /* flags are equal - almost impossible */ gd->env_valid = 1; } free(env_ptr); if(gd->env_valid == 1) { env_ptr = tmp_env1; free(tmp_env2); } else { env_ptr = tmp_env2; free(tmp_env1); } #endif /* ! ENV_IS_EMBEDDED */ }
int K9F2G08_ReadTags(u32 block, u32 page, u8 *spare, int ofs, int len) { int i; u32 _page = block*PAGES_PER_BLOCK + page; /* NF_RSTECC(); */ /* Initialize ECC */ nand_cs_en(); nand_write_cmd(NAND_CMD_READ0); nand_write_addr((PAGE_DATA_SIZE+ofs)&0xff); nand_write_addr(((PAGE_DATA_SIZE+ofs)>>8)&0xff); nand_write_addr(_page&0xff); nand_write_addr((_page>>8)&0xff); nand_write_addr((_page>>16)&0xff); nand_write_cmd(NAND_CMD_READSTART); nand_wait(); /* Wait tR(max 12us) */ for(i=0;i<len;i++) { spare[i] = nand_read(); /* Read one page */ } nand_cs_ds(); return 1; }
int K9F2G08_ReadPage(u32 block, u32 page, u8 *buffer, int len, u8 *ecc) { int i; u32 _page = block*PAGES_PER_BLOCK + page; /* NF_RSTECC(); */ /* Initialize ECC*/ nand_cs_en(); nand_write_cmd(NAND_CMD_READ0); /* Read command */ nand_write_addr(0x00); /* Column = 0 */ nand_write_addr(0x00); nand_write_addr(_page&0xff); nand_write_addr((_page>>8)&0xff); nand_write_addr((_page>>16)&0xff); nand_write_cmd(NAND_CMD_READSTART); nand_wait(); /* Wait tR(max 12us) */ for(i=0;i<len;i++) { buffer[i] = nand_read(); /* Read one page */ } nand_cs_ds(); return 1; }
/* * 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. */ void env_relocate_spec_nand(void) { #if !defined(ENV_IS_EMBEDDED) size_t total; int ret, i; u_char *data; data = (u_char*)malloc(CFG_ENV_SIZE); total = CFG_ENV_SIZE; for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) { if (nand_scan(&nand_info[i], 1) == 0) { ret = nand_read(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)data); env_ptr = data; if (ret || total != CFG_ENV_SIZE) return use_default(); if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc) return use_default(); } else { printf("no devices available\n"); return use_default(); } } /* */ #endif /* ! ENV_IS_EMBEDDED */ }
int main(void) { int i; uart_init(); /* ³õʼ»¯UART0 */ wy_printf("LCD initialize ...\n"); lcd_init(); while (1) { wy_printf("display red\n"); lcd_clear_screen(0xff0000); for(i=50;i>0;i--) delay(); wy_printf("display green\n"); lcd_clear_screen(0x00ff00); for(i=50;i>0;i--) delay(); wy_printf("display blue\n"); lcd_clear_screen(0x0000ff); for(i=50;i>0;i--) delay(); nand_read((unsigned char *)0x3fc00000, 0xC00000, 0x300000); wy_printf("display girl\n"); lcd_draw_bmp(0x3fc00000); for(i=150;i>0;i--) delay(); } return 0; }
int main( void ) { void (*theKernel)(int zero, int arch, unsigned int params); /* 1. 帮内核设置串口:内核启动的开始部分会从串口打印一些log,但是内核一开始还没有初始化串口 */ uart0_init(); puts("\r\n---------welcome----------\r\n"); /* 2. 从NAND FLASH把内核读入内存 */ puts("Copy kernel from NAND.\n\r"); nand_read(0xa0000+64, (unsigned char *)0x30008000, 0x400000);/*boot(512K),params(128K),kernel(4M),rootfs(...)*/ /* 3. 设置参数 */ puts("Set boot params\n\r"); setup_start_tag(); setup_memory_tags(); setup_commandline_tag("noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0,115200"); setup_end_tag(); /* 4. 跳转执行 */ puts("Boot kernel\n\r"); theKernel = (void (*)(int, int, unsigned int))0x30008000; theKernel(0, 362, 0x30000100); puts("Error!\n\r"); return -1; }
static int warp_nand_bmload(int saveno) { int ret; unsigned long size, off; nand_info_t *nand = &nand_info[0]; off = warp_nand_skipbad(nand, warp_savearea[saveno].bootflag_area, warp_savearea[saveno].bootflag_size); if (off == (unsigned long)-1) return 1; off += WARP_MODE_OFFSET; off = warp_nand_skipbad(nand, off, warp_savearea[saveno].bootflag_size); if (off == (unsigned long)-1) return 1; ret = nand_read(nand, off, &size, warp_bfaddr); if (ret != 0) { printf("bootmode read error %d\n", ret); return ret; } return 0; }
int readenv (size_t offset, u_char * buf) { size_t end = offset + CONFIG_ENV_RANGE; size_t amount_loaded = 0; size_t blocksize, len; u_char *char_ptr; /* fail if no nand detected */ if (nand_info[0].type == 0) return 1; blocksize = nand_info[0].erasesize; if (!blocksize) return 1; len = min(blocksize, CONFIG_ENV_SIZE); while (amount_loaded < CONFIG_ENV_SIZE && offset < end) { if (nand_block_isbad(&nand_info[0], offset)) { offset += blocksize; } else { char_ptr = &buf[amount_loaded]; if (nand_read(&nand_info[0], offset, &len, char_ptr)) return 1; offset += blocksize; amount_loaded += len; } } if (amount_loaded != CONFIG_ENV_SIZE) return 1; return 0; }
void nand_read_test(void) { int i; char buf[100]; unsigned long addr; unsigned long size; printf("enter the start address: "); scanf("%s", buf); addr = strtoul(buf, NULL, 0); printf("read addr = 0x%x\n\r", addr); printf("enter the size: "); scanf("%s", buf); size = strtoul(buf, NULL, 0); if (size > 100) { printf("the max size is 100\n\r"); size = 100; } nand_read(addr, buf, size); printf("datas: \n\r"); for (i = 0; i < size; i++) { printf("%02x ", buf[i]); if ((i+1) % 16 == 0) { printf("\n\r"); } } printf("\n\r"); }
void cmd_nand_read_spare(int argc, char** argv) { if(argc < 4) { bufferPrintf("Usage: %s <address> <bank> <page> [pages]\r\n", argv[0]); return; } uint32_t address = parseNumber(argv[1]); uint32_t bank = parseNumber(argv[2]); uint32_t page = parseNumber(argv[3]); uint32_t pages = 1; if(argc >= 5) { pages = parseNumber(argv[4]); } bufferPrintf("reading bank %d, pages %d - %d spare into %x\r\n", bank, page, page + pages - 1, address); NANDData* Data = nand_get_geometry(); while(pages > 0) { int ret = nand_read(bank, page, NULL, (uint8_t*) address, FALSE, FALSE); if(ret != 0) bufferPrintf("nand_read: %x\r\n", ret); pages--; page++; address += Data->bytesPerSpare; } bufferPrintf("done!\r\n"); }
int nand(int argc, char *argv[]) { int nand_addr, sdram_addr; unsigned int size; if (argc < 5) { wy_printf("nand read sdram_addr nand_addr size\n"); wy_printf("nand write sdram_addr nand_addr size\n"); return 0; } sdram_addr = atoi(argv[2]); nand_addr = atoi(argv[3]); size = atoi(argv[4]); wy_printf("do_command <%s> \n", argv[0]); wy_printf("sdram 0x%x, nand 0x%x, size 0x%x\n", sdram_addr, nand_addr, size); if (strcmp(argv[1], "read") == 0) nand_read((unsigned char *)sdram_addr, nand_addr, size); if (strcmp(argv[1], "write") == 0) nand_write(sdram_addr, nand_addr, size); wy_printf("nand %s finished!\n", argv[1]); return 0; }
void nand_read_total(int start, int end) { nand_read(start,end); nand_read2(start,end); nand_read3(start,end); }
/* * check block is bad? * return 1 if it's a bad block, 0 if it's good. */ int K9F2G08_Check_badblk(u32 block) { u8 data; u32 _page;/* frist page in block */ _page = block*PAGES_PER_BLOCK; /* For 2'nd cycle I/O[7:5] */ nand_cs_en(); nand_write_cmd(NAND_CMD_READ0); /* Spare array read command */ nand_write_addr(PAGE_DATA_SIZE&0xff); /* Read the mark of bad block in spare array(M addr=5) */ nand_write_addr((PAGE_DATA_SIZE>>8)&0xff); nand_write_addr(_page&0xff); /* The mark of bad block is in 0 page */ nand_write_addr((_page>>8)&0xff); /* For block number A[24:17] */ nand_write_addr((_page>>16)&0xff); /* For block number A[25] */ nand_write_cmd(NAND_CMD_READSTART); nand_wait(); /* Wait tR(max 12us) */ data=nand_read(); nand_cs_ds(); if(data==0x00) return 1;/* bad */ else return 0;/* good */ }
static void nand_strategy(struct bio *bp) { struct nand_chip *chip; struct cdev *dev; int err = 0; dev = bp->bio_dev; chip = dev->si_drv1; nand_debug(NDBG_CDEV, "Strategy %s on chip %d [%p]\n", bp->bio_cmd == BIO_READ ? "READ" : "WRITE", chip->num, chip); if (bp->bio_cmd == BIO_READ) { err = nand_read(chip, bp->bio_offset & 0xffffffff, bp->bio_data, bp->bio_bcount); } else { err = nand_write(chip, bp->bio_offset & 0xffffffff, bp->bio_data, bp->bio_bcount); } if (err == 0) bp->bio_resid = 0; else { bp->bio_error = EIO; bp->bio_flags |= BIO_ERROR; bp->bio_resid = bp->bio_bcount; } biodone(bp); }
void arm_boot(void) { int *ddr_p = (void *)0x57000000; WTCON = 0; __asm__ __volatile__( "mrs r0, cpsr\n" "bic r0, r0, #0xc0\n" "msr cpsr, r0\n" : : :"r0" ); clock_init(); ddr_init(); nand_init(); led_init(); nand_read(ddr_p, 0, 0x40000); __asm__ __volatile__( "mov sp, #0x58000000\n" "mov lr, pc\n" "ldr pc, =main\n" "there:\n" "b there\n" ); }
void nand_read_test() { int i; unsigned long addr; char buf[100]; unsigned long size; printf("Enter the start address: "); scanf("%lu",&addr); printf("\nRead address: 0x%x\n",addr); printf("Enter the read size(<=100): "); scanf("%lu",&size); printf("\nRead size: %d\n",size); if(size > 100) { size = 100; } nand_read(addr,buf,size); printf("The datas: \n"); for(i = 0; i < size; i++) { printf("%02x ",buf[i]); if((i+1)%16 == 0) { printf("\n"); } } printf("\n"); }
unsigned char * ath_eth_mac_addr(unsigned char *sectorBuff) { ulong off, size; nand_info_t *nand; unsigned char ret; /* * caldata partition is of 128k * */ nand = &nand_info[nand_curr_device]; size = ATH_ETH_MAC_READ_SIZE; /* To read 4k setting size as 4k */ /* * Get the Offset of Caldata partition */ off = ath_nand_get_cal_offset(getenv("bootargs")); if(off == ATH_CAL_OFF_INVAL) { printf("Invalid CAL offset \n"); return NULL; } /* * Get the values from flash, and program into the MAC address * registers */ ret = nand_read(nand, (loff_t)off, &size, (u_char *)sectorBuff); printf(" %d bytes %s: %s\n", size, "read", ret ? "ERROR" : "OK"); if(ret != 0 ) { return NULL; } return sectorBuff; }
void music_play() { printf("music_play\r\n"); nand_init(); short *pData = (short *)0x33000000; short *pData_end = pData + 882046/4; int send_cnt = 0; int i = 0; printf("read start\r\n"); nand_read((unsigned char *)pData, 0x60000, 0x200000); printf("the head of wav : 0x%x\r\n", *pData); pData += 0x2e;//real data offset while(1) { while (IISCON & IS_FIFO_READY); IISFIFO = *pData; if (pData == pData_end) { return 0; } pData++; } }
static void nand_io_proc(void *arg, int pending) { struct nand_chip *chip = arg; struct bio *bp; int err = 0; for (;;) { mtx_lock(&chip->qlock); bp = bioq_takefirst(&chip->bioq); mtx_unlock(&chip->qlock); if (bp == NULL) break; if (bp->bio_driver1 == BIO_NAND_STD) { if (bp->bio_cmd == BIO_READ) { err = nand_read(chip, bp->bio_offset & 0xffffffff, bp->bio_data, bp->bio_bcount); } else if (bp->bio_cmd == BIO_WRITE) { err = nand_write(chip, bp->bio_offset & 0xffffffff, bp->bio_data, bp->bio_bcount); } } else if (bp->bio_driver1 == BIO_NAND_RAW) { if (bp->bio_cmd == BIO_READ) { err = nand_read_raw(chip, bp->bio_offset & 0xffffffff, bp->bio_data, bp->bio_bcount); } else if (bp->bio_cmd == BIO_WRITE) { err = nand_write_raw(chip, bp->bio_offset & 0xffffffff, bp->bio_data, bp->bio_bcount); } } else panic("Unknown access type in bio->bio_driver1\n"); if (bp->bio_cmd == BIO_DELETE) { nand_debug(NDBG_GEOM, "Delete on chip%d offset %lld " "length %ld\n", chip->num, bp->bio_offset, bp->bio_bcount); err = nand_erase_blocks(chip, bp->bio_offset & 0xffffffff, bp->bio_bcount); } if (err == 0 || err == ECC_CORRECTABLE) bp->bio_resid = 0; else { nand_debug(NDBG_GEOM,"nand_[read|write|erase_blocks] " "error: %d\n", err); bp->bio_error = EIO; bp->bio_flags |= BIO_ERROR; bp->bio_resid = bp->bio_bcount; } biodone(bp); } }
int nandf_read(void* u32DescBuffAddr, unsigned int u32SrcFlashAddr, unsigned int u32Length, unsigned int *skip_len) { int ret = 0; ret = nand_read(u32SrcFlashAddr, (u32)u32DescBuffAddr, u32Length, skip_len); return ret; }
/* when all is true,read all byte */ void K9F2G08_ReadChipID(u8* buf, UBOOL all) { nand_cs_en(); nand_write_cmd(NAND_CMD_READID); nand_write_addr(NAND_CMD_READ0); buf[0] = nand_read();/* manufacturer ID */ buf[1] = nand_read();/* physical chip ID */ if(all) { buf[2] = nand_read(); buf[3] = nand_read(); /* buf[4] = nand_read(); */ /* Some chips have no 5th byte */ } nand_cs_ds(); }
static int do_imls_nand(void) { struct mtd_info *mtd; int nand_dev = nand_curr_device; size_t len; loff_t off; u32 buffer[16]; if (nand_dev < 0 || nand_dev >= CONFIG_SYS_MAX_NAND_DEVICE) { puts("\nNo NAND devices available\n"); return -ENODEV; } printf("\n"); for (nand_dev = 0; nand_dev < CONFIG_SYS_MAX_NAND_DEVICE; nand_dev++) { mtd = nand_info[nand_dev]; if (!mtd->name || !mtd->size) continue; for (off = 0; off < mtd->size; off += mtd->erasesize) { const image_header_t *header; int ret; if (nand_block_isbad(mtd, off)) continue; len = sizeof(buffer); ret = nand_read(mtd, off, &len, (u8 *)buffer); if (ret < 0 && ret != -EUCLEAN) { printf("NAND read error %d at offset %08llX\n", ret, off); continue; } switch (genimg_get_format(buffer)) { #if defined(CONFIG_IMAGE_FORMAT_LEGACY) case IMAGE_FORMAT_LEGACY: header = (const image_header_t *)buffer; len = image_get_image_size(header); nand_imls_legacyimage(mtd, nand_dev, off, len); break; #endif #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: len = fit_get_size(buffer); nand_imls_fitimage(mtd, nand_dev, off, len); break; #endif } } } return 0; }
static int upgrade_erase_nftl_part() { char str[128]; nand_erase_options_t opts; int error, nand_scrub_flag = 0, i, blk_num; size_t pagesize, blocksize, len; loff_t nftl_erase_addr; struct mtd_info *mtd = nand_info[nand_curr_device]; if (mtd == NULL) { printk("mtd name err: %s\n", mtd->name); return -1; } pagesize = mtd->writesize; blocksize = mtd->erasesize; len = pagesize; u_char temp_buf[pagesize]; nftl_erase_addr = 0; blk_num = mtd->size / mtd->erasesize; printk("nftl_erase_addr %llx blks: %d\n", nftl_erase_addr, blk_num); for (i=0; i<blk_num; i++) { memset(temp_buf, 0xff, 16); error = nand_read(mtd, nftl_erase_addr + i*blocksize, &len, temp_buf); if ((error) && (error != -EUCLEAN)) { printf("read data from nand error: %d\n",error); //continue; } if(!strncmp(temp_buf, "amlnftl", 7) || !strncmp((temp_buf + pagesize / 2), "amlnftl", 7)) { nand_scrub_flag = 1; break; } } printk("nand_scrub_flag: %d\n", nand_scrub_flag); if (nand_scrub_flag) { i = 0; memset(&opts, 0, sizeof(opts)); opts.offset = 0; opts.length = mtd->size; opts.quiet = 1; opts.scrub = 1; nand_erase_opts(mtd, &opts); sprintf(str, "fatload mmc 0:%d ${loadaddr} ${bootloader_path}", (i + 1)); UPGRADE_DPRINT("command: %s\n", str); run_command (str, 0); run_command ("nand rom_protect off", 0); run_command ("nand rom_write ${loadaddr} ${bootloader_start} ${bootloader_size}", 0); run_command ("nand rom_protect on", 0); } return 0; }
int read_nand_stats(void) /* R/B is fixed? */ { u8 stat; nand_write_cmd(NAND_CMD_STATUS); stat = nand_read();/* read byte */ if(stat&1) return 1; /* I/O0=1 successful */ else return 0; /* I/O0=0 unsuccessful */ }
// pageBuffer and spareBuffer are represented by single BUF struct within Whimory static bool nand_read_vfl_cxt_page(int bank, int block, int page, u8* pageBuffer, u8* spareBuffer) { int i; for(i = 0; i < 8; i++) { if(nand_read(bank, (block * NANDGeometry->pagesPerBlock) + page + i, pageBuffer, spareBuffer, true, true) == 0) { SpareData* spareData = (SpareData*) spareBuffer; if(spareData->type2 == 0 && spareData->type1 == 0x80) return true; } } return false; }