@@ -343,23 +343,22 @@ int SPINANDBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size)
343
343
goto exit_point;
344
344
}
345
345
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
-
351
346
memcpy (_ecc_code, _page_buf + _page_size + _ecc_layout_pos, _ecc_bytes * _ecc_steps);
352
347
353
348
p = (uint8_t *)_page_buf;
354
349
ecc_steps = _ecc_steps;
355
350
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));
357
355
if (res < 0 ) {
358
356
tr_error (" Reading data failed" );
359
357
status = SPINAND_BD_ERROR_DEVICE_ERROR;
360
358
read_failed = true ;
361
359
goto exit_point;
362
360
}
361
+ memcpy (p, _nbc.bch ->input_data + _ecc_bytes, _ecc_size);
363
362
}
364
363
memcpy (buffer, _page_buf + offset, read_bytes);
365
364
}
@@ -431,7 +430,9 @@ int SPINANDBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t si
431
430
432
431
// calculate the software ECC
433
432
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);
435
436
}
436
437
437
438
// prepare ECC code
@@ -532,7 +533,7 @@ bool SPINANDBlockDevice::is_bad_block(uint16_t blk_idx)
532
533
{
533
534
mbed::bd_addr_t addr;
534
535
uint8_t mark[2 ];
535
-
536
+
536
537
addr = (blk_idx << _block_shift) + _page_size;
537
538
if (QSPI_STATUS_OK != _read_oob (mark, addr, sizeof (mark))) {
538
539
tr_error (" Read Command failed" );
@@ -547,8 +548,8 @@ int SPINANDBlockDevice::mark_bad_block(uint16_t blk_idx)
547
548
mbed::bd_addr_t addr;
548
549
uint8_t mark[2 ];
549
550
550
- mark[0 ] = 0x00 ;
551
- mark[1 ] = 0x00 ;
551
+ mark[0 ] = 0x00 ;
552
+ mark[1 ] = 0x00 ;
552
553
addr = (blk_idx << _block_shift) + _page_size;
553
554
if (QSPI_STATUS_OK != _program_oob (mark, addr, sizeof (mark))) {
554
555
tr_error (" Program Command failed" );
@@ -707,6 +708,12 @@ bool SPINANDBlockDevice::_read_otp_onfi()
707
708
_ecc_bits = onfi_table[112 ];
708
709
if (_ecc_bits > 0 ) {
709
710
_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
+ }
710
717
} else {
711
718
secur_reg |= SPINAND_SECURE_BIT_ECC_EN;
712
719
@@ -768,7 +775,7 @@ int SPINANDBlockDevice::_program_oob(const void *buffer, bd_addr_t addr, bd_size
768
775
int status = SPINAND_BD_ERROR_OK;
769
776
770
777
_mutex.lock ();
771
-
778
+
772
779
// Send WREN
773
780
if (_set_write_enable () != 0 ) {
774
781
tr_error (" Write Enable failed" );
@@ -892,7 +899,7 @@ int SPINANDBlockDevice::_set_write_enable()
892
899
893
900
int SPINANDBlockDevice::_set_conti_read_enable ()
894
901
{
895
- uint8_t secur_reg = 0 ;uint8_t secur_reg1 = 0 ;
902
+ uint8_t secur_reg = 0 ;
896
903
897
904
if (false == _is_mem_ready ()) {
898
905
tr_error (" Device not ready, set quad enable failed" );
@@ -918,10 +925,6 @@ int SPINANDBlockDevice::_set_conti_read_enable()
918
925
tr_error (" Device not ready, set quad enable failed" );
919
926
return -1 ;
920
927
}
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
- }
925
928
926
929
return 0 ;
927
930
}
@@ -1249,26 +1252,26 @@ void SPINANDBlockDevice::_bch_init(uint8_t ecc_bits)
1249
1252
{
1250
1253
unsigned int m, t, i;
1251
1254
unsigned char *erased_page;
1252
- unsigned int eccsize = 512 ;
1255
+ unsigned int eccsize = 410 ;
1253
1256
unsigned int eccbytes = 0 ;
1254
1257
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 ;
1256
1262
_ecc_size = eccsize;
1257
1263
_ecc_steps = _page_size / eccsize;
1258
1264
_ecc_layout_pos = 2 ; // skip the bad block mark for Macronix spi nand
1259
1265
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);
1264
1267
if (!_nbc.bch ) {
1265
1268
return ;
1266
1269
}
1267
1270
1268
1271
/* verify that eccbytes has the expected value */
1269
- if (_nbc.bch ->ecc_bytes != eccbytes) {
1272
+ if (_nbc.bch ->ecc_words * 4 != eccbytes) {
1270
1273
tr_error (" invalid eccbytes %u, should be %u\n " ,
1271
- eccbytes, _nbc.bch ->ecc_bytes );
1274
+ eccbytes, _nbc.bch ->ecc_words );
1272
1275
return ;
1273
1276
}
1274
1277
@@ -1290,7 +1293,7 @@ void SPINANDBlockDevice::_bch_init(uint8_t ecc_bits)
1290
1293
memset (_page_buf, 0xff , _page_size + _oob_size);
1291
1294
memset (erased_page, 0xff , eccsize);
1292
1295
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 );
1294
1297
free (erased_page);
1295
1298
1296
1299
for (i = 0 ; i < eccbytes; i++) {
@@ -1300,7 +1303,7 @@ void SPINANDBlockDevice::_bch_init(uint8_t ecc_bits)
1300
1303
1301
1304
void SPINANDBlockDevice::_bch_free ()
1302
1305
{
1303
- free_bch (_nbc.bch );
1306
+ bch_free (_nbc.bch );
1304
1307
free (_nbc.errloc );
1305
1308
free (_nbc.eccmask );
1306
1309
free (_page_buf);
@@ -1310,42 +1313,11 @@ void SPINANDBlockDevice::_bch_free()
1310
1313
1311
1314
int SPINANDBlockDevice::_bch_calculate_ecc (unsigned char *buf, unsigned char *code)
1312
1315
{
1313
- unsigned int i;
1314
1316
1315
1317
memset (code, 0 , _ecc_bytes);
1316
1318
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);
1323
1320
1324
1321
return 0 ;
1325
1322
}
1326
1323
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