Stefan Reinauer has uploaded this change for review. ( https://review.coreboot.org/c/em100/+/37186 )
Change subject: WIP: Automatic firmware update ......................................................................
WIP: Automatic firmware update
em100 will autoselect the best firmware image for your device when running em100 -U && em100 -F auto.
Signed-off-by: Stefan Reinauer stefan.reinauer@coreboot.org Change-Id: Iec7e640ee6a3574d1031a06d92d1cf5ebdd0da7f --- M em100.c M firmware.c 2 files changed, 69 insertions(+), 27 deletions(-)
git pull ssh://review.coreboot.org:29418/em100 refs/changes/86/37186/1
diff --git a/em100.c b/em100.c index 83fa06a..2d0d8e2 100644 --- a/em100.c +++ b/em100.c @@ -774,7 +774,7 @@ " -t|--trace: trace mode\n" " -O|--offset HEX_VAL: address offset for trace mode\n" " -T|--terminal: terminal mode\n" - " -F|--firmware-update FILE: update EM100pro firmware (dangerous)\n" + " -F|--firmware-update FILE|auto: update EM100pro firmware (dangerous)\n" " -f|--firmware-dump FILE: export raw EM100pro firmware to file\n" " -g|--firmware-write FILE: export EM100pro firmware to DPFW file\n" " -S|--set-serialno NUM: set serial number to NUM\n" diff --git a/firmware.c b/firmware.c index 8712d62..0f1c1d0 100644 --- a/firmware.c +++ b/firmware.c @@ -211,11 +211,40 @@ return 0; }
+typedef struct { + TFILE *autoupdate_file; + struct em100 *em100; +} firmware_update_t; + +static int firmware_update_entry(char *name, TFILE *file, void *data, int ok __unused) +{ + firmware_update_t *update = (firmware_update_t *)data; + + /* firmware files are sorted oldest to newest */ + /* filenames look like firmware/em100pro_fw_2.27_0.89_3.3V.dpfw */ + if (update->em100->hwversion == 4) { + if (memcmp(name, "firmware/em100pro_fw_", 21)) + return 0; + /* The last file that matches is therefore the newest */ + + if ((update->em100->fpga & 0x8000 && + strstr(name, "1.8V")) || strstr(name, "3.3V")) { + update->autoupdate_file=file; + printf("select %s\n", name); + } + return 0; + } + + /* hwversion 6 */ + // double free or corruption (out) + + return 0; +} + int firmware_update(struct em100 *em100, const char *filename, int verify) { #define MAX_VERSION_LENGTH 10 unsigned char page[256], vpage[256]; - FILE *f; long fsize; unsigned char *fw; int i; @@ -236,36 +265,49 @@ exit(1); }
- printf("\nAttempting firmware update with file %s\n", filename); + if (!strncasecmp(filename, "auto", 5)) { + printf("\nAutomatic firmware update.\n"); + TFILE *f = tar_load_compressed(get_em100_file("firmware.tar.xz")); + firmware_update_t data; + data.em100 = em100; + tar_for_each(f, firmware_update_entry, (void *)&data); + fw = data.autoupdate_file->address; + // FIXME this code will try to free(): invalid pointer + // later. + } else { + FILE *f;
- f = fopen(filename, "rb"); - if (!f) { - perror(filename); - return 0; - } + printf("\nFirmware update with file %s\n", filename);
- fseek(f, 0, SEEK_END); - fsize = ftell(f); - if (fsize < 0) { - perror(filename); - fclose(f); - return 0; - } - fseek(f, 0, SEEK_SET); + f = fopen(filename, "rb"); + if (!f) { + perror(filename); + return 0; + }
- fw = malloc(fsize); - if (!fw) { - printf("ERROR: out of memory.\n"); + fseek(f, 0, SEEK_END); + fsize = ftell(f); + if (fsize < 0) { + perror(filename); + fclose(f); + return 0; + } + fseek(f, 0, SEEK_SET); + + fw = malloc(fsize); + if (!fw) { + printf("ERROR: out of memory.\n"); + fclose(f); + return 0; + } + if (fread(fw, fsize, 1, f) != 1) { + perror(filename); + fclose(f); + free(fw); + return 0; + } fclose(f); - return 0; } - if (fread(fw, fsize, 1, f) != 1) { - perror(filename); - fclose(f); - free(fw); - return 0; - } - fclose(f);
if (em100->hwversion == HWVERSION_EM100PRO && (memcmp(fw, "em100pro", 8) != 0 || memcmp(fw + 0x28, "WFPD", 4) != 0)) {