Previously using layout files was useful for write operations only, for
reads it was ignored. This patch added layout handling for reads.

Based on the "Add -i <image>[:<file>] support" patch this one will
output the selected regions to files. If the optional argument is given
it is used as a file name, else the image name will be used.

---
TODO: man page

side note: the execution path of forced reads is wrong or at least
worth a look. it does not use doit() but calls read_flash_to_file()
directly.

Signed-off-by: Stefan Tauner <stefan.tau...@student.tuwien.ac.at>
---
 flash.h    |    8 ++++++
 flashrom.c |   75 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------
 layout.c   |    8 ------
 3 files changed, 73 insertions(+), 18 deletions(-)

diff --git a/flash.h b/flash.h
index 6151e1c..c4d747b 100644
--- a/flash.h
+++ b/flash.h
@@ -39,6 +39,13 @@
 #define TIMEOUT_ERROR  -101
 
 typedef unsigned long chipaddr;
+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, unsigned long phys_addr,
@@ -292,6 +299,7 @@ int print(int type, const char *fmt, ...) 
__attribute__((format(printf, 2, 3)));
 int register_include_arg(char *name);
 int process_include_args(void);
 int read_romlayout(char *name);
+romlayout_t *get_next_included_romentry(unsigned int start);
 int build_new_image(struct flashctx *flash, int oldcontents_valid, uint8_t 
*oldcontents, uint8_t *newcontents);
 
 /* spi.c */
diff --git a/flashrom.c b/flashrom.c
index 708dba0..2eec0d6 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -1069,7 +1069,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;
@@ -1094,26 +1094,81 @@ 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->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->read(flash, buf, 0, flash->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->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->total_size * 1024;
-       unsigned char *buf = calloc(size, sizeof(char));
        int ret = 0;
+       uint8_t *buf;
 
        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->read) {
-               msg_cerr("No read function available for this flash chip.\n");
                ret = 1;
                goto out_free;
        }
-       if (flash->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;
        }
 
diff --git a/layout.c b/layout.c
index dac9dac..9b10bb3 100644
--- a/layout.c
+++ b/layout.c
@@ -34,14 +34,6 @@ static int romimages = 0;
 
 #define MAX_ROMLAYOUT  32
 
-typedef struct {
-       unsigned int start;
-       unsigned int end;
-       unsigned int included;
-       char name[256];
-       char file[256]; /* file == "" means not specified. */
-} 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.
-- 
1.7.1


_______________________________________________
flashrom mailing list
flashrom@flashrom.org
http://www.flashrom.org/mailman/listinfo/flashrom

Reply via email to