1
0
mirror of https://review.coreboot.org/flashrom.git synced 2025-05-13 14:50:59 +02:00

flashrom.c:Add function to get a flattened view of the chip erase blocks

Add a function to flatten out the addresses of the flash chip as per the
different erase functions. This function will return a list of layouts
which is dynamically allocated. So after use all the layouts as well as
the list itself should be freed. The free_erase_layout function does
that.

Change-Id: Iafe78de00daa55f7114bd4ce09465dd88074ece4
Signed-off-by: Aarya Chaumal <aarya.chaumal@gmail.com>
This commit is contained in:
Aarya Chaumal 2022-07-15 16:51:27 +05:30 committed by Simon Buhrow
parent dcdf301010
commit 22c621aed2
2 changed files with 95 additions and 0 deletions

View File

@ -1062,6 +1062,86 @@ static int walk_by_layout(struct flashctx *const flashctx, struct walk_info *con
return 0;
}
static void free_erase_layout(struct erase_layout *layout, int erasefn_count);
static void free_erase_layout(struct erase_layout *layout, int erasefn_count)
{
if (layout) {
for (int i = 0; i < erasefn_count; i++) {
free(layout[i].layout_list);
}
free(layout);
}
}
struct erase_layout *create_erase_layout(struct flashctx *const flashctx);
struct erase_layout *create_erase_layout(struct flashctx *const flashctx)
{
struct flashchip *chip = flashctx->chip;
struct erase_layout *layout;
size_t erasefn_count = count_usable_erasers(flashctx);
layout = (struct erase_layout *)malloc(sizeof(struct erase_layout) * erasefn_count);
if (layout == NULL)
return NULL;
size_t i;
size_t index = 0;
for (i = 0; i < NUM_ERASEFUNCTIONS; i++) {
if (check_block_eraser(flashctx, i, 0))
continue;
layout[index].erasefn = chip->block_erasers[i].block_erase;
size_t block_count = 0;
size_t sub_block_index = 0;
chipoff_t addr = 0;
int j = 0;
while(addr < chip->total_size * 1024) {
block_count += chip->block_erasers[i].eraseblocks[j].count;
addr += chip->block_erasers[i].eraseblocks[j].size * chip->block_erasers[i].eraseblocks[j].count;
j++;
}
layout[index].block_count = block_count;
layout[index].layout_list = (struct eraseblock_data *)malloc(sizeof(struct eraseblock_data) * block_count);
if (layout[index].layout_list == NULL)
{
free_erase_layout(layout, index);
return NULL;
}
size_t block_num = 0;
chipoff_t start_addr = 0;
chipoff_t end_addr = 0;
for (j = 0; block_num < block_count; j++) {
size_t num;
for (num = 0; num < chip->block_erasers[i].eraseblocks[j].count; num++) {
end_addr = start_addr + chip->block_erasers[i].eraseblocks[j].size - 1;
layout[index].layout_list[block_num].start_addr = start_addr;
layout[index].layout_list[block_num].end_addr = end_addr;
layout[index].layout_list[block_num].selected = false;
layout[index].layout_list[block_num].block_num = block_num;
if (index > 0) {
layout[index].layout_list[block_num].first_sub_block_index = sub_block_index;
while (layout[index-1].layout_list[sub_block_index].start_addr >= start_addr &&
layout[index-1].layout_list[sub_block_index].end_addr <= end_addr &&
sub_block_index < layout[index-1].block_count) {
sub_block_index++;
}
layout[index].layout_list[block_num].last_sub_block_index = sub_block_index - 1;
}
block_num += 1;
start_addr = end_addr + 1;
}
}
index++;
}
return layout;
}
static int erase_block(struct flashctx *const flashctx,
const struct walk_info *const info, const erasefn_t erasefn)
{

View File

@ -359,6 +359,21 @@ struct flashrom_flashctx {
struct flashrom_progress *progress_state;
};
struct eraseblock_data {
chipoff_t start_addr;
chipoff_t end_addr;
bool selected;
size_t block_num;
size_t first_sub_block_index;
size_t last_sub_block_index;
};
struct erase_layout {
struct eraseblock_data* layout_list;
size_t block_count;
erasefunc_t* erasefn;
};
/* Timing used in probe routines. ZERO is -2 to differentiate between an unset
* field and zero delay.
*