flashrom.c: Add a function to get list of sectors that need erasing
Add a function that returns a list of sectors (as seen by the first
erase function) that need erasing.
Change-Id: Ic57ca1cca3d1646543f6b5939ba9c35db8d08256
Signed-off-by: Aarya Chaumal <aarya.chaumal@gmail.com>
Reviewed-on: https://review.coreboot.org/c/flashrom-stable/+/72552
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Nico Huber <nico.h@gmx.de>
diff --git a/flashrom.c b/flashrom.c
index 634820e..53693ff 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -1062,6 +1062,58 @@
return layout_idx;
}
+/*
+ * @brief Function to select the list of sectors that need erasing
+ *
+ * @param flashctx flash context
+ * @param layout erase layout
+ * @param findex index of the erase function
+ * @param block_num index of the block to erase according to the erase function index
+ * @param curcontents buffer containg the current contents of the flash
+ * @param newcontents buffer containg the new contents of the flash
+ * @param rstart start address of the region
+ * @rend rend end address of the region
+ */
+void select_erase_functions(struct flashctx *flashctx, const struct erase_layout *layout,
+ size_t findex, size_t block_num, uint8_t *curcontents, uint8_t *newcontents,
+ chipoff_t rstart, chipoff_t rend);
+void select_erase_functions(struct flashctx *flashctx, const struct erase_layout *layout,
+ size_t findex, size_t block_num, uint8_t *curcontents, uint8_t *newcontents,
+ chipoff_t rstart, chipoff_t rend)
+{
+ struct eraseblock_data *ll = &layout[findex].layout_list[block_num];
+ if (!findex) {
+ if (ll->start_addr >= rstart && ll->end_addr <= rend) {
+ chipoff_t start_addr = ll->start_addr;
+ chipoff_t end_addr = ll->end_addr;
+ const chipsize_t erase_len = end_addr - start_addr + 1;
+ const uint8_t erased_value = ERASED_VALUE(flashctx);
+ ll->selected = need_erase(curcontents + start_addr, newcontents + start_addr, erase_len,
+ flashctx->chip->gran, erased_value);
+ }
+ } else {
+ int count = 0;
+ const int sub_block_start = ll->first_sub_block_index;
+ const int sub_block_end = ll->last_sub_block_index;
+
+ for (int j = sub_block_start; j <= sub_block_end; j++) {
+ select_erase_functions(flashctx, layout, findex - 1, j, curcontents, newcontents,
+ rstart, rend);
+ if (layout[findex - 1].layout_list[j].selected)
+ count++;
+ }
+
+ const int total_blocks = sub_block_end - sub_block_start + 1;
+ if (count && count > total_blocks/2) {
+ if (ll->start_addr >= rstart && ll->end_addr <= rend) {
+ for (int j = sub_block_start; j <= sub_block_end; j++)
+ layout[findex - 1].layout_list[j].selected = false;
+ ll->selected = true;
+ }
+ }
+ }
+}
+
static int write_range(struct flashctx *const flashctx, const chipoff_t flash_offset,
const uint8_t *const curcontents, const uint8_t *const newcontents,
const chipsize_t len, bool *const skipped)