Explorar el Código

fwupdate: update esp32 when flashing from sdcard

Add support for flashing the ESP32 when updating firmware from SD
card. Note that this method of updates only works when both FPGA and
ESP32 are up and running.
H. Peter Anvin hace 2 años
padre
commit
0e09a7c608

+ 8 - 0
esp32/max80/esplink.h

@@ -57,6 +57,11 @@ struct esplink_timesync {
     } get, set;
 };
 
+struct esplink_ota {
+    const void *data;
+    uint32_t len;
+};
+
 #define ESPLINK_HEAD_MAGIC	0x3648dec4
 #define MAX_SIGNATURE_LEN	64
 
@@ -76,6 +81,7 @@ struct esplink_head {
     } board;
 
     volatile struct esplink_timesync *tsync;
+    volatile struct esplink_ota *ota;
 
     struct esplink_ringbuf_head {
 	uint32_t count;
@@ -91,11 +97,13 @@ struct esplink_head {
 #define EL_DIRQ_HELLO		1
 #define EL_DIRQ_RINGBUF		2
 #define EL_DIRQ_TIME		3
+#define EL_DIRQ_DONE		4	/* Some operation completed */
 
 #define EL_UIRQ_WREN		0	/* Remote write enable bit, not IRQ */
 #define EL_UIRQ_READY		1
 #define EL_UIRQ_RINGBUF		2
 #define EL_UIRQ_TIME		3
+#define EL_UIRQ_OTA		4
 
 /*
  * Well known ring buffer indicies; must match for both sides.

+ 3 - 3
esp32/max80/fpga.h

@@ -26,7 +26,7 @@ extern_c void fpga_timesync_trigger(void);
 struct fpga_iov {
     unsigned int cmd;
     union {
-	const void *addr;
+	const volatile void *addr;
 	uint32_t iaddr;
     };
     union {
@@ -37,9 +37,9 @@ struct fpga_iov {
 };
 
 extern_c esp_err_t fpga_iov(const struct fpga_iov *iov, size_t niov);
-extern_c esp_err_t fpga_io_write(unsigned int cmd, const void *addr,
+extern_c esp_err_t fpga_io_write(unsigned int cmd, const volatile void *addr,
 				 const void *data, size_t len);
-extern_c esp_err_t fpga_io_read(unsigned int cmd, const void *addr,
+extern_c esp_err_t fpga_io_read(unsigned int cmd, const volatile void *addr,
 				void *data, size_t len);
 extern_c uint32_t fpga_io_status(unsigned int cmd);
 

+ 45 - 17
esp32/max80/fpgasvc.c

@@ -59,7 +59,7 @@ static TimerHandle_t fpga_timesync_timer;
 static SemaphoreHandle_t spi_mutex;
 static EventGroupHandle_t spi_done_evgroup;
 static volatile bool spi_abort_all;
-static const volatile struct esplink_timesync *tsync_addr;
+static struct esplink_head head;
 
 #define NOTIFY_INDEX	0
 #define NOTIFY_FPGA	(1 << 0)
@@ -235,8 +235,6 @@ static void fpga_poll_set_time(void);
 
 static bool fpga_online(void)
 {
-    struct esplink_head head;
-
     fpga_io_read(FPGA_CMD_ACK(EL_UIRQ_READY), ESPLINK_HDR_ADDR,
 		 &head, sizeof head);
 
@@ -255,8 +253,6 @@ static bool fpga_online(void)
 	   head.board.major, head.board.minor,
 	   head.board.fixes, head.board.fpga);
 
-    tsync_addr = head.tsync;
-
     printf("[FPGA] online, signature \"%.*s\"\n",
 	   (int)(sizeof head.signature - 1), head.signature);
     esplink_start(&head);
@@ -272,7 +268,7 @@ static bool fpga_online(void)
 
 static void fpga_offline(void)
 {
-    tsync_addr = NULL;
+    memset(&head, 0, sizeof head);
     xSemaphoreTakeRecursive(spi_mutex, portMAX_DELAY);
     xTimerStop(fpga_timesync_timer, portMAX_DELAY);
     setenv_bool("status.max80.fpga", false);
@@ -363,7 +359,7 @@ fail:
     return err;
 }
 
-esp_err_t fpga_io_write(unsigned int cmd, const void *addr,
+esp_err_t fpga_io_write(unsigned int cmd, const volatile void *addr,
 			const void *data, size_t len)
 {
     struct fpga_iov iov;
@@ -376,7 +372,7 @@ esp_err_t fpga_io_write(unsigned int cmd, const void *addr,
     return fpga_iov(&iov, 1);
 }
 
-esp_err_t fpga_io_read(unsigned int cmd, const void *addr,
+esp_err_t fpga_io_read(unsigned int cmd, const volatile void *addr,
 		       void *data, size_t len)
 {
     struct fpga_iov iov;
@@ -406,7 +402,7 @@ static void fpga_get_time(void)
 	struct esplink_timesync_buf get;
     } tsbuf;
 
-    if (!tsync_addr) {
+    if (!head.tsync) {
 	fpga_io_status(FPGA_CMD_ACK(EL_UIRQ_TIME));
 	return;
     }
@@ -422,7 +418,7 @@ static void fpga_get_time(void)
     trans.base.rxlength = sizeof tsbuf << 3;
     trans.base.rx_buffer = &tsbuf;
 
-    trans.base.addr = (size_t)&tsync_addr->get;
+    trans.base.addr = (size_t)&head.tsync->get;
     trans.base.cmd  = FPGA_CMD_RD | FPGA_CMD_ACK(EL_UIRQ_TIME);
 
     xSemaphoreTakeRecursive(spi_mutex, portMAX_DELAY);
@@ -454,7 +450,7 @@ static void fpga_get_time(void)
 
 static void fpga_poll_set_time(void)
 {
-    if (!tsync_addr)
+    if (!head.tsync)
 	return;
 
     if (!time_net_sync_status) {
@@ -494,7 +490,7 @@ static void fpga_poll_set_time(void)
     trans.length = sizeof tset << 3;
     trans.tx_buffer = &tset;
 
-    trans.addr = (size_t)&tsync_addr->set;
+    trans.addr = (size_t)&head.tsync->set;
     trans.cmd  = FPGA_CMD_WR | FPGA_CMD_IRQ(EL_DIRQ_TIME) |
 	FPGA_CMD_ACK(EL_UIRQ_TIME);
 
@@ -533,6 +529,34 @@ uint32_t fpga_io_status(unsigned int cmd)
     return err ? 0 : *(const uint32_t *)trans.rx_data;
 }
 
+static int fpga_read_func(token_t token, void *buf, size_t len)
+{
+    const void **pp = token;
+    const char *p = *pp;
+    esp_err_t err;
+
+    err = fpga_io_read(0, p, buf, len);
+    if (err)
+	return -1;
+
+    p += len;
+    *pp = p;
+    return len;
+}
+
+static void fpga_ota_update(void)
+{
+    struct esplink_ota ota;
+
+    fpga_io_read(0, head.ota, &ota, sizeof ota);
+    if (!ota.data)
+	return;
+
+    esp_update(fpga_read_func, &ota.data, ota.len);
+    fpga_io_status(FPGA_CMD_ACK(EL_UIRQ_OTA)|FPGA_CMD_IRQ(EL_DIRQ_DONE));
+    reboot_delayed();
+}
+
 static void fpga_service_task(void *dummy)
 {
     (void)dummy;
@@ -565,17 +589,18 @@ static void fpga_service_task(void *dummy)
 	  printf("[FPGA] FPGA status flags = 0x%08x\n", status);
 
 	  if (!digitalRead(PIN_FPGA_INT)) {
-	      for (unsigned int i = 2; i < 8; i++) {
+	      for (unsigned int i = 1; i < 8; i++) {
 		  if (status & (0x100 << i))
 		      status = fpga_io_status(FPGA_CMD_ACK(i));
 	      }
 	      if ((status & 0x301) == 0x300) {
-		  if (fpga_online())
+		  if (fpga_online()) {
 		      fpga_state = FPGA_ONLINE;
+		      break;
+		  }
 	      }
-	  } else {
-	      notifiers = notify_wait_for(NOTIFY_FPGA|NOTIFY_DISABLE);
 	  }
+	  notifiers = notify_wait_for(NOTIFY_FPGA|NOTIFY_DISABLE);
 	  break;
 
 	case FPGA_ONLINE:
@@ -604,7 +629,10 @@ static void fpga_service_task(void *dummy)
 		if (status & (0x100 << EL_UIRQ_RINGBUF))
 		    esplink_poll();
 
-		for (unsigned int i = 4; i < 8; i++) {
+		if (status & (0x100 << EL_UIRQ_OTA))
+		    fpga_ota_update();
+		
+		for (unsigned int i = 5; i < 8; i++) {
 		    if (status & (0x100 << i)) {
 			printf("[FPGA] Invalid interrupt %u received\n", i);
 			status = fpga_io_status(FPGA_CMD_ACK(i));

+ 1 - 7
esp32/max80/ota.c

@@ -39,13 +39,7 @@ int esp_update(read_func_t read_func, token_t token, size_t size)
     esp_ota_handle_t handle;
     bool ota_started = false;
     int len;
-    char *buf = NULL;
-
-    buf = malloc(BUFFER_SIZE);
-    if (!buf) {
-	err = ESP_ERR_NO_MEM;
-	goto fail;
-    }
+    char *buf = xmalloc_dma(BUFFER_SIZE);
 
     partition = esp_ota_get_next_update_partition(NULL);
     if (!partition) {

+ 0 - 1
esp32/max80/reboot.c

@@ -9,7 +9,6 @@ void reboot_now(void)
     }
 }
 
-
 int reboot_delayed(void)
 {
     const int reboot_delay = 5; /* seconds */

+ 4 - 4
esp32/max80/xmalloc.c

@@ -14,22 +14,22 @@ no_return __noinline alloc_panic(void)
 
 void *xrealloc(void *ptr, size_t len)
 {
-    return null_check(realloc(ptr, Min(len,1)));
+    return null_check(realloc(ptr, Max(len,1)));
 }
 
 void *xmalloc(size_t len)
 {
-    return null_check(malloc(Min(len,1)));
+    return null_check(malloc(Max(len,1)));
 }
 
 void *xmalloc_dma(size_t len)
 {
-    return null_check(heap_caps_malloc(Min(len,1), MALLOC_CAP_DMA));
+    return null_check(heap_caps_malloc(Max(len,1), MALLOC_CAP_DMA));
 }
 
 void *xzalloc(size_t len)
 {
-    return null_check(calloc(Min(len,1), 1));
+    return null_check(calloc(Max(len,1), 1));
 }
 
 static inline size_t nsize(size_t nmemb, size_t size)

BIN
esp32/output/max80.ino.bin


+ 1 - 1
fpga/Makefile

@@ -181,7 +181,7 @@ $(outdir)/%.fw: $(outdir)/%.rpf $(outdir)/bypass.rbf \
 		-type fpgainit -addr $(IDCODE) -optional -file $(outdir)/bypass.rbf \
 		-type data -addr 0 -file $< \
 		-type data -addr $(DRAM_ADDR) -file $(DRAM_IMAGE) \
-		-type espota -optional -file $(ESP_IMAGE) \
+		-type espota -file $(ESP_IMAGE) \
 	| $(GZIP) -9 > $@
 
 $(outdir)/%.update.svf: ./scripts/flashsvf.pl \

+ 2 - 2
fpga/max80.qpf

@@ -19,12 +19,12 @@
 #
 # Quartus Prime
 # Version 21.1.0 Build 842 10/21/2021 SJ Lite Edition
-# Date created = 16:40:14  May 19, 2022
+# Date created = 02:29:56  May 20, 2022
 #
 # -------------------------------------------------------------------------- #
 
 QUARTUS_VERSION = "21.1"
-DATE = "16:40:14  May 19, 2022"
+DATE = "02:29:56  May 20, 2022"
 
 # Revisions
 

BIN
fpga/output/bypass.jic


BIN
fpga/output/v1.fw


BIN
fpga/output/v1.jic


BIN
fpga/output/v1.rbf.gz


BIN
fpga/output/v1.rpd.gz


BIN
fpga/output/v1.sof


BIN
fpga/output/v1.svf.gz


BIN
fpga/output/v1.xsvf.gz


BIN
fpga/output/v2.fw


BIN
fpga/output/v2.jic


BIN
fpga/output/v2.rbf.gz


BIN
fpga/output/v2.rpd.gz


BIN
fpga/output/v2.sof


BIN
fpga/output/v2.svf.gz


BIN
fpga/output/v2.xsvf.gz


+ 1 - 1
rv32/checksum.h

@@ -1,4 +1,4 @@
 #ifndef CHECKSUM_H
 #define CHECKSUM_H
-#define SDRAM_SUM 0x9acb8541
+#define SDRAM_SUM 0xbd6632a6
 #endif

+ 1 - 0
rv32/common.h

@@ -91,5 +91,6 @@ extern void rom_flash_from_memory(void *, size_t);
 extern void rom_flash_from_sdcard(void);
 
 extern void esp_init(void);
+extern void esp_ota(const void *, size_t);
 
 #endif /* FW_H */

+ 2 - 2
rv32/compiler.h

@@ -97,8 +97,8 @@ typedef union xcptr {
 #define __string_hot	___section(".rodata.hot.str","aMS")
 #define __sbss		___section(".sbss.hot","aw",@nobits)
 #define __bss_hot	___section(".bss.hot","aw",@nobits)
-#define __esplink_head	___section(".dram.esplink.head","a",@nobits)
-#define __esplink	___section(".dram.esplink","a",@nobits)
+#define __esplink_head	___section(".dram.esplink.head","aw",@nobits)
+#define __esplink	___section(".dram.bss.esplink","aw",@nobits)
 #define __dram_text	___section(".dram.text","ax")
 #define __dram_rodata	___section(".dram.rodata","a")
 #define __dram_string	___section(".dram.rodata.str","aMS")

+ 30 - 13
rv32/diskcache.c

@@ -48,6 +48,7 @@ enum block_status {
     FL_FREE      = FL_CACHE_BIT,
     FL_VALID_BIT = 2,
     FL_VALID     = FL_CACHE_BIT | FL_VALID_BIT,
+    FL_CLEAN     = FL_VALID,
     FL_DIRTY_BIT = 4,
     FL_DIRTY     = FL_VALID | FL_DIRTY_BIT
 };
@@ -82,6 +83,8 @@ static struct dll free_list;
 static size_t cur_brk;
 static size_t cache_base;
 
+static void invalidate_all(void);
+
 static inline __constfunc struct dll *hash_slot(block_t block)
 {
     uint64_t m;
@@ -122,19 +125,28 @@ static void invalidate_block(struct cache_block *bp)
 
 static DRESULT sync_block(struct cache_block *bp)
 {
+    if (sdc.status & (STA_NOINIT | STA_NODISK))
+	goto err;
+
     if (bp->flags == FL_DIRTY) {
 	sector_t sector = bp->block << CACHE_BLOCK_BITS;
 	sector_t size = sdc.lbasize;
 	sector_t sectors = min(CACHE_BLOCK_SECTORS, size - sector);
 
-	if (sdcard_write_sectors(bp_to_data(bp), sector, sectors) != (int)sectors) {
+	if (sdcard_write_sectors(bp_to_data(bp), sector, sectors)
+	    != (int)sectors) {
 	    invalidate_block(bp); /* Or...? */
-	    return RES_ERROR;
+	    goto err;
 	}
-	bp->flags = FL_VALID;
+	bp->flags = FL_CLEAN;
     }
 
     return RES_OK;
+
+err:
+    if (sdc.status & (STA_NOINIT | STA_NODISK))
+	invalidate_all();
+    return RES_ERROR;
 }
 
 static DRESULT clear_block(struct cache_block *bp)
@@ -179,7 +191,7 @@ static DRESULT sync_kill_block(struct cache_block *bp)
     DRESULT rv = RES_OK;
 
     if (!(bp->flags & FL_CACHE_BIT))
-	return;
+	return rv;
 
     if (bp->flags == FL_DIRTY)
 	rv = sync_block(bp);
@@ -199,6 +211,9 @@ static struct cache_block *disk_cache_get(block_t block, bool do_read)
     const sector_t size = sdc.lbasize;
     struct cache_block *bp;
 
+    if (sdc.status & (STA_NOINIT | STA_NODISK))
+	goto err;
+
     bp = disk_cache_find(block);
 
     if (!bp) {
@@ -218,9 +233,9 @@ static struct cache_block *disk_cache_get(block_t block, bool do_read)
 
 	if (do_read) {
 	    if (sdcard_read_sectors(bp_to_data(bp), sector, sectors) != sectors)
-		return NULL;
+		goto err;
 
-	    bp->flags = FL_VALID;
+	    bp->flags = FL_CLEAN;
 	}
 
 	bp->block = block;
@@ -229,6 +244,11 @@ static struct cache_block *disk_cache_get(block_t block, bool do_read)
 
     dll_promote(&lru_list, &bp->lru);
     return bp;
+
+err:
+    if (sdc.status & (STA_NOINIT | STA_NODISK))
+	invalidate_all();
+    return NULL;
 }
 
 /* --------------------------------------------------------------------------
@@ -331,17 +351,14 @@ void heap_init(void)
 
 DSTATUS disk_initialize(BYTE drive)
 {
-    DSTATUS status, old_status;
+    DSTATUS status;
 
     if (drive != 0)
 	return STA_NOINIT | STA_NODISK;
 
-    old_status = sdc.status;
-    status = sdcard_init();
-    if ((status ^ old_status) & STA_NOINIT)
-	invalidate_all();
-
-    return sdc.fsstatus = status;
+    /* If we get here, STA_NOINIT was set at some point, so cache is bad */
+    invalidate_all();
+    return sdc.fsstatus = sdcard_init();
 }
 
 DRESULT disk_ioctl(BYTE drive, BYTE command, void *buffer)

+ 28 - 3
rv32/esp.c

@@ -5,15 +5,15 @@
 #include "esplink.h"
 
 struct esplink_head __esplink_head esplink_head;
-static volatile struct esplink_timesync tsync;
-
-uint32_t __esplink esplink[(65536 - sizeof(struct esplink_head)) >> 2];
+static volatile __esplink struct esplink_timesync tsync;
+static volatile __esplink struct esplink_ota ota;
 
 IRQHANDLER(esp,0)
 {
     uint32_t irqstatus = ESP_CPU_IRQ;
     ESP_CPU_IRQ_CLR = irqstatus;
 
+
     if (irqstatus & (1 << EL_DIRQ_UNDERRUN)) {
 	con_printf("[ESP] ESP link memory underrun!!\n");
 	ESP_SPI_IRQ = (1 << EL_UIRQ_READY); /* Block writes, reinitialize! */
@@ -31,11 +31,35 @@ IRQHANDLER(esp,0)
 	    ESP_SPI_IRQ_SET = 1 << EL_UIRQ_TIME;
 	}
     }
+
     if (irqstatus & (1 << EL_DIRQ_HELLO)) {
 	con_printf("[ESP] Got hello, sending ready...\n");
 	/* Hello, are you there? Yes, I'm here, and you can write data now */
 	ESP_SPI_IRQ_SET = (1 << EL_UIRQ_READY)|(1 << EL_UIRQ_WREN);
     }
+
+    /*
+     * Check to see if we got hello after an OTA process was completed
+     * or aborted; ESP will send EL_DIRQ_DONE to wake us up.
+     */
+    if (!(ESP_SPI_IRQ & (1 << EL_UIRQ_OTA))) {
+	ota.data = NULL;
+	ota.len  = 0;
+    }
+}
+
+void esp_ota(const void *data, size_t len)
+{
+    mask_irq(ESP_IRQ);
+    
+    ota.data = data;
+    ota.len  = len;
+    ESP_SPI_IRQ_SET = 1 << EL_UIRQ_OTA;
+
+    unmask_irq(ESP_IRQ);
+
+    while (ota.data)
+	waitfor(ESP_IRQ);
 }
 
 void esp_init(void)
@@ -52,6 +76,7 @@ void esp_init(void)
     memcpy(esplink_head.signature, esp_signature, sizeof esp_signature);
 
     esplink_head.tsync         = &tsync;
+    esplink_head.ota           = &ota;
 
     esplink_head.magic         = ESPLINK_HEAD_MAGIC;
     ESP_SPI_IRQ                = (1 << EL_UIRQ_READY);

+ 57 - 69
rv32/spiflash.c

@@ -560,6 +560,41 @@ static int spiflash_skip_chunk(spz_stream *spz)
     return 0;
 }
 
+/* Read a chunk into malloc()'d storage */
+static int spiflash_load_chunk(spz_stream *spz, void **dptr)
+{
+    void *data;
+    int len = spz->header.len;
+
+    *dptr = NULL;
+    data = spz_malloc(spz, len);
+    if (!data) {
+	spiflash_skip_chunk(spz);
+	return spz->err;
+    } else {
+	int rv = spiflash_read_data(spz, data, len);
+	if (!spz->err && rv != len)
+	    spz->err = Z_DATA_ERROR;
+	if (spz->err) {
+	    free(data);
+	    return spz->err;
+	}
+	*dptr = data;
+	return rv;
+    }
+}
+
+static int esp_ota_chunk(spz_stream *spz)
+{
+    void *data;
+    int len = spiflash_load_chunk(spz, &data);
+    if (data) {
+	esp_ota(data, len);
+	free(data);
+    }
+    return spz->err;
+}
+
 /* Process a data chunk; return a nonzero value if done */
 static int spiflash_process_chunk(spz_stream *spz)
 {
@@ -579,14 +614,16 @@ static int spiflash_process_chunk(spz_stream *spz)
 	return spz->err = Z_DATA_ERROR;
     }
 
+    con_printf("update: chunk type %u size %u addr 0x%08x\n",
+	       spz->header.type, spz->header.len, spz->header.addr);
+    
     switch (spz->header.type) {
     case FDT_END:
 	return Z_STREAM_END;	/* End of data - not an error */
     case FDT_DATA:
 	if (!spz->flash->ops)
-	    return spiflash_skip_chunk(spz);
-	else
-	    return spiflash_flash_chunk(spz);
+	    goto skip;
+	return spiflash_flash_chunk(spz);
     case FDT_TARGET:
 	str = spiflash_read_chunk_str(spz);
 	if (!str || strcmp(str, spz->flash->target)) {
@@ -594,19 +631,28 @@ static int spiflash_process_chunk(spz_stream *spz)
 		str, spz->flash->target);
 	    return spz->err = Z_DATA_ERROR;
 	}
-	return Z_OK;
+	break;
     case FDT_NOTE:
 	str = spiflash_read_chunk_str(spz);
 	MSG("update: %s\n", str);
-	return Z_OK;
+	break;
+    case FDT_FPGA_INIT:		/* Used only when flashing from ESP32 */
+	return spiflash_skip_chunk(spz);
+    case FDT_ESP_OTA:
+	if (!spz->flash->ops)
+	    goto skip;
+	return esp_ota_chunk(spz);
     default:
-	if (spz->header.flags & FDF_OPTIONAL) {
-	    return spiflash_skip_chunk(spz);
-	} else {
-	    MSG("update: unknown chunk type: %u\n", spz->header.type);
-	    return spz->err = Z_DATA_ERROR;
-	}
+	if (spz->header.flags & FDF_OPTIONAL)
+	    goto skip;
+
+	MSG("update: unknown chunk type: %u\n", spz->header.type);
+	return spz->err = Z_DATA_ERROR;
     }
+    return spz->err;
+
+skip:
+    return spiflash_skip_chunk(spz);
 }
 
 int spiflash_flash_file(const struct spiflash *flash, void *buf, size_t buflen)
@@ -624,64 +670,6 @@ int spiflash_flash_file(const struct spiflash *flash, void *buf, size_t buflen)
     if (err)
 	return err;
 
-    if (0 && flash->ops) {
-	static const uint8_t read_sr_cmd[2] = { ROM_READ_SR1, ROM_READ_SR2 };
-	uint8_t sr1;
-	uint32_t *sfdp;
-
-	sfdp = malloc(SPIFLASH_SFDP_SIZE);
-	memset(sfdp, 0, SPIFLASH_SFDP_SIZE);
-
-	/* Note: SFDP data is littleendian! */
-	err = spiflash_get_sfdp(flash, sfdp);
-	if (err)
-	    return err;
-
-	for (int i = 0; i < SPIFLASH_SFDP_SIZE; i += 16) {
-	    MSG("%04x :", i);
-	    for (int j = 0; j < 16; j += 4) {
-		MSG(" %08x", sfdp[(i+j) >> 2]);
-	    }
-	    MSG("\n");
-	}
-
-	if (sfdp[0] != 0x50444653) {
-	    MSG("update: invalid SFDP information read\n");
-	    return SPIFLASH_ERR_DETECT;
-	}
-
-	/*
-	 * If the flash is busy, try to reset it
-	 */
-	err = spiflash_get_status(flash, ROM_READ_SR1, &sr1);
-	if (err)
-	    return err;
-	if (sr1 & 0x01) {
-	    udelay(60);
-	    err = spiflash_get_status(flash, ROM_READ_SR1, &sr1);
-	    if (err)
-		return err;
-	    if (sr1 & 0x01) {
-		MSG("update: flash busy, trying reset... ");
-
-		err = spiflash_simple_command(flash, ROM_ENABLE_RESET);
-		if (err)
-		    return err;
-		err = spiflash_simple_command(flash, ROM_RESET);
-		if (err)
-		    return err;
-
-		udelay(60);
-		err = spiflash_get_status(flash, ROM_READ_SR1, &sr1);
-		if (err || (sr1 & 0x01)) {
-		    MSG("failed\n");
-		    return SPIFLASH_ERR_NOT_READY;
-		}
-		MSG("ok\n");
-	    }
-	}
-    }
-
     while (!spiflash_process_chunk(spz)) {
 	/* Process data chunks until end */
     }

+ 5 - 3
rv32/spiflash.h

@@ -73,11 +73,13 @@ struct spiflash_header {
     uint32_t addr;		/* Address or similar */
 };
 
-enum flash_data_type {
+enum fw_data_type {
     FDT_END,			/* End of stream */
-    FDT_DATA,			/* Data to be flashed */
+    FDT_DATA,			/* FPGA firmware ata to be flashed */
     FDT_TARGET,			/* Subsystem string (must match) */
-    FDT_NOTE			/* Version: XXXXX or similar */
+    FDT_NOTE,			/* Version: XXXXX or similar */
+    FDT_ESP_OTA,		/* ESP32 OTA image */
+    FDT_FPGA_INIT		/* FPGA bitstream for update */
 };
 enum flash_data_flags {
     FDF_OPTIONAL     = 0x0001	/* Ignore if chunk data type unknown */