From 4cc3eee15403c8bf87914034cb71b17b0c61627f Mon Sep 17 00:00:00 2001 From: James Turton Date: Sun, 4 Sep 2022 10:33:56 +0200 Subject: [PATCH] rp: Define enter_flash_mode and exit_flash_mode Defining these methods highly accelerates the flash loading time as we no longer return the flash to XIP mode after each buffered write, instead we wait until the entire transaction has finished before returning to XIP mode. --- src/target/rp.c | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/target/rp.c b/src/target/rp.c index 395a3ae..6e9f1a3 100644 --- a/src/target/rp.c +++ b/src/target/rp.c @@ -157,8 +157,8 @@ static bool rp_flash_write(target_flash_s *f, target_addr_t dest, const void *sr static bool rp_read_rom_func_table(target *t); static bool rp_attach(target *t); -static void rp_flash_prepare(target *t); -static void rp_flash_resume(target *t); +static bool rp_flash_prepare(target *t); +static bool rp_flash_resume(target *t); static void rp_spi_read(target *t, uint16_t command, target_addr_t address, void *buffer, size_t length); static uint32_t rp_get_flash_length(target *t, rp_flash_s *flash); static bool rp_mass_erase(target *t); @@ -221,6 +221,8 @@ bool rp_probe(target *t) t->driver = RP_ID; t->target_options |= CORTEXM_TOPT_INHIBIT_NRST; t->attach = rp_attach; + t->enter_flash_mode = rp_flash_prepare; + t->exit_flash_mode = rp_flash_resume; target_add_commands(t, rp_cmd_list, RP_ID); return true; } @@ -345,30 +347,34 @@ static bool rp_rom_call(target *t, uint32_t *regs, uint32_t cmd, uint32_t timeou return ret; } -static void rp_flash_prepare(target *t) +static bool rp_flash_prepare(target *t) { rp_priv_s *ps = (rp_priv_s *)t->target_storage; + bool ret = true; /* catch false returns with &= */ if (!ps->is_prepared) { DEBUG_INFO("rp_flash_prepare\n"); /* connect*/ - rp_rom_call(t, ps->regs, ps->rom_connect_internal_flash, 100); + ret &= rp_rom_call(t, ps->regs, ps->rom_connect_internal_flash, 100); /* exit_xip */ - rp_rom_call(t, ps->regs, ps->rom_flash_exit_xip, 100); + ret &= rp_rom_call(t, ps->regs, ps->rom_flash_exit_xip, 100); ps->is_prepared = true; } + return ret; } -static void rp_flash_resume(target *t) +static bool rp_flash_resume(target *t) { rp_priv_s *ps = (rp_priv_s *)t->target_storage; + bool ret = true; /* catch false returns with &= */ if (ps->is_prepared) { DEBUG_INFO("rp_flash_resume\n"); /* flush */ - rp_rom_call(t, ps->regs, ps->rom_flash_flush_cache, 100); + ret &= rp_rom_call(t, ps->regs, ps->rom_flash_flush_cache, 100); /* enter_cmd_xip */ - rp_rom_call(t, ps->regs, ps->rom_flash_enter_xip, 100); + ret &= rp_rom_call(t, ps->regs, ps->rom_flash_enter_xip, 100); ps->is_prepared = false; } + return ret; } /* @@ -384,7 +390,6 @@ static bool rp_flash_erase(target_flash_s *f, target_addr_t addr, size_t len) target *t = f->t; /* Update our assumptions with the SFDP params */ - rp_flash_prepare(t); spi_parameters_s spi_parameters; rp_flash_s *flash = (rp_flash_s *)f; if (!(flash->table_has_been_read) && sfdp_read_parameters(t, &spi_parameters, rp_spi_read_sfdp)) { @@ -396,12 +401,10 @@ static bool rp_flash_erase(target_flash_s *f, target_addr_t addr, size_t len) if (addr & (f->blocksize - 1)) { DEBUG_WARN("Unaligned erase\n"); - rp_flash_resume(t); return false; } if ((addr < f->start) || (addr >= f->start + f->length)) { DEBUG_WARN("Address is invalid\n"); - rp_flash_resume(t); return false; } addr -= f->start; @@ -451,7 +454,6 @@ static bool rp_flash_erase(target_flash_s *f, target_addr_t addr, size_t len) if (full_erase) target_print_progress(&timeout); } - rp_flash_resume(t); DEBUG_INFO("Erase done!\n"); return ret; } @@ -467,7 +469,6 @@ static bool rp_flash_write(target_flash_s *f, target_addr_t dest, const void *sr dest -= f->start; rp_priv_s *ps = (rp_priv_s *)t->target_storage; /* Write payload to target ram */ - rp_flash_prepare(t); bool ret = true; while (len) { uint32_t chunksize = (len <= MAX_WRITE_CHUNK) ? len : MAX_WRITE_CHUNK; @@ -489,7 +490,6 @@ static bool rp_flash_write(target_flash_s *f, target_addr_t dest, const void *sr src += chunksize; dest += chunksize; } - rp_flash_resume(t); DEBUG_INFO("Write done!\n"); return ret; } @@ -498,9 +498,12 @@ static bool rp_mass_erase(target *t) { rp_priv_s *ps = (rp_priv_s *)t->target_storage; ps->is_monitor = true; - const bool result = rp_flash_erase(t->flash, t->flash->start, t->flash->length); + bool ret = true; /* catch false returns with &= */ + ret &= rp_flash_prepare(t); + ret &= rp_flash_erase(t->flash, t->flash->start, t->flash->length); + ret &= rp_flash_resume(t); ps->is_monitor = false; - return result; + return ret; } static void rp_spi_chip_select(target *const t, const bool active) @@ -638,13 +641,16 @@ static bool rp_cmd_erase_sector(target *t, int argc, const char **argv) } else if (argc == 2) length = strtoul(argv[1], NULL, 0); else - return -1; + return false; rp_priv_s *ps = (rp_priv_s *)t->target_storage; ps->is_monitor = true; - const bool result = rp_flash_erase(t->flash, start, length); + bool ret = true; /* catch false returns with &= */ + ret &= rp_flash_prepare(t); + ret &= rp_flash_erase(t->flash, start, length); + ret &= rp_flash_resume(t); ps->is_monitor = false; - return result; + return ret; } static bool rp_cmd_reset_usb_boot(target *t, int argc, const char **argv)