@@ -107,9 +107,9 @@ SPIFBlockDevice::SPIFBlockDevice(
107
107
_write_dummy_and_mode_cycles = 0 ;
108
108
_dummy_and_mode_cycles = _read_dummy_and_mode_cycles;
109
109
110
- _min_common_erase_size = 0 ;
111
- _regions_count = 1 ;
112
- _region_erase_types_bitfield [0 ] = SFDP_ERASE_BITMASK_NONE;
110
+ _sfdp_info. smtbl . regions_min_common_erase_size = 0 ;
111
+ _sfdp_info. smtbl . region_cnt = 1 ;
112
+ _sfdp_info. smtbl . region_erase_types_bitfld [0 ] = SFDP_ERASE_BITMASK_NONE;
113
113
114
114
if (SPIF_BD_ERROR_OK != _spi_set_frequency (freq)) {
115
115
tr_error (" SPI Set Frequency Failed" );
@@ -190,14 +190,15 @@ int SPIFBlockDevice::init()
190
190
}
191
191
192
192
/* *************************** Parse Sector Map Table ***********************************/
193
- _region_size_bytes [0 ] =
193
+ _sfdp_info. smtbl . region_size [0 ] =
194
194
_device_size_bytes; // If there's no region map, we have a single region sized the entire device size
195
- _region_high_boundary [0 ] = _device_size_bytes - 1 ;
195
+ _sfdp_info. smtbl . region_high_boundary [0 ] = _device_size_bytes - 1 ;
196
196
197
197
if ((hdr_info.smtbl .addr != 0 ) && (0 != hdr_info.smtbl .size )) {
198
198
tr_debug (" init - Parsing Sector Map Table - addr: 0x%" PRIx32 " h, Size: %d" , hdr_info.smtbl .addr ,
199
199
hdr_info.smtbl .size );
200
- if (0 != _sfdp_parse_sector_map_table (hdr_info.smtbl .addr , hdr_info.smtbl .size )) {
200
+ if (sfdp_parse_sector_map_table (callback (this , &SPIFBlockDevice::_spi_send_read_sfdp_command),
201
+ _sfdp_info.smtbl ) < 0 ) {
201
202
tr_error (" init - Parse Sector Map Table Failed" );
202
203
status = SPIF_BD_ERROR_PARSING_FAILED;
203
204
goto exit_point;
@@ -341,13 +342,13 @@ int SPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
341
342
bool erase_failed = false ;
342
343
int status = SPIF_BD_ERROR_OK;
343
344
// Find region of erased address
344
- int region = _utils_find_addr_region (addr);
345
+ int region = _utils_find_addr_region (addr, _sfdp_info. smtbl );
345
346
if (region < 0 ) {
346
347
tr_error (" no region found for address %llu" , addr);
347
348
return SPIF_BD_ERROR_INVALID_ERASE_PARAMS;
348
349
}
349
350
// Erase Types of selected region
350
- uint8_t bitfield = _region_erase_types_bitfield [region];
351
+ uint8_t bitfield = _sfdp_info. smtbl . region_erase_types_bitfld [region];
351
352
352
353
tr_debug (" erase - addr: %llu, in_size: %llu" , addr, in_size);
353
354
@@ -366,10 +367,11 @@ int SPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
366
367
367
368
// iterate to find next Largest erase type ( a. supported by region, b. smaller than size)
368
369
// find the matching instruction and erase size chunk for that type.
369
- type = _utils_iterate_next_largest_erase_type (bitfield, size, (unsigned int )addr, _region_high_boundary[region]);
370
- cur_erase_inst = _erase_type_inst_arr[type];
371
- offset = addr % _erase_type_size_arr[type];
372
- chunk = ((offset + size) < _erase_type_size_arr[type]) ? size : (_erase_type_size_arr[type] - offset);
370
+ type = _utils_iterate_next_largest_erase_type (bitfield, size, (unsigned int )addr, region, _sfdp_info.smtbl );
371
+ cur_erase_inst = _sfdp_info.smtbl .erase_type_inst_arr [type];
372
+ offset = addr % _sfdp_info.smtbl .erase_type_size_arr [type];
373
+ chunk = ((offset + size) < _sfdp_info.smtbl .erase_type_size_arr [type]) ?
374
+ size : (_sfdp_info.smtbl .erase_type_size_arr [type] - offset);
373
375
374
376
tr_debug (" erase - addr: %llu, size:%d, Inst: 0x%xh, chunk: %" PRIu32 " , " ,
375
377
addr, size, cur_erase_inst, chunk);
@@ -390,10 +392,10 @@ int SPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
390
392
addr += chunk;
391
393
size -= chunk;
392
394
393
- if ((size > 0 ) && (addr > _region_high_boundary [region])) {
395
+ if ((size > 0 ) && (addr > _sfdp_info. smtbl . region_high_boundary [region])) {
394
396
// erase crossed to next region
395
397
region++;
396
- bitfield = _region_erase_types_bitfield [region];
398
+ bitfield = _sfdp_info. smtbl . region_erase_types_bitfld [region];
397
399
}
398
400
399
401
if (false == _is_mem_ready ()) {
@@ -429,16 +431,16 @@ bd_size_t SPIFBlockDevice::get_program_size() const
429
431
bd_size_t SPIFBlockDevice::get_erase_size () const
430
432
{
431
433
// return minimal erase size supported by all regions (0 if none exists)
432
- return _min_common_erase_size ;
434
+ return _sfdp_info. smtbl . regions_min_common_erase_size ;
433
435
}
434
436
435
437
// Find minimal erase size supported by the region to which the address belongs to
436
438
bd_size_t SPIFBlockDevice::get_erase_size (bd_addr_t addr) const
437
439
{
438
440
// Find region of current address
439
- int region = _utils_find_addr_region (addr);
441
+ int region = _utils_find_addr_region (addr, _sfdp_info. smtbl );
440
442
441
- unsigned int min_region_erase_size = _min_common_erase_size ;
443
+ unsigned int min_region_erase_size = _sfdp_info. smtbl . regions_min_common_erase_size ;
442
444
int8_t type_mask = SFDP_ERASE_BITMASK_TYPE1;
443
445
int i_ind = 0 ;
444
446
@@ -447,9 +449,9 @@ bd_size_t SPIFBlockDevice::get_erase_size(bd_addr_t addr) const
447
449
448
450
for (i_ind = 0 ; i_ind < 4 ; i_ind++) {
449
451
// loop through erase types bitfield supported by region
450
- if (_region_erase_types_bitfield [region] & type_mask) {
452
+ if (_sfdp_info. smtbl . region_erase_types_bitfld [region] & type_mask) {
451
453
452
- min_region_erase_size = _erase_type_size_arr [i_ind];
454
+ min_region_erase_size = _sfdp_info. smtbl . erase_type_size_arr [i_ind];
453
455
break ;
454
456
}
455
457
type_mask = type_mask << 1 ;
@@ -618,65 +620,6 @@ spif_bd_error SPIFBlockDevice::_spi_send_general_command(int instruction, bd_add
618
620
/* ********************************************************/
619
621
/* ********* SFDP Parsing and Detection Functions *********/
620
622
/* ********************************************************/
621
- int SPIFBlockDevice::_sfdp_parse_sector_map_table (uint32_t sector_map_table_addr, size_t sector_map_table_size)
622
- {
623
- uint8_t sector_map_table[SFDP_DEFAULT_BASIC_PARAMS_TABLE_SIZE_BYTES]; /* Up To 16 DWORDS = 64 Bytes */
624
- uint32_t tmp_region_size = 0 ;
625
- int i_ind = 0 ;
626
- int prev_boundary = 0 ;
627
- // Default set to all type bits 1-4 are common
628
- int min_common_erase_type_bits = SFDP_ERASE_BITMASK_ALL;
629
-
630
-
631
- spif_bd_error status = _spi_send_read_command (SPIF_SFDP, sector_map_table, sector_map_table_addr /* address*/ ,
632
- sector_map_table_size);
633
- if (status != SPIF_BD_ERROR_OK) {
634
- tr_error (" init - Read SFDP First Table Failed" );
635
- return -1 ;
636
- }
637
-
638
- // Currently we support only Single Map Descriptor
639
- if (!((sector_map_table[0 ] & 0x3 ) == 0x03 ) && (sector_map_table[1 ] == 0x0 )) {
640
- tr_error (" Sector Map - Supporting Only Single! Map Descriptor (not map commands)" );
641
- return -1 ;
642
- }
643
-
644
- _regions_count = sector_map_table[2 ] + 1 ;
645
- if (_regions_count > SPIF_MAX_REGIONS) {
646
- tr_error (" Supporting up to %d regions, current setup to %d regions - fail" ,
647
- SPIF_MAX_REGIONS, _regions_count);
648
- return -1 ;
649
- }
650
-
651
- // Loop through Regions and set for each one: size, supported erase types, high boundary offset
652
- // Calculate minimum Common Erase Type for all Regions
653
- for (i_ind = 0 ; i_ind < _regions_count; i_ind++) {
654
- tmp_region_size = ((*((uint32_t *)§or_map_table[(i_ind + 1 ) * 4 ])) >> 8 ) & 0x00FFFFFF ; // bits 9-32
655
- _region_size_bytes[i_ind] = (tmp_region_size + 1 ) * 256 ; // Region size is 0 based multiple of 256 bytes;
656
- _region_erase_types_bitfield[i_ind] = sector_map_table[(i_ind + 1 ) * 4 ] & 0x0F ; // bits 1-4
657
- min_common_erase_type_bits &= _region_erase_types_bitfield[i_ind];
658
- _region_high_boundary[i_ind] = (_region_size_bytes[i_ind] - 1 ) + prev_boundary;
659
- prev_boundary = _region_high_boundary[i_ind] + 1 ;
660
- }
661
-
662
- // Calc minimum Common Erase Size from min_common_erase_type_bits
663
- uint8_t type_mask = SFDP_ERASE_BITMASK_TYPE1;
664
- for (i_ind = 0 ; i_ind < 4 ; i_ind++) {
665
- if (min_common_erase_type_bits & type_mask) {
666
- _min_common_erase_size = _erase_type_size_arr[i_ind];
667
- break ;
668
- }
669
- type_mask = type_mask << 1 ;
670
- }
671
-
672
- if (i_ind == 4 ) {
673
- // No common erase type was found between regions
674
- _min_common_erase_size = 0 ;
675
- }
676
-
677
- return 0 ;
678
- }
679
-
680
623
int SPIFBlockDevice::_sfdp_parse_basic_param_table (uint32_t basic_table_addr, size_t basic_table_size)
681
624
{
682
625
uint8_t param_table[SFDP_DEFAULT_BASIC_PARAMS_TABLE_SIZE_BYTES]; /* Up To 16 DWORDS = 64 Bytes */
@@ -713,8 +656,7 @@ int SPIFBlockDevice::_sfdp_parse_basic_param_table(uint32_t basic_table_addr, si
713
656
_page_size_bytes = _sfdp_detect_page_size (param_table, basic_table_size);
714
657
715
658
// Detect and Set Erase Types
716
- _sfdp_detect_erase_types_inst_and_size (param_table, basic_table_size, _erase4k_inst, _erase_type_inst_arr,
717
- _erase_type_size_arr);
659
+ _sfdp_detect_erase_types_inst_and_size (param_table, basic_table_size, _erase4k_inst, _sfdp_info.smtbl );
718
660
_erase_instruction = _erase4k_inst;
719
661
720
662
// Detect and Set fastest Bus mode (default 1-1-1)
@@ -745,7 +687,7 @@ unsigned int SPIFBlockDevice::_sfdp_detect_page_size(uint8_t *basic_param_table_
745
687
746
688
int SPIFBlockDevice::_sfdp_detect_erase_types_inst_and_size (uint8_t *basic_param_table_ptr, int basic_param_table_size,
747
689
int &erase4k_inst,
748
- int *erase_type_inst_arr, unsigned int *erase_type_size_arr )
690
+ sfdp_smtbl_info &smtbl )
749
691
{
750
692
erase4k_inst = 0xff ;
751
693
bool found_4Kerase_type = false ;
@@ -757,34 +699,36 @@ int SPIFBlockDevice::_sfdp_detect_erase_types_inst_and_size(uint8_t *basic_param
757
699
if (basic_param_table_size > SPIF_BASIC_PARAM_ERASE_TYPE_1_SIZE_BYTE) {
758
700
// Loop Erase Types 1-4
759
701
for (int i_ind = 0 ; i_ind < 4 ; i_ind++) {
760
- erase_type_inst_arr[i_ind] = 0xff ; // 0xFF default for unsupported type
761
- erase_type_size_arr[i_ind] = local_math_power (2 ,
762
- basic_param_table_ptr[SPIF_BASIC_PARAM_ERASE_TYPE_1_SIZE_BYTE + 2 * i_ind]); // Size given as 2^N
763
- tr_debug (" Erase Type(A) %d - Inst: 0x%xh, Size: %d" , (i_ind + 1 ), erase_type_inst_arr[i_ind],
764
- erase_type_size_arr[i_ind]);
765
- if (erase_type_size_arr[i_ind] > 1 ) {
702
+ smtbl. erase_type_inst_arr [i_ind] = 0xff ; // 0xFF default for unsupported type
703
+ smtbl. erase_type_size_arr [i_ind] = local_math_power (
704
+ 2 , basic_param_table_ptr[SPIF_BASIC_PARAM_ERASE_TYPE_1_SIZE_BYTE + 2 * i_ind]); // Size given as 2^N
705
+ tr_debug (" Erase Type(A) %d - Inst: 0x%xh, Size: %d" , (i_ind + 1 ), smtbl. erase_type_inst_arr [i_ind],
706
+ smtbl. erase_type_size_arr [i_ind]);
707
+ if (smtbl. erase_type_size_arr [i_ind] > 1 ) {
766
708
// if size==1 type is not supported
767
- erase_type_inst_arr[i_ind] = basic_param_table_ptr[SPIF_BASIC_PARAM_ERASE_TYPE_1_BYTE + 2 * i_ind];
709
+ smtbl.erase_type_inst_arr [i_ind] =
710
+ basic_param_table_ptr[SPIF_BASIC_PARAM_ERASE_TYPE_1_BYTE + 2 * i_ind];
768
711
769
- if ((erase_type_size_arr[i_ind] < _min_common_erase_size) || (_min_common_erase_size == 0 )) {
712
+ if ((smtbl.erase_type_size_arr [i_ind] < smtbl.regions_min_common_erase_size )
713
+ || (smtbl.regions_min_common_erase_size == 0 )) {
770
714
// Set default minimal common erase for singal region
771
- _min_common_erase_size = erase_type_size_arr[i_ind];
715
+ smtbl. regions_min_common_erase_size = smtbl. erase_type_size_arr [i_ind];
772
716
}
773
717
774
718
// SFDP standard requires 4K Erase type to exist and its instruction to be identical to legacy field erase instruction
775
- if (erase_type_size_arr[i_ind] == 4096 ) {
719
+ if (smtbl. erase_type_size_arr [i_ind] == 4096 ) {
776
720
found_4Kerase_type = true ;
777
- if (erase4k_inst != erase_type_inst_arr[i_ind]) {
721
+ if (erase4k_inst != smtbl. erase_type_inst_arr [i_ind]) {
778
722
// Verify 4KErase Type is identical to Legacy 4K erase type specified in Byte 1 of Param Table
779
- erase4k_inst = erase_type_inst_arr[i_ind];
723
+ erase4k_inst = smtbl. erase_type_inst_arr [i_ind];
780
724
tr_warning (" _detectEraseTypesInstAndSize - Default 4K erase Inst is different than erase type Inst for 4K" );
781
725
782
726
}
783
727
}
784
- _region_erase_types_bitfield [0 ] |= bitfield; // If there's no region map, set region "0" types bitfield as defualt;
728
+ smtbl. region_erase_types_bitfld [0 ] |= bitfield; // no region map, set region "0" types bitfield as default
785
729
}
786
730
tr_info (" Erase Type %d - Inst: 0x%xh, Size: %d" , (i_ind + 1 ),
787
- erase_type_inst_arr[i_ind], erase_type_size_arr[i_ind]);
731
+ smtbl. erase_type_inst_arr [i_ind], smtbl. erase_type_size_arr [i_ind]);
788
732
bitfield = bitfield << 1 ;
789
733
}
790
734
}
@@ -912,28 +856,32 @@ int SPIFBlockDevice::_set_write_enable()
912
856
/* ********************************************/
913
857
/* ************ Utility Functions *************/
914
858
/* ********************************************/
915
- int SPIFBlockDevice::_utils_find_addr_region (bd_size_t offset) const
859
+ int SPIFBlockDevice::_utils_find_addr_region (bd_size_t offset, const sfdp_smtbl_info &smtbl ) const
916
860
{
917
861
// Find the region to which the given offset belong to
918
- if ((offset > _device_size_bytes) || (_regions_count == 0 )) {
862
+ if ((offset > _device_size_bytes) || (smtbl. region_cnt == 0 )) {
919
863
return -1 ;
920
864
}
921
865
922
- if (_regions_count == 1 ) {
866
+ if (smtbl. region_cnt == 1 ) {
923
867
return 0 ;
924
868
}
925
869
926
- for (int i_ind = _regions_count - 2 ; i_ind >= 0 ; i_ind--) {
870
+ for (int i_ind = smtbl. region_cnt - 2 ; i_ind >= 0 ; i_ind--) {
927
871
928
- if (offset > _region_high_boundary [i_ind]) {
872
+ if (offset > smtbl. region_high_boundary [i_ind]) {
929
873
return (i_ind + 1 );
930
874
}
931
875
}
932
876
return -1 ;
933
877
934
878
}
935
879
936
- int SPIFBlockDevice::_utils_iterate_next_largest_erase_type (uint8_t &bitfield, int size, int offset, int boundry)
880
+ int SPIFBlockDevice::_utils_iterate_next_largest_erase_type (uint8_t &bitfield,
881
+ int size,
882
+ int offset,
883
+ int region,
884
+ sfdp_smtbl_info &smtbl)
937
885
{
938
886
// Iterate on all supported Erase Types of the Region to which the offset belong to.
939
887
// Iterates from highest type to lowest
@@ -943,8 +891,9 @@ int SPIFBlockDevice::_utils_iterate_next_largest_erase_type(uint8_t &bitfield, i
943
891
for (i_ind = 3 ; i_ind >= 0 ; i_ind--) {
944
892
if (bitfield & type_mask) {
945
893
largest_erase_type = i_ind;
946
- if ((size > (int )(_erase_type_size_arr[largest_erase_type])) &&
947
- ((boundry - offset) > (int )(_erase_type_size_arr[largest_erase_type]))) {
894
+ if ((size > (int )(smtbl.erase_type_size_arr [largest_erase_type])) &&
895
+ ((_sfdp_info.smtbl .region_high_boundary [region] - offset)
896
+ > (int )(smtbl.erase_type_size_arr [largest_erase_type]))) {
948
897
break ;
949
898
} else {
950
899
bitfield &= ~type_mask;
@@ -954,10 +903,9 @@ int SPIFBlockDevice::_utils_iterate_next_largest_erase_type(uint8_t &bitfield, i
954
903
}
955
904
956
905
if (i_ind == 4 ) {
957
- tr_error (" no erase type was found for current region addr" );
906
+ tr_error (" No erase type was found for current region addr" );
958
907
}
959
908
return largest_erase_type;
960
-
961
909
}
962
910
963
911
/* ********************************************/
0 commit comments