bsps/shared/dev/nor: Added support for multiple CFI regions

CFI parser now returns largest block size when multiple regions
are present allowing for block erase to be used with returned size.
This commit is contained in:
Aaron Nyholm
2025-11-03 15:18:01 +11:00
committed by Kinsey Moore
parent f77bb9762a
commit fabfef6c24

View File

@@ -120,7 +120,6 @@ rtems_status_code CFI_parse_from_buffer(
/* get device geometry */
uint8_t bufbyte;
/* Device size for at least s25fl512s is off by 1, calculate with sectors */
if (read_config_byte(cfi_raw, cfi_raw_len, datalen, 0x27, &bufbyte)) {
return RTEMS_INVALID_ADDRESS;
}
@@ -135,24 +134,35 @@ rtems_status_code CFI_parse_from_buffer(
if (read_config_byte(cfi_raw, cfi_raw_len, datalen, 0x2c, &bufbyte)) {
return RTEMS_INVALID_ADDRESS;
}
/* this parser only supports one erase block region */
if (bufbyte != 1) {
return RTEMS_TOO_MANY;
/* Get largest block */
uint8_t num_regions = bufbyte;
data->SectorSize = 0;
for (int region = 0; region < num_regions; ++region) {
uint16_t num_sectors_sub;
if (read_config_short(cfi_raw, cfi_raw_len, datalen, 0x2d + (region * 4),
&num_sectors_sub)) {
return RTEMS_INVALID_ADDRESS;
}
uint16_t sector_base;
if (read_config_short(cfi_raw, cfi_raw_len, datalen, 0x2f + (region * 4),
&sector_base)) {
return RTEMS_INVALID_ADDRESS;
}
if (data->SectorSize < (sector_base * 256UL)) {
data->NumSectors = num_sectors_sub + 1;
data->SectorSize = sector_base * 256UL;
}
}
uint16_t num_sectors_sub;
if (read_config_short(cfi_raw, cfi_raw_len, datalen, 0x2d, &num_sectors_sub)) {
return RTEMS_INVALID_ADDRESS;
if (num_regions == 1) {
/* Device size for at least s25fl512s is off by 1, calculate with sectors */
data->DeviceSize = data->NumSectors * data->SectorSize;
} else {
data->NumSectors = data->DeviceSize / data->SectorSize;
}
data->NumSectors = num_sectors_sub + 1;
uint16_t sector_base;
if (read_config_short(cfi_raw, cfi_raw_len, datalen, 0x2f, &sector_base)) {
return RTEMS_INVALID_ADDRESS;
}
data->SectorSize = sector_base * 256UL;
data->DeviceSize = data->NumSectors * data->SectorSize;
return RTEMS_SUCCESSFUL;
}