summaryrefslogtreecommitdiffstats
path: root/flashrom.c
diff options
context:
space:
mode:
authorPaul Kocialkowski <contact@paulk.fr>2018-01-15 01:10:36 +0300
committerNico Huber <nico.h@gmx.de>2018-02-11 16:54:14 +0000
commitf701f343117270b4373320eb25ae259b8e513b7d (patch)
tree2749940aec9f2b1dc0ad53069079b78f225d76cf /flashrom.c
parent3a826043dbd389b4be2f5783c1b984ba297b8179 (diff)
downloadflashrom-f701f343117270b4373320eb25ae259b8e513b7d.tar.gz
flashrom-f701f343117270b4373320eb25ae259b8e513b7d.tar.bz2
flashrom-f701f343117270b4373320eb25ae259b8e513b7d.zip
Add support for reading the current flash contents from a file
When developing software that has to be flashed to a flash chip to be executed, it often takes a long time to read the current flash contents (for flashrom to know what pages to erase and reprogram) each time when writing the new image. However, when the flash was just reprogrammed, its current state is known to be the previous image that was flashed (assuming it was verified). Thus, it makes sense to provide that image as a file for the flash contents instead of wasting valuable time read the whole flash each time. Change-Id: Idf153b6955f37779ae9bfb228a434ed10c304947 Signed-off-by: Mike Banon <mikebdp2@gmail.com> Signed-off-by: Paul Kocialkowski <contact@paulk.fr> Reviewed-on: https://review.coreboot.org/23263 Reviewed-by: Nico Huber <nico.h@gmx.de> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
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;
}