Skip to content

Commit cefae90

Browse files
author
Veijo Pesonen
committed
SFDP: splits header parsing to its own file
SFDP logic is the same between SPIF and QSIP.
1 parent ad43f23 commit cefae90

File tree

6 files changed

+251
-125
lines changed

6 files changed

+251
-125
lines changed

components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.cpp

Lines changed: 43 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17+
#include "drivers/internal/SFDP.h"
1718
#include "QSPIFBlockDevice.h"
1819
#include <string.h>
1920
#include "rtos/ThisThread.h"
@@ -204,10 +205,8 @@ int QSPIFBlockDevice::init()
204205
}
205206

206207
int status = QSPIF_BD_ERROR_OK;
207-
uint32_t basic_table_addr = 0;
208-
size_t basic_table_size = 0;
209-
uint32_t sector_map_table_addr = 0;
210-
size_t sector_map_table_size = 0;
208+
sfdp_hdr_info hdr_info;
209+
memset(&hdr_info, 0, sizeof hdr_info);
211210

212211
_mutex.lock();
213212

@@ -251,14 +250,14 @@ int QSPIFBlockDevice::init()
251250
}
252251

253252
/**************************** Parse SFDP Header ***********************************/
254-
if (0 != _sfdp_parse_sfdp_headers(basic_table_addr, basic_table_size, sector_map_table_addr, sector_map_table_size)) {
253+
if (0 != _sfdp_parse_sfdp_headers(hdr_info)) {
255254
tr_error("Init - Parse SFDP Headers Failed");
256255
status = QSPIF_BD_ERROR_PARSING_FAILED;
257256
goto exit_point;
258257
}
259258

260259
/**************************** Parse Basic Parameters Table ***********************************/
261-
if (0 != _sfdp_parse_basic_param_table(basic_table_addr, basic_table_size)) {
260+
if (0 != _sfdp_parse_basic_param_table(hdr_info.basic_table_addr, hdr_info.basic_table_size)) {
262261
tr_error("Init - Parse Basic Param Table Failed");
263262
status = QSPIF_BD_ERROR_PARSING_FAILED;
264263
goto exit_point;
@@ -269,10 +268,10 @@ int QSPIFBlockDevice::init()
269268
_device_size_bytes; // If there's no region map, we have a single region sized the entire device size
270269
_region_high_boundary[0] = _device_size_bytes - 1;
271270

272-
if ((sector_map_table_addr != 0) && (0 != sector_map_table_size)) {
273-
tr_debug("Init - Parsing Sector Map Table - addr: 0x%lxh, Size: %d", sector_map_table_addr,
274-
sector_map_table_size);
275-
if (0 != _sfdp_parse_sector_map_table(sector_map_table_addr, sector_map_table_size)) {
271+
if ((hdr_info.sector_map_table_addr != 0) && (0 != hdr_info.sector_map_table_size)) {
272+
tr_debug("Init - Parsing Sector Map Table - addr: 0x%lxh, Size: %d", hdr_info.sector_map_table_addr,
273+
hdr_info.sector_map_table_size);
274+
if (0 != _sfdp_parse_sector_map_table(hdr_info.sector_map_table_addr, hdr_info.sector_map_table_size)) {
276275
tr_error("Init - Parse Sector Map Table Failed");
277276
status = QSPIF_BD_ERROR_PARSING_FAILED;
278277
goto exit_point;
@@ -629,65 +628,51 @@ int QSPIFBlockDevice::remove_csel_instance(PinName csel)
629628
/*********************************************************/
630629
/********** SFDP Parsing and Detection Functions *********/
631630
/*********************************************************/
632-
int QSPIFBlockDevice::_sfdp_parse_sfdp_headers(uint32_t &basic_table_addr, size_t &basic_table_size,
633-
uint32_t &sector_map_table_addr, size_t &sector_map_table_size)
631+
int QSPIFBlockDevice::_sfdp_parse_sfdp_headers(mbed::sfdp_hdr_info &hdr_info)
634632
{
635-
uint8_t sfdp_header[QSPIF_SFDP_HEADER_SIZE];
636-
uint8_t param_header[QSPIF_PARAM_HEADER_SIZE];
637-
size_t data_length = QSPIF_SFDP_HEADER_SIZE;
638633
bd_addr_t addr = 0x0;
634+
int number_of_param_headers = 0;
635+
size_t data_length;
639636

640-
qspi_status_t status = _qspi_send_read_sfdp_command(addr, (char *) sfdp_header, data_length);
641-
if (status != QSPI_STATUS_OK) {
642-
tr_error("Init - Read SFDP Failed");
643-
return -1;
644-
}
645-
646-
// Verify SFDP signature for sanity
647-
// Also check that major/minor version is acceptable
648-
if (!(memcmp(&sfdp_header[0], "SFDP", 4) == 0 && sfdp_header[5] == 1)) {
649-
tr_error("Init - Verification of SFDP signature and version failed");
650-
return -1;
651-
} else {
652-
tr_debug("Init - Verification of SFDP signature and version succeeded");
653-
}
654-
655-
// Discover Number of Parameter Headers
656-
int number_of_param_headers = (int)(sfdp_header[6]) + 1;
657-
tr_debug("Number of Param Headers: %d", number_of_param_headers);
658-
659-
660-
addr += QSPIF_SFDP_HEADER_SIZE;
661-
data_length = QSPIF_PARAM_HEADER_SIZE;
637+
{
638+
data_length = QSPIF_SFDP_HEADER_SIZE;
639+
uint8_t sfdp_header[QSPIF_SFDP_HEADER_SIZE];
662640

663-
// Loop over Param Headers and parse them (currently supports Basic Param Table and Sector Region Map Table)
664-
for (int i_ind = 0; i_ind < number_of_param_headers; i_ind++) {
665-
status = _qspi_send_read_sfdp_command(addr, (char *) param_header, data_length);
641+
qspi_status_t status = _qspi_send_read_sfdp_command(addr, (char *)sfdp_header, data_length);
666642
if (status != QSPI_STATUS_OK) {
667-
tr_error("Init - Read Param Table %d Failed", i_ind + 1);
643+
tr_error("init - Retrieving SFDP Header failed");
668644
return -1;
669645
}
670646

671-
// The SFDP spec indicates the standard table is always at offset 0
672-
// in the parameter headers, we check just to be safe
673-
if (param_header[2] != 1) {
674-
tr_error("Param Table %d - Major Version should be 1!", i_ind + 1);
675-
return -1;
647+
number_of_param_headers = sfdp_parse_sfdp_header((sfdp_hdr *)sfdp_header);
648+
if (number_of_param_headers < 0) {
649+
return number_of_param_headers;
676650
}
651+
}
677652

678-
if ((param_header[0] == 0) && (param_header[7] == 0xFF)) {
679-
tr_debug("Parameter Header %d: Basic Parameter Header", i_ind);
680-
basic_table_addr = ((param_header[6] << 16) | (param_header[5] << 8) | (param_header[4]));
681-
// Supporting up to 64 Bytes Table (16 DWORDS)
682-
basic_table_size = ((param_header[3] * 4) < SFDP_DEFAULT_BASIC_PARAMS_TABLE_SIZE_BYTES) ? (param_header[3] * 4) : 64;
683-
} else if ((param_header[0] == 0x81) && (param_header[7] == 0xFF)) {
684-
tr_debug("Parameter Header %d: Sector Map Parameter Header", i_ind);
685-
sector_map_table_addr = ((param_header[6] << 16) | (param_header[5] << 8) | (param_header[4]));
686-
sector_map_table_size = param_header[3] * 4;
687-
} else {
688-
tr_debug("Parameter Header %d: Vendor specific or unknown header", i_ind);
653+
addr += QSPIF_SFDP_HEADER_SIZE;
654+
655+
{
656+
data_length = QSPIF_PARAM_HEADER_SIZE;
657+
uint8_t param_header[QSPIF_PARAM_HEADER_SIZE];
658+
qspi_status_t status;
659+
int hdr_status;
660+
661+
// Loop over Param Headers and parse them (currently supports Basic Param Table and Sector Region Map Table)
662+
for (int i_ind = 0; i_ind < number_of_param_headers; i_ind++) {
663+
status = _qspi_send_read_sfdp_command(addr, (char *)param_header, data_length);
664+
if (status != QSPI_STATUS_OK) {
665+
tr_error("init - Retrieving Parameter Header %d failed", i_ind + 1);
666+
return -1;
667+
}
668+
669+
hdr_status = sfdp_parse_single_param_header((sfdp_prm_hdr *)param_header, hdr_info);
670+
if (hdr_status < 0) {
671+
return hdr_status;
672+
}
673+
674+
addr += QSPIF_PARAM_HEADER_SIZE;
689675
}
690-
addr += QSPIF_PARAM_HEADER_SIZE;
691676
}
692677

693678
return 0;

components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#define MBED_QSPIF_BLOCK_DEVICE_H
1818

1919
#include "drivers/QSPI.h"
20+
#include "drivers/internal/SFDP.h"
2021
#include "features/storage/blockdevice/BlockDevice.h"
2122

2223
#ifndef MBED_CONF_QSPIF_QSPI_IO0
@@ -312,8 +313,7 @@ class QSPIFBlockDevice : public mbed::BlockDevice {
312313
/* SFDP Detection and Parsing Functions */
313314
/****************************************/
314315
// Parse SFDP Headers and retrieve Basic Param and Sector Map Tables (if exist)
315-
int _sfdp_parse_sfdp_headers(uint32_t &basic_table_addr, size_t &basic_table_size,
316-
uint32_t &sector_map_table_addr, size_t &sector_map_table_size);
316+
int _sfdp_parse_sfdp_headers(mbed::sfdp_hdr_info &hdr_info);
317317

318318
// Parse and Detect required Basic Parameters from Table
319319
int _sfdp_parse_basic_param_table(uint32_t basic_table_addr, size_t basic_table_size);

components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.cpp

Lines changed: 47 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17+
#include "drivers/internal/SFDP.h"
1718
#include "SPIFBlockDevice.h"
1819
#include "rtos/ThisThread.h"
1920
#include "mbed_critical.h"
@@ -133,12 +134,11 @@ int SPIFBlockDevice::init()
133134
uint8_t vendor_device_ids[4];
134135
size_t data_length = 3;
135136
int status = SPIF_BD_ERROR_OK;
136-
uint32_t basic_table_addr = 0;
137-
size_t basic_table_size = 0;
138-
uint32_t sector_map_table_addr = 0;
139-
size_t sector_map_table_size = 0;
137+
struct sfdp_hdr_info hdr_info;
140138
spif_bd_error spi_status = SPIF_BD_ERROR_OK;
141139

140+
memset(&hdr_info, 0, sizeof hdr_info);
141+
142142
_mutex->lock();
143143

144144
if (!_is_initialized) {
@@ -186,15 +186,15 @@ int SPIFBlockDevice::init()
186186
}
187187

188188
/**************************** Parse SFDP Header ***********************************/
189-
if (0 != _sfdp_parse_sfdp_headers(basic_table_addr, basic_table_size, sector_map_table_addr, sector_map_table_size)) {
189+
if (0 != _sfdp_parse_sfdp_headers(hdr_info)) {
190190
tr_error("init - Parse SFDP Headers Failed");
191191
status = SPIF_BD_ERROR_PARSING_FAILED;
192192
goto exit_point;
193193
}
194194

195195

196196
/**************************** Parse Basic Parameters Table ***********************************/
197-
if (0 != _sfdp_parse_basic_param_table(basic_table_addr, basic_table_size)) {
197+
if (0 != _sfdp_parse_basic_param_table(hdr_info.basic_table_addr, hdr_info.basic_table_size)) {
198198
tr_error("init - Parse Basic Param Table Failed");
199199
status = SPIF_BD_ERROR_PARSING_FAILED;
200200
goto exit_point;
@@ -205,10 +205,10 @@ int SPIFBlockDevice::init()
205205
_device_size_bytes; // If there's no region map, we have a single region sized the entire device size
206206
_region_high_boundary[0] = _device_size_bytes - 1;
207207

208-
if ((sector_map_table_addr != 0) && (0 != sector_map_table_size)) {
209-
tr_debug("init - Parsing Sector Map Table - addr: 0x%" PRIx32 "h, Size: %d", sector_map_table_addr,
210-
sector_map_table_size);
211-
if (0 != _sfdp_parse_sector_map_table(sector_map_table_addr, sector_map_table_size)) {
208+
if ((hdr_info.sector_map_table_addr != 0) && (0 != hdr_info.sector_map_table_size)) {
209+
tr_debug("init - Parsing Sector Map Table - addr: 0x%" PRIx32 "h, Size: %d", hdr_info.sector_map_table_addr,
210+
hdr_info.sector_map_table_size);
211+
if (0 != _sfdp_parse_sector_map_table(hdr_info.sector_map_table_addr, hdr_info.sector_map_table_size)) {
212212
tr_error("init - Parse Sector Map Table Failed");
213213
status = SPIF_BD_ERROR_PARSING_FAILED;
214214
goto exit_point;
@@ -719,73 +719,57 @@ int SPIFBlockDevice::_sfdp_parse_basic_param_table(uint32_t basic_table_addr, si
719719
return 0;
720720
}
721721

722-
int SPIFBlockDevice::_sfdp_parse_sfdp_headers(uint32_t &basic_table_addr, size_t &basic_table_size,
723-
uint32_t &sector_map_table_addr, size_t &sector_map_table_size)
722+
int SPIFBlockDevice::_sfdp_parse_sfdp_headers(sfdp_hdr_info &hdr_info)
724723
{
725-
uint8_t sfdp_header[16];
726-
uint8_t param_header[SPIF_SFDP_HEADER_SIZE];
727-
size_t data_length = SPIF_SFDP_HEADER_SIZE;
728724
bd_addr_t addr = 0x0;
725+
int number_of_param_headers = 0;
726+
size_t data_length;
729727

730-
// Set 1-1-1 bus mode for SFDP header parsing
731-
// Initial SFDP read tables are read with 8 dummy cycles
732-
_read_dummy_and_mode_cycles = 8;
733-
_dummy_and_mode_cycles = 8;
734-
735-
spif_bd_error status = _spi_send_read_command(SPIF_SFDP, sfdp_header, addr /*address*/, data_length);
736-
if (status != SPIF_BD_ERROR_OK) {
737-
tr_error("init - Read SFDP Failed");
738-
return -1;
739-
}
740-
741-
// Verify SFDP signature for sanity
742-
// Also check that major/minor version is acceptable
743-
if (!(memcmp(&sfdp_header[0], "SFDP", 4) == 0 && sfdp_header[5] == 1)) {
744-
tr_error("init - _verify SFDP signature and version Failed");
745-
return -1;
746-
} else {
747-
tr_debug("init - verified SFDP Signature and version Successfully");
748-
}
749-
750-
// Discover Number of Parameter Headers
751-
int number_of_param_headers = (int)(sfdp_header[6]) + 1;
752-
tr_debug("number of Param Headers: %d", number_of_param_headers);
728+
{
729+
data_length = SPIF_SFDP_HEADER_SIZE;
730+
uint8_t sfdp_header[SPIF_SFDP_HEADER_SIZE];
753731

754-
addr += SPIF_SFDP_HEADER_SIZE;
755-
data_length = SPIF_PARAM_HEADER_SIZE;
756-
757-
// Loop over Param Headers and parse them (currently supported Basic Param Table and Sector Region Map Table)
758-
for (int i_ind = 0; i_ind < number_of_param_headers; i_ind++) {
732+
// Set 1-1-1 bus mode for SFDP header parsing
733+
// Initial SFDP read tables are read with 8 dummy cycles
734+
_read_dummy_and_mode_cycles = 8;
735+
_dummy_and_mode_cycles = 8;
759736

760-
status = _spi_send_read_command(SPIF_SFDP, param_header, addr, data_length);
737+
spif_bd_error status = _spi_send_read_command(SPIF_SFDP, sfdp_header, addr /*address*/, data_length);
761738
if (status != SPIF_BD_ERROR_OK) {
762-
tr_error("init - Read Param Table %d Failed", i_ind + 1);
739+
tr_error("init - Read SFDP Failed");
763740
return -1;
764741
}
765742

766-
// The SFDP spec indicates the standard table is always at offset 0
767-
// in the parameter headers, we check just to be safe
768-
if (param_header[2] != 1) {
769-
tr_error("Param Table %d - Major Version should be 1!", i_ind + 1);
770-
return -1;
743+
number_of_param_headers = sfdp_parse_sfdp_header((sfdp_hdr *)sfdp_header);
744+
if (number_of_param_headers < 0) {
745+
return number_of_param_headers;
771746
}
747+
}
772748

773-
if ((param_header[0] == 0) && (param_header[7] == 0xFF)) {
774-
tr_debug("Parameter Header %d: Basic Parameter Header", i_ind);
775-
basic_table_addr = ((param_header[6] << 16) | (param_header[5] << 8) | (param_header[4]));
776-
// Supporting up to 64 Bytes Table (16 DWORDS)
777-
basic_table_size = ((param_header[3] * 4) < SFDP_DEFAULT_BASIC_PARAMS_TABLE_SIZE_BYTES) ? (param_header[3] * 4) : 64;
749+
addr += SPIF_SFDP_HEADER_SIZE;
778750

779-
} else if ((param_header[0] == 0x81) && (param_header[7] == 0xFF)) {
780-
tr_debug("Parameter Header %d: Sector Map Parameter Header", i_ind);
781-
sector_map_table_addr = ((param_header[6] << 16) | (param_header[5] << 8) | (param_header[4]));
782-
sector_map_table_size = param_header[3] * 4;
751+
{
752+
data_length = SPIF_PARAM_HEADER_SIZE;
753+
uint8_t param_header[SPIF_SFDP_HEADER_SIZE];
754+
spif_bd_error status;
755+
int hdr_status;
783756

784-
} else {
785-
tr_debug("Parameter Header %d: Vendor specific or unknown header", i_ind);
786-
}
787-
addr += SPIF_PARAM_HEADER_SIZE;
757+
// Loop over Param Headers and parse them (currently supported Basic Param Table and Sector Region Map Table)
758+
for (int i_ind = 0; i_ind < number_of_param_headers; i_ind++) {
759+
760+
status = _spi_send_read_command(SPIF_SFDP, param_header, addr, data_length);
761+
if (status != SPIF_BD_ERROR_OK) {
762+
tr_error("init - Read Param Table %d Failed", i_ind + 1);
763+
return -1;
764+
}
788765

766+
hdr_status = sfdp_parse_single_param_header((sfdp_prm_hdr *)param_header, hdr_info);
767+
if (hdr_status < 0) {
768+
return hdr_status;
769+
}
770+
771+
addr += SPIF_PARAM_HEADER_SIZE;
772+
}
789773
}
790774
return 0;
791775
}

components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "platform/SingletonPtr.h"
2020
#include "drivers/SPI.h"
2121
#include "drivers/DigitalOut.h"
22+
#include "drivers/internal/SFDP.h"
2223
#include "features/storage/blockdevice/BlockDevice.h"
2324

2425
#ifndef MBED_CONF_SPIF_DRIVER_SPI_MOSI
@@ -225,8 +226,7 @@ class SPIFBlockDevice : public mbed::BlockDevice {
225226
/* SFDP Detection and Parsing Functions */
226227
/****************************************/
227228
// Parse SFDP Headers and retrieve Basic Param and Sector Map Tables (if exist)
228-
int _sfdp_parse_sfdp_headers(uint32_t &basic_table_addr, size_t &basic_table_size,
229-
uint32_t &sector_map_table_addr, size_t &sector_map_table_size);
229+
int _sfdp_parse_sfdp_headers(mbed::sfdp_hdr_info &hdr_info);
230230

231231
// Parse and Detect required Basic Parameters from Table
232232
int _sfdp_parse_basic_param_table(uint32_t basic_table_addr, size_t basic_table_size);

0 commit comments

Comments
 (0)