@@ -343,23 +343,22 @@ int SPINANDBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size)
343343 goto exit_point;
344344 }
345345
346- // calculate the software ECC
347- for (uint8_t i = 0 ; ecc_steps; ecc_steps--, i += _ecc_bytes, p += _ecc_size) {
348- _bch_calculate_ecc (p, _ecc_calc + i);
349- }
350-
351346 memcpy (_ecc_code, _page_buf + _page_size + _ecc_layout_pos, _ecc_bytes * _ecc_steps);
352347
353348 p = (uint8_t *)_page_buf;
354349 ecc_steps = _ecc_steps;
355350 for (uint8_t i = 0 ; ecc_steps; ecc_steps--, i += _ecc_bytes, p += _ecc_size) {
356- int res = _bch_correct_data (p, _ecc_code + i, _ecc_calc + i);
351+ memset (_nbc.bch ->input_data , 0x0 , (1 << _nbc.bch ->m ) / 8 );
352+ memcpy (_nbc.bch ->input_data + _ecc_bytes, p, _ecc_size);
353+
354+ int res = bch_decode (_nbc.bch , _nbc.bch ->input_data , (unsigned int *)(_ecc_code + i));
357355 if (res < 0 ) {
358356 tr_error (" Reading data failed" );
359357 status = SPINAND_BD_ERROR_DEVICE_ERROR;
360358 read_failed = true ;
361359 goto exit_point;
362360 }
361+ memcpy (p, _nbc.bch ->input_data + _ecc_bytes, _ecc_size);
363362 }
364363 memcpy (buffer, _page_buf + offset, read_bytes);
365364 }
@@ -431,7 +430,9 @@ int SPINANDBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t si
431430
432431 // calculate the software ECC
433432 for (uint8_t i = 0 ; ecc_steps; ecc_steps--, i += _ecc_bytes, p += _ecc_size) {
434- _bch_calculate_ecc (p, _ecc_calc + i);
433+ memset (_nbc.bch ->input_data , 0x0 , (1 << _nbc.bch ->m ) / 8 );
434+ memcpy (_nbc.bch ->input_data + _ecc_bytes, p, _ecc_size);
435+ _bch_calculate_ecc (_nbc.bch ->input_data , _ecc_calc + i);
435436 }
436437
437438 // prepare ECC code
@@ -532,7 +533,7 @@ bool SPINANDBlockDevice::is_bad_block(uint16_t blk_idx)
532533{
533534 mbed::bd_addr_t addr;
534535 uint8_t mark[2 ];
535-
536+
536537 addr = (blk_idx << _block_shift) + _page_size;
537538 if (QSPI_STATUS_OK != _read_oob (mark, addr, sizeof (mark))) {
538539 tr_error (" Read Command failed" );
@@ -547,8 +548,8 @@ int SPINANDBlockDevice::mark_bad_block(uint16_t blk_idx)
547548 mbed::bd_addr_t addr;
548549 uint8_t mark[2 ];
549550
550- mark[0 ] = 0x00 ;
551- mark[1 ] = 0x00 ;
551+ mark[0 ] = 0x00 ;
552+ mark[1 ] = 0x00 ;
552553 addr = (blk_idx << _block_shift) + _page_size;
553554 if (QSPI_STATUS_OK != _program_oob (mark, addr, sizeof (mark))) {
554555 tr_error (" Program Command failed" );
@@ -707,6 +708,12 @@ bool SPINANDBlockDevice::_read_otp_onfi()
707708 _ecc_bits = onfi_table[112 ];
708709 if (_ecc_bits > 0 ) {
709710 _bch_init (_ecc_bits);
711+ secur_reg &= ~SPINAND_SECURE_BIT_ECC_EN;
712+
713+ if (QSPI_STATUS_OK != _qspi_send_general_command (SPINAND_INST_SET_FEATURE, FEATURES_ADDR_SECURE_OTP,
714+ (char *) &secur_reg, 1 , NULL , 0 )) {
715+ tr_error (" Writing Register failed" );
716+ }
710717 } else {
711718 secur_reg |= SPINAND_SECURE_BIT_ECC_EN;
712719
@@ -768,7 +775,7 @@ int SPINANDBlockDevice::_program_oob(const void *buffer, bd_addr_t addr, bd_size
768775 int status = SPINAND_BD_ERROR_OK;
769776
770777 _mutex.lock ();
771-
778+
772779 // Send WREN
773780 if (_set_write_enable () != 0 ) {
774781 tr_error (" Write Enable failed" );
@@ -892,7 +899,7 @@ int SPINANDBlockDevice::_set_write_enable()
892899
893900int SPINANDBlockDevice::_set_conti_read_enable ()
894901{
895- uint8_t secur_reg = 0 ;uint8_t secur_reg1 = 0 ;
902+ uint8_t secur_reg = 0 ;
896903
897904 if (false == _is_mem_ready ()) {
898905 tr_error (" Device not ready, set quad enable failed" );
@@ -918,10 +925,6 @@ int SPINANDBlockDevice::_set_conti_read_enable()
918925 tr_error (" Device not ready, set quad enable failed" );
919926 return -1 ;
920927 }
921- if (QSPI_STATUS_OK != _qspi_send_general_command (SPINAND_INST_GET_FEATURE, FEATURES_ADDR_SECURE_OTP,
922- NULL , 0 , (char *) &secur_reg1, 1 )) {
923- tr_error (" Reading Security Register failed" );
924- }
925928
926929 return 0 ;
927930}
@@ -1249,26 +1252,26 @@ void SPINANDBlockDevice::_bch_init(uint8_t ecc_bits)
12491252{
12501253 unsigned int m, t, i;
12511254 unsigned char *erased_page;
1252- unsigned int eccsize = 512 ;
1255+ unsigned int eccsize = 410 ;
12531256 unsigned int eccbytes = 0 ;
12541257
1255- _ecc_bytes = eccbytes = DIV_ROUND_UP (ecc_bits * fls (8 * eccsize), 8 );
1258+ m = fls (1 + 8 * eccsize);
1259+ t = ecc_bits;
1260+
1261+ _ecc_bytes = eccbytes = ((m * t + 31 ) / 32 ) * 4 ;
12561262 _ecc_size = eccsize;
12571263 _ecc_steps = _page_size / eccsize;
12581264 _ecc_layout_pos = 2 ; // skip the bad block mark for Macronix spi nand
12591265
1260- m = fls (1 + 8 * eccsize);
1261- t = (eccbytes * 8 ) / m;
1262-
1263- _nbc.bch = init_bch (m, t, 0 );
1266+ _nbc.bch = bch_init (m, t);
12641267 if (!_nbc.bch ) {
12651268 return ;
12661269 }
12671270
12681271 /* verify that eccbytes has the expected value */
1269- if (_nbc.bch ->ecc_bytes != eccbytes) {
1272+ if (_nbc.bch ->ecc_words * 4 != eccbytes) {
12701273 tr_error (" invalid eccbytes %u, should be %u\n " ,
1271- eccbytes, _nbc.bch ->ecc_bytes );
1274+ eccbytes, _nbc.bch ->ecc_words );
12721275 return ;
12731276 }
12741277
@@ -1290,7 +1293,7 @@ void SPINANDBlockDevice::_bch_init(uint8_t ecc_bits)
12901293 memset (_page_buf, 0xff , _page_size + _oob_size);
12911294 memset (erased_page, 0xff , eccsize);
12921295 memset (_nbc.eccmask , 0 , eccbytes);
1293- encode_bch (_nbc.bch , erased_page, eccsize, _nbc.eccmask );
1296+ bch_encode (_nbc.bch , erased_page, ( unsigned int *) _nbc.eccmask );
12941297 free (erased_page);
12951298
12961299 for (i = 0 ; i < eccbytes; i++) {
@@ -1300,7 +1303,7 @@ void SPINANDBlockDevice::_bch_init(uint8_t ecc_bits)
13001303
13011304void SPINANDBlockDevice::_bch_free ()
13021305{
1303- free_bch (_nbc.bch );
1306+ bch_free (_nbc.bch );
13041307 free (_nbc.errloc );
13051308 free (_nbc.eccmask );
13061309 free (_page_buf);
@@ -1310,42 +1313,11 @@ void SPINANDBlockDevice::_bch_free()
13101313
13111314int SPINANDBlockDevice::_bch_calculate_ecc (unsigned char *buf, unsigned char *code)
13121315{
1313- unsigned int i;
13141316
13151317 memset (code, 0 , _ecc_bytes);
13161318
1317- encode_bch (_nbc.bch , buf, _ecc_size, code);
1318-
1319- /* apply mask so that an erased page is a valid codeword */
1320- for (i = 0 ; i < _ecc_bytes; i++) {
1321- code[i] ^= _nbc.eccmask [i];
1322- }
1319+ bch_encode (_nbc.bch , buf, (unsigned int *)code);
13231320
13241321 return 0 ;
13251322}
13261323
1327- int SPINANDBlockDevice::_bch_correct_data (unsigned char *buf, unsigned char *read_ecc, unsigned char *calc_ecc)
1328- {
1329- unsigned int *errloc = _nbc.errloc ;
1330- int i, count;
1331-
1332- count = decode_bch (_nbc.bch , NULL , _ecc_size, read_ecc, calc_ecc,
1333- NULL , errloc);
1334- if (count > 0 ) {
1335- for (i = 0 ; i < count; i++) {
1336- if (errloc[i] < (_ecc_size * 8 )) {
1337- /* error is located in data, correct it */
1338- buf[(errloc[i] >> 3 ) ^ 3 ] ^= (1 << (errloc[i] & 7 ));
1339- }
1340-
1341- /* else error in ecc, no action needed */
1342- tr_error (" corrected bitflip %04x:%d\n " , (errloc[i] >> 3 ) ^ 3 , errloc[i] & 7 );
1343- }
1344- } else if (count < 0 ) {
1345- tr_error (" ecc unrecoverable error\n " );
1346- count = -EBADMSG;
1347- }
1348- return count;
1349- }
1350-
1351-
0 commit comments