mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			SFDP: splits header parsing to its own file
SFDP logic is the same between SPIF and QSIP.pull/12270/head
							parent
							
								
									ad43f23b09
								
							
						
					
					
						commit
						cefae9020e
					
				| 
						 | 
				
			
			@ -14,6 +14,7 @@
 | 
			
		|||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "drivers/internal/SFDP.h"
 | 
			
		||||
#include "QSPIFBlockDevice.h"
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "rtos/ThisThread.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -204,10 +205,8 @@ int QSPIFBlockDevice::init()
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    int status = QSPIF_BD_ERROR_OK;
 | 
			
		||||
    uint32_t basic_table_addr = 0;
 | 
			
		||||
    size_t basic_table_size = 0;
 | 
			
		||||
    uint32_t sector_map_table_addr = 0;
 | 
			
		||||
    size_t sector_map_table_size = 0;
 | 
			
		||||
    sfdp_hdr_info hdr_info;
 | 
			
		||||
    memset(&hdr_info, 0, sizeof hdr_info);
 | 
			
		||||
 | 
			
		||||
    _mutex.lock();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -251,14 +250,14 @@ int QSPIFBlockDevice::init()
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    /**************************** Parse SFDP Header ***********************************/
 | 
			
		||||
    if (0 != _sfdp_parse_sfdp_headers(basic_table_addr, basic_table_size, sector_map_table_addr, sector_map_table_size)) {
 | 
			
		||||
    if (0 != _sfdp_parse_sfdp_headers(hdr_info)) {
 | 
			
		||||
        tr_error("Init - Parse SFDP Headers Failed");
 | 
			
		||||
        status = QSPIF_BD_ERROR_PARSING_FAILED;
 | 
			
		||||
        goto exit_point;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**************************** Parse Basic Parameters Table ***********************************/
 | 
			
		||||
    if (0 != _sfdp_parse_basic_param_table(basic_table_addr, basic_table_size)) {
 | 
			
		||||
    if (0 != _sfdp_parse_basic_param_table(hdr_info.basic_table_addr, hdr_info.basic_table_size)) {
 | 
			
		||||
        tr_error("Init - Parse Basic Param Table Failed");
 | 
			
		||||
        status = QSPIF_BD_ERROR_PARSING_FAILED;
 | 
			
		||||
        goto exit_point;
 | 
			
		||||
| 
						 | 
				
			
			@ -269,10 +268,10 @@ int QSPIFBlockDevice::init()
 | 
			
		|||
        _device_size_bytes; // If there's no region map, we have a single region sized the entire device size
 | 
			
		||||
    _region_high_boundary[0] = _device_size_bytes - 1;
 | 
			
		||||
 | 
			
		||||
    if ((sector_map_table_addr != 0) && (0 != sector_map_table_size)) {
 | 
			
		||||
        tr_debug("Init - Parsing Sector Map Table - addr: 0x%lxh, Size: %d", sector_map_table_addr,
 | 
			
		||||
                 sector_map_table_size);
 | 
			
		||||
        if (0 != _sfdp_parse_sector_map_table(sector_map_table_addr, sector_map_table_size)) {
 | 
			
		||||
    if ((hdr_info.sector_map_table_addr != 0) && (0 != hdr_info.sector_map_table_size)) {
 | 
			
		||||
        tr_debug("Init - Parsing Sector Map Table - addr: 0x%lxh, Size: %d", hdr_info.sector_map_table_addr,
 | 
			
		||||
                 hdr_info.sector_map_table_size);
 | 
			
		||||
        if (0 != _sfdp_parse_sector_map_table(hdr_info.sector_map_table_addr, hdr_info.sector_map_table_size)) {
 | 
			
		||||
            tr_error("Init - Parse Sector Map Table Failed");
 | 
			
		||||
            status = QSPIF_BD_ERROR_PARSING_FAILED;
 | 
			
		||||
            goto exit_point;
 | 
			
		||||
| 
						 | 
				
			
			@ -629,65 +628,51 @@ int QSPIFBlockDevice::remove_csel_instance(PinName csel)
 | 
			
		|||
/*********************************************************/
 | 
			
		||||
/********** SFDP Parsing and Detection Functions *********/
 | 
			
		||||
/*********************************************************/
 | 
			
		||||
int QSPIFBlockDevice::_sfdp_parse_sfdp_headers(uint32_t &basic_table_addr, size_t &basic_table_size,
 | 
			
		||||
                                               uint32_t §or_map_table_addr, size_t §or_map_table_size)
 | 
			
		||||
int QSPIFBlockDevice::_sfdp_parse_sfdp_headers(mbed::sfdp_hdr_info &hdr_info)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t sfdp_header[QSPIF_SFDP_HEADER_SIZE];
 | 
			
		||||
    uint8_t param_header[QSPIF_PARAM_HEADER_SIZE];
 | 
			
		||||
    size_t data_length = QSPIF_SFDP_HEADER_SIZE;
 | 
			
		||||
    bd_addr_t addr = 0x0;
 | 
			
		||||
    int number_of_param_headers = 0;
 | 
			
		||||
    size_t data_length;
 | 
			
		||||
 | 
			
		||||
    qspi_status_t status = _qspi_send_read_sfdp_command(addr, (char *) sfdp_header, data_length);
 | 
			
		||||
    if (status != QSPI_STATUS_OK) {
 | 
			
		||||
        tr_error("Init - Read SFDP Failed");
 | 
			
		||||
        return -1;
 | 
			
		||||
    {
 | 
			
		||||
        data_length = QSPIF_SFDP_HEADER_SIZE;
 | 
			
		||||
        uint8_t sfdp_header[QSPIF_SFDP_HEADER_SIZE];
 | 
			
		||||
 | 
			
		||||
        qspi_status_t status = _qspi_send_read_sfdp_command(addr, (char *)sfdp_header, data_length);
 | 
			
		||||
        if (status != QSPI_STATUS_OK) {
 | 
			
		||||
            tr_error("init - Retrieving SFDP Header failed");
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        number_of_param_headers = sfdp_parse_sfdp_header((sfdp_hdr *)sfdp_header);
 | 
			
		||||
        if (number_of_param_headers < 0) {
 | 
			
		||||
            return number_of_param_headers;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Verify SFDP signature for sanity
 | 
			
		||||
    // Also check that major/minor version is acceptable
 | 
			
		||||
    if (!(memcmp(&sfdp_header[0], "SFDP", 4) == 0 && sfdp_header[5] == 1)) {
 | 
			
		||||
        tr_error("Init - Verification of SFDP signature and version failed");
 | 
			
		||||
        return -1;
 | 
			
		||||
    } else {
 | 
			
		||||
        tr_debug("Init - Verification of SFDP signature and version succeeded");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Discover Number of Parameter Headers
 | 
			
		||||
    int number_of_param_headers = (int)(sfdp_header[6]) + 1;
 | 
			
		||||
    tr_debug("Number of Param Headers: %d", number_of_param_headers);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    addr += QSPIF_SFDP_HEADER_SIZE;
 | 
			
		||||
    data_length = QSPIF_PARAM_HEADER_SIZE;
 | 
			
		||||
 | 
			
		||||
    // 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++) {
 | 
			
		||||
        status = _qspi_send_read_sfdp_command(addr, (char *) param_header, data_length);
 | 
			
		||||
        if (status != QSPI_STATUS_OK) {
 | 
			
		||||
            tr_error("Init - Read Param Table %d Failed", i_ind + 1);
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
    {
 | 
			
		||||
        data_length = QSPIF_PARAM_HEADER_SIZE;
 | 
			
		||||
        uint8_t param_header[QSPIF_PARAM_HEADER_SIZE];
 | 
			
		||||
        qspi_status_t status;
 | 
			
		||||
        int hdr_status;
 | 
			
		||||
 | 
			
		||||
        // The SFDP spec indicates the standard table is always at offset 0
 | 
			
		||||
        // in the parameter headers, we check just to be safe
 | 
			
		||||
        if (param_header[2] != 1) {
 | 
			
		||||
            tr_error("Param Table %d - Major Version should be 1!", i_ind + 1);
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
        // 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++) {
 | 
			
		||||
            status = _qspi_send_read_sfdp_command(addr, (char *)param_header, data_length);
 | 
			
		||||
            if (status != QSPI_STATUS_OK) {
 | 
			
		||||
                tr_error("init - Retrieving Parameter Header %d failed", i_ind + 1);
 | 
			
		||||
                return -1;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        if ((param_header[0] == 0) && (param_header[7] == 0xFF)) {
 | 
			
		||||
            tr_debug("Parameter Header %d: Basic Parameter Header", i_ind);
 | 
			
		||||
            basic_table_addr = ((param_header[6] << 16) | (param_header[5] << 8) | (param_header[4]));
 | 
			
		||||
            // Supporting up to 64 Bytes Table (16 DWORDS)
 | 
			
		||||
            basic_table_size = ((param_header[3] * 4) < SFDP_DEFAULT_BASIC_PARAMS_TABLE_SIZE_BYTES) ? (param_header[3] * 4) : 64;
 | 
			
		||||
        } else if ((param_header[0] == 0x81) && (param_header[7] == 0xFF)) {
 | 
			
		||||
            tr_debug("Parameter Header %d: Sector Map Parameter Header", i_ind);
 | 
			
		||||
            sector_map_table_addr = ((param_header[6] << 16) | (param_header[5] << 8) | (param_header[4]));
 | 
			
		||||
            sector_map_table_size = param_header[3] * 4;
 | 
			
		||||
        } else {
 | 
			
		||||
            tr_debug("Parameter Header %d: Vendor specific or unknown header", i_ind);
 | 
			
		||||
            hdr_status = sfdp_parse_single_param_header((sfdp_prm_hdr *)param_header, hdr_info);
 | 
			
		||||
            if (hdr_status < 0) {
 | 
			
		||||
                return hdr_status;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            addr += QSPIF_PARAM_HEADER_SIZE;
 | 
			
		||||
        }
 | 
			
		||||
        addr += QSPIF_PARAM_HEADER_SIZE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,6 +17,7 @@
 | 
			
		|||
#define MBED_QSPIF_BLOCK_DEVICE_H
 | 
			
		||||
 | 
			
		||||
#include "drivers/QSPI.h"
 | 
			
		||||
#include "drivers/internal/SFDP.h"
 | 
			
		||||
#include "features/storage/blockdevice/BlockDevice.h"
 | 
			
		||||
 | 
			
		||||
#ifndef MBED_CONF_QSPIF_QSPI_IO0
 | 
			
		||||
| 
						 | 
				
			
			@ -312,8 +313,7 @@ private:
 | 
			
		|||
    /* SFDP Detection and Parsing Functions */
 | 
			
		||||
    /****************************************/
 | 
			
		||||
    // Parse SFDP Headers and retrieve Basic Param and Sector Map Tables (if exist)
 | 
			
		||||
    int _sfdp_parse_sfdp_headers(uint32_t &basic_table_addr, size_t &basic_table_size,
 | 
			
		||||
                                 uint32_t §or_map_table_addr, size_t §or_map_table_size);
 | 
			
		||||
    int _sfdp_parse_sfdp_headers(mbed::sfdp_hdr_info &hdr_info);
 | 
			
		||||
 | 
			
		||||
    // Parse and Detect required Basic Parameters from Table
 | 
			
		||||
    int _sfdp_parse_basic_param_table(uint32_t basic_table_addr, size_t basic_table_size);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,6 +14,7 @@
 | 
			
		|||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "drivers/internal/SFDP.h"
 | 
			
		||||
#include "SPIFBlockDevice.h"
 | 
			
		||||
#include "rtos/ThisThread.h"
 | 
			
		||||
#include "mbed_critical.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -133,12 +134,11 @@ int SPIFBlockDevice::init()
 | 
			
		|||
    uint8_t vendor_device_ids[4];
 | 
			
		||||
    size_t data_length = 3;
 | 
			
		||||
    int status = SPIF_BD_ERROR_OK;
 | 
			
		||||
    uint32_t basic_table_addr = 0;
 | 
			
		||||
    size_t basic_table_size = 0;
 | 
			
		||||
    uint32_t sector_map_table_addr = 0;
 | 
			
		||||
    size_t sector_map_table_size = 0;
 | 
			
		||||
    struct sfdp_hdr_info hdr_info;
 | 
			
		||||
    spif_bd_error spi_status = SPIF_BD_ERROR_OK;
 | 
			
		||||
 | 
			
		||||
    memset(&hdr_info, 0, sizeof hdr_info);
 | 
			
		||||
 | 
			
		||||
    _mutex->lock();
 | 
			
		||||
 | 
			
		||||
    if (!_is_initialized) {
 | 
			
		||||
| 
						 | 
				
			
			@ -186,7 +186,7 @@ int SPIFBlockDevice::init()
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    /**************************** Parse SFDP Header ***********************************/
 | 
			
		||||
    if (0 != _sfdp_parse_sfdp_headers(basic_table_addr, basic_table_size, sector_map_table_addr, sector_map_table_size)) {
 | 
			
		||||
    if (0 != _sfdp_parse_sfdp_headers(hdr_info)) {
 | 
			
		||||
        tr_error("init - Parse SFDP Headers Failed");
 | 
			
		||||
        status = SPIF_BD_ERROR_PARSING_FAILED;
 | 
			
		||||
        goto exit_point;
 | 
			
		||||
| 
						 | 
				
			
			@ -194,7 +194,7 @@ int SPIFBlockDevice::init()
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
    /**************************** Parse Basic Parameters Table ***********************************/
 | 
			
		||||
    if (0 != _sfdp_parse_basic_param_table(basic_table_addr, basic_table_size)) {
 | 
			
		||||
    if (0 != _sfdp_parse_basic_param_table(hdr_info.basic_table_addr, hdr_info.basic_table_size)) {
 | 
			
		||||
        tr_error("init - Parse Basic Param Table Failed");
 | 
			
		||||
        status = SPIF_BD_ERROR_PARSING_FAILED;
 | 
			
		||||
        goto exit_point;
 | 
			
		||||
| 
						 | 
				
			
			@ -205,10 +205,10 @@ int SPIFBlockDevice::init()
 | 
			
		|||
        _device_size_bytes; // If there's no region map, we have a single region sized the entire device size
 | 
			
		||||
    _region_high_boundary[0] = _device_size_bytes - 1;
 | 
			
		||||
 | 
			
		||||
    if ((sector_map_table_addr != 0) && (0 != sector_map_table_size)) {
 | 
			
		||||
        tr_debug("init - Parsing Sector Map Table - addr: 0x%" PRIx32 "h, Size: %d", sector_map_table_addr,
 | 
			
		||||
                 sector_map_table_size);
 | 
			
		||||
        if (0 != _sfdp_parse_sector_map_table(sector_map_table_addr, sector_map_table_size)) {
 | 
			
		||||
    if ((hdr_info.sector_map_table_addr != 0) && (0 != hdr_info.sector_map_table_size)) {
 | 
			
		||||
        tr_debug("init - Parsing Sector Map Table - addr: 0x%" PRIx32 "h, Size: %d", hdr_info.sector_map_table_addr,
 | 
			
		||||
                 hdr_info.sector_map_table_size);
 | 
			
		||||
        if (0 != _sfdp_parse_sector_map_table(hdr_info.sector_map_table_addr, hdr_info.sector_map_table_size)) {
 | 
			
		||||
            tr_error("init - Parse Sector Map Table Failed");
 | 
			
		||||
            status = SPIF_BD_ERROR_PARSING_FAILED;
 | 
			
		||||
            goto exit_point;
 | 
			
		||||
| 
						 | 
				
			
			@ -719,73 +719,57 @@ int SPIFBlockDevice::_sfdp_parse_basic_param_table(uint32_t basic_table_addr, si
 | 
			
		|||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int SPIFBlockDevice::_sfdp_parse_sfdp_headers(uint32_t &basic_table_addr, size_t &basic_table_size,
 | 
			
		||||
                                              uint32_t §or_map_table_addr, size_t §or_map_table_size)
 | 
			
		||||
int SPIFBlockDevice::_sfdp_parse_sfdp_headers(sfdp_hdr_info &hdr_info)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t sfdp_header[16];
 | 
			
		||||
    uint8_t param_header[SPIF_SFDP_HEADER_SIZE];
 | 
			
		||||
    size_t data_length = SPIF_SFDP_HEADER_SIZE;
 | 
			
		||||
    bd_addr_t addr = 0x0;
 | 
			
		||||
    int number_of_param_headers = 0;
 | 
			
		||||
    size_t data_length;
 | 
			
		||||
 | 
			
		||||
    // Set 1-1-1 bus mode for SFDP header parsing
 | 
			
		||||
    // Initial SFDP read tables are read with 8 dummy cycles
 | 
			
		||||
    _read_dummy_and_mode_cycles = 8;
 | 
			
		||||
    _dummy_and_mode_cycles = 8;
 | 
			
		||||
    {
 | 
			
		||||
        data_length = SPIF_SFDP_HEADER_SIZE;
 | 
			
		||||
        uint8_t sfdp_header[SPIF_SFDP_HEADER_SIZE];
 | 
			
		||||
 | 
			
		||||
    spif_bd_error status = _spi_send_read_command(SPIF_SFDP, sfdp_header, addr /*address*/, data_length);
 | 
			
		||||
    if (status != SPIF_BD_ERROR_OK) {
 | 
			
		||||
        tr_error("init - Read SFDP Failed");
 | 
			
		||||
        return -1;
 | 
			
		||||
        // Set 1-1-1 bus mode for SFDP header parsing
 | 
			
		||||
        // Initial SFDP read tables are read with 8 dummy cycles
 | 
			
		||||
        _read_dummy_and_mode_cycles = 8;
 | 
			
		||||
        _dummy_and_mode_cycles = 8;
 | 
			
		||||
 | 
			
		||||
        spif_bd_error status = _spi_send_read_command(SPIF_SFDP, sfdp_header, addr /*address*/, data_length);
 | 
			
		||||
        if (status != SPIF_BD_ERROR_OK) {
 | 
			
		||||
            tr_error("init - Read SFDP Failed");
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        number_of_param_headers = sfdp_parse_sfdp_header((sfdp_hdr *)sfdp_header);
 | 
			
		||||
        if (number_of_param_headers < 0) {
 | 
			
		||||
            return number_of_param_headers;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Verify SFDP signature for sanity
 | 
			
		||||
    // Also check that major/minor version is acceptable
 | 
			
		||||
    if (!(memcmp(&sfdp_header[0], "SFDP", 4) == 0 && sfdp_header[5] == 1)) {
 | 
			
		||||
        tr_error("init - _verify SFDP signature and version Failed");
 | 
			
		||||
        return -1;
 | 
			
		||||
    } else {
 | 
			
		||||
        tr_debug("init - verified SFDP Signature and version Successfully");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Discover Number of Parameter Headers
 | 
			
		||||
    int number_of_param_headers = (int)(sfdp_header[6]) + 1;
 | 
			
		||||
    tr_debug("number of Param Headers: %d", number_of_param_headers);
 | 
			
		||||
 | 
			
		||||
    addr += SPIF_SFDP_HEADER_SIZE;
 | 
			
		||||
    data_length = SPIF_PARAM_HEADER_SIZE;
 | 
			
		||||
 | 
			
		||||
    // Loop over Param Headers and parse them (currently supported Basic Param Table and Sector Region Map Table)
 | 
			
		||||
    for (int i_ind = 0; i_ind < number_of_param_headers; i_ind++) {
 | 
			
		||||
    {
 | 
			
		||||
        data_length = SPIF_PARAM_HEADER_SIZE;
 | 
			
		||||
        uint8_t param_header[SPIF_SFDP_HEADER_SIZE];
 | 
			
		||||
        spif_bd_error status;
 | 
			
		||||
        int hdr_status;
 | 
			
		||||
 | 
			
		||||
        status = _spi_send_read_command(SPIF_SFDP, param_header, addr, data_length);
 | 
			
		||||
        if (status != SPIF_BD_ERROR_OK) {
 | 
			
		||||
            tr_error("init - Read Param Table %d Failed", i_ind + 1);
 | 
			
		||||
            return -1;
 | 
			
		||||
        // Loop over Param Headers and parse them (currently supported Basic Param Table and Sector Region Map Table)
 | 
			
		||||
        for (int i_ind = 0; i_ind < number_of_param_headers; i_ind++) {
 | 
			
		||||
 | 
			
		||||
            status = _spi_send_read_command(SPIF_SFDP, param_header, addr, data_length);
 | 
			
		||||
            if (status != SPIF_BD_ERROR_OK) {
 | 
			
		||||
                tr_error("init - Read Param Table %d Failed", i_ind + 1);
 | 
			
		||||
                return -1;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            hdr_status = sfdp_parse_single_param_header((sfdp_prm_hdr *)param_header, hdr_info);
 | 
			
		||||
            if (hdr_status < 0) {
 | 
			
		||||
                return hdr_status;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            addr += SPIF_PARAM_HEADER_SIZE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // The SFDP spec indicates the standard table is always at offset 0
 | 
			
		||||
        // in the parameter headers, we check just to be safe
 | 
			
		||||
        if (param_header[2] != 1) {
 | 
			
		||||
            tr_error("Param Table %d - Major Version should be 1!", i_ind + 1);
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ((param_header[0] == 0) && (param_header[7] == 0xFF)) {
 | 
			
		||||
            tr_debug("Parameter Header %d: Basic Parameter Header", i_ind);
 | 
			
		||||
            basic_table_addr = ((param_header[6] << 16) | (param_header[5] << 8) | (param_header[4]));
 | 
			
		||||
            // Supporting up to 64 Bytes Table (16 DWORDS)
 | 
			
		||||
            basic_table_size = ((param_header[3] * 4) < SFDP_DEFAULT_BASIC_PARAMS_TABLE_SIZE_BYTES) ? (param_header[3] * 4) : 64;
 | 
			
		||||
 | 
			
		||||
        } else if ((param_header[0] == 0x81) && (param_header[7] == 0xFF)) {
 | 
			
		||||
            tr_debug("Parameter Header %d: Sector Map Parameter Header", i_ind);
 | 
			
		||||
            sector_map_table_addr = ((param_header[6] << 16) | (param_header[5] << 8) | (param_header[4]));
 | 
			
		||||
            sector_map_table_size = param_header[3] * 4;
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
            tr_debug("Parameter Header %d: Vendor specific or unknown header", i_ind);
 | 
			
		||||
        }
 | 
			
		||||
        addr += SPIF_PARAM_HEADER_SIZE;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,6 +19,7 @@
 | 
			
		|||
#include "platform/SingletonPtr.h"
 | 
			
		||||
#include "drivers/SPI.h"
 | 
			
		||||
#include "drivers/DigitalOut.h"
 | 
			
		||||
#include "drivers/internal/SFDP.h"
 | 
			
		||||
#include "features/storage/blockdevice/BlockDevice.h"
 | 
			
		||||
 | 
			
		||||
#ifndef MBED_CONF_SPIF_DRIVER_SPI_MOSI
 | 
			
		||||
| 
						 | 
				
			
			@ -225,8 +226,7 @@ private:
 | 
			
		|||
    /* SFDP Detection and Parsing Functions */
 | 
			
		||||
    /****************************************/
 | 
			
		||||
    // Parse SFDP Headers and retrieve Basic Param and Sector Map Tables (if exist)
 | 
			
		||||
    int _sfdp_parse_sfdp_headers(uint32_t &basic_table_addr, size_t &basic_table_size,
 | 
			
		||||
                                 uint32_t §or_map_table_addr, size_t §or_map_table_size);
 | 
			
		||||
    int _sfdp_parse_sfdp_headers(mbed::sfdp_hdr_info &hdr_info);
 | 
			
		||||
 | 
			
		||||
    // Parse and Detect required Basic Parameters from Table
 | 
			
		||||
    int _sfdp_parse_basic_param_table(uint32_t basic_table_addr, size_t basic_table_size);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,72 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2020, Arm Limited and affiliates.
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef SFDP_H
 | 
			
		||||
#define SFDP_H
 | 
			
		||||
 | 
			
		||||
#include <cstddef>
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
 | 
			
		||||
namespace mbed {
 | 
			
		||||
 | 
			
		||||
static const int SFDP_HEADER_SIZE = 8; ///< Size of an SFDP header */
 | 
			
		||||
static const int SFDP_BASIC_PARAMS_TBL_SIZE = 80; ///< Basic Parameter Table size in Bytes, 20 DWORDS  */
 | 
			
		||||
 | 
			
		||||
/** SFDP Parameter Table addresses and sizes */
 | 
			
		||||
struct sfdp_hdr_info {
 | 
			
		||||
    uint32_t basic_table_addr;
 | 
			
		||||
    size_t basic_table_size;
 | 
			
		||||
    uint32_t sector_map_table_addr;
 | 
			
		||||
    size_t sector_map_table_size;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** SFDP Header */
 | 
			
		||||
struct sfdp_hdr {
 | 
			
		||||
    uint8_t SIG_B0;
 | 
			
		||||
    uint8_t SIG_B1;
 | 
			
		||||
    uint8_t SIG_B2;
 | 
			
		||||
    uint8_t SIG_B3;
 | 
			
		||||
    uint8_t R_MINOR;
 | 
			
		||||
    uint8_t R_MAJOR;
 | 
			
		||||
    uint8_t NPH;
 | 
			
		||||
    uint8_t ACP;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** SFDP Parameter header */
 | 
			
		||||
struct sfdp_prm_hdr {
 | 
			
		||||
    uint8_t PID_LSB; // Parameter ID LSB
 | 
			
		||||
    uint8_t P_MINOR; // Parameter Minor Revision
 | 
			
		||||
    uint8_t P_MAJOR; // Parameter Major Revision
 | 
			
		||||
    uint8_t P_LEN;   // Parameter length in DWORDS(64bits)
 | 
			
		||||
    uint32_t DWORD2; // Parameter ID MSB + Parameter Table Pointer
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Parse SFDP Header
 | 
			
		||||
 * @param Pointer to memory holding an SFDP header
 | 
			
		||||
 * @return Number of Parameter Headers on success, -1 on failure
 | 
			
		||||
 */
 | 
			
		||||
int sfdp_parse_sfdp_header(sfdp_hdr *sfdp_hdr_ptr);
 | 
			
		||||
 | 
			
		||||
/** Parse Parameter Headers
 | 
			
		||||
 * @param parameter_header Pointer to memory holding a single SFDP Parameter header
 | 
			
		||||
 * @param hdr_info Reference to a Parameter Table structure where info about the table is written
 | 
			
		||||
 * @return 0 on success, -1 on failure
 | 
			
		||||
 */
 | 
			
		||||
int sfdp_parse_single_param_header(sfdp_prm_hdr *parameter_header, sfdp_hdr_info &hdr_info);
 | 
			
		||||
 | 
			
		||||
} /* namespace mbed */
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,85 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2020, Arm Limited and affiliates.
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include "drivers/internal/SFDP.h"
 | 
			
		||||
 | 
			
		||||
#if (DEVICE_SPI || DEVICE_QSPI)
 | 
			
		||||
 | 
			
		||||
#include "mbed_trace.h"
 | 
			
		||||
#define TRACE_GROUP "SFDP"
 | 
			
		||||
 | 
			
		||||
namespace mbed {
 | 
			
		||||
 | 
			
		||||
/* Extracts Parameter ID MSB from the second DWORD of a parameter header */
 | 
			
		||||
static inline uint8_t sfdp_get_param_id_msb(uint32_t dword2)
 | 
			
		||||
{
 | 
			
		||||
    return (dword2 & 0xFF000000) >> 24;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Extracts Parameter Table Pointer from the second DWORD of a parameter header */
 | 
			
		||||
static inline uint32_t sfdp_get_param_tbl_ptr(uint32_t dword2)
 | 
			
		||||
{
 | 
			
		||||
    return dword2 & 0x00FFFFFF;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Verifies SFDP Header and return number of parameter headers */
 | 
			
		||||
int sfdp_parse_sfdp_header(sfdp_hdr *sfdp_hdr_ptr)
 | 
			
		||||
{
 | 
			
		||||
    if (!(memcmp(sfdp_hdr_ptr, "SFDP", 4) == 0 && sfdp_hdr_ptr->R_MAJOR == 1)) {
 | 
			
		||||
        tr_error("verify SFDP signature and version Failed");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    tr_debug("init - verified SFDP Signature and version Successfully");
 | 
			
		||||
 | 
			
		||||
    int hdr_cnt = sfdp_hdr_ptr->NPH + 1;
 | 
			
		||||
    tr_debug("number of Param Headers: %d", hdr_cnt);
 | 
			
		||||
 | 
			
		||||
    return hdr_cnt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int sfdp_parse_single_param_header(sfdp_prm_hdr *phdr, sfdp_hdr_info &hdr_info)
 | 
			
		||||
{
 | 
			
		||||
    if (phdr->P_MAJOR != 1) {
 | 
			
		||||
        tr_error("Param Header: - Major Version should be 1!");
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((phdr->PID_LSB == 0) && (sfdp_get_param_id_msb(phdr->DWORD2) == 0xFF)) {
 | 
			
		||||
        tr_debug("Parameter Header: Basic Parameter Header");
 | 
			
		||||
        hdr_info.basic_table_addr = sfdp_get_param_tbl_ptr(phdr->DWORD2);
 | 
			
		||||
        hdr_info.basic_table_size = std::min((phdr->P_LEN * 4), SFDP_BASIC_PARAMS_TBL_SIZE);
 | 
			
		||||
 | 
			
		||||
    } else if ((phdr->PID_LSB == 0x81) && (sfdp_get_param_id_msb(phdr->DWORD2) == 0xFF)) {
 | 
			
		||||
        tr_debug("Parameter Header: Sector Map Parameter Header");
 | 
			
		||||
        hdr_info.sector_map_table_addr = sfdp_get_param_tbl_ptr(phdr->DWORD2);
 | 
			
		||||
        hdr_info.sector_map_table_size = phdr->P_LEN * 4;
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
        tr_debug("Parameter Header vendor specific or unknown. Parameter ID LSB: 0x%" PRIX8 "; MSB: 0x%" PRIX8 "",
 | 
			
		||||
                 phdr->PID_LSB,
 | 
			
		||||
                 sfdp_get_param_id_msb(phdr->DWORD2));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
} /* namespace mbed */
 | 
			
		||||
#endif /* (DEVICE_SPI || DEVICE_QSPI) */
 | 
			
		||||
		Loading…
	
		Reference in New Issue