Patchwork Use layout for write/verify (for 0.9.7) (unstable)

login
register
about
Submitter Vasiliy Vylegzhanin
Date 2013-11-06 14:53:09
Message ID <CAHp+LVW3UGHmco404Q-WfyxWqa=id4iiqYvos_Wqu5eQ4-ZSYw@mail.gmail.com>
Download mbox | patch
Permalink /patch/4089/
State New
Headers show

Comments

Vasiliy Vylegzhanin - 2013-11-06 14:53:09
Adpoted patch from http://patchwork.coreboot.org/user/bundle/37/ for
layout support for read ops and new code for verify. Doesn't read
whole chip when writing regions, useful when some regions are locked
(e.g. ME).

DO NOT USE UNLESS YOU KNOW WHAT YOU ARE DOING

If flashrom can't erase desired blocks for some reason, it can erase
the whole chip.

Patch

diff --git a/flashrom-0.9.7/flash.h b/flashrom-0.9.7-m/flash.h
index 63701ed..699ce5d 100644
--- a/flashrom-0.9.7/flash.h
+++ b/flashrom-0.9.7-m/flash.h
@@ -45,6 +45,14 @@ 
 typedef uintptr_t chipaddr;
 #define PRIxPTR_WIDTH ((int)(sizeof(uintptr_t)*2))
 
+typedef struct {
+	unsigned int start;
+	unsigned int end;
+	unsigned int included;
+	char name[256];
+	char file[256]; /* file == "" means not specified. */
+} romlayout_t;
+
 int register_shutdown(int (*function) (void *data), void *data);
 void *programmer_map_flash_region(const char *descr, uintptr_t phys_addr, size_t len);
 void programmer_unmap_flash_region(void *virt_addr, size_t len);
@@ -320,6 +328,7 @@  int register_include_arg(char *name);
 int process_include_args(void);
 int read_romlayout(char *name);
 int handle_romentries(const struct flashctx *flash, uint8_t *oldcontents, uint8_t *newcontents);
+romlayout_t *get_next_included_romentry(unsigned int start);
 
 /* spi.c */
 struct spi_command {
diff --git a/flashrom-0.9.7/flashrom.c b/flashrom-0.9.7-m/flashrom.c
index 86e64a2..52e8542 100644
--- a/flashrom-0.9.7/flashrom.c
+++ b/flashrom-0.9.7-m/flashrom.c
@@ -701,6 +701,30 @@  out_free:
 	return ret;
 }
 
+int verify_flash(struct flashctx *flash, uint8_t *cmpbuf)
+{
+	romlayout_t *l;
+
+	l = get_next_included_romentry(0);
+	/* No included rom entries. Assume complete readout wanted. */
+	if (l == NULL)
+		return verify_range(flash, cmpbuf, 0, flash->chip->total_size * 1024);
+
+	do {
+		unsigned int len = l->end - l->start + 1;
+		msg_gdbg2("Verifying \"%s\" 0x%08x - 0x%08x (%uB)... ", l->name,
+			  l->start, l->end, len);
+		if(verify_range(flash, cmpbuf, l->start, len)) {
+			msg_gdbg2("failed. ");
+			return 1;
+		}
+		msg_gdbg2("done. ");
+		l = get_next_included_romentry(l->end + 1);
+	} while (l != NULL);
+
+	return 0;
+}
+
 /* Helper function for need_erase() that focuses on granularities of gran bytes. */
 static int need_erase_gran_bytes(uint8_t *have, uint8_t *want, unsigned int len, unsigned int gran)
 {
@@ -1198,7 +1222,7 @@  int read_buf_from_file(unsigned char *buf, unsigned long size,
 	return 0;
 }
 
-int write_buf_to_file(unsigned char *buf, unsigned long size,
+int write_dump_to_file(unsigned char *buf, unsigned long size,
 		      const char *filename)
 {
 	unsigned long numbytes;
@@ -1223,26 +1247,79 @@  int write_buf_to_file(unsigned char *buf, unsigned long size,
 	return 0;
 }
 
+int write_buf_to_file(unsigned char *buf, unsigned long size,
+		      const char *filename)
+{
+	romlayout_t *l;
+	int ret = 0;
+
+	ret = write_dump_to_file(buf, size, filename);
+	if (ret)
+		return ret;
+
+	l = get_next_included_romentry(0);
+
+	while (l != NULL) {
+		const char* name = (l->file[0] == '\0') ? l->name : l->file;
+		unsigned int len = l->end - l->start + 1;
+		msg_gdbg2("Writing \"%s\" to \"%s\" 0x%08x - 0x%08x (%uB)... ",
+			  l->name, l->file, l->start, l->end, len);
+		if(write_dump_to_file(buf + l->start, len, name)) {
+			msg_gdbg2("failed. ");
+			return 1;
+		}
+		msg_gdbg2("done. ");
+		l = get_next_included_romentry(l->end + 1);
+	};
+
+	return 0;
+}
+
+int read_flash_to_buf(struct flashctx *flash, uint8_t *buf)
+{
+	romlayout_t *l;
+
+	if (!flash->chip->read) {
+		msg_cerr("No read function available for this flash chip.\n");
+		return 1;
+	}
+
+	l = get_next_included_romentry(0);
+	/* No included rom entries. Assume complete readout wanted. */
+	if (l == NULL)
+		return flash->chip->read(flash, buf, 0, flash->chip->total_size * 1024);
+
+	do {
+		unsigned int len = l->end - l->start + 1;
+		msg_gdbg2("Reading \"%s\" 0x%08x - 0x%08x (%uB)... ", l->name,
+			  l->start, l->end, len);
+		if(flash->chip->read(flash, buf + l->start, l->start, len)) {
+			msg_gdbg2("failed. ");
+			return 1;
+		}
+		msg_gdbg2("done. ");
+		l = get_next_included_romentry(l->end + 1);
+	} while (l != NULL);
+
+	return 0;
+}
+
 int read_flash_to_file(struct flashctx *flash, const char *filename)
 {
 	unsigned long size = flash->chip->total_size * 1024;
-	unsigned char *buf = calloc(size, sizeof(char));
+	unsigned char *buf;
 	int ret = 0;
 
 	msg_cinfo("Reading flash... ");
-	if (!buf) {
+	buf = calloc(size, sizeof(uint8_t));
+	if (buf == NULL) {
 		msg_gerr("Memory allocation failed!\n");
-		msg_cinfo("FAILED.\n");
-		return 1;
-	}
-	if (!flash->chip->read) {
-		msg_cerr("No read function available for this flash chip.\n");
 		ret = 1;
 		goto out_free;
 	}
-	if (flash->chip->read(flash, buf, 0, size)) {
+	ret = read_flash_to_buf(flash, buf);
+	if (ret != 0) {
 		msg_cerr("Read operation failed!\n");
-		ret = 1;
 		goto out_free;
 	}
 
@@ -1976,7 +2053,8 @@  int doit(struct flashctx *flash, int force, const char *filename, int read_it,
 	 * takes time as well.
 	 */
 	msg_cinfo("Reading old flash chip contents... ");
-	if (flash->chip->read(flash, oldcontents, 0, size)) {
+//	if (flash->chip->read(flash, oldcontents, 0, size)) {
+	if (read_flash_to_buf(flash, oldcontents)) {
 		ret = 1;
 		msg_cinfo("FAILED.\n");
 		goto out;
@@ -1993,7 +2071,8 @@  int doit(struct flashctx *flash, int force, const char *filename, int read_it,
 		if (erase_and_write_flash(flash, oldcontents, newcontents)) {
 			msg_cerr("Uh oh. Erase/write failed. Checking if "
 				 "anything changed.\n");
-			if (!flash->chip->read(flash, newcontents, 0, size)) {
+//			if (!flash->chip->read(flash, newcontents, 0, size)) {
+			if (!read_flash_to_buf(flash, oldcontents)) {
 				if (!memcmp(oldcontents, newcontents, size)) {
 					msg_cinfo("Good. It seems nothing was changed.\n");
 					nonfatal_help_message();
@@ -2014,7 +2093,7 @@  int doit(struct flashctx *flash, int force, const char *filename, int read_it,
 		if (write_it) {
 			/* Work around chips which need some time to calm down. */
 			programmer_delay(1000*1000);
-			ret = verify_range(flash, newcontents, 0, size);
+			ret = verify_flash(flash, newcontents);
 			/* If we tried to write, and verification now fails, we
 			 * might have an emergency situation.
 			 */
diff --git a/flashrom-0.9.7/layout.c b/flashrom-0.9.7-m/layout.c
index 1bd3152..c53047d 100644
--- a/flashrom-0.9.7/layout.c
+++ b/flashrom-0.9.7-m/layout.c
@@ -29,13 +29,6 @@  static int romimages = 0;
 
 #define MAX_ROMLAYOUT	32
 
-typedef struct {
-	unsigned int start;
-	unsigned int end;
-	unsigned int included;
-	char name[256];
-} romlayout_t;
-
 /* include_args lists arguments specified at the command line with -i. They
  * must be processed at some point so that desired regions are marked as
  * "included" in the rom_entries list.