Skip to content

Commit 98dbebb

Browse files
author
Veijo Pesonen
committed
SFDP: Refactor Sector Map Parameter Table parsing
Doxygen documentation was updated. Code reorganized to make it more readable. Moves SFDP specific bits out from Q/SPIFBlockDevices.
1 parent 4f9fcf8 commit 98dbebb

File tree

4 files changed

+69
-71
lines changed

4 files changed

+69
-71
lines changed

components/storage/blockdevice/COMPONENT_QSPIF/QSPIFBlockDevice.cpp

Lines changed: 19 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -232,35 +232,27 @@ int QSPIFBlockDevice::init()
232232
goto exit_point;
233233
}
234234

235-
_sfdp_info.bptbl.addr = 0x0;
236-
_sfdp_info.bptbl.size = 0;
237-
_sfdp_info.smptbl.addr = 0x0;
238-
_sfdp_info.smptbl.size = 0;
239-
240-
/**************************** Parse SFDP Header ***********************************/
241-
if (sfdp_parse_headers(callback(this, &QSPIFBlockDevice::_qspi_send_read_sfdp_command), _sfdp_info) < 0) {
242-
tr_error("Init - Parse SFDP Headers Failed");
243-
status = QSPIF_BD_ERROR_PARSING_FAILED;
244-
goto exit_point;
245-
}
246-
247-
/**************************** Parse Basic Parameters Table ***********************************/
248-
if (_sfdp_parse_basic_param_table(callback(this, &QSPIFBlockDevice::_qspi_send_read_sfdp_command),
249-
_sfdp_info) < 0) {
250-
tr_error("Init - Parse Basic Param Table Failed");
251-
status = QSPIF_BD_ERROR_PARSING_FAILED;
252-
goto exit_point;
253-
}
235+
/**************************** Parse SFDP data ***********************************/
236+
{
237+
_sfdp_info.bptbl.addr = 0x0;
238+
_sfdp_info.bptbl.size = 0;
239+
_sfdp_info.smptbl.addr = 0x0;
240+
_sfdp_info.smptbl.size = 0;
241+
242+
if (sfdp_parse_headers(callback(this, &QSPIFBlockDevice::_qspi_send_read_sfdp_command), _sfdp_info) < 0) {
243+
tr_error("Init - Parse SFDP Headers Failed");
244+
status = QSPIF_BD_ERROR_PARSING_FAILED;
245+
goto exit_point;
246+
}
254247

255-
/**************************** Parse Sector Map Table ***********************************/
256-
_sfdp_info.smptbl.region_size[0] = _sfdp_info.bptbl.device_size_bytes; // If there's no region map, we have a single region sized the entire device size
257-
_sfdp_info.smptbl.region_high_boundary[0] = _sfdp_info.bptbl.device_size_bytes - 1;
248+
if (_sfdp_parse_basic_param_table(callback(this, &QSPIFBlockDevice::_qspi_send_read_sfdp_command),
249+
_sfdp_info) < 0) {
250+
tr_error("Init - Parse Basic Param Table Failed");
251+
status = QSPIF_BD_ERROR_PARSING_FAILED;
252+
goto exit_point;
253+
}
258254

259-
if ((_sfdp_info.smptbl.addr != 0) && (0 != _sfdp_info.smptbl.size)) {
260-
tr_debug("Init - Parsing Sector Map Table - addr: 0x%lxh, Size: %d", _sfdp_info.smptbl.addr,
261-
_sfdp_info.smptbl.size);
262-
if (sfdp_parse_sector_map_table(callback(this, &QSPIFBlockDevice::_qspi_send_read_sfdp_command),
263-
_sfdp_info.smptbl) < 0) {
255+
if (sfdp_parse_sector_map_table(callback(this, &QSPIFBlockDevice::_qspi_send_read_sfdp_command), _sfdp_info) < 0) {
264256
tr_error("Init - Parse Sector Map Table Failed");
265257
status = QSPIF_BD_ERROR_PARSING_FAILED;
266258
goto exit_point;

components/storage/blockdevice/COMPONENT_SPIF/SPIFBlockDevice.cpp

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -166,36 +166,26 @@ int SPIFBlockDevice::init()
166166
goto exit_point;
167167
}
168168

169-
_sfdp_info.bptbl.addr = 0x0;
170-
_sfdp_info.bptbl.size = 0;
171-
_sfdp_info.smptbl.addr = 0x0;
172-
_sfdp_info.smptbl.size = 0;
173-
174-
/**************************** Parse SFDP Header ***********************************/
175-
if (sfdp_parse_headers(callback(this, &SPIFBlockDevice::_spi_send_read_sfdp_command), _sfdp_info) < 0) {
176-
tr_error("init - Parse SFDP Headers Failed");
177-
status = SPIF_BD_ERROR_PARSING_FAILED;
178-
goto exit_point;
179-
}
180-
181-
182-
/**************************** Parse Basic Parameters Table ***********************************/
183-
if (_sfdp_parse_basic_param_table(callback(this, &SPIFBlockDevice::_spi_send_read_sfdp_command), _sfdp_info) < 0) {
184-
tr_error("init - Parse Basic Param Table Failed");
185-
status = SPIF_BD_ERROR_PARSING_FAILED;
186-
goto exit_point;
187-
}
169+
/**************************** Parse SFDP headers and tables ***********************************/
170+
{
171+
_sfdp_info.bptbl.addr = 0x0;
172+
_sfdp_info.bptbl.size = 0;
173+
_sfdp_info.smptbl.addr = 0x0;
174+
_sfdp_info.smptbl.size = 0;
175+
176+
if (sfdp_parse_headers(callback(this, &SPIFBlockDevice::_spi_send_read_sfdp_command), _sfdp_info) < 0) {
177+
tr_error("init - Parse SFDP Headers Failed");
178+
status = SPIF_BD_ERROR_PARSING_FAILED;
179+
goto exit_point;
180+
}
188181

189-
/**************************** Parse Sector Map Table ***********************************/
190-
_sfdp_info.smptbl.region_size[0] = _sfdp_info.bptbl.device_size_bytes;
191-
// If there's no region map, we have a single region sized the entire device size
192-
_sfdp_info.smptbl.region_high_boundary[0] = _sfdp_info.bptbl.device_size_bytes - 1;
182+
if (_sfdp_parse_basic_param_table(callback(this, &SPIFBlockDevice::_spi_send_read_sfdp_command), _sfdp_info) < 0) {
183+
tr_error("init - Parse Basic Param Table Failed");
184+
status = SPIF_BD_ERROR_PARSING_FAILED;
185+
goto exit_point;
186+
}
193187

194-
if ((_sfdp_info.smptbl.addr != 0) && (0 != _sfdp_info.smptbl.size)) {
195-
tr_debug("init - Parsing Sector Map Table - addr: 0x%" PRIx32 "h, Size: %d", _sfdp_info.smptbl.addr,
196-
_sfdp_info.smptbl.size);
197-
if (sfdp_parse_sector_map_table(callback(this, &SPIFBlockDevice::_spi_send_read_sfdp_command),
198-
_sfdp_info.smptbl) < 0) {
188+
if (sfdp_parse_sector_map_table(callback(this, &SPIFBlockDevice::_spi_send_read_sfdp_command), _sfdp_info) < 0) {
199189
tr_error("init - Parse Sector Map Table Failed");
200190
status = SPIF_BD_ERROR_PARSING_FAILED;
201191
goto exit_point;

drivers/internal/SFDP.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,11 @@ int sfdp_parse_headers(Callback<int(bd_addr_t, void *, bd_size_t)> sfdp_reader,
9090
* Retrieves the table from a device and parses the information contained by the table
9191
*
9292
* @param sfdp_reader Callback function used to read headers from within a device
93-
* @param[out] smtbl Contains the results of parsing the JEDEC Sector Map Table
93+
* @param[out] sfdp_info Contains the results of parsing the JEDEC Sector Map Table
9494
*
9595
* @return MBED_SUCCESS on success, negative error code on failure
9696
*/
97-
int sfdp_parse_sector_map_table(Callback<int(bd_addr_t, void *, bd_size_t)> sfdp_reader, sfdp_smptbl_info &smtbl);
97+
int sfdp_parse_sector_map_table(Callback<int(bd_addr_t, void *, bd_size_t)> sfdp_reader, sfdp_hdr_info &sfdp_info);
9898

9999
/** Detect page size used for writing on flash
100100
*
@@ -131,7 +131,7 @@ int sfdp_find_addr_region(bd_size_t offset, const sfdp_hdr_info &sfdp_info);
131131
* @param size Upper limit for region size
132132
* @param offset Offset value
133133
* @param region Region number
134-
* @param smtbl Information about different erase types
134+
* @param smptbl Information about different erase types
135135
*
136136
* @return Largest erase type
137137
*/

drivers/source/SFDP.cpp

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ int sfdp_parse_headers(Callback<int(bd_addr_t, void *, bd_size_t)> sfdp_reader,
176176
return 0;
177177
}
178178

179-
int sfdp_parse_sector_map_table(Callback<int(bd_addr_t, void *, bd_size_t)> sfdp_reader, sfdp_smptbl_info &smptbl)
179+
int sfdp_parse_sector_map_table(Callback<int(bd_addr_t, void *, bd_size_t)> sfdp_reader, sfdp_hdr_info &sfdp_info)
180180
{
181181
uint8_t sector_map_table[SFDP_BASIC_PARAMS_TBL_SIZE]; /* Up To 20 DWORDS = 80 Bytes */
182182
uint32_t tmp_region_size = 0;
@@ -185,7 +185,19 @@ int sfdp_parse_sector_map_table(Callback<int(bd_addr_t, void *, bd_size_t)> sfdp
185185
// Default set to all type bits 1-4 are common
186186
int min_common_erase_type_bits = SFDP_ERASE_BITMASK_ALL;
187187

188-
int status = sfdp_reader(smptbl.addr, sector_map_table, smptbl.size);
188+
// If there's no region map, we have a single region sized the entire device size
189+
sfdp_info.smptbl.region_size[0] = sfdp_info.bptbl.device_size_bytes;
190+
sfdp_info.smptbl.region_high_boundary[0] = sfdp_info.bptbl.device_size_bytes - 1;
191+
192+
if (!sfdp_info.smptbl.addr || !sfdp_info.smptbl.size) {
193+
tr_debug("No Sector Map Table");
194+
return 0;
195+
}
196+
197+
tr_debug("Parsing Sector Map Table - addr: 0x%" PRIx32 ", Size: %d", sfdp_info.smptbl.addr, sfdp_info.smptbl.size);
198+
199+
200+
int status = sfdp_reader(sfdp_info.smptbl.addr, sector_map_table, sfdp_info.smptbl.size);
189201
if (status < 0) {
190202
tr_error("Sector Map: Table retrieval failed");
191203
return -1;
@@ -197,38 +209,42 @@ int sfdp_parse_sector_map_table(Callback<int(bd_addr_t, void *, bd_size_t)> sfdp
197209
return -1;
198210
}
199211

200-
smptbl.region_cnt = sector_map_table[2] + 1;
201-
if (smptbl.region_cnt > SFDP_SECTOR_MAP_MAX_REGIONS) {
212+
sfdp_info.smptbl.region_cnt = sector_map_table[2] + 1;
213+
if (sfdp_info.smptbl.region_cnt > SFDP_SECTOR_MAP_MAX_REGIONS) {
202214
tr_error("Sector Map: Supporting up to %d regions, current setup to %d regions - fail",
203215
SFDP_SECTOR_MAP_MAX_REGIONS,
204-
smptbl.region_cnt);
216+
sfdp_info.smptbl.region_cnt);
205217
return -1;
206218
}
207219

208220
// Loop through Regions and set for each one: size, supported erase types, high boundary offset
209221
// Calculate minimum Common Erase Type for all Regions
210-
for (i_ind = 0; i_ind < smptbl.region_cnt; i_ind++) {
222+
for (i_ind = 0; i_ind < sfdp_info.smptbl.region_cnt; i_ind++) {
211223
tmp_region_size = ((*((uint32_t *)&sector_map_table[(i_ind + 1) * 4])) >> 8) & 0x00FFFFFF; // bits 9-32
212-
smptbl.region_size[i_ind] = (tmp_region_size + 1) * 256; // Region size is 0 based multiple of 256 bytes;
213-
smptbl.region_erase_types_bitfld[i_ind] = sector_map_table[(i_ind + 1) * 4] & 0x0F; // bits 1-4
214-
min_common_erase_type_bits &= smptbl.region_erase_types_bitfld[i_ind];
215-
smptbl.region_high_boundary[i_ind] = (smptbl.region_size[i_ind] - 1) + prev_boundary;
216-
prev_boundary = smptbl.region_high_boundary[i_ind] + 1;
224+
sfdp_info.smptbl.region_size[i_ind] = (tmp_region_size + 1) * 256; // Region size is 0 based multiple of 256 bytes;
225+
226+
sfdp_info.smptbl.region_erase_types_bitfld[i_ind] = sector_map_table[(i_ind + 1) * 4] & 0x0F; // bits 1-4
227+
228+
min_common_erase_type_bits &= sfdp_info.smptbl.region_erase_types_bitfld[i_ind];
229+
230+
sfdp_info.smptbl.region_high_boundary[i_ind] = (sfdp_info.smptbl.region_size[i_ind] - 1) + prev_boundary;
231+
232+
prev_boundary = sfdp_info.smptbl.region_high_boundary[i_ind] + 1;
217233
}
218234

219235
// Calc minimum Common Erase Size from min_common_erase_type_bits
220236
uint8_t type_mask = SFDP_ERASE_BITMASK_TYPE1;
221237
for (i_ind = 0; i_ind < 4; i_ind++) {
222238
if (min_common_erase_type_bits & type_mask) {
223-
smptbl.regions_min_common_erase_size = smptbl.erase_type_size_arr[i_ind];
239+
sfdp_info.smptbl.regions_min_common_erase_size = sfdp_info.smptbl.erase_type_size_arr[i_ind];
224240
break;
225241
}
226242
type_mask = type_mask << 1;
227243
}
228244

229245
if (i_ind == 4) {
230246
// No common erase type was found between regions
231-
smptbl.regions_min_common_erase_size = 0;
247+
sfdp_info.smptbl.regions_min_common_erase_size = 0;
232248
}
233249

234250
return 0;

0 commit comments

Comments
 (0)