2
0

fwupdate.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. #define MODULE "fwupdate"
  2. #define DEBUG 1
  3. #include "common.h"
  4. #include "jtag.h"
  5. #include "spiflash.h"
  6. #include "fpga.h"
  7. #include "ota.h"
  8. #include "spz.h"
  9. #include "httpd.h"
  10. #include "fw.h"
  11. #include <unzipLIB.h>
  12. #include <zlib.h>
  13. /* Needed for struct inflate_state, due to unziplib hacks */
  14. #include <zutil.h>
  15. #include <inftrees.h>
  16. #include <inflate.h>
  17. #ifndef local
  18. # define local static
  19. #endif
  20. #define BUFFER_SIZE SPIFLASH_SECTOR_SIZE
  21. #define FWUPDATE_STACK 8192
  22. #define FWUPDATE_PRIORITY 3
  23. static void heap_info(void)
  24. {
  25. #if DEBUG > 1
  26. MSG("Heap: sram ");
  27. MSG("%u/", heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL));
  28. MSG("%u, spiram ", heap_caps_get_free_size(MALLOC_CAP_INTERNAL));
  29. MSG("%u/", heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM));
  30. MSG("%u\n", heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
  31. #endif
  32. }
  33. static void *spz_calloc(void *opaque, unsigned int items, unsigned int size)
  34. {
  35. spz_stream *spz = opaque;
  36. heap_info();
  37. MSG("spz_calloc(%u,%u) = %u = ", items, size, items*size);
  38. void *p = calloc(items, size);
  39. CMSG("%p\n", p);
  40. heap_info();
  41. if (!p)
  42. spz->err = Z_MEM_ERROR;
  43. return p;
  44. }
  45. static void *spz_malloc(void *opaque, unsigned int size)
  46. {
  47. spz_stream *spz = opaque;
  48. heap_info();
  49. MSG("spz_malloc(%u) = ", size);
  50. void *p = malloc(size);
  51. CMSG("%p\n", p);
  52. heap_info();
  53. if (!p)
  54. spz->err = Z_MEM_ERROR;
  55. return p;
  56. }
  57. static void spz_free(void *opaque, void *ptr)
  58. {
  59. heap_info();
  60. MSG("spz_free(%p)\n", ptr);
  61. (void)opaque;
  62. free(ptr);
  63. heap_info();
  64. }
  65. int spz_read_data(spz_stream *spz, void *buf, size_t len)
  66. {
  67. uint8_t *p = buf;
  68. while (len) {
  69. unsigned int avail = spz->zs.next_out - spz->optr;
  70. if (spz->err)
  71. break;
  72. if (avail) {
  73. if (avail > len)
  74. avail = len;
  75. memcpy(p, spz->optr, avail);
  76. p += avail;
  77. spz->optr += avail;
  78. len -= avail;
  79. } else {
  80. spz->optr = spz->zs.next_out = spz->obuf;
  81. spz->zs.avail_out = BUFFER_SIZE;
  82. while (spz->zs.avail_out) {
  83. if (!spz->zs.avail_in && !spz->eoi) {
  84. int rlen;
  85. spz->zs.next_in = spz->ibuf;
  86. rlen = spz->read_data(spz->token, spz->ibuf, BUFFER_SIZE);
  87. if (rlen < 0) {
  88. if (!spz->err)
  89. spz->err = rlen;
  90. rlen = 0;
  91. }
  92. spz->eoi = !rlen;
  93. spz->zs.avail_in = rlen;
  94. }
  95. int rv = inflate(&spz->zs, Z_SYNC_FLUSH);
  96. if (rv == Z_OK || (rv == Z_BUF_ERROR && !spz->eoi))
  97. continue;
  98. spz->eoi = true;
  99. if (rv != Z_STREAM_END && !spz->err)
  100. spz->err = rv;
  101. break;
  102. }
  103. }
  104. }
  105. return p - (uint8_t *)buf;
  106. }
  107. /*
  108. * spz needs to be initialized to zero except the read_data and cookie
  109. * fields.
  110. */
  111. static int fwupdate_data_init(spz_stream *spz)
  112. {
  113. spz->zs.zalloc = spz_calloc;
  114. spz->zs.zfree = spz_free;
  115. spz->zs.opaque = spz; /* For error reporting */
  116. spz->err = Z_OK;
  117. /* This is necessary due to unziplib damage */
  118. spz->zs.state = spz_calloc(spz, 1, sizeof(struct inflate_state));
  119. if (!spz->zs.state)
  120. goto err;
  121. for (int i = 0; i < SPZ_NBUF; i++) {
  122. spz->bufs[i] = spz_malloc(spz, BUFFER_SIZE);
  123. if (!spz->bufs[i])
  124. goto err;
  125. }
  126. /* gzip, max window size */
  127. int rv = inflateInit2(&spz->zs, 16 + 15);
  128. printf("[FWUP] fwupdate_data_init: inflateInit2 returned %d\n", rv);
  129. if (rv != Z_OK && rv != Z_STREAM_END) {
  130. spz->err = rv;
  131. goto err;
  132. }
  133. spz->cleanup = true;
  134. err:
  135. return spz->err;
  136. }
  137. static int fwupdate_data_cleanup(spz_stream *spz)
  138. {
  139. int err = 0;
  140. if (!spz)
  141. return 0;
  142. err = spz->err;
  143. if (spz->cleanup)
  144. inflateEnd(&spz->zs);
  145. /* Don't reload the FPGA on error; it wedges the JTAG bus */
  146. if (spz->fpga_updated && !err)
  147. fpga_reset();
  148. for (int i = 0; i < SPZ_NBUF; i++) {
  149. if (spz->bufs[i])
  150. free(spz->bufs[i]);
  151. }
  152. if (spz->zs.state)
  153. free(spz->zs.state);
  154. return err;
  155. }
  156. /*
  157. * Blash a full chunk of data as a JTAG SHIFT_DR transaction
  158. */
  159. int jtag_shift_spz(spz_stream *spz, enum jtag_io_flags flags)
  160. {
  161. unsigned int data_left = spz->header.len;
  162. int err = 0;
  163. if (!data_left)
  164. return 0;
  165. while (data_left) {
  166. unsigned int bytes = data_left;
  167. int rv;
  168. if (bytes > BUFFER_SIZE)
  169. bytes = BUFFER_SIZE;
  170. rv = spz_read_data(spz, spz->dbuf, bytes);
  171. if (rv < 1) {
  172. err = Z_DATA_ERROR;
  173. break;
  174. }
  175. data_left -= rv;
  176. jtag_io(rv << 3, data_left ? 0 : flags, spz->dbuf, NULL);
  177. }
  178. return err;
  179. }
  180. static void *fwupdate_read_chunk_str(spz_stream *spz)
  181. {
  182. int rv;
  183. if (spz->header.len >= BUFFER_SIZE) {
  184. spz->err = Z_DATA_ERROR;
  185. return NULL;
  186. }
  187. rv = spz_read_data(spz, spz->dbuf, spz->header.len);
  188. if (spz->err) {
  189. return NULL;
  190. }
  191. if (rv != (int)spz->header.len) {
  192. spz->err = Z_DATA_ERROR;
  193. return NULL;
  194. }
  195. spz->dbuf[spz->header.len] = '\0';
  196. return spz->dbuf;
  197. }
  198. /* Skip a data chunk */
  199. static int fwupdate_skip_chunk(spz_stream *spz)
  200. {
  201. unsigned int skip = spz->header.len;
  202. while (skip) {
  203. unsigned int block = skip;
  204. if (block > BUFFER_SIZE)
  205. block = BUFFER_SIZE;
  206. int rv = spz_read_data(spz, spz->dbuf, block);
  207. if (spz->err)
  208. return spz->err;
  209. if (rv != (int)block) {
  210. return spz->err = Z_DATA_ERROR;
  211. }
  212. skip -= block;
  213. }
  214. return 0;
  215. }
  216. /* Process a data chunk; return a nonzero value if done */
  217. static int fwupdate_process_chunk(spz_stream *spz)
  218. {
  219. int rv;
  220. char *str;
  221. rv = spz_read_data(spz, &spz->header, sizeof spz->header);
  222. if (spz->err)
  223. return spz->err;
  224. else if (!rv)
  225. return Z_STREAM_END;
  226. else if (rv != sizeof spz->header)
  227. return spz->err = Z_STREAM_ERROR;
  228. if (spz->header.magic != FW_MAGIC) {
  229. MSG("bad chunk header magic 0x%08x\n", spz->header.magic);
  230. return spz->err = Z_DATA_ERROR;
  231. }
  232. switch (spz->header.type) {
  233. case FDT_END:
  234. return Z_STREAM_END; /* End of data - not an error */
  235. case FDT_DATA:
  236. MSG("updating FPGA flash\n");
  237. return spiflash_write_spz(spz);
  238. case FDT_TARGET:
  239. str = fwupdate_read_chunk_str(spz);
  240. #if 0
  241. if (!str || strcmp(str, spz->flash->target)) {
  242. MSG("this firmware file targets \"%s\", need \"%s\"\n",
  243. str, spz->flash->target);
  244. return spz->err = Z_DATA_ERROR;
  245. }
  246. #else
  247. MSG("firmware target: \"%s\"\n", str);
  248. #endif
  249. return Z_OK;
  250. case FDT_NOTE:
  251. str = fwupdate_read_chunk_str(spz);
  252. MSG("%s\n", str);
  253. return Z_OK;
  254. case FDT_ESP_OTA:
  255. MSG("updating ESP32... ");
  256. spz->esp_updated = true;
  257. rv = esp_update((read_func_t)spz_read_data, (token_t)spz,
  258. spz->header.len);
  259. CMSG("done.\n");
  260. return rv;
  261. case FDT_FPGA_INIT:
  262. MSG("initializing FPGA for flash programming... ");
  263. spz->fpga_updated = true;
  264. rv = fpga_program_spz(spz);
  265. CMSG("done\n");
  266. return rv;
  267. default:
  268. if (spz->header.flags & FDF_OPTIONAL) {
  269. return fwupdate_skip_chunk(spz);
  270. } else {
  271. MSG("unknown chunk type: %u\n", spz->header.type);
  272. return spz->err = Z_DATA_ERROR;
  273. }
  274. }
  275. }
  276. const char *firmware_errstr(int err)
  277. {
  278. static char unknown_err[32];
  279. static const char * const errstr[] = {
  280. [-Z_STREAM_ERROR] = "Decompression error",
  281. [-Z_DATA_ERROR] = "Invalid data stream",
  282. [-Z_MEM_ERROR] = "Out of memory",
  283. [-Z_BUF_ERROR] = "Decompression error",
  284. [-FWUPDATE_ERR_IN_PROGRESS] =
  285. "Firmware update already in progress",
  286. [-FWUPDATE_ERR_BAD_CHUNK] = "Invalid firmware chunk header",
  287. [-FWUPDATE_ERR_ERASE_FAILED] = "FPGA flash erase failed",
  288. [-FWUPDATE_ERR_PROGRAM_FAILED] = "FGPA flash program failed",
  289. [-FWUPDATE_ERR_WRITE_PROTECT] = "FPGA flash write protected",
  290. [-FWUPDATE_ERR_NOT_READY] = "FPGA flash stuck at not ready",
  291. [-FWUPDATE_ERR_FPGA_JTAG] =
  292. "FPGA JTAG bus stuck, check for JTAG adapter or power cycle board",
  293. [-FWUPDATE_ERR_FPGA_MISMATCH] =
  294. "Bad FPGA IDCODE, check for JTAG adapter or power cycle board",
  295. [-FWUPDATE_ERR_FPGA_FAILED] = "FPGA reboot failed",
  296. [-FWUPDATE_ERR_UNKNOWN] = "Unidentified error",
  297. [-FWUPDATE_ERR_ESP_NO_PARTITION] = "No available ESP partition",
  298. [-FWUPDATE_ERR_ESP_BAD_OTA] = "ESP OTA information corrupt",
  299. [-FWUPDATE_ERR_ESP_FLASH_FAILED] = "ESP flash program failed",
  300. [-FWUPDATE_ERR_ESP_BAD_DATA] = "ESP firmware image corrupt",
  301. [-FWUPDATE_ERR_CONFIG_READ] = "Configuration upload failure",
  302. [-FWUPDATE_ERR_CONFIG_SAVE] = "Error saving configuration"
  303. };
  304. switch (err) {
  305. case Z_OK:
  306. return errstr[-FWUPDATE_ERR_UNKNOWN];
  307. case Z_ERRNO:
  308. return strerror(errno);
  309. case -ARRAY_SIZE(errstr)+1 ... Z_STREAM_ERROR:
  310. if (errstr[-err])
  311. return errstr[-err];
  312. /* fall through */
  313. default:
  314. snprintf(unknown_err, sizeof unknown_err, "error %d", -err);
  315. return unknown_err;
  316. }
  317. }
  318. static TaskHandle_t fwupdate_task;
  319. static spz_stream *fwupdate_spz;
  320. static SemaphoreHandle_t fwupdate_done;
  321. static int fwupdate_err;
  322. static bool do_reboot;
  323. static void firmware_update_task(void *pvt)
  324. {
  325. spz_stream *spz = pvt;
  326. fpga_service_enable(false);
  327. printf("[FWUP] fwupdate_data_init()\n");
  328. spz->err = fwupdate_data_init(spz);
  329. if (spz->err)
  330. goto fail;
  331. printf("[FWUP] fwupdate_process_chunk loop\n");
  332. int err;
  333. while (!(err = fwupdate_process_chunk(spz))) {
  334. /* Process data chunks until end */
  335. }
  336. if (!spz->err && err != Z_STREAM_END)
  337. spz->err = err;
  338. printf("[FWUP] fwupdate_data_cleanup\n");
  339. err = fwupdate_data_cleanup(spz);
  340. if (err)
  341. spz->err = err;
  342. fail:
  343. if (spz->err)
  344. MSG("failed (err %d)\n", spz->err);
  345. xSemaphoreGive(fwupdate_done);
  346. if (do_reboot) {
  347. printf("[FWUP] rebooting in %d seconds\n", reboot_delayed());
  348. while (1)
  349. vTaskSuspend(NULL);
  350. } else {
  351. exit_task();
  352. }
  353. }
  354. static int firmware_update_cleanup(void)
  355. {
  356. int err = Z_OK;
  357. fwupdate_task = NULL;
  358. if (fwupdate_done) {
  359. SemaphoreHandle_t done = fwupdate_done;
  360. fwupdate_done = NULL;
  361. vSemaphoreDelete(done);
  362. } else {
  363. err = Z_MEM_ERROR;
  364. }
  365. if (fwupdate_spz) {
  366. struct spz_stream *spz = fwupdate_spz;
  367. if (spz->err)
  368. err = spz->err;
  369. fwupdate_spz = NULL;
  370. free(spz);
  371. } else {
  372. err = Z_MEM_ERROR;
  373. }
  374. return err;
  375. }
  376. int firmware_update_start(read_func_t read_data, token_t token, bool autoreboot)
  377. {
  378. int err;
  379. SemaphoreHandle_t done = NULL;
  380. do_reboot = autoreboot;
  381. if (fwupdate_spz)
  382. return FWUPDATE_ERR_IN_PROGRESS;
  383. fwupdate_spz = calloc(1, sizeof *fwupdate_spz);
  384. if (!fwupdate_spz)
  385. goto err;
  386. fwupdate_spz->read_data = read_data;
  387. fwupdate_spz->token = token;
  388. fwupdate_done = xSemaphoreCreateBinary();
  389. if (!fwupdate_done)
  390. goto err;
  391. if (xTaskCreate(firmware_update_task, "fwupdate",
  392. FWUPDATE_STACK, fwupdate_spz,
  393. FWUPDATE_PRIORITY, &fwupdate_task) != pdPASS) {
  394. xSemaphoreGive(fwupdate_done);
  395. }
  396. return Z_OK;
  397. err:
  398. return firmware_update_cleanup();
  399. }
  400. int firmware_update_wait(TickType_t delay)
  401. {
  402. if (!fwupdate_done)
  403. return Z_MEM_ERROR;
  404. if (!xSemaphoreTake(fwupdate_done, delay))
  405. return FWUPDATE_ERR_IN_PROGRESS;
  406. return firmware_update_cleanup();
  407. }