Skip to content

Commit 9f1529d

Browse files
keirftom-van
authored andcommitted
flash/nor/stm32f2x: Support value line chips with trimmed flash
The current code assumes an STM32's flash bank is laid-out in either of two configurations: - 4 x 16kB + 1 x 64kB + n x 128kB - 4 x 32kB + 1 x 128kB + n x 256kB This is quite ad-hoc but works fine in practice, as long as there are at least 5 sectors (if n=0). Unfortunately, some newer STM32s are shipping with only 64 kB of flash (4 x 16kB sectors). This patch still assumes the same sector layout, but only keeps adding sectors to the bank if the bank's capacity has not been reached. This prevents openocd from crashing on some newer STM32s. Change-Id: If00e5d7a328d11b399babc0bb2111e3ad8a3217e Signed-off-by: Romain Goyet <[email protected]> Signed-off-by: Keir Fraser <[email protected]> Reviewed-on: http://openocd.zylin.com/4926 Tested-by: jenkins Reviewed-by: Andreas Bolsch <[email protected]> Reviewed-by: Tomas Vanek <[email protected]>
1 parent be2d25e commit 9f1529d

File tree

1 file changed

+56
-19
lines changed

1 file changed

+56
-19
lines changed

src/flash/nor/stm32f2x.c

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -894,31 +894,68 @@ static int stm32x_write(struct flash_bank *bank, const uint8_t *buffer,
894894
return target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK);
895895
}
896896

897-
static int setup_sector(struct flash_bank *bank, int start, int num, int size)
897+
static void setup_sector(struct flash_bank *bank, int i, int size)
898898
{
899+
assert(i < bank->num_sectors);
900+
bank->sectors[i].offset = bank->size;
901+
bank->sectors[i].size = size;
902+
bank->size += bank->sectors[i].size;
903+
LOG_DEBUG("sector %d: %dkBytes", i, size >> 10);
904+
}
905+
906+
static uint16_t sector_size_in_kb(int i, uint16_t max_sector_size_in_kb)
907+
{
908+
assert(i >= 0);
909+
if (i < 4)
910+
return max_sector_size_in_kb / 8;
911+
if (i == 4)
912+
return max_sector_size_in_kb / 2;
913+
return max_sector_size_in_kb;
914+
}
915+
916+
static int calculate_number_of_sectors(struct flash_bank *bank,
917+
uint16_t flash_size_in_kb,
918+
uint16_t max_sector_size_in_kb)
919+
{
920+
struct stm32x_flash_bank *stm32x_info = bank->driver_priv;
921+
uint16_t remaining_flash_size_in_kb = flash_size_in_kb;
922+
int nr_sectors;
899923

900-
for (int i = start; i < (start + num) ; i++) {
901-
assert(i < bank->num_sectors);
902-
bank->sectors[i].offset = bank->size;
903-
bank->sectors[i].size = size;
904-
bank->size += bank->sectors[i].size;
905-
LOG_DEBUG("sector %d: %d kBytes", i, size >> 10);
924+
/* Dual Bank Flash has two identically-arranged banks of sectors. */
925+
if (stm32x_info->has_large_mem)
926+
remaining_flash_size_in_kb /= 2;
927+
928+
for (nr_sectors = 0; remaining_flash_size_in_kb > 0; nr_sectors++) {
929+
uint16_t size_in_kb = sector_size_in_kb(nr_sectors, max_sector_size_in_kb);
930+
if (size_in_kb > remaining_flash_size_in_kb) {
931+
LOG_INFO("%s Bank %" PRIu16 " kiB final sector clipped to %" PRIu16 " kiB",
932+
stm32x_info->has_large_mem ? "Dual" : "Single",
933+
flash_size_in_kb, remaining_flash_size_in_kb);
934+
remaining_flash_size_in_kb = 0;
935+
} else {
936+
remaining_flash_size_in_kb -= size_in_kb;
937+
}
906938
}
907939

908-
return start + num;
940+
return stm32x_info->has_large_mem ? nr_sectors*2 : nr_sectors;
909941
}
910942

911943
static void setup_bank(struct flash_bank *bank, int start,
912944
uint16_t flash_size_in_kb, uint16_t max_sector_size_in_kb)
913945
{
914-
int remain;
915-
916-
start = setup_sector(bank, start, 4, (max_sector_size_in_kb / 8) * 1024);
917-
start = setup_sector(bank, start, 1, (max_sector_size_in_kb / 2) * 1024);
918-
919-
/* remaining sectors all of size max_sector_size_in_kb */
920-
remain = (flash_size_in_kb / max_sector_size_in_kb) - 1;
921-
start = setup_sector(bank, start, remain, max_sector_size_in_kb * 1024);
946+
uint16_t remaining_flash_size_in_kb = flash_size_in_kb;
947+
int sector_index = 0;
948+
while (remaining_flash_size_in_kb > 0) {
949+
uint16_t size_in_kb = sector_size_in_kb(sector_index, max_sector_size_in_kb);
950+
if (size_in_kb > remaining_flash_size_in_kb) {
951+
/* Clip last sector. Already warned in
952+
* calculate_number_of_sectors. */
953+
size_in_kb = remaining_flash_size_in_kb;
954+
}
955+
setup_sector(bank, start + sector_index, size_in_kb * 1024);
956+
remaining_flash_size_in_kb -= size_in_kb;
957+
sector_index++;
958+
}
922959
}
923960

924961
static int stm32x_get_device_id(struct flash_bank *bank, uint32_t *device_id)
@@ -1150,12 +1187,12 @@ static int stm32x_probe(struct flash_bank *bank)
11501187
}
11511188

11521189
/* calculate numbers of pages */
1153-
int num_pages = flash_size_in_kb / max_sector_size_in_kb
1154-
+ (stm32x_info->has_large_mem ? 8 : 4);
1190+
int num_pages = calculate_number_of_sectors(
1191+
bank, flash_size_in_kb, max_sector_size_in_kb);
11551192

11561193
bank->base = base_address;
11571194
bank->num_sectors = num_pages;
1158-
bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
1195+
bank->sectors = calloc(num_pages, sizeof(struct flash_sector));
11591196
for (i = 0; i < num_pages; i++) {
11601197
bank->sectors[i].is_erased = -1;
11611198
bank->sectors[i].is_protected = 0;

0 commit comments

Comments
 (0)