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:
parent
dcdf301010
commit
22c621aed2
80
flashrom.c
80
flashrom.c
@ -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)
|
||||
{
|
||||
|
@ -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.
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user