mirror of
https://review.coreboot.org/flashrom.git
synced 2025-04-26 22:52:34 +02:00
erase/write: Deselect all smaller blocks when large block is selected
Previously the logic which selected large block did deselect of smaller blocks, but only one level below. So some even smaller blocks could still remain selected, and this would result in duplicate erase. This patch deselects all smaller blocks of all levels below, down to the smallest size. If the area is covered by one large block, no other smaller blocks inside are needed. Change-Id: Icfc18d5c090b1dcb92ab157e2c139be71af59300 Spotted-by: persmule <persmule@hardenedlinux.org> Signed-off-by: Anastasia Klimchuk <aklm@flashrom.org> Co-authored-by: persmule <persmule@hardenedlinux.org> Reviewed-on: https://review.coreboot.org/c/flashrom/+/84686 Reviewed-by: Peter Marheine <pmarheine@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
dc88d5d618
commit
25819a432d
@ -189,6 +189,27 @@ static void align_region(const struct erase_layout *layout, struct flashctx *con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Deselect all the blocks from index_to_deselect and down to the smallest. */
|
||||||
|
static void deselect_erase_functions(const struct erase_layout *layout, size_t index_to_deselect,
|
||||||
|
int sub_block_start, const int sub_block_end)
|
||||||
|
{
|
||||||
|
for (int j = sub_block_start; j <= sub_block_end; j++)
|
||||||
|
layout[index_to_deselect].layout_list[j].selected = false;
|
||||||
|
|
||||||
|
int block_start_to_deselect =
|
||||||
|
layout[index_to_deselect].layout_list[sub_block_start].first_sub_block_index;
|
||||||
|
int block_end_to_deselect =
|
||||||
|
layout[index_to_deselect].layout_list[sub_block_end].last_sub_block_index;
|
||||||
|
|
||||||
|
if (index_to_deselect)
|
||||||
|
deselect_erase_functions(layout,
|
||||||
|
index_to_deselect - 1,
|
||||||
|
block_start_to_deselect,
|
||||||
|
block_end_to_deselect);
|
||||||
|
else
|
||||||
|
return; // index_to_deselect has already reached 0, the smallest size of block. we are done.
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @brief Function to select the list of sectors that need erasing
|
* @brief Function to select the list of sectors that need erasing
|
||||||
*
|
*
|
||||||
@ -229,9 +250,17 @@ static void select_erase_functions(struct flashctx *flashctx, const struct erase
|
|||||||
|
|
||||||
const int total_blocks = sub_block_end - sub_block_start + 1;
|
const int total_blocks = sub_block_end - sub_block_start + 1;
|
||||||
if (count == total_blocks) {
|
if (count == total_blocks) {
|
||||||
|
/* We are selecting one large block instead, so send opcode once
|
||||||
|
* instead of sending many smaller ones.
|
||||||
|
*/
|
||||||
if (ll->start_addr >= rstart && ll->end_addr <= rend) {
|
if (ll->start_addr >= rstart && ll->end_addr <= rend) {
|
||||||
for (int j = sub_block_start; j <= sub_block_end; j++)
|
/* Deselect all smaller blocks covering the same region. */
|
||||||
layout[findex - 1].layout_list[j].selected = false;
|
deselect_erase_functions(layout,
|
||||||
|
findex - 1,
|
||||||
|
sub_block_start,
|
||||||
|
sub_block_end);
|
||||||
|
|
||||||
|
/* Select large block. */
|
||||||
ll->selected = true;
|
ll->selected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user