00001
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #define _TRACE_ (DISABLE)
00053 #include "config.h"
00054 #include "conf_nf.h"
00055 #include "nf.h"
00056 #include "nf_drv.h"
00057 #include "nf_mngt.h"
00058 #include "lib_mcu/debug.h"
00059
00060
00061 #ifndef __GNUC__
00062 extern __no_init volatile xdata Byte nf_send_cmd At(NF_CMD_LATCH_ENABLE_ADD);
00063 extern __no_init volatile xdata Byte nf_send_add At(NF_ADD_LATCH_ENABLE_ADD);
00064 extern __no_init volatile xdata Byte nf_data At(NF_ADDRESS_CMD_DATA);
00065 #else
00066 extern volatile unsigned char nf_send_cmd __attribute__ ((section (".nf_cmd")));
00067 extern volatile unsigned char nf_send_add __attribute__ ((section (".nf_add")));
00068 extern volatile unsigned char nf_data __attribute__ ((section (".nf_dat")));
00069 #endif
00070
00071
00072
00073
00074 #if (NF_GENERIC_DRIVER==TRUE) || (defined NF_AUTO_DETECT_2KB) ||(defined NF_AUTO_DETECT_512B)
00075 extern _MEM_TYPE_SLOW_ U8 g_n_zones ;
00076 extern _MEM_TYPE_SLOW_ U16 g_n_blocks ;
00077 #endif
00078 extern _MEM_TYPE_SLOW_ U8 g_page_buffer[NF_FULL_PAGE_BUFFER_SIZE] ;
00079 extern _MEM_TYPE_BIT_ bit g_nf_init ;
00080 extern _MEM_TYPE_SLOW_ U16 g_last_sub_lut_log_sz ;
00081 extern _MEM_TYPE_SLOW_ U16 g_sub_lut_log_sz ;
00082 Bool g_is_found_lut ;
00083 Bool g_is_found_fbb ;
00084 extern Bool g_fatal ;
00085 _MEM_TYPE_SLOW_ U8 g_n_real_sub_lut;
00086 _MEM_TYPE_SLOW_ U16 g_curr_block_addr[ NF_N_DEVICES];
00087 _MEM_TYPE_SLOW_ U8 g_byte[16] ;
00088 extern _MEM_TYPE_SLOW_ U8 g_n_sub_lut ;
00089 extern _MEM_TYPE_SLOW_ U16 g_lut_block_addr [ N_SUBLUT ] ;
00090 extern _MEM_TYPE_SLOW_ U8 g_lut_block_index[ N_SUBLUT ] ;
00091 static _MEM_TYPE_SLOW_ U8 s_nfd_rev ;
00092 extern _MEM_TYPE_SLOW_ U16 g_nf_first_block ;
00093 static _MEM_TYPE_SLOW_ U8 s_n_quarantine_blocks[NF_N_DEVICES] ;
00094 static _MEM_TYPE_SLOW_ U16 s_n_invalid_blocks[ NF_N_DEVICES] ;
00095 extern _MEM_TYPE_SLOW_ U16 g_n_export_blocks ;
00096 extern _MEM_TYPE_SLOW_ U16 g_n_free_blocks ;
00097 extern _MEM_TYPE_SLOW_ U16 g_fbb_block_addr ;
00098 extern _MEM_TYPE_SLOW_ U8 g_fbb_block_index ;
00099 extern _MEM_TYPE_SLOW_ U32 g_last_log_sector ;
00100 extern _MEM_TYPE_SLOW_ U32 g_copy_src ;
00101 extern _MEM_TYPE_SLOW_ U16 g_block_to_kill[ NF_N_DEVICES] ;
00102 extern _MEM_TYPE_FAST_ U32 g_phys_page_addr[NF_N_DEVICES] ;
00103 extern _MEM_TYPE_FAST_ U8 g_curr_dev_id ;
00104
00105 extern _MEM_TYPE_MEDFAST_ U16 g_log_block_id ;
00106
00107 extern _MEM_TYPE_SLOW_ Cache_lut g_cache_lut;
00108 extern _MEM_TYPE_SLOW_ Cache_fbb g_cache_fbb;
00109
00110
00111 #if (ERASING_ALL==ENABLE)
00112 static void ut_nfc_erase_all( void );
00113 #endif
00114
00115
00116 static void nf_init_buffer( void );
00117 static Status_bool nf_scan( void );
00118 static Status_bool nf_rebuild( void );
00119 static Bool is_nf_invalid( void );
00120
00121 static U16 nf_fetch_free_block( U8 i_dev );
00122
00123 static U8 nf_refine_index( U16 block_addr, U8 inc, U8 pattern) ;
00124
00125
00130 static void nf_init_buffer( void )
00131 {
00132 U16 u16_tmp;
00133 for ( u16_tmp=NF_FULL_PAGE_BUFFER_SIZE ; u16_tmp!=0 ; u16_tmp-=2 )
00134 {
00135 g_page_buffer[u16_tmp-1]=0xFF;
00136 g_page_buffer[u16_tmp-2]=0xFF;
00137 }
00138 }
00139
00140
00141
00151 void nf_init ( void )
00152 {
00153 g_nf_init=FALSE;
00154
00155
00156 #if (NF_GENERIC_DRIVER==TRUE)
00157 #error Check this init...
00158 g_n_zones = NF_N_ZONES;
00159 g_n_blocks = NF_N_BLOCKS;
00160 g_shift_block_page = NF_SHIFT_BLOCK_PAGE;
00161 g_shift_page_byte = NF_SHIFT_PAGE_BYTE;
00162 s_shift_sector_byte = NF_SHIFT_SECTOR_BYTE;
00163 g_n_row_cycles = NF_N_ROW_CYCLES;
00164
00165 if ( Is_nf_2k() )
00166 {
00167 g_ofst_blk_status = 0;
00168 }
00169 if ( Is_nf_512() )
00170 {
00171 g_ofst_blk_status = 5;
00172 }
00173
00174 s_shift_log_page_sector = G_SHIFT_PAGE_BYTE - S_SHIFT_SECTOR_BYTE + NF_SHIFT_N_DEVICES;
00175 s_shift_log_block_sector = s_shift_log_page_sector + G_SHIFT_BLOCK_PAGE;
00176 #endif
00177
00178 g_cache_lut.ctrl.valid = FALSE; g_cache_lut.ctrl.dirty = FALSE;
00179 g_cache_fbb.ctrl.valid = FALSE; g_cache_fbb.ctrl.dirty = FALSE;
00180 g_last_log_sector= 0xFFFFFFFF;
00181 }
00182
00183
00196 Status_bool nf_verify_resume( void )
00197 {
00198 U8 u8_nb_loop;
00199 Bool status_bool;
00200
00201
00202 #if (ERASING_ALL==ENABLE)
00203 ut_nfc_erase_all();
00204 #endif
00205
00206 status_bool = nf_scan();
00207
00208 if(( PASS!=status_bool )
00209 || ( is_nf_invalid() )
00210 ) {
00211
00212
00213 u8_nb_loop = 0;
00214 while( 1 )
00215 {
00216 u8_nb_loop++;
00217 if( u8_nb_loop > 2 )
00218 {
00219 status_bool=FAIL;
00220 break;
00221 }
00222 nf_cleanup_memory();
00223 if( PASS != nf_scan() )
00224 continue;
00225 if( PASS != nf_rebuild() )
00226 continue;
00227 status_bool = PASS;
00228 break;
00229 }
00230 }
00231 if (status_bool==PASS)
00232 {
00233 g_nf_init = TRUE;
00234 Nf_check_lut();
00235 Nf_check_fbb( FALSE );
00236 }
00237
00238 return status_bool;
00239 }
00240
00241
00242
00250 void nf_cleanup_memory(void)
00251 {
00252 U8 i_dev =0;
00253 U16 i_block=0;
00254 U8 block_valid;
00255 U8 block_id;
00256
00257
00258
00259
00260
00261
00262 for( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
00263 {
00264
00265
00266 Nfc_action(NFC_ACT_DEV_SELECT, i_dev);
00267
00268 for( i_block=g_nf_first_block ; i_block<G_N_BLOCKS ; i_block++ )
00269 {
00270
00271 nfc_open_page_read( nf_block_2_page(i_block), NF_SPARE_POS);
00272 block_valid = Nfc_rd_data_fetch_next();
00273 block_id = Nfc_rd_data() ;
00274
00275 if ( block_valid!=0xFF )
00276 {
00277 continue;
00278 }
00279
00280 if(( NFC_BLK_ID_SUBLUT==block_id )
00281 || ( NFC_BLK_ID_FBB ==block_id ))
00282 {
00283 nfc_erase_block( nf_block_2_page(i_block), TRUE ) ;
00284 if ( FAIL==nfc_check_status() )
00285 {
00286 nfc_mark_bad_block( nf_block_2_page(i_block) );
00287 }
00288 }
00289 }
00290 }
00291 }
00292
00293
00294
00303 static Status_bool nf_scan( void )
00304 {
00305 U8 i_dev =0;
00306 U16 i_block=0;
00307 U8 n_quarantine_blocks=0;
00308 U16 n_invalid_blocks=0;
00309
00310 g_last_sub_lut_log_sz =(U16)-1;
00311 g_sub_lut_log_sz =(U16)NF_SUBLUT_SIZE/NF_N_DEVICES;
00312
00313
00314
00315
00316 g_is_found_lut =FALSE;
00317 g_is_found_fbb =FALSE;
00318 g_fatal =FALSE;
00319 g_n_real_sub_lut=0;
00320
00321
00322
00323
00324
00325
00326 for( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
00327 {
00328 n_invalid_blocks = 0;
00329 n_quarantine_blocks= 0;
00330 g_curr_block_addr[i_dev]= G_N_BLOCKS -1;
00331
00332 trace("Device "); trace_hex(i_dev); trace("\n\r");
00333 Nfc_action(NFC_ACT_DEV_SELECT, i_dev);
00334
00335 for( i_block=g_nf_first_block ; i_block<G_N_BLOCKS ; i_block++ )
00336 {
00337 nfc_read_spare_byte( g_byte, 16, nf_block_2_page(i_block) );
00338 if ( g_byte[G_OFST_BLK_STATUS]!=0xFF )
00339 {
00340 n_invalid_blocks +=1 ;
00341 trace_hex16(i_block); trace(" ("); trace_u32(i_block); trace("): bad Block\n\r");
00342 continue;
00343 }
00344
00345 if(( g_byte[NFC_SPARE_OFST_1_BLK_ID]!=NFC_BLK_ID_SUBLUT )
00346 && ( g_byte[NFC_SPARE_OFST_1_BLK_ID]!=NFC_BLK_ID_FBB )
00347 && ( g_byte[NFC_SPARE_OFST_1_BLK_ID]!=NFC_BLK_ID_QUARANTINE )
00348 && ( g_byte[NFC_SPARE_OFST_1_BLK_ID]!=NFC_BLK_ID_DATA ))
00349 {
00350 n_invalid_blocks +=1;
00351 trace_hex16(i_block); trace(" ("); trace_u32(i_block); trace("): Unknown\n\r");
00352 continue;
00353 }
00354 else if ( g_byte[NFC_SPARE_OFST_1_BLK_ID]==NFC_BLK_ID_QUARANTINE )
00355 {
00356 n_quarantine_blocks +=1;
00357 trace_hex16(i_block); trace(" ("); trace_u32(i_block); trace("): Quarantine\n\r");
00358 continue;
00359 }
00360 else if ( g_byte[NFC_SPARE_OFST_1_BLK_ID]==NFC_BLK_ID_SUBLUT )
00361 {
00362 n_invalid_blocks +=1;
00363 if ( i_dev==S_MNGT_DEV )
00364 {
00365 U8 sub_lut_id = g_byte[NFC_SPARE_OFST_2_BYTE_2];
00366 g_n_sub_lut = g_byte[NFC_SPARE_OFST_4_BYTE_4];
00367 g_is_found_lut = TRUE;
00368 g_n_real_sub_lut++;
00369 g_lut_block_addr[sub_lut_id] = i_block;
00370 if ( sub_lut_id==(g_n_sub_lut-1) )
00371 {
00372 MSB(g_last_sub_lut_log_sz)= g_byte[NFC_SPARE_OFST_6_LBA ];
00373 LSB(g_last_sub_lut_log_sz)= g_byte[NFC_SPARE_OFST_6_LBA+1];
00374 }
00375 g_lut_block_index[sub_lut_id]= nf_refine_index(i_block, 1, NFC_BLK_ID_SUBLUT);
00376 trace_hex16(i_block); trace(" ("); trace_u32(i_block); trace("): SUB-LUT (id ");trace_hex(sub_lut_id);trace(" ofst "); trace_hex(g_lut_block_index[sub_lut_id]); trace(")\n\r");
00377 continue ;
00378 }
00379 else
00380 {
00381 g_fatal=TRUE;
00382 break;
00383 }
00384 }
00385
00386 else if ( g_byte[NFC_SPARE_OFST_1_BLK_ID]==NFC_BLK_ID_FBB )
00387 {
00388 n_invalid_blocks +=1;
00389 if ( i_dev==S_MNGT_DEV )
00390 {
00391 if ( TRUE==g_is_found_fbb )
00392 {
00393 g_fatal=TRUE;
00394 break;
00395 }
00396 g_fbb_block_addr = i_block;
00397 g_fbb_block_index = nf_refine_index(i_block, 1, NFC_BLK_ID_FBB);
00398 nfc_read_spare_byte( g_byte, 16, nf_block_2_page(i_block) + (U32)g_fbb_block_index );
00399 if( NFC_OFST_6_FBB_VALID!=g_byte[NFC_SPARE_OFST_6_LBA] )
00400 {
00401 g_fatal=TRUE;
00402 break;
00403 }
00404
00405 MSB(g_n_free_blocks) = g_byte[NFC_SPARE_OFST_2_BYTE_2];
00406 LSB(g_n_free_blocks) = g_byte[NFC_SPARE_OFST_3_BYTE_3];
00407 s_nfd_rev = g_byte[NFC_SPARE_OFST_4_BYTE_4];
00408 MSB(g_n_export_blocks) = g_byte[NFC_SPARE_OFST_EXPORT];
00409 LSB(g_n_export_blocks) = g_byte[NFC_SPARE_OFST_EXPORT+1];
00410 trace(" g_n_free_blocks="); trace_hex16(g_n_free_blocks); trace_nl();
00411 trace(" g_n_export_blocks="); trace_hex16(g_n_export_blocks); trace_nl();
00412 g_is_found_fbb=TRUE;
00413 trace_hex16(i_block); trace(" ("); trace_u32(i_block); trace("): FBB (ofst "); trace_hex( g_fbb_block_index ); trace(")\n\r");
00414 continue ;
00415 }
00416 else
00417 {
00418 g_fatal=TRUE;
00419 break;
00420 }
00421 }
00422 }
00423
00424
00425
00426 s_n_invalid_blocks[ i_dev]= n_invalid_blocks;
00427 s_n_quarantine_blocks[i_dev]= n_quarantine_blocks;
00428
00429 if ( TRUE==g_fatal ) { break; }
00430 }
00431
00432 return (g_fatal==TRUE) ? FAIL: PASS;
00433 }
00434
00435
00444 static Bool is_nf_invalid ( void )
00445 {
00446 if(
00447 ( FALSE==g_is_found_lut )
00448 || ( FALSE==g_is_found_fbb )
00449 ) {
00450 g_fatal=TRUE;
00451 }
00452
00453
00454
00455 if(( TRUE ==g_is_found_lut )
00456 && ( g_n_sub_lut!=g_n_real_sub_lut ))
00457 {
00458 g_fatal=TRUE;
00459 }
00460
00461
00462 if ( (U16)-1==g_n_export_blocks ) { g_fatal=TRUE; }
00463 if ( 0==g_n_export_blocks ) { g_fatal=TRUE; }
00464 if ( (U16)-1==g_last_sub_lut_log_sz ) { g_fatal=TRUE; }
00465
00466
00467
00468 if ( s_nfd_rev!=NFC_OFST_4_FBB_DRIVER_RELEASE )
00469 {
00470 g_fatal=TRUE;
00471 }
00472
00473 return g_fatal;
00474 }
00475
00476
00477
00490 static Status_bool nf_rebuild ( void )
00491 {
00492 Status_bool status_bool=PASS;
00493 Bool b_duplicate;
00494 U8 i_sub_lut;
00495 U8 i_dev =0;
00496 _MEM_TYPE_SLOW_ U16 i_block=0;
00497 _MEM_TYPE_SLOW_ U16 u16_tmp;
00498 _MEM_TYPE_SLOW_ U16 sub_lut_log_sz;
00499 _MEM_TYPE_SLOW_ U16 log_block_addr;
00500 _MEM_TYPE_SLOW_ U16 log_block_addr_min;
00501 _MEM_TYPE_SLOW_ U16 log_block_addr_max;
00502
00503
00504
00505 s_n_invalid_blocks[S_MNGT_DEV] +=
00506 1
00507 + (G_N_BLOCKS*NF_N_DEVICES)/NF_SUBLUT_SIZE
00508 ;
00509
00510
00511
00512 u16_tmp=s_n_invalid_blocks[0] ;
00513 for ( i_dev=1 ; i_dev<NF_N_DEVICES ; i_dev++ )
00514 {
00515 u16_tmp=Max( u16_tmp, s_n_invalid_blocks[i_dev] );
00516 }
00517
00518
00519
00520 i_sub_lut=s_n_quarantine_blocks[0] ;
00521 for ( i_dev=1 ; i_dev<NF_N_DEVICES ; i_dev++ )
00522 {
00523 i_sub_lut=Max( i_sub_lut, s_n_quarantine_blocks[i_dev] );
00524 }
00525
00526 sub_lut_log_sz = (U16)NF_N_DEVICES*(G_N_BLOCKS -g_nf_first_block -u16_tmp);
00527
00528
00529
00530 Assert( u16_tmp<(G_N_BLOCKS -g_nf_first_block) );
00531 g_n_export_blocks= (U16)( ((U32)( (U32)sub_lut_log_sz ) * 1000) / 1024);
00532 g_n_export_blocks= Align_down( g_n_export_blocks, NF_N_DEVICES);
00533
00534 g_n_free_blocks = (U16)sub_lut_log_sz - g_n_export_blocks;
00535 g_n_free_blocks -= (U16)NF_N_DEVICES*i_sub_lut;
00536
00537 if( g_n_free_blocks<=NF_LOW_N_FREE_THRESHOLD )
00538 {
00539 while(1);
00540 }
00541
00542 Assert( g_n_free_blocks>0 );
00543 Assert( g_n_free_blocks<(1L<<NF_SHIFT_PAGE_BYTE) );
00544
00545
00546
00547
00548 Nfc_action(NFC_ACT_DEV_SELECT, S_MNGT_DEV);
00549 g_fbb_block_addr = nf_fetch_free_block(S_MNGT_DEV);
00550 nfc_erase_block( nf_block_2_page( g_fbb_block_addr ), TRUE );
00551 g_n_sub_lut= 0;
00552 u16_tmp = g_n_export_blocks;
00553
00554 while(1)
00555 {
00556 Assert( g_n_sub_lut<N_SUBLUT );
00557 g_lut_block_addr [g_n_sub_lut]=nf_fetch_free_block(S_MNGT_DEV);
00558 g_lut_block_index[g_n_sub_lut]=0;
00559 nfc_erase_block( nf_block_2_page( g_lut_block_addr [g_n_sub_lut] ), TRUE );
00560 g_n_sub_lut++;
00561 if( u16_tmp>NF_SUBLUT_SIZE ) u16_tmp-=NF_SUBLUT_SIZE;
00562 else break;
00563 }
00564 g_last_sub_lut_log_sz=u16_tmp/NF_N_DEVICES;
00565
00566
00567
00568 for ( i_sub_lut=0 ; i_sub_lut<g_n_sub_lut ; )
00569 {
00570 U8 n_sublut_in_buf = g_n_sub_lut - i_sub_lut;
00571
00572 log_block_addr_max =
00573 log_block_addr_min = (U16)i_sub_lut<<(NF_SHIFT_SUBLUT_PHYS-NF_SHIFT_N_DEVICES);
00574
00575 if( n_sublut_in_buf>(NF_PAGE_BUFFER_SIZE/(2*NF_SUBLUT_SIZE)) )
00576 {
00577 n_sublut_in_buf = NF_PAGE_BUFFER_SIZE/(2*NF_SUBLUT_SIZE);
00578 log_block_addr_max += ((U16)n_sublut_in_buf)*g_sub_lut_log_sz;
00579 }
00580 else
00581 {
00582 log_block_addr_max += ((U16)n_sublut_in_buf-1)*g_sub_lut_log_sz +g_last_sub_lut_log_sz;
00583 }
00584
00585 nf_init_buffer();
00586
00587
00588
00589 u16_tmp=g_n_export_blocks/NF_N_DEVICES;
00590
00591 b_duplicate=FALSE;
00592
00593 for ( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
00594 {
00595 Nfc_action(NFC_ACT_DEV_SELECT, i_dev);
00596
00597 g_block_to_kill[i_dev]=0xFFFF;
00598
00599 for ( i_block=g_nf_first_block ; i_block<G_N_BLOCKS ; i_block++ )
00600 {
00601 nfc_read_spare_byte( g_byte, 8, nf_block_2_page(i_block) );
00602 if(( 0xFF !=g_byte[G_OFST_BLK_STATUS ] )
00603 || ( NFC_BLK_ID_DATA!=g_byte[NFC_SPARE_OFST_1_BLK_ID ] )
00604 || ( ( 0xFF ==g_byte[NFC_SPARE_OFST_6_LBA ] )
00605 && ( 0xFF ==g_byte[NFC_SPARE_OFST_6_LBA+1 ] )
00606 )
00607 ) {
00608 continue;
00609 }
00610
00611 MSB(log_block_addr) = g_byte[NFC_SPARE_OFST_6_LBA ];
00612 LSB(log_block_addr) = g_byte[NFC_SPARE_OFST_6_LBA+1];
00613
00614 if( log_block_addr>=u16_tmp )
00615 {
00616
00617
00618 nfc_erase_block( nf_block_2_page(i_block), TRUE );
00619 status_bool=FAIL;
00620 }
00621
00622 if(( log_block_addr>=log_block_addr_min )
00623 && ( log_block_addr< log_block_addr_max ))
00624 {
00625 U16 ofst=2*((U16)i_dev + (log_block_addr%((U16)NF_PAGE_BUFFER_SIZE/2/NF_N_DEVICES))*NF_N_DEVICES) ;
00626 if(
00627 ( 0xFF==g_page_buffer[ ofst ] )
00628 && ( 0xFF==g_page_buffer[ ofst +1 ] )
00629 )
00630 {
00631 Assert( ( ofst +1 ) < NF_PAGE_BUFFER_SIZE );
00632 g_page_buffer[ ofst ] = MSB(i_block);
00633 g_page_buffer[ ofst +1 ] = LSB(i_block);
00634 }
00635 else
00636 {
00637
00638 _MEM_TYPE_SLOW_ U16 tmp_addr;
00639 MSB(tmp_addr)=g_page_buffer[ ofst ];
00640 LSB(tmp_addr)=g_page_buffer[ ofst +1 ];
00641
00642
00643 if(0xFFFF!=g_block_to_kill[i_dev])
00644 {
00645 nfc_erase_block( nf_block_2_page(g_block_to_kill[i_dev]), TRUE );
00646 return FAIL;
00647 }
00648
00649 b_duplicate=TRUE;
00650 g_log_block_id=log_block_addr;
00651
00652 nfc_open_page_read(
00653 nf_block_2_page(i_block)
00654 , NF_SPARE_POS+NFC_SPARE_OFST_3_BYTE_3
00655 );
00656 if( NFC_OFST_3_DATA_DST!=Nfc_rd_data_fetch_next() )
00657 {
00658 trace("1. Src block="); trace_hex16(i_block); trace_nl();
00659 trace("1. Dst block="); trace_hex16(tmp_addr); trace_nl();
00660
00661
00662
00663 g_block_to_kill[i_dev]=i_block;
00664 g_phys_page_addr[i_dev] = nf_block_2_page( tmp_addr );
00665 }
00666 else
00667 {
00668 trace("2. Src block="); trace_hex16(tmp_addr); trace_nl();
00669 trace("2. Dst block="); trace_hex16(i_block); trace_nl();
00670
00671
00672
00673 g_block_to_kill[i_dev]= tmp_addr ;
00674 g_page_buffer[ ofst ]=MSB(i_block);
00675 g_page_buffer[ ofst +1 ]=LSB(i_block);
00676 g_phys_page_addr[i_dev] = nf_block_2_page( i_block );
00677 }
00678 }
00679 }
00680 }
00681 }
00682
00683 if( b_duplicate )
00684 {
00685 U8 i_page;
00686 U8 i_sect;
00687
00688 trace("recovery\n\r");
00689
00690 for ( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
00691 {
00692 if( 0xFFFF==g_block_to_kill[i_dev] )
00693 {
00694
00695 for ( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
00696 {
00697 if( 0xFFFF!=g_block_to_kill[i_dev] )
00698 {
00699 nfc_erase_block( nf_block_2_page(g_block_to_kill[i_dev]), TRUE );
00700 }
00701 }
00702 return FAIL;
00703 }
00704 }
00705
00706
00707 g_curr_dev_id=0;
00708 g_last_log_sector= ((U32)g_log_block_id) << S_SHIFT_LOG_BLOCK_SECTOR;
00709
00710
00711 for( i_page=0 ; i_page<SIZE_BLOCK_PAGE ; i_page++ )
00712 {
00713 Nfc_action(NFC_ACT_DEV_SELECT, g_curr_dev_id);
00714 for( i_sect=0 ; i_sect<SIZE_PAGE_SECTOR ; i_sect++ )
00715 {
00716 nfc_open_page_read(
00717 g_phys_page_addr[g_curr_dev_id]
00718 , NF_SPARE_POS + (((U16)i_sect)*16) + NFC_SPARE_OFST_6_LBA
00719 );
00720 if(( 0xFF==Nfc_rd_data_fetch_next() )
00721 && ( 0xFF==Nfc_rd_data_fetch_next() ))
00722 goto recovery_exit;
00723 else
00724 {
00725 g_last_log_sector++;
00726 trace("g_last_log_sector="); trace_hex32(g_last_log_sector); trace_nl();
00727 }
00728 }
00729 g_phys_page_addr[g_curr_dev_id]++;
00730 g_curr_dev_id++;
00731 if( g_curr_dev_id==NF_N_DEVICES ) { g_curr_dev_id=0; }
00732 trace("g_curr_dev_id="); trace_hex(g_curr_dev_id); trace_nl();
00733 trace("g_phys_page_addr="); trace_hex32(g_phys_page_addr[g_curr_dev_id]); trace_nl();
00734 }
00735 recovery_exit:
00736 trace("recovery stop on g_last_log_sector="); trace_hex32(g_last_log_sector); trace_nl();
00737 trace("g_curr_dev_id="); trace_hex(g_curr_dev_id); trace_nl();
00738 trace("g_phys_page_addr="); trace_hex32(g_phys_page_addr[g_curr_dev_id]); trace_nl();
00739
00740 nf_copy_tail();
00741 return FAIL;
00742 }
00743
00744
00745
00746 if( PASS!=status_bool ) { return FAIL; }
00747
00748
00749
00750 for( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
00751 {
00752 Nfc_action(NFC_ACT_DEV_SELECT, i_dev);
00753
00754 for(u16_tmp=0
00755 ; u16_tmp<(log_block_addr_max-log_block_addr_min)
00756 ; u16_tmp++ )
00757 {
00758 U16 ofst=2*((U16)i_dev + u16_tmp*NF_N_DEVICES);
00759 if(( 0xFF==g_page_buffer[ofst ] )
00760 && ( 0xFF==g_page_buffer[ofst+1] ))
00761 {
00762 i_block=nf_fetch_free_block(i_dev);
00763 Assert( ofst+1<NF_PAGE_BUFFER_SIZE);
00764 g_page_buffer[ofst ] = MSB(i_block);
00765 g_page_buffer[ofst+1] = LSB(i_block);
00766 }
00767 }
00768 }
00769
00770
00771
00772
00773 for( ; n_sublut_in_buf!=0 ; n_sublut_in_buf--, i_sub_lut++ )
00774 {
00775 sub_lut_log_sz= ( i_sub_lut==(g_n_sub_lut-1) ) ? g_last_sub_lut_log_sz : g_sub_lut_log_sz ;
00776
00777
00778
00779 status_bool = nf_write_lut(i_sub_lut%(NF_PAGE_BUFFER_SIZE/(2*NF_SUBLUT_SIZE)), i_sub_lut, sub_lut_log_sz);
00780 if ( PASS!=status_bool )
00781 {
00782 nfc_mark_bad_block( nf_block_2_page( g_lut_block_addr[i_sub_lut] ) );
00783 return FAIL;
00784 }
00785 }
00786 }
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796 for ( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
00797 {
00798 Nfc_action(NFC_ACT_DEV_SELECT, i_dev);
00799
00800 for ( u16_tmp=0 ; u16_tmp<(g_n_free_blocks/NF_N_DEVICES) ; u16_tmp++ )
00801 {
00802
00803 #define OFST (2*(i_dev + u16_tmp*NF_N_DEVICES))
00804 i_block=nf_fetch_free_block(i_dev);
00805 nfc_erase_block( nf_block_2_page(i_block), TRUE );
00806 Assert( OFST <NF_PAGE_BUFFER_SIZE);
00807 Assert( OFST +1<NF_PAGE_BUFFER_SIZE);
00808 Assert( i_block>=g_nf_first_block );
00809 Assert( i_block< G_N_BLOCKS );
00810 g_page_buffer[OFST ] = MSB(i_block);
00811 g_page_buffer[OFST +1] = LSB(i_block);
00812 #undef OFST
00813 }
00814 }
00815
00816
00817
00818
00819
00820 g_fbb_block_index=0;
00821 status_bool = nf_write_fbb();
00822 if ( PASS!=status_bool )
00823 {
00824 nfc_mark_bad_block( nf_block_2_page( g_fbb_block_addr ) );
00825 return FAIL;
00826 }
00827
00828
00829
00830
00831
00832
00833
00834 return PASS;
00835 }
00836
00837
00838
00847 static U16 nf_fetch_free_block(U8 i_dev)
00848 {
00849
00850 U16 block_addr= g_curr_block_addr[i_dev];
00851
00852 while ( block_addr>=g_nf_first_block )
00853 {
00854 nfc_read_spare_byte( g_byte, 8, nf_block_2_page( block_addr ) );
00855 if(( 0xFF ==g_byte[G_OFST_BLK_STATUS ] )
00856 && ( NFC_BLK_ID_DATA==g_byte[NFC_SPARE_OFST_1_BLK_ID ] )
00857 && ( 0xFF ==g_byte[NFC_SPARE_OFST_6_LBA ] )
00858 && ( 0xFF ==g_byte[NFC_SPARE_OFST_6_LBA+1 ] ))
00859 {
00860
00861
00862 Assert( NFC_BLK_ID_SUBLUT!=g_byte[NFC_SPARE_OFST_1_BLK_ID] );
00863 Assert( NFC_BLK_ID_FBB !=g_byte[NFC_SPARE_OFST_1_BLK_ID] );
00864
00865
00866
00867 g_curr_block_addr[i_dev] = block_addr-1;
00868 return block_addr;
00869 }
00870 block_addr-=1 ;
00871 }
00872
00873
00874 nfc_erase_block( nf_block_2_page( g_fbb_block_addr ), TRUE );
00875 while(1);
00876 Assert( FALSE ) ;
00877 }
00878
00879
00880
00894 static U8 nf_refine_index(
00895 U16 block_addr
00896 , U8 inc
00897 , U8 pattern)
00898 {
00899 _MEM_TYPE_SLOW_ U8 u8_tmp;
00900 _MEM_TYPE_SLOW_ U8 val=0;
00901 do
00902 {
00903 val+= inc;
00904 if( val>=SIZE_BLOCK_PAGE )
00905 { break; }
00906 nfc_open_page_read(
00907 nf_block_2_page(block_addr) + val
00908 , NF_SPARE_POS+NFC_SPARE_OFST_1_BLK_ID
00909 );
00910 u8_tmp = Nfc_rd_data();
00911 } while( pattern==u8_tmp );
00912 val-= inc;
00913 Assert( val<(1<<G_SHIFT_BLOCK_PAGE) );
00914 return val;
00915 }
00916
00917
00918
00919 #if (ERASING_ALL==ENABLE)
00920 static void ut_nfc_erase_all( void )
00921 {
00922 _MEM_TYPE_SLOW_ U8 i_dev =0;
00923 _MEM_TYPE_SLOW_ U16 i_block=0;
00924 _MEM_TYPE_SLOW_ U32 page_addr;
00925
00926 for( i_dev=0 ; i_dev<NF_N_DEVICES ; i_dev++ )
00927 {
00928
00929
00930 Nfc_action(NFC_ACT_DEV_SELECT, i_dev);
00931
00932 for( i_block=g_nf_first_block ; i_block<G_N_BLOCKS ; i_block++ )
00933 {
00934 page_addr= (U32)i_block<<NF_SHIFT_BLOCK_PAGE;
00935 nfc_erase_block( page_addr, FALSE ) ;
00936 }
00937 }
00938 }
00939 #endif
00940