mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			Merge pull request #12528 from VeijoPesonen/sfdp_split_5
SFDP: consolidation of SFDP parsing [5/5]pull/12666/head
						commit
						4a5fac34a1
					
				| 
						 | 
				
			
			@ -131,7 +131,7 @@ int sfdp_find_addr_region(bd_size_t offset, const sfdp_hdr_info &sfdp_info);
 | 
			
		|||
 * @param size     Upper limit for region size
 | 
			
		||||
 * @param offset   Offset value
 | 
			
		||||
 * @param region   Region number
 | 
			
		||||
 * @param smptbl    Information about different erase types
 | 
			
		||||
 * @param smptbl   Information about different erase types
 | 
			
		||||
 *
 | 
			
		||||
 * @return Largest erase type
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,8 +16,12 @@
 | 
			
		|||
 */
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "platform/mbed_error.h"
 | 
			
		||||
#include "drivers/internal/SFDP.h"
 | 
			
		||||
 | 
			
		||||
#if (DEVICE_SPI || DEVICE_QSPI)
 | 
			
		||||
| 
						 | 
				
			
			@ -107,20 +111,69 @@ int sfdp_parse_single_param_header(sfdp_prm_hdr *phdr_ptr, sfdp_hdr_info &hdr_in
 | 
			
		|||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((phdr_ptr->PID_LSB == 0) && (sfdp_get_param_id_msb(phdr_ptr->DWORD2) == 0xFF)) {
 | 
			
		||||
        tr_debug("Parameter header: Basic Parameter Header");
 | 
			
		||||
        hdr_info.bptbl.addr = sfdp_get_param_tbl_ptr(phdr_ptr->DWORD2);
 | 
			
		||||
        hdr_info.bptbl.size = std::min((phdr_ptr->P_LEN * 4), SFDP_BASIC_PARAMS_TBL_SIZE);
 | 
			
		||||
    int param_id_msb = sfdp_get_param_id_msb(phdr_ptr->DWORD2);
 | 
			
		||||
 | 
			
		||||
    } else if ((phdr_ptr->PID_LSB == 0x81) && (sfdp_get_param_id_msb(phdr_ptr->DWORD2) == 0xFF)) {
 | 
			
		||||
        tr_debug("Parameter header: Sector Map Parameter Header");
 | 
			
		||||
        hdr_info.smptbl.addr = sfdp_get_param_tbl_ptr(phdr_ptr->DWORD2);
 | 
			
		||||
        hdr_info.smptbl.size = phdr_ptr->P_LEN * 4;
 | 
			
		||||
    /* MSB JEDEC ID */
 | 
			
		||||
    if (param_id_msb == 0xFF) {
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
        tr_debug("Parameter header: header vendor specific or unknown. Parameter ID LSB: 0x%" PRIX8 "; MSB: 0x%" PRIX8 "",
 | 
			
		||||
        /* LSB JEDEC ID */
 | 
			
		||||
        switch (phdr_ptr->PID_LSB) {
 | 
			
		||||
            case 0x0:
 | 
			
		||||
                tr_debug("Parameter header: JEDEC Basic Flash - Revision %" PRIX8 ".%" PRIX8 "",
 | 
			
		||||
                         phdr_ptr->P_MAJOR,
 | 
			
		||||
                         phdr_ptr->P_MINOR);
 | 
			
		||||
                hdr_info.bptbl.addr = sfdp_get_param_tbl_ptr(phdr_ptr->DWORD2);
 | 
			
		||||
                hdr_info.bptbl.size = std::min((phdr_ptr->P_LEN * 4), SFDP_BASIC_PARAMS_TBL_SIZE);
 | 
			
		||||
                break;
 | 
			
		||||
            case 0x81:
 | 
			
		||||
                tr_info("Parameter header: Sector Map");
 | 
			
		||||
                hdr_info.smptbl.addr = sfdp_get_param_tbl_ptr(phdr_ptr->DWORD2);
 | 
			
		||||
                hdr_info.smptbl.size = phdr_ptr->P_LEN * 4;
 | 
			
		||||
                break;
 | 
			
		||||
            /* Unsupported */
 | 
			
		||||
            case 0x03:
 | 
			
		||||
                tr_info("UNSUPPORTED:Parameter header: Replay Protected Monotonic Counters");
 | 
			
		||||
                break;
 | 
			
		||||
            case 0x84:
 | 
			
		||||
                tr_info("UNSUPPORTED:Parameter header: 4-byte Address Instruction");
 | 
			
		||||
                break;
 | 
			
		||||
            case 0x05:
 | 
			
		||||
                tr_info("UNSUPPORTED:Parameter header: eXtended Serial Peripheral Interface (xSPI) Profile 1.0");
 | 
			
		||||
                break;
 | 
			
		||||
            case 0x06:
 | 
			
		||||
                tr_info("UNSUPPORTED:Parameter header: eXtended Serial Peripheral Interface (xSPI) Profile 2.0");
 | 
			
		||||
                break;
 | 
			
		||||
            case 0x87:
 | 
			
		||||
                tr_info("UNSUPPORTED:Parameter header: SCCR Map for SPI Memory Devices");
 | 
			
		||||
                break;
 | 
			
		||||
            case 0x88:
 | 
			
		||||
                tr_info("UNSUPPORTED:Parameter header: SCCR Map Offsets for Multi-Chip SPI Memory Devices");
 | 
			
		||||
                break;
 | 
			
		||||
            case 0x09:
 | 
			
		||||
                tr_info("UNSUPPORTED:Parameter header: SCCR Map for xSPI Profile 2.0 Memory Devices");
 | 
			
		||||
                break;
 | 
			
		||||
            case 0x0A:
 | 
			
		||||
                tr_info("UNSUPPORTED:Parameter header: Command Sequences to Change to Octal DDR (8D-8D-8D) mode");
 | 
			
		||||
                break;
 | 
			
		||||
            case 0x0C:
 | 
			
		||||
                tr_info("UNSUPPORTED:Parameter header: x4 Quad IO with DS");
 | 
			
		||||
                break;
 | 
			
		||||
            case 0x8D:
 | 
			
		||||
                tr_info("UNSUPPORTED:Parameter header: Command Sequences to Change to Quad DDR (4S-4D-4D) mode");
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                tr_debug("Parameter header: unknown JEDEC header. Parameter ID LSB: 0x%" PRIX8 "; MSB: 0x%" PRIX8 "",
 | 
			
		||||
                         phdr_ptr->PID_LSB,
 | 
			
		||||
                         sfdp_get_param_id_msb(phdr_ptr->DWORD2));
 | 
			
		||||
        }
 | 
			
		||||
    } else if (param_id_msb >= 0x80) { // MSB JEDEC ID
 | 
			
		||||
        tr_debug("Parameter header: unknown JEDEC header. Parameter ID LSB: 0x%" PRIX8 "; MSB: 0x%" PRIX8 "",
 | 
			
		||||
                 phdr_ptr->PID_LSB,
 | 
			
		||||
                 sfdp_get_param_id_msb(phdr_ptr->DWORD2));
 | 
			
		||||
    } else { // MSB Vendor ID
 | 
			
		||||
        tr_info("Parameter header: vendor specific header. Parameter ID LSB: 0x%" PRIX8 "; MSB: 0x%" PRIX8 "",
 | 
			
		||||
                phdr_ptr->PID_LSB,
 | 
			
		||||
                sfdp_get_param_id_msb(phdr_ptr->DWORD2));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -157,10 +210,10 @@ int sfdp_parse_headers(Callback<int(bd_addr_t, void *, bd_size_t)> sfdp_reader,
 | 
			
		|||
        int hdr_status;
 | 
			
		||||
 | 
			
		||||
        // Loop over Param Headers and parse them (currently supports Basic Param Table and Sector Region Map Table)
 | 
			
		||||
        for (int i_ind = 0; i_ind < number_of_param_headers; i_ind++) {
 | 
			
		||||
        for (int idx = 0; idx < number_of_param_headers; idx++) {
 | 
			
		||||
            status = sfdp_reader(addr, param_header, data_length);
 | 
			
		||||
            if (status < 0) {
 | 
			
		||||
                tr_error("Retrieving a parameter header %d failed", i_ind + 1);
 | 
			
		||||
                tr_error("Retrieving a parameter header %d failed", idx + 1);
 | 
			
		||||
                return -1;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -178,9 +231,8 @@ int sfdp_parse_headers(Callback<int(bd_addr_t, void *, bd_size_t)> sfdp_reader,
 | 
			
		|||
 | 
			
		||||
int sfdp_parse_sector_map_table(Callback<int(bd_addr_t, void *, bd_size_t)> sfdp_reader, sfdp_hdr_info &sfdp_info)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t sector_map_table[SFDP_BASIC_PARAMS_TBL_SIZE]; /* Up To 20 DWORDS = 80 Bytes */
 | 
			
		||||
    uint32_t tmp_region_size = 0;
 | 
			
		||||
    int i_ind = 0;
 | 
			
		||||
    uint8_t type_mask;
 | 
			
		||||
    int prev_boundary = 0;
 | 
			
		||||
    // Default set to all type bits 1-4 are common
 | 
			
		||||
    int min_common_erase_type_bits = SFDP_ERASE_BITMASK_ALL;
 | 
			
		||||
| 
						 | 
				
			
			@ -191,25 +243,36 @@ int sfdp_parse_sector_map_table(Callback<int(bd_addr_t, void *, bd_size_t)> sfdp
 | 
			
		|||
 | 
			
		||||
    if (!sfdp_info.smptbl.addr || !sfdp_info.smptbl.size) {
 | 
			
		||||
        tr_debug("No Sector Map Table");
 | 
			
		||||
        return 0;
 | 
			
		||||
        return MBED_SUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* The number of
 | 
			
		||||
     * - sector map configuration detection commands
 | 
			
		||||
     * - configurations
 | 
			
		||||
     * - regions in each configuration
 | 
			
		||||
     *  is variable -> the size of this table is variable
 | 
			
		||||
     */
 | 
			
		||||
    auto smptbl_buff = std::make_unique<uint8_t[]>(sfdp_info.smptbl.size);
 | 
			
		||||
    if (!smptbl_buff) {
 | 
			
		||||
        tr_error("Failed to allocate memory");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    tr_debug("Parsing Sector Map Table - addr: 0x%" PRIx32 ", Size: %d", sfdp_info.smptbl.addr, sfdp_info.smptbl.size);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    int status = sfdp_reader(sfdp_info.smptbl.addr, sector_map_table, sfdp_info.smptbl.size);
 | 
			
		||||
    int status = sfdp_reader(sfdp_info.smptbl.addr, smptbl_buff.get(), sfdp_info.smptbl.size);
 | 
			
		||||
    if (status < 0) {
 | 
			
		||||
        tr_error("Sector Map: Table retrieval failed");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Currently we support only Single Map Descriptor
 | 
			
		||||
    if (!((sector_map_table[0] & 0x3) == 0x03) && (sector_map_table[1] == 0x0)) {
 | 
			
		||||
    if (!((smptbl_buff[0] & 0x3) == 0x03) && (smptbl_buff[1] == 0x0)) {
 | 
			
		||||
        tr_error("Sector Map: Supporting Only Single Map Descriptor (not map commands)");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sfdp_info.smptbl.region_cnt = sector_map_table[2] + 1;
 | 
			
		||||
    sfdp_info.smptbl.region_cnt = smptbl_buff[2] + 1;
 | 
			
		||||
    if (sfdp_info.smptbl.region_cnt > SFDP_SECTOR_MAP_MAX_REGIONS) {
 | 
			
		||||
        tr_error("Sector Map: Supporting up to %d regions, current setup to %d regions - fail",
 | 
			
		||||
                 SFDP_SECTOR_MAP_MAX_REGIONS,
 | 
			
		||||
| 
						 | 
				
			
			@ -219,34 +282,31 @@ int sfdp_parse_sector_map_table(Callback<int(bd_addr_t, void *, bd_size_t)> sfdp
 | 
			
		|||
 | 
			
		||||
    // Loop through Regions and set for each one: size, supported erase types, high boundary offset
 | 
			
		||||
    // Calculate minimum Common Erase Type for all Regions
 | 
			
		||||
    for (i_ind = 0; i_ind < sfdp_info.smptbl.region_cnt; i_ind++) {
 | 
			
		||||
        tmp_region_size = ((*((uint32_t *)§or_map_table[(i_ind + 1) * 4])) >> 8) & 0x00FFFFFF; // bits 9-32
 | 
			
		||||
        sfdp_info.smptbl.region_size[i_ind] = (tmp_region_size + 1) * 256; // Region size is 0 based multiple of 256 bytes;
 | 
			
		||||
    for (auto idx = 0; idx < sfdp_info.smptbl.region_cnt; idx++) {
 | 
			
		||||
        tmp_region_size = ((*((uint32_t *)&smptbl_buff[(idx + 1) * 4])) >> 8) & 0x00FFFFFF; // bits 9-32
 | 
			
		||||
        sfdp_info.smptbl.region_size[idx] = (tmp_region_size + 1) * 256; // Region size is 0 based multiple of 256 bytes;
 | 
			
		||||
 | 
			
		||||
        sfdp_info.smptbl.region_erase_types_bitfld[i_ind] = sector_map_table[(i_ind + 1) * 4] & 0x0F; // bits 1-4
 | 
			
		||||
        sfdp_info.smptbl.region_erase_types_bitfld[idx] = smptbl_buff[(idx + 1) * 4] & 0x0F; // bits 1-4
 | 
			
		||||
 | 
			
		||||
        min_common_erase_type_bits &= sfdp_info.smptbl.region_erase_types_bitfld[i_ind];
 | 
			
		||||
        min_common_erase_type_bits &= sfdp_info.smptbl.region_erase_types_bitfld[idx];
 | 
			
		||||
 | 
			
		||||
        sfdp_info.smptbl.region_high_boundary[i_ind] = (sfdp_info.smptbl.region_size[i_ind] - 1) + prev_boundary;
 | 
			
		||||
        sfdp_info.smptbl.region_high_boundary[idx] = (sfdp_info.smptbl.region_size[idx] - 1) + prev_boundary;
 | 
			
		||||
 | 
			
		||||
        prev_boundary = sfdp_info.smptbl.region_high_boundary[i_ind] + 1;
 | 
			
		||||
        prev_boundary = sfdp_info.smptbl.region_high_boundary[idx] + 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Calc minimum Common Erase Size from min_common_erase_type_bits
 | 
			
		||||
    uint8_t type_mask = SFDP_ERASE_BITMASK_TYPE1;
 | 
			
		||||
    for (i_ind = 0; i_ind < 4; i_ind++) {
 | 
			
		||||
    type_mask = SFDP_ERASE_BITMASK_TYPE1;
 | 
			
		||||
    // If no common erase type is found between regions
 | 
			
		||||
    sfdp_info.smptbl.regions_min_common_erase_size = 0;
 | 
			
		||||
    for (auto idx = 0; idx < 4; idx++) {
 | 
			
		||||
        if (min_common_erase_type_bits & type_mask) {
 | 
			
		||||
            sfdp_info.smptbl.regions_min_common_erase_size = sfdp_info.smptbl.erase_type_size_arr[i_ind];
 | 
			
		||||
            sfdp_info.smptbl.regions_min_common_erase_size = sfdp_info.smptbl.erase_type_size_arr[idx];
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        type_mask = type_mask << 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (i_ind == 4) {
 | 
			
		||||
        // No common erase type was found between regions
 | 
			
		||||
        sfdp_info.smptbl.regions_min_common_erase_size = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -275,27 +335,27 @@ int sfdp_detect_erase_types_inst_and_size(uint8_t *bptbl_ptr, sfdp_hdr_info &sfd
 | 
			
		|||
    // Erase 4K Inst is taken either from param table legacy 4K erase or superseded by erase Instruction for type of size 4K
 | 
			
		||||
    if (sfdp_info.bptbl.size > SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE) {
 | 
			
		||||
        // Loop Erase Types 1-4
 | 
			
		||||
        for (int i_ind = 0; i_ind < 4; i_ind++) {
 | 
			
		||||
            sfdp_info.smptbl.erase_type_inst_arr[i_ind] = -1; // Default for unsupported type
 | 
			
		||||
            sfdp_info.smptbl.erase_type_size_arr[i_ind] = 1
 | 
			
		||||
                                                          << bptbl_ptr[SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE + 2 * i_ind]; // Size is 2^N where N is the table value
 | 
			
		||||
            tr_debug("Erase Type(A) %d - Inst: 0x%xh, Size: %d", (i_ind + 1), sfdp_info.smptbl.erase_type_inst_arr[i_ind],
 | 
			
		||||
                     sfdp_info.smptbl.erase_type_size_arr[i_ind]);
 | 
			
		||||
            if (sfdp_info.smptbl.erase_type_size_arr[i_ind] > 1) {
 | 
			
		||||
        for (int idx = 0; idx < 4; idx++) {
 | 
			
		||||
            sfdp_info.smptbl.erase_type_inst_arr[idx] = -1; // Default for unsupported type
 | 
			
		||||
            sfdp_info.smptbl.erase_type_size_arr[idx] = 1
 | 
			
		||||
                                                        << bptbl_ptr[SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_SIZE_BYTE + 2 * idx]; // Size is 2^N where N is the table value
 | 
			
		||||
            tr_debug("Erase Type(A) %d - Inst: 0x%xh, Size: %d", (idx + 1), sfdp_info.smptbl.erase_type_inst_arr[idx],
 | 
			
		||||
                     sfdp_info.smptbl.erase_type_size_arr[idx]);
 | 
			
		||||
            if (sfdp_info.smptbl.erase_type_size_arr[idx] > 1) {
 | 
			
		||||
                // if size==1 type is not supported
 | 
			
		||||
                sfdp_info.smptbl.erase_type_inst_arr[i_ind] = bptbl_ptr[SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_BYTE
 | 
			
		||||
                                                                        + 2 * i_ind];
 | 
			
		||||
                sfdp_info.smptbl.erase_type_inst_arr[idx] = bptbl_ptr[SFDP_BASIC_PARAM_TABLE_ERASE_TYPE_1_BYTE
 | 
			
		||||
                                                                      + 2 * idx];
 | 
			
		||||
 | 
			
		||||
                if ((sfdp_info.smptbl.erase_type_size_arr[i_ind] < sfdp_info.smptbl.regions_min_common_erase_size)
 | 
			
		||||
                if ((sfdp_info.smptbl.erase_type_size_arr[idx] < sfdp_info.smptbl.regions_min_common_erase_size)
 | 
			
		||||
                        || (sfdp_info.smptbl.regions_min_common_erase_size == 0)) {
 | 
			
		||||
                    //Set default minimal common erase for signal region
 | 
			
		||||
                    sfdp_info.smptbl.regions_min_common_erase_size = sfdp_info.smptbl.erase_type_size_arr[i_ind];
 | 
			
		||||
                    sfdp_info.smptbl.regions_min_common_erase_size = sfdp_info.smptbl.erase_type_size_arr[idx];
 | 
			
		||||
                }
 | 
			
		||||
                sfdp_info.smptbl.region_erase_types_bitfld[0] |= bitfield; // If there's no region map, set region "0" types bitfield as default
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            tr_debug("Erase Type %d - Inst: 0x%xh, Size: %d", (i_ind + 1), sfdp_info.smptbl.erase_type_inst_arr[i_ind],
 | 
			
		||||
                     sfdp_info.smptbl.erase_type_size_arr[i_ind]);
 | 
			
		||||
            tr_debug("Erase Type %d - Inst: 0x%xh, Size: %d", (idx + 1), sfdp_info.smptbl.erase_type_inst_arr[idx],
 | 
			
		||||
                     sfdp_info.smptbl.erase_type_size_arr[idx]);
 | 
			
		||||
            bitfield = bitfield << 1;
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
| 
						 | 
				
			
			@ -321,10 +381,10 @@ int sfdp_find_addr_region(bd_size_t offset, const sfdp_hdr_info &sfdp_info)
 | 
			
		|||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (int i_ind = sfdp_info.smptbl.region_cnt - 2; i_ind >= 0; i_ind--) {
 | 
			
		||||
    for (int idx = sfdp_info.smptbl.region_cnt - 2; idx >= 0; idx--) {
 | 
			
		||||
 | 
			
		||||
        if (offset > sfdp_info.smptbl.region_high_boundary[i_ind]) {
 | 
			
		||||
            return (i_ind + 1);
 | 
			
		||||
        if (offset > sfdp_info.smptbl.region_high_boundary[idx]) {
 | 
			
		||||
            return (idx + 1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return -1;
 | 
			
		||||
| 
						 | 
				
			
			@ -338,11 +398,12 @@ int sfdp_iterate_next_largest_erase_type(uint8_t &bitfield,
 | 
			
		|||
                                         const sfdp_smptbl_info &smptbl)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t type_mask = SFDP_ERASE_BITMASK_TYPE4;
 | 
			
		||||
    int i_ind = 0;
 | 
			
		||||
    int largest_erase_type = 0;
 | 
			
		||||
    for (i_ind = 3; i_ind >= 0; i_ind--) {
 | 
			
		||||
 | 
			
		||||
    int idx;
 | 
			
		||||
    for (idx = 3; idx >= 0; idx--) {
 | 
			
		||||
        if (bitfield & type_mask) {
 | 
			
		||||
            largest_erase_type = i_ind;
 | 
			
		||||
            largest_erase_type = idx;
 | 
			
		||||
            if ((size > (int)(smptbl.erase_type_size_arr[largest_erase_type])) &&
 | 
			
		||||
                    ((smptbl.region_high_boundary[region] - offset)
 | 
			
		||||
                     > (int)(smptbl.erase_type_size_arr[largest_erase_type]))) {
 | 
			
		||||
| 
						 | 
				
			
			@ -354,7 +415,7 @@ int sfdp_iterate_next_largest_erase_type(uint8_t &bitfield,
 | 
			
		|||
        type_mask = type_mask >> 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (i_ind == 4) {
 | 
			
		||||
    if (idx == -1) {
 | 
			
		||||
        tr_error("No erase type was found for current region addr");
 | 
			
		||||
    }
 | 
			
		||||
    return largest_erase_type;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue