summaryrefslogtreecommitdiffstats
path: root/flashrom.c
diff options
context:
space:
mode:
Diffstat (limited to 'flashrom.c')
-rw-r--r--flashrom.c63
1 files changed, 41 insertions, 22 deletions
diff --git a/flashrom.c b/flashrom.c
index 26b9863c8..d87a43171 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -2345,13 +2345,15 @@ static void combine_image_by_layout(const struct flashctx *const flashctx,
* @param flashctx The context of the flash chip.
* @param buffer Source buffer to read image from (may be altered for full verification).
* @param buffer_len Size of source buffer in bytes.
+ * @param refbuffer If given, assume flash chip contains same data as `refbuffer`.
* @return 0 on success,
* 4 if buffer_len doesn't match the size of the flash chip,
* 3 if write was tried but nothing has changed,
* 2 if write failed and flash contents changed,
* or 1 on any other failure.
*/
-int flashrom_image_write(struct flashctx *const flashctx, void *const buffer, const size_t buffer_len)
+int flashrom_image_write(struct flashctx *const flashctx, void *const buffer, const size_t buffer_len,
+ const void *const refbuffer)
{
const size_t flash_size = flashctx->chip->total_size * 1024;
const bool verify_all = flashctx->flags.verify_whole_chip;
@@ -2363,6 +2365,7 @@ int flashrom_image_write(struct flashctx *const flashctx, void *const buffer, co
int ret = 1;
uint8_t *const newcontents = buffer;
+ const uint8_t *const refcontents = refbuffer;
uint8_t *const curcontents = malloc(flash_size);
uint8_t *oldcontents = NULL;
if (verify_all)
@@ -2387,27 +2390,35 @@ int flashrom_image_write(struct flashctx *const flashctx, void *const buffer, co
if (prepare_flash_access(flashctx, false, true, false, verify))
goto _free_ret;
- /*
- * Read the whole chip to be able to check whether regions need to be
- * erased and to give better diagnostics in case write fails.
- * The alternative is to read only the regions which are to be
- * preserved, but in that case we might perform unneeded erase which
- * takes time as well.
- */
- msg_cinfo("Reading old flash chip contents... ");
- if (verify_all) {
- if (flashctx->chip->read(flashctx, oldcontents, 0, flash_size)) {
- msg_cinfo("FAILED.\n");
- goto _finalize_ret;
- }
- memcpy(curcontents, oldcontents, flash_size);
+ /* If given, assume flash chip contains same data as `refcontents`. */
+ if (refcontents) {
+ msg_cinfo("Assuming old flash chip contents as ref-file...\n");
+ memcpy(curcontents, refcontents, flash_size);
+ if (oldcontents)
+ memcpy(oldcontents, refcontents, flash_size);
} else {
- if (read_by_layout(flashctx, curcontents)) {
- msg_cinfo("FAILED.\n");
- goto _finalize_ret;
+ /*
+ * Read the whole chip to be able to check whether regions need to be
+ * erased and to give better diagnostics in case write fails.
+ * The alternative is to read only the regions which are to be
+ * preserved, but in that case we might perform unneeded erase which
+ * takes time as well.
+ */
+ msg_cinfo("Reading old flash chip contents... ");
+ if (verify_all) {
+ if (flashctx->chip->read(flashctx, oldcontents, 0, flash_size)) {
+ msg_cinfo("FAILED.\n");
+ goto _finalize_ret;
+ }
+ memcpy(curcontents, oldcontents, flash_size);
+ } else {
+ if (read_by_layout(flashctx, curcontents)) {
+ msg_cinfo("FAILED.\n");
+ goto _finalize_ret;
+ }
}
+ msg_cinfo("done.\n");
}
- msg_cinfo("done.\n");
if (write_by_layout(flashctx, curcontents, newcontents)) {
msg_cerr("Uh oh. Erase/write failed. ");
@@ -2542,13 +2553,15 @@ int do_erase(struct flashctx *const flash)
return ret;
}
-int do_write(struct flashctx *const flash, const char *const filename)
+int do_write(struct flashctx *const flash, const char *const filename, const char *const referencefile)
{
const size_t flash_size = flash->chip->total_size * 1024;
int ret = 1;
uint8_t *const newcontents = malloc(flash_size);
- if (!newcontents) {
+ uint8_t *const refcontents = referencefile ? malloc(flash_size) : NULL;
+
+ if (!newcontents || (referencefile && !refcontents)) {
msg_gerr("Out of memory!\n");
goto _free_ret;
}
@@ -2556,9 +2569,15 @@ int do_write(struct flashctx *const flash, const char *const filename)
if (read_buf_from_file(newcontents, flash_size, filename))
goto _free_ret;
- ret = flashrom_image_write(flash, newcontents, flash_size);
+ if (referencefile) {
+ if (read_buf_from_file(refcontents, flash_size, referencefile))
+ goto _free_ret;
+ }
+
+ ret = flashrom_image_write(flash, newcontents, flash_size, refcontents);
_free_ret:
+ free(refcontents);
free(newcontents);
return ret;
}