flashrom.c: Simplify read_erase_write_block()
Since erase_block() learned to handle potentially unaligned regions,
and read_erase_write_block() uses it internally, we don't have to
handle that inside the latter anymore. This allows a much simpler
implementation. Also change the name to write_block().
Change-Id: I46826951d8bd345957368da83f8d4e8b3b6c53b2
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.coreboot.org/c/flashrom-stable/+/72548
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/flashrom.c b/flashrom.c
index cb84bdd..302d27a 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -1097,82 +1097,36 @@
return walk_by_layout(flashctx, &info, &erase_block);
}
-static int read_erase_write_block(struct flashctx *const flashctx,
- const struct walk_info *const info, const erasefn_t erasefn)
+static int write_block(struct flashctx *const flashctx,
+ const struct walk_info *const info, const erasefn_t erasefn)
{
- const chipsize_t erase_len = info->erase_end + 1 - info->erase_start;
- const bool region_unaligned = info->region_start > info->erase_start ||
- info->erase_end > info->region_end;
- const uint8_t *newcontents = NULL;
- int ret = 2;
-
- /*
- * If the region is not erase-block aligned, merge current flash con-
- * tents into `info->curcontents` and a new buffer `newc`. The former
- * is necessary since we have no guarantee that the full erase block
- * was already read into `info->curcontents`. For the latter a new
- * buffer is used since `info->newcontents` might contain data for
- * other unaligned regions that touch this erase block too.
- */
- if (region_unaligned) {
- msg_cdbg("R");
- uint8_t *const newc = malloc(erase_len);
- if (!newc) {
- msg_cerr("Out of memory!\n");
- return 1;
- }
- memcpy(newc, info->newcontents + info->erase_start, erase_len);
-
- /* Merge data preceding the current region. */
- if (info->region_start > info->erase_start) {
- const chipoff_t start = info->erase_start;
- const chipsize_t len = info->region_start - info->erase_start;
- if (flashctx->chip->read(flashctx, newc, start, len)) {
- msg_cerr("Can't read! Aborting.\n");
- goto _free_ret;
- }
- memcpy(info->curcontents + start, newc, len);
- }
- /* Merge data following the current region. */
- if (info->erase_end > info->region_end) {
- const chipoff_t start = info->region_end + 1;
- const chipoff_t rel_start = start - info->erase_start; /* within this erase block */
- const chipsize_t len = info->erase_end - info->region_end;
- if (flashctx->chip->read(flashctx, newc + rel_start, start, len)) {
- msg_cerr("Can't read! Aborting.\n");
- goto _free_ret;
- }
- memcpy(info->curcontents + start, newc + rel_start, len);
- }
-
- newcontents = newc;
- } else {
- newcontents = info->newcontents + info->erase_start;
- }
-
- ret = 1;
- bool skipped = true;
- uint8_t *const curcontents = info->curcontents + info->erase_start;
+ const chipoff_t write_start = MAX(info->region_start, info->erase_start);
+ const chipoff_t write_end = MIN(info->region_end, info->erase_end);
+ const chipsize_t write_len = write_end + 1 - write_start;
+ const uint8_t *const newcontents = info->newcontents + write_start;
+ uint8_t *const curcontents = info->curcontents + write_start;
const uint8_t erased_value = ERASED_VALUE(flashctx);
+ bool skipped = true;
+
if (!(flashctx->chip->feature_bits & FEATURE_NO_ERASE) &&
- need_erase(curcontents, newcontents, erase_len, flashctx->chip->gran, erased_value)) {
+ need_erase(curcontents, newcontents, write_len, flashctx->chip->gran, erased_value)) {
if (erase_block(flashctx, info, erasefn))
- goto _free_ret;
+ return 1;
/* Erase was successful. Adjust curcontents. */
- memset(curcontents, erased_value, erase_len);
+ memset(curcontents, erased_value, write_len);
skipped = false;
}
unsigned int starthere = 0, lenhere = 0, writecount = 0;
/* get_next_write() sets starthere to a new value after the call. */
while ((lenhere = get_next_write(curcontents + starthere, newcontents + starthere,
- erase_len - starthere, &starthere, flashctx->chip->gran))) {
+ write_len - starthere, &starthere, flashctx->chip->gran))) {
if (!writecount++)
msg_cdbg("W");
/* Needs the partial write function signature. */
if (flashctx->chip->write(flashctx, newcontents + starthere,
- info->erase_start + starthere, lenhere))
- goto _free_ret;
+ write_start + starthere, lenhere))
+ return 1;
starthere += lenhere;
skipped = false;
}
@@ -1183,13 +1137,8 @@
/* Update curcontents, other regions with overlapping erase blocks
might rely on this. */
- memcpy(curcontents, newcontents, erase_len);
- ret = 0;
-
-_free_ret:
- if (region_unaligned)
- free((void *)newcontents);
- return ret;
+ memcpy(curcontents, newcontents, write_len);
+ return 0;
}
/**
@@ -1210,7 +1159,7 @@
struct walk_info info;
info.curcontents = curcontents;
info.newcontents = newcontents;
- return walk_by_layout(flashctx, &info, read_erase_write_block);
+ return walk_by_layout(flashctx, &info, write_block);
}
/**