📄 nand_util.c
字号:
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x10, 0x02,
0xff, 0xff, 0xff, 0x10, 0x02, 0xaa, 0xaa, 0x97
};
void util_create_bad_128mb_media(void) reentrant
{
trace0(0, util, 0, "Creating bad 128 mb media...") ;
// safe-erase media
util_safe_erase_media() ;
// allocate a write block
g_addr_rd_phy_blk = k_block_free ;
g_addr_zone = 0 ;
g_addr_log_blk = 0;
g_addr_page=0 ;
_media_data(sector_buffer) = g_sector_buffer ;
map_alloc_wr_blk() ;
// write log 0 pg 0
memcpy(g_sector_buffer, k_tbl_sm_log_0_pg_0, 512) ;
memcpy(x_sm_redt_data, k_tbl_sm_log_0_pg_0+512, 16) ;
trace4(0, util, 0, "writing zone %d logical block %d, page %d, to phy block %d", g_addr_zone, g_addr_log_blk, g_addr_page, g_addr_wr_phy_blk) ;
_media_write_sector() ;
util_trace_buffer(g_sector_buffer, 512) ;
util_trace_buffer(x_sm_redt_data, 16) ;
// clear extra data and write log 0 pg 1-end of block
memset(g_sector_buffer, 0xff, 512) ;
_media_clear_extra_data() ;
_media_bind_log2phy() ;
for(g_addr_page=1;g_addr_page<_media_data(pages_per_block);g_addr_page++)
{
trace4(0, util, 0, "writing zone %d logical block %d, page %d, to phy block %d", g_addr_zone, g_addr_log_blk, g_addr_page, g_addr_wr_phy_blk) ;
_media_write_sector() ;
util_trace_buffer(g_sector_buffer, 512) ;
util_trace_buffer(x_sm_redt_data, 16) ;
}
// write log 1 pg 0-14
g_addr_log_blk=1 ;
map_alloc_wr_blk() ;
_media_clear_extra_data() ;
_media_bind_log2phy() ;
for(g_addr_page=0; g_addr_page<15; g_addr_page++)
{
trace4(0, util, 0, "writing zone %d logical block %d, page %d, to phy block %d", g_addr_zone, g_addr_log_blk, g_addr_page, g_addr_wr_phy_blk) ;
_media_write_sector() ;
util_trace_buffer(g_sector_buffer, 512) ;
util_trace_buffer(x_sm_redt_data, 16) ;
}
// write log 1 pg 15
memcpy(g_sector_buffer, k_tbl_sm_log_1_pg_15, 512) ;
memcpy(x_sm_redt_data, k_tbl_sm_log_1_pg_15+512, 16) ;
g_addr_page=15 ;
trace4(0, util, 0, "writing zone %d logical block %d, page %d, to phy block %d", g_addr_zone, g_addr_log_blk, g_addr_page, g_addr_wr_phy_blk) ;
_media_write_sector() ;
util_trace_buffer(g_sector_buffer, 512) ;
util_trace_buffer(x_sm_redt_data, 16) ;
// write log 1 pg 16
memcpy(g_sector_buffer, k_tbl_sm_log_1_pg_16, 512) ;
memcpy(x_sm_redt_data, k_tbl_sm_log_1_pg_16+512, 16) ;
g_addr_page=16 ;
trace4(0, util, 0, "writing zone %d logical block %d, page %d, to phy block %d", g_addr_zone, g_addr_log_blk, g_addr_page, g_addr_wr_phy_blk) ;
_media_write_sector() ;
util_trace_buffer(g_sector_buffer, 512) ;
util_trace_buffer(x_sm_redt_data, 16) ;
memset(g_sector_buffer, 0x00, 512) ;
_media_clear_extra_data() ;
_media_bind_log2phy() ;
for(g_addr_page=17; g_addr_page<_media_data(pages_per_block);g_addr_page++)
{
trace4(0, util, 0, "writing zone %d logical block %d, page %d, to phy block %d", g_addr_zone, g_addr_log_blk, g_addr_page, g_addr_wr_phy_blk) ;
_media_write_sector() ;
util_trace_buffer(g_sector_buffer, 512) ;
util_trace_buffer(x_sm_redt_data, 16) ;
}
// write log 2,3 pgs 0-31
for(g_addr_log_blk=2;g_addr_log_blk<=3;g_addr_log_blk++)
{
map_alloc_wr_blk() ;
_media_bind_log2phy() ;
for(g_addr_page=0 ;g_addr_page < _media_data(pages_per_block);g_addr_page++)
{
trace4(0, util, 0, "writing zone %d logical block %d, page %d, to phy block %d", g_addr_zone, g_addr_log_blk, g_addr_page, g_addr_wr_phy_blk) ;
_media_write_sector() ;
util_trace_buffer(g_sector_buffer, 512) ;
util_trace_buffer(x_sm_redt_data, 16) ;
}
}
// done
trace0(0, util, 0, "create bad media: done") ;
trace0(0, util, 0, "dumping phy blocks 0-5") ;
for(g_addr_rd_phy_blk=0; g_addr_rd_phy_blk<5; g_addr_rd_phy_blk++)
{
util_trace_phy_block() ;
}
trace0(0, util, 0, "done") ;
}
#endif // ghosting an optimized format onto blank media
// --------------------------------------------------------------------
// --------------------------------------------------------------------
#define kbm_map_soft_l2p_binding (0x8000)
#define kbm_map_l2p_bits (0x03FF)
#if 0
void map_debug(uint8 zone) reentrant
{
_l2p_map = _log_map(zone);
_a_map = _assign_map(zone);
#ifdef k_opt_erase_cache
if( _media_data(options)&kbm_media_data_opt_erase_cache)
{
_e_map = _erase_cache(zone);
}
else
#endif
{
// this simplifies the clearing of the data below
_e_map = _a_map;
}
trace1(0, map, 0, "&_l2p_map :%04x", ((uint16)_l2p_map));
trace1(0, map, 0, "&_a_map :%04x", ((uint16)_a_map));
trace1(0, map, 0, "&_e_map :%04x", ((uint16)_e_map));
for(g_addr_wr_phy_blk=0;g_addr_wr_phy_blk<1024;g_addr_wr_phy_blk++)
{
g_addr_rd_phy_blk=k_block_free;
for(g_addr_log_blk=0;g_addr_log_blk<1000;g_addr_log_blk++)
{
if( (_l2p_map[g_addr_log_blk]&kbm_map_l2p_bits) ==g_addr_wr_phy_blk)
{
g_addr_rd_phy_blk=g_addr_log_blk;
break;
}
}
trace4(0, map, 0, "phy_blk:%d - in_use:%c in_cache:%c log_binding:%d", g_addr_wr_phy_blk, (_map_is_phy_blk_used(_a_map,g_addr_wr_phy_blk)?'Y':'N'), (_map_is_phy_blk_used(_e_map,g_addr_wr_phy_blk)?'Y':'N'), g_addr_log_blk);
for(g_addr_log_blk++;g_addr_log_blk<1000;g_addr_log_blk++)
{
if((_l2p_map[g_addr_log_blk]&kbm_map_l2p_bits)==g_addr_wr_phy_blk)
{
trace1(0, map, 0, " - *** also bound to log:%d", g_addr_log_blk);
}
}
}
}
#endif
void util_read_lba(uint32 lba) reentrant
{
map_lba2addr_rd(lba) ;
_media_data(sector_buffer)=g_sector_buffer;
_media_read_sector();
}
xdata _tmp_buf[16];
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void util_write_lba(uint32 lba) reentrant
{
memcpy(_tmp_buf, x_sm_redt_data, 16);
map_write_begin(lba);
_media_data(sector_buffer)=g_sector_buffer;
memcpy(x_sm_redt_data, _tmp_buf, 16);
_media_write_sector();
map_write_flush();
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void util_test_hardware_ecc(uint32 lba, uint16 ix_bit) reentrant
{
trace2(0, util, 0, "util_test_hardware_ecc() - creating 1-bit error in lba %d bit %d", lba, ix_bit) ;
util_read_lba(lba);
// there's a bug in _flipbit that won't go higher than 256 bytes. should be a non-issue for mapper
if(ix_bit<2048)
{
_flpbit((g_sector_buffer), ix_bit);
}
else
{
_flpbit(((g_sector_buffer)+100), ix_bit);
}
util_write_lba(lba);
}
void util_create_2bit_error(uint32 lba) reentrant
{
util_read_lba(lba);
_flpbit(g_sector_buffer,0);
_flpbit(g_sector_buffer,1);
util_write_lba(lba);
}
void util_create_1bit_error(uint32 lba) reentrant
{
util_read_lba(lba);
_flpbit(g_sector_buffer,0);
util_write_lba(lba);
}
#if 0
xdata uint8 buffer1[528];
xdata uint8 buffer2[528];
void util_compare_blocks(uint16 blk1, uint16 blk2) reentrant
{
uint16 offset;
trace0(0, util, 0, "Compare Block Data") ;
trace1(0, util, 0, "block 1: %d",blk1) ;
trace1(0, util, 0, "block 2: %d",blk2) ;
for(g_addr_page=0;g_addr_page<_media_data(pages_per_block);g_addr_page++)
{
trace1(0, util, 0, "--- page %d ---", g_addr_page);
g_addr_rd_phy_blk=blk1;
_media_data(sector_buffer)=buffer1;
_media_read_sector();
memcpy(buffer1+512, x_sm_redt_data, 16);
g_addr_rd_phy_blk=blk2;
_media_data(sector_buffer)=buffer2;
_media_read_sector();
memcpy(buffer2+512, x_sm_redt_data, 16);
if(memcmp(buffer1, buffer2, 512))
{
for(offset=0; offset<512;offset++)
{
if(buffer1[offset]!=buffer2[offset])
{
trace5(0, util, 0, "page data difference at offset %d -- block %d:%02X block %d:%02X", offset, blk1, buffer1[offset], blk2, buffer2[offset]);
}
}
}
else
{
trace0(0, util, 0, "page data identical") ;
}
if(memcmp(buffer1+512, buffer2+512, 16))
{
trace0(0, util, 0, "extra data differs");
for(offset=0;offset<16;offset++)
{
if(buffer1[offset+512]!=buffer2[offset+512])
{
trace5(0, util, 0, "extra data difference at offset %d -- block %d:%02X block %d:%02X", offset, blk1, buffer1[offset+512], blk2, buffer2[offset+512]);
}
}
}
else
{
trace0(0, util, 0, "extra data identical") ;
}
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void util_test_copy_double_bit_ecc(uint32 lba) reentrant
{
uint16 first_rd_blk;
uint16 org_rd_blk;
uint16 err_rd_blk;
trace0(0, util, 0, "------------ 2-bit during copy head (copy before starting user data)") ;
map_lba2addr_rd(lba) ;
trace5(0, util, 0, "------------ creating 2-bit error on block %d:%d[r%d|w%d]:%d", g_addr_zone, g_addr_log_blk, g_addr_rd_phy_blk, g_addr_wr_phy_blk, g_addr_page);
trace0(0, util, 0, "------------ original data/redundant") ;
first_rd_blk=org_rd_blk = g_addr_rd_phy_blk;
util_trace_page();
util_create_2bit_error(lba);
trace0(0, util, 0, "------------ compare org blk to err blk to verify only difference is 2-bit error");
map_lba2addr_rd(lba);
err_rd_blk=g_addr_rd_phy_blk;
util_compare_blocks(org_rd_blk, err_rd_blk);
// read n write a block back to simulate "user" data
trace0(0, util, 0, "------------ writing 'user data'") ;
util_read_lba(lba+1);
util_write_lba(lba+1);
trace0(0, util, 0, "------------ compare err blk w/ new blk(verify blk status 'bad' in err blk, verify data status 'bad' in error page, verify ecc data updated in error page, verify page data identical for ALL pages)");
map_lba2addr_rd(lba);
util_compare_blocks(err_rd_blk, g_addr_rd_phy_blk);
trace0(0, util, 0, "------------ compare org blk w/ new blk (verify only differnce is in page that has error)") ;
map_lba2addr_rd(lba);
util_compare_blocks(org_rd_blk, g_addr_rd_phy_blk);
map_lba2addr_rd(lba+2) ;
trace5(0, util, 0, "------------ creating 2-bit error on block %d:%d[r%d|w%d]:%d", g_addr_zone, g_addr_log_blk, g_addr_rd_phy_blk, g_addr_wr_phy_blk, g_addr_page);
org_rd_blk = g_addr_rd_phy_blk;
util_create_2bit_error(lba+2);
trace0(0, util, 0, "------------ compare org blk to err blk to verify only difference is 2-bit error");
map_lba2addr_rd(lba);
err_rd_blk = g_addr_rd_phy_blk;
util_compare_blocks(org_rd_blk, err_rd_blk);
trace0(0, util, 0, "------------ causing copy-tail 2-bit ecc error") ;
// do a read/write before the 2-bit error to cause problem in copy-tail
util_read_lba(lba+1);
util_write_lba(lba+1);
trace0(0, util, 0, "------------ compare err blk w/ new blk(verify blk status 'bad' in err blk, verify data status 'bad' in error page, verify ecc data updated in error page, verify page data identical for ALL pages)");
map_lba2addr_rd(lba+2);
util_compare_blocks(err_rd_blk, g_addr_rd_phy_blk);
trace0(0, util, 0, "------------ compare org blk w/ new blk (verify only differnce is in page that has error)") ;
map_lba2addr_rd(lba+2);
util_compare_blocks(org_rd_blk, g_addr_rd_phy_blk);
trace0(0, util, 0, "------------ dump of Final Logical Block") ;
util_trace_phy_block();
trace0(0, util, 0, "------------ dump of First Logical Block") ;
g_addr_rd_phy_blk=first_rd_blk;
util_trace_phy_block();
if( _media_data(options)&kbm_media_data_opt_erase_cache)
{
trace0(0, nand, 0, "flushing erase cache()") ;
map_erase_cache_flush_all();
}
mcu_halt();
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -