|
@@ -3,6 +3,7 @@
|
|
|
#include "spiflash.h"
|
|
|
#include "esp.h"
|
|
|
#include "matchver.h"
|
|
|
+#include "boardinfo_fpga.h"
|
|
|
|
|
|
#if 1
|
|
|
# include "console.h"
|
|
@@ -30,6 +31,7 @@ struct spz_stream {
|
|
|
};
|
|
|
};
|
|
|
struct fw_header header; /* Header of currently processed chunk */
|
|
|
+ struct fw_header vmatch; /* Matched firmware version string */
|
|
|
int err; /* Error code to return */
|
|
|
bool eoi; /* Reached end of input */
|
|
|
bool cleanup; /* Call inflateEnd() */
|
|
@@ -451,7 +453,7 @@ static int spiflash_flash_chunk(spz_stream *spz)
|
|
|
|
|
|
spiflash_check_block(spz, addr, &erase_mask, prog_mask);
|
|
|
if (erase_mask) {
|
|
|
- spz->err = SPIFLASH_ERR_ERASE_FAILED;
|
|
|
+ spz->err = FWUPDATE_ERR_ERASE_FAILED;
|
|
|
MSG("%04x left, ", erase_mask);
|
|
|
goto err;
|
|
|
}
|
|
@@ -491,7 +493,7 @@ static int spiflash_flash_chunk(spz_stream *spz)
|
|
|
if (memcmp(spz->dbuf + page_offs, spz->vbuf + page_offs,
|
|
|
SPIFLASH_PAGE_SIZE)) {
|
|
|
MSG("verify ");
|
|
|
- spz->err = SPIFLASH_ERR_PROGRAM_FAILED;
|
|
|
+ spz->err = FWUPDATE_ERR_PROGRAM_FAILED;
|
|
|
goto err;
|
|
|
}
|
|
|
MSG("ok\n");
|
|
@@ -600,23 +602,89 @@ static int esp_ota_chunk(spz_stream *spz)
|
|
|
return spz->err;
|
|
|
}
|
|
|
|
|
|
-/* Process a data chunk; return a nonzero value if done */
|
|
|
-static int spiflash_process_chunk(spz_stream *spz)
|
|
|
+/* Get a piece of the chunk header */
|
|
|
+static int fwupdate_get_header_data(spz_stream *spz, void *buf, int len)
|
|
|
{
|
|
|
int rv;
|
|
|
- char *str;
|
|
|
|
|
|
- rv = spiflash_read_data(spz, &spz->header, sizeof spz->header);
|
|
|
+ rv = spiflash_read_data(spz, buf, len);
|
|
|
if (spz->err)
|
|
|
return spz->err;
|
|
|
else if (!rv)
|
|
|
return Z_STREAM_END;
|
|
|
- else if (rv != sizeof spz->header)
|
|
|
+ else if (rv != len)
|
|
|
return spz->err = Z_STREAM_ERROR;
|
|
|
+ else
|
|
|
+ return Z_OK;
|
|
|
+}
|
|
|
|
|
|
- if (spz->header.magic != FW_MAGIC) {
|
|
|
- MSG("update: bad chunk header magic 0x%08x\n", spz->header.magic);
|
|
|
- return spz->err = Z_DATA_ERROR;
|
|
|
+/* Get and validate a chunk header */
|
|
|
+static int fwupdate_get_header(spz_stream *spz)
|
|
|
+{
|
|
|
+ struct fw_header * const hdr = &spz->header;
|
|
|
+ uint8_t *hptr = (uint8_t *)hdr;
|
|
|
+ int rv;
|
|
|
+ unsigned int hlen;
|
|
|
+
|
|
|
+ memset(hdr, 0, sizeof *hdr);
|
|
|
+ hdr->vmax = -1;
|
|
|
+
|
|
|
+ rv = fwupdate_get_header_data(spz, hptr, FW_HDR_LEN_V1);
|
|
|
+ if (rv)
|
|
|
+ return rv;
|
|
|
+
|
|
|
+ switch (hdr->magic) {
|
|
|
+ case FW_MAGIC_V1:
|
|
|
+ hlen = FW_HDR_LEN_V1;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case FW_MAGIC_V2:
|
|
|
+ hlen = FW_HDR_LEN_V2;
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ MSG("update: bad chunk header magic 0x%08x\n", hdr->magic);
|
|
|
+ hlen = 0;
|
|
|
+ rv = Z_DATA_ERROR;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (hlen > FW_HDR_LEN_V1) {
|
|
|
+ rv = fwupdate_get_header_data(spz, hptr + FW_HDR_LEN_V1,
|
|
|
+ hlen - FW_HDR_LEN_V1);
|
|
|
+
|
|
|
+ if (rv == Z_STREAM_END) /* Only valid for the first chunk */
|
|
|
+ rv = Z_STREAM_ERROR;
|
|
|
+ }
|
|
|
+
|
|
|
+ return spz->err = rv;
|
|
|
+}
|
|
|
+
|
|
|
+/* Process a data chunk; return a nonzero value if done */
|
|
|
+static int spiflash_process_chunk(spz_stream *spz)
|
|
|
+{
|
|
|
+ int rv;
|
|
|
+ char *str;
|
|
|
+
|
|
|
+ rv = fwupdate_get_header(spz);
|
|
|
+ if (rv)
|
|
|
+ return rv;
|
|
|
+
|
|
|
+ if (spz->header.type != FDT_NOTE &&
|
|
|
+ spz->header.type != FDT_TARGET &&
|
|
|
+ spz->header.type != FDT_END &&
|
|
|
+ !(spz->header.flags & FDF_PRETARGET)) {
|
|
|
+ if (!spz->vmatch.magic) {
|
|
|
+ /* No matching firmware target support */
|
|
|
+ return spz->err = FWUPDATE_ERR_NOT_MINE;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (spz->header.vmin > spz->vmatch.vmax ||
|
|
|
+ spz->header.vmax < spz->vmatch.vmin ||
|
|
|
+ ((spz->header.vmatch ^ spz->header.vmatch) & spz->header.vmask)) {
|
|
|
+ /* Chunk not applicable to this target */
|
|
|
+ goto skip;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
con_printf("update: chunk type %u size %u addr 0x%08x\n",
|
|
@@ -630,14 +698,17 @@ static int spiflash_process_chunk(spz_stream *spz)
|
|
|
goto skip;
|
|
|
return spiflash_flash_chunk(spz);
|
|
|
case FDT_TARGET:
|
|
|
+ {
|
|
|
+ bool match;
|
|
|
str = spiflash_read_chunk_str(spz);
|
|
|
- /* XXX: replace with proper matching algorithm */
|
|
|
- if (!str || !match_version(spz->flash->target, str)) {
|
|
|
- MSG("update: this firmware file targets \"%s\", need \"%s\"\n",
|
|
|
- str, spz->flash->target);
|
|
|
- return spz->err = Z_DATA_ERROR;
|
|
|
- }
|
|
|
- break;
|
|
|
+ match = match_version(board_info.version_str, str);
|
|
|
+ if (match || spz->header.magic == FW_MAGIC_V1)
|
|
|
+ spz->vmatch = spz->header;
|
|
|
+
|
|
|
+ MSG("update: firmware file supports: %s%s\n",
|
|
|
+ str, match ? " (match)" : "");
|
|
|
+ return Z_OK;
|
|
|
+ }
|
|
|
case FDT_NOTE:
|
|
|
str = spiflash_read_chunk_str(spz);
|
|
|
MSG("update: %s\n", str);
|