From 9bcf2684d7781de71551ab14d3c3be46890ca432 Mon Sep 17 00:00:00 2001 From: Louis Yung-Chieh Lo Date: Sun, 25 Dec 2011 09:12:16 +0000 Subject: Add deferred --image processing The general idea and most of the code are based on the following commits in the chromiumos flashrom tree: Corresponding to flashrom svn r1482. 8fc0740356ca15d02fb1c65ab43b10844f148c3b bb9049c66ca55e0dc621dd2c70b5d2cb6e5179bf Signed-off-by: Louis Yung-Chieh Lo and the main part: d0ea9ed71e7f86bb8e8db2ca7c32a96de25343d8 Signed-off-by: David Hendricks This implementation does not defer the processing until doit(), but after the argument parsing loop only (doit() should not contain argument checks). This allows to specify -i and -l parameters in any order. Signed-off-by: Stefan Tauner Acked-by: David Hendricks --- cli_classic.c | 10 +++---- flash.h | 3 ++- layout.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 78 insertions(+), 20 deletions(-) diff --git a/cli_classic.c b/cli_classic.c index a931de8..3928ded 100644 --- a/cli_classic.c +++ b/cli_classic.c @@ -295,14 +295,9 @@ int main(int argc, char *argv[]) cli_classic_abort_usage(); break; case 'i': - /* FIXME: -l has to be specified before -i. */ tempstr = strdup(optarg); - if (find_romentry(tempstr) < 0) { - fprintf(stderr, "Error: image %s not found in " - "layout file or -i specified before " - "-l\n", tempstr); + if (register_include_arg(tempstr)) cli_classic_abort_usage(); - } break; case 'L': if (++operation_specified > 1) { @@ -395,6 +390,9 @@ int main(int argc, char *argv[]) cli_classic_abort_usage(); } + if (process_include_args()) + cli_classic_abort_usage(); + /* FIXME: Print the actions flashrom will take. */ if (list_supported) { diff --git a/flash.h b/flash.h index e21a986..e51b6d4 100644 --- a/flash.h +++ b/flash.h @@ -289,8 +289,9 @@ int print(int type, const char *fmt, ...) __attribute__((format(printf, 2, 3))); #define msg_cspew(...) print(MSG_BARF, __VA_ARGS__) /* chip debug barf */ /* layout.c */ +int register_include_arg(char *name); +int process_include_args(void); int read_romlayout(char *name); -int find_romentry(char *name); int handle_romentries(struct flashctx *flash, uint8_t *oldcontents, uint8_t *newcontents); /* spi.c */ diff --git a/layout.c b/layout.c index aef520c..1f7f01a 100644 --- a/layout.c +++ b/layout.c @@ -41,6 +41,12 @@ typedef struct { 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. + */ +static char *include_args[MAX_ROMLAYOUT]; +static int num_include_args = 0; /* the number of valid entries. */ static romlayout_t rom_entries[MAX_ROMLAYOUT]; #if CONFIG_INTERNAL == 1 /* FIXME: Move the whole block to cbtable.c? */ @@ -156,10 +162,8 @@ int read_romlayout(char *name) if (romimages >= MAX_ROMLAYOUT) { msg_gerr("Maximum number of ROM images (%i) in layout " - "file reached before end of layout file.\n", - MAX_ROMLAYOUT); - msg_gerr("Ignoring the rest of the layout file.\n"); - break; + "file reached.\n", MAX_ROMLAYOUT); + return 1; } if (2 != fscanf(romlayout, "%s %s\n", tempstr, rom_entries[romimages].name)) continue; @@ -194,27 +198,80 @@ int read_romlayout(char *name) } #endif -int find_romentry(char *name) +/* register an include argument (-i) for later processing */ +int register_include_arg(char *name) +{ + if (num_include_args >= MAX_ROMLAYOUT) { + msg_gerr("Too many regions included (%i).\n", num_include_args); + return 1; + } + + if (name == NULL) { + msg_gerr(" is a bad region name.\n"); + return 1; + } + + include_args[num_include_args] = name; + num_include_args++; + return 0; +} + +/* returns the index of the entry (or a negative value if it is not found) */ +static int find_romentry(char *name) { int i; if (!romimages) return -1; - msg_ginfo("Looking for \"%s\"... ", name); - + msg_gspew("Looking for region \"%s\"... ", name); for (i = 0; i < romimages; i++) { if (!strcmp(rom_entries[i].name, name)) { rom_entries[i].included = 1; - msg_ginfo("found.\n"); + msg_gspew("found.\n"); return i; } } - msg_ginfo("not found.\n"); // Not found. Error. - + msg_gspew("not found.\n"); return -1; } +/* process -i arguments + * returns 0 to indicate success, >0 to indicate failure + */ +int process_include_args(void) +{ + int i; + unsigned int found = 0; + + if (num_include_args == 0) + return 0; + + for (i = 0; i < num_include_args; i++) { + /* User has specified an area, but no layout file is loaded. */ + if (!romimages) { + msg_gerr("Region requested (with -i \"%s\"), " + "but no layout data is available.\n", + include_args[i]); + return 1; + } + + if (find_romentry(include_args[i]) < 0) { + msg_gerr("Invalid region specified: \"%s\"\n", + include_args[i]); + return 1; + } + found++; + } + + msg_ginfo("Using region%s: \"%s\"", num_include_args > 1 ? "s" : "", + include_args[0]); + for (i = 1; i < num_include_args; i++) + msg_ginfo(", \"%s\"", include_args[i]); + msg_ginfo(".\n"); + return 0; +} + romlayout_t *get_next_included_romentry(unsigned int start) { int i; @@ -248,11 +305,12 @@ int handle_romentries(struct flashctx *flash, uint8_t *oldcontents, uint8_t *new romlayout_t *entry; unsigned int size = flash->total_size * 1024; - /* If no layout file was specified or the layout file was empty, assume - * that the user wants to flash the complete new image. + /* If no regions were specified for inclusion, assume + * that the user wants to write the complete new image. */ - if (!romimages) + if (num_include_args == 0) return 0; + /* Non-included romentries are ignored. * The union of all included romentries is used from the new image. */ @@ -264,6 +322,7 @@ int handle_romentries(struct flashctx *flash, uint8_t *oldcontents, uint8_t *new size - start); break; } + /* For non-included region, copy from old content. */ if (entry->start > start) memcpy(newcontents + start, oldcontents + start, entry->start - start); -- cgit v1.1