Skip to content

Commit 7525134

Browse files
committed
[Q/O/]SPIFBlockDevice: remove logic for unaligned erase, as alignment is checked
[Q/O/SPIFBlockDevice::erase() begin with an alignment check, after which unaligned erases should not happen or be allowed. If the erase address is not aligned to the value returned by sfdp_iterate_next_largest_erase_type(), it indicates an internal error in erase table parsing which should not be hidden.
1 parent 52627db commit 7525134

File tree

3 files changed

+34
-25
lines changed

3 files changed

+34
-25
lines changed

storage/blockdevice/COMPONENT_OSPIF/source/OSPIFBlockDevice.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -460,8 +460,6 @@ int OSPIFBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t size
460460
int OSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
461461
{
462462
int type = 0;
463-
uint32_t offset = 0;
464-
uint32_t chunk = 4096;
465463
ospi_inst_t cur_erase_inst = OSPI_NO_INST;
466464
int size = (int)in_size;
467465
bool erase_failed = false;
@@ -500,11 +498,16 @@ int OSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
500498
cur_erase_inst = _sfdp_info.bptbl.legacy_erase_instruction;
501499
eu_size = OSPIF_DEFAULT_SE_SIZE;
502500
}
503-
offset = addr % eu_size;
504-
chunk = ((offset + size) < eu_size) ? size : (eu_size - offset);
505501

506-
tr_debug("Erase - addr: %llu, size:%d, Inst: 0x%xh, chunk: %lu ",
507-
addr, size, cur_erase_inst, chunk);
502+
if (addr % eu_size != 0 || addr + size < eu_size) {
503+
// Should not happen if the erase table parsing
504+
// and alignment checks were performed correctly
505+
tr_error("internal error: address %llu not aligned to erase size %llu (type %d)",
506+
addr, eu_size, type);
507+
}
508+
509+
tr_debug("Erase - addr: %llu, size:%d, Inst: 0x%xh, erase size: %lu ",
510+
addr, size, cur_erase_inst, eu_size);
508511
tr_debug("Erase - Region: %d, Type:%d ",
509512
region, type);
510513

@@ -524,8 +527,8 @@ int OSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
524527
goto exit_point;
525528
}
526529

527-
addr += chunk;
528-
size -= chunk;
530+
addr += eu_size;
531+
size -= eu_size;
529532

530533
if ((size > 0) && (addr > _sfdp_info.smptbl.region_high_boundary[region])) {
531534
// erase crossed to next region

storage/blockdevice/COMPONENT_QSPIF/source/QSPIFBlockDevice.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -388,8 +388,6 @@ int QSPIFBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t size
388388
int QSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
389389
{
390390
int type = 0;
391-
uint32_t offset = 0;
392-
uint32_t chunk = 4096;
393391
qspi_inst_t cur_erase_inst = QSPI_NO_INST;
394392
int size = (int)in_size;
395393
bool erase_failed = false;
@@ -427,11 +425,16 @@ int QSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
427425
cur_erase_inst = _sfdp_info.bptbl.legacy_erase_instruction;
428426
eu_size = QSPIF_DEFAULT_SE_SIZE;
429427
}
430-
offset = addr % eu_size;
431-
chunk = ((offset + size) < eu_size) ? size : (eu_size - offset);
432428

433-
tr_debug("Erase - addr: %llu, size:%d, Inst: 0x%xh, chunk: %lu ",
434-
addr, size, cur_erase_inst, chunk);
429+
if (addr % eu_size != 0 || addr + size < eu_size) {
430+
// Should not happen if the erase table parsing
431+
// and alignment checks were performed correctly
432+
tr_error("internal error: address %llu not aligned to erase size %llu (type %d)",
433+
addr, eu_size, type);
434+
}
435+
436+
tr_debug("Erase - addr: %llu, size:%d, Inst: 0x%xh, erase size: %lu ",
437+
addr, size, cur_erase_inst, eu_size);
435438
tr_debug("Erase - Region: %d, Type:%d ",
436439
region, type);
437440

@@ -451,8 +454,8 @@ int QSPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
451454
goto exit_point;
452455
}
453456

454-
addr += chunk;
455-
size -= chunk;
457+
addr += eu_size;
458+
size -= eu_size;
456459

457460
if ((size > 0) && (addr > _sfdp_info.smptbl.region_high_boundary[region])) {
458461
// erase crossed to next region

storage/blockdevice/COMPONENT_SPIF/source/SPIFBlockDevice.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -305,9 +305,8 @@ int SPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
305305
}
306306

307307
int type = 0;
308-
uint32_t offset = 0;
309-
uint32_t chunk = 4096;
310308
int cur_erase_inst = _erase_instruction;
309+
unsigned int curr_erase_size = 0;
311310
int size = (int)in_size;
312311
bool erase_failed = false;
313312
int status = SPIF_BD_ERROR_OK;
@@ -339,12 +338,16 @@ int SPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
339338
// find the matching instruction and erase size chunk for that type.
340339
type = sfdp_iterate_next_largest_erase_type(bitfield, size, (unsigned int)addr, region, _sfdp_info.smptbl);
341340
cur_erase_inst = _sfdp_info.smptbl.erase_type_inst_arr[type];
342-
offset = addr % _sfdp_info.smptbl.erase_type_size_arr[type];
343-
chunk = ((offset + size) < _sfdp_info.smptbl.erase_type_size_arr[type]) ?
344-
size : (_sfdp_info.smptbl.erase_type_size_arr[type] - offset);
341+
curr_erase_size = _sfdp_info.smptbl.erase_type_size_arr[type];
342+
if (addr % curr_erase_size != 0 || addr + size < curr_erase_size) {
343+
// Should not happen if the erase table parsing
344+
// and alignment checks were performed correctly
345+
tr_error("internal error: address %llu not aligned to erase size %llu (type %d)",
346+
addr, curr_erase_size, type);
347+
}
345348

346-
tr_debug("erase - addr: %llu, size:%d, Inst: 0x%xh, chunk: %" PRIu32 " , ",
347-
addr, size, cur_erase_inst, chunk);
349+
tr_debug("erase - addr: %llu, size:%d, Inst: 0x%xh, erase size: %" PRIu32 " , ",
350+
addr, size, cur_erase_inst, curr_erase_size);
348351
tr_debug("erase - Region: %d, Type:%d",
349352
region, type);
350353

@@ -359,8 +362,8 @@ int SPIFBlockDevice::erase(bd_addr_t addr, bd_size_t in_size)
359362

360363
_spi_send_erase_command(cur_erase_inst, addr, size);
361364

362-
addr += chunk;
363-
size -= chunk;
365+
addr += curr_erase_size;
366+
size -= curr_erase_size;
364367

365368
if ((size > 0) && (addr > _sfdp_info.smptbl.region_high_boundary[region])) {
366369
// erase crossed to next region

0 commit comments

Comments
 (0)