Skip to content

Commit

Permalink
esp32c3: Implemented i-cache invalidation and reload for post-complet…
Browse files Browse the repository at this point in the history
…ion of Flash operations
  • Loading branch information
dragonmux committed Nov 27, 2023
1 parent 6df92aa commit 6824850
Showing 1 changed file with 33 additions and 0 deletions.
33 changes: 33 additions & 0 deletions src/target/esp32c3.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,22 @@
#define ESP32_C3_TIMG1_WDT_FEED (ESP32_C3_TIMG1_BASE + 0x060U)
#define ESP32_C3_TIMG1_WDT_WRITE_PROT (ESP32_C3_TIMG1_BASE + 0x064U)

#define ESP32_C3_EXTMEM_BASE 0x600c4000U
#define ESP32_C3_EXTMEM_ICACHE_SYNC_CTRL (ESP32_C3_EXTMEM_BASE + 0x028U)
#define ESP32_C3_EXTMEM_ICACHE_SYNC_ADDR (ESP32_C3_EXTMEM_BASE + 0x02cU)
#define ESP32_C3_EXTMEM_ICACHE_SYNC_SIZE (ESP32_C3_EXTMEM_BASE + 0x030U)
#define ESP32_C3_EXTMEM_ICACHE_PRELOAD_CTRL (ESP32_C3_EXTMEM_BASE + 0x034U)
#define ESP32_C3_EXTMEM_ICACHE_PRELOAD_ADDR (ESP32_C3_EXTMEM_BASE + 0x038U)
#define ESP32_C3_EXTMEM_ICACHE_PRELOAD_SIZE (ESP32_C3_EXTMEM_BASE + 0x03cU)

#define ESP32_C3_EXTMEM_ICACHE_INVALIDATE 0x00000001U
#define ESP32_C3_EXTMEM_ICACHE_SYNC_DONE 0x00000002U
#define ESP32_C3_EXTMEM_ICACHE_PRELOAD 0x00000001U
#define ESP32_C3_EXTMEM_ICACHE_PRELOAD_DONE 0x00000002U

typedef struct esp32c3_priv {
uint32_t wdt_config[4];
target_addr_t last_invalidated_sector;
} esp32c3_priv_s;

static void esp32c3_disable_wdts(target_s *target);
Expand All @@ -125,6 +139,7 @@ static void esp32c3_spi_write(
static void esp32c3_spi_run_command(target_s *target, uint16_t command, target_addr_t address);

static bool esp32c3_enter_flash_mode(target_s *target);
static bool esp32c3_exit_flash_mode(target_s *target);
static bool esp32c3_spi_flash_erase(target_flash_s *flash, target_addr_t addr, size_t length);
static bool esp32c3_spi_flash_write(target_flash_s *flash, target_addr_t dest, const void *src, size_t length);

Expand Down Expand Up @@ -169,6 +184,7 @@ bool esp32c3_probe(target_s *const target)
target->mass_erase = bmp_spi_mass_erase;
/* Special care must be taken during Flash programming */
target->enter_flash_mode = esp32c3_enter_flash_mode;
target->exit_flash_mode = esp32c3_exit_flash_mode;

/* Establish the target RAM mappings */
target_add_ram(target, ESP32_C3_IBUS_SRAM0_BASE, ESP32_C3_IBUS_SRAM0_SIZE);
Expand Down Expand Up @@ -393,6 +409,20 @@ static bool esp32c3_enter_flash_mode(target_s *const target)
return true;
}

static bool esp32c3_exit_flash_mode(target_s *const target)
{
esp32c3_priv_s *const priv = (esp32c3_priv_s *)target->target_storage;
/* Invalidate the i-cache for the required length */
target_mem_write32(target, ESP32_C3_EXTMEM_ICACHE_SYNC_ADDR, ESP32_C3_IBUS_FLASH_BASE);
target_mem_write32(target, ESP32_C3_EXTMEM_ICACHE_SYNC_SIZE, priv->last_invalidated_sector);
target_mem_write32(target, ESP32_C3_EXTMEM_ICACHE_SYNC_CTRL, ESP32_C3_EXTMEM_ICACHE_INVALIDATE);
/* Wait for invalidation to complete */
while (!(target_mem_read32(target, ESP32_C3_EXTMEM_ICACHE_SYNC_CTRL) & ESP32_C3_EXTMEM_ICACHE_SYNC_DONE))
continue;
target_reset(target);
return true;
}

static bool esp32c3_spi_flash_erase(target_flash_s *const flash, const target_addr_t addr, const size_t length)
{
(void)length;
Expand All @@ -406,6 +436,9 @@ static bool esp32c3_spi_flash_erase(target_flash_s *const flash, const target_ad
target, SPI_FLASH_CMD_SECTOR_ERASE | SPI_FLASH_OPCODE(spi_flash->sector_erase_opcode), addr - flash->start);
while (esp32c3_spi_read_status(target) & SPI_FLASH_STATUS_BUSY)
continue;
/* Update the address of the last invalidated sector so we can correctly invalidate the i-cache and reload it */
esp32c3_priv_s *const priv = (esp32c3_priv_s *)target->target_storage;
priv->last_invalidated_sector = (addr - flash->start) + length;
return true;
}

Expand Down

0 comments on commit 6824850

Please sign in to comment.