@@ -107,9 +107,9 @@ SPIFBlockDevice::SPIFBlockDevice(
107107 _write_dummy_and_mode_cycles = 0 ;
108108 _dummy_and_mode_cycles = _read_dummy_and_mode_cycles;
109109
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;
113113
114114 if (SPIF_BD_ERROR_OK != _spi_set_frequency (freq)) {
115115 tr_error (" SPI Set Frequency Failed" );
@@ -190,14 +190,15 @@ int SPIFBlockDevice::init()
190190 }
191191
192192 /* *************************** Parse Sector Map Table ***********************************/
193- _region_size_bytes [0 ] =
193+ _sfdp_info. smtbl . region_size [0 ] =
194194 _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 ;
196196
197197 if ((hdr_info.smtbl .addr != 0 ) && (0 != hdr_info.smtbl .size )) {
198198 tr_debug (" init - Parsing Sector Map Table - addr: 0x%" PRIx32 " h, Size: %d" , hdr_info.smtbl .addr ,
199199 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 ) {
201202 tr_error (" init - Parse Sector Map Table Failed" );
202203 status = SPIF_BD_ERROR_PARSING_FAILED;
203204 goto exit_point;
@@ -341,13 +342,13 @@ int SPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
341342 bool erase_failed = false ;
342343 int status = SPIF_BD_ERROR_OK;
343344 // Find region of erased address
344- int region = _utils_find_addr_region (addr);
345+ int region = _utils_find_addr_region (addr, _sfdp_info. smtbl );
345346 if (region < 0 ) {
346347 tr_error (" no region found for address %llu" , addr);
347348 return SPIF_BD_ERROR_INVALID_ERASE_PARAMS;
348349 }
349350 // 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];
351352
352353 tr_debug (" erase - addr: %llu, in_size: %llu" , addr, in_size);
353354
@@ -366,10 +367,11 @@ int SPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
366367
367368 // iterate to find next Largest erase type ( a. supported by region, b. smaller than size)
368369 // 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);
373375
374376 tr_debug (" erase - addr: %llu, size:%d, Inst: 0x%xh, chunk: %" PRIu32 " , " ,
375377 addr, size, cur_erase_inst, chunk);
@@ -390,10 +392,10 @@ int SPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
390392 addr += chunk;
391393 size -= chunk;
392394
393- if ((size > 0 ) && (addr > _region_high_boundary [region])) {
395+ if ((size > 0 ) && (addr > _sfdp_info. smtbl . region_high_boundary [region])) {
394396 // erase crossed to next region
395397 region++;
396- bitfield = _region_erase_types_bitfield [region];
398+ bitfield = _sfdp_info. smtbl . region_erase_types_bitfld [region];
397399 }
398400
399401 if (false == _is_mem_ready ()) {
@@ -429,16 +431,16 @@ bd_size_t SPIFBlockDevice::get_program_size() const
429431bd_size_t SPIFBlockDevice::get_erase_size () const
430432{
431433 // 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 ;
433435}
434436
435437// Find minimal erase size supported by the region to which the address belongs to
436438bd_size_t SPIFBlockDevice::get_erase_size (bd_addr_t addr) const
437439{
438440 // Find region of current address
439- int region = _utils_find_addr_region (addr);
441+ int region = _utils_find_addr_region (addr, _sfdp_info. smtbl );
440442
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 ;
442444 int8_t type_mask = SFDP_ERASE_BITMASK_TYPE1;
443445 int i_ind = 0 ;
444446
@@ -447,9 +449,9 @@ bd_size_t SPIFBlockDevice::get_erase_size(bd_addr_t addr) const
447449
448450 for (i_ind = 0 ; i_ind < 4 ; i_ind++) {
449451 // 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) {
451453
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];
453455 break ;
454456 }
455457 type_mask = type_mask << 1 ;
@@ -618,65 +620,6 @@ spif_bd_error SPIFBlockDevice::_spi_send_general_command(int instruction, bd_add
618620/* ********************************************************/
619621/* ********* SFDP Parsing and Detection Functions *********/
620622/* ********************************************************/
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-
680623int SPIFBlockDevice::_sfdp_parse_basic_param_table (uint32_t basic_table_addr, size_t basic_table_size)
681624{
682625 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
713656 _page_size_bytes = _sfdp_detect_page_size (param_table, basic_table_size);
714657
715658 // 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 );
718660 _erase_instruction = _erase4k_inst;
719661
720662 // 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_
745687
746688int SPIFBlockDevice::_sfdp_detect_erase_types_inst_and_size (uint8_t *basic_param_table_ptr, int basic_param_table_size,
747689 int &erase4k_inst,
748- int *erase_type_inst_arr, unsigned int *erase_type_size_arr )
690+ sfdp_smtbl_info &smtbl )
749691{
750692 erase4k_inst = 0xff ;
751693 bool found_4Kerase_type = false ;
@@ -757,34 +699,36 @@ int SPIFBlockDevice::_sfdp_detect_erase_types_inst_and_size(uint8_t *basic_param
757699 if (basic_param_table_size > SPIF_BASIC_PARAM_ERASE_TYPE_1_SIZE_BYTE) {
758700 // Loop Erase Types 1-4
759701 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 ) {
766708 // 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];
768711
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 )) {
770714 // 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];
772716 }
773717
774718 // 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 ) {
776720 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]) {
778722 // 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];
780724 tr_warning (" _detectEraseTypesInstAndSize - Default 4K erase Inst is different than erase type Inst for 4K" );
781725
782726 }
783727 }
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
785729 }
786730 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]);
788732 bitfield = bitfield << 1 ;
789733 }
790734 }
@@ -912,28 +856,32 @@ int SPIFBlockDevice::_set_write_enable()
912856/* ********************************************/
913857/* ************ Utility Functions *************/
914858/* ********************************************/
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
916860{
917861 // 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 )) {
919863 return -1 ;
920864 }
921865
922- if (_regions_count == 1 ) {
866+ if (smtbl. region_cnt == 1 ) {
923867 return 0 ;
924868 }
925869
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--) {
927871
928- if (offset > _region_high_boundary [i_ind]) {
872+ if (offset > smtbl. region_high_boundary [i_ind]) {
929873 return (i_ind + 1 );
930874 }
931875 }
932876 return -1 ;
933877
934878}
935879
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)
937885{
938886 // Iterate on all supported Erase Types of the Region to which the offset belong to.
939887 // Iterates from highest type to lowest
@@ -943,8 +891,9 @@ int SPIFBlockDevice::_utils_iterate_next_largest_erase_type(uint8_t &bitfield, i
943891 for (i_ind = 3 ; i_ind >= 0 ; i_ind--) {
944892 if (bitfield & type_mask) {
945893 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]))) {
948897 break ;
949898 } else {
950899 bitfield &= ~type_mask;
@@ -954,10 +903,9 @@ int SPIFBlockDevice::_utils_iterate_next_largest_erase_type(uint8_t &bitfield, i
954903 }
955904
956905 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" );
958907 }
959908 return largest_erase_type;
960-
961909}
962910
963911/* ********************************************/
0 commit comments