Stefan Reinauer has submitted this change. ( https://review.coreboot.org/c/em100/+/37186 )
Change subject: Automatic firmware update ......................................................................
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 Reviewed-on: https://review.coreboot.org/c/em100/+/37186 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Patrick Georgi pgeorgi@google.com --- M em100.c M firmware.c 2 files changed, 82 insertions(+), 28 deletions(-)
Approvals: build bot (Jenkins): Verified Patrick Georgi: Looks good to me, approved
diff --git a/em100.c b/em100.c index 1f9f4b6..25d9732 100644 --- a/em100.c +++ b/em100.c @@ -784,7 +784,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 384e3f3..59e1765 100644 --- a/firmware.c +++ b/firmware.c @@ -208,14 +208,45 @@ 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 == HWVERSION_EM100PRO_EARLY || + update->em100->hwversion == HWVERSION_EM100PRO) { +#define FIRMWARE_PATH "firmware/em100pro_fw_" + if (strncmp(name, FIRMWARE_PATH, strlen(FIRMWARE_PATH))) + 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 */ + printf("EM100Pro-G2 currently does not support auto-updating firmware.\n"); + + return 1; +} + 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; + int i, automatic = 0; int fpga_offset, fpga_len, mcu_offset, mcu_len; char fpga_version[MAX_VERSION_LENGTH + 1], mcu_version[MAX_VERSION_LENGTH + 1]; @@ -234,36 +265,59 @@ 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; + data.autoupdate_file = NULL; + tar_for_each(f, firmware_update_entry, (void *)&data); + if (data.autoupdate_file == NULL) { + printf("Could not find suitable firmware for autoupdate\n"); + return 0; + } + fsize = data.autoupdate_file->length; + fw = malloc(fsize); + if (!fw) { + printf("ERROR: out of memory.\n"); + return 0; + } + memcpy(fw, data.autoupdate_file->address, fsize); + automatic = 1; + } 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_EARLY && (memcmp(fw, "em100pro", 8) != 0 || memcmp(fw + 0x28, "WFPD", 4) != 0)) {