This is an automated email from Gerrit. "Tomas Vanek <van...@fbl.cz>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/8444
-- gerrit commit 1b750edbaef53ffcb4467068efc88285f3476618 Author: Luke Wren <l...@raspberrypi.com> Date: Thu Jul 25 10:55:41 2024 +0100 flash/nor/rp2040: Avoid ROM call timeout on long erases by splitting into chunks Also add keep_alive() to erase/program to avoid nasty GDB message. TV: Fixed style problems. Signed-off-by: Tomas Vanek <van...@fbl.cz> Change-Id: Ibb18775aeed192361ae1585bfdaad03760583cf3 diff --git a/src/flash/nor/rp2040.c b/src/flash/nor/rp2040.c index dc7595f303..78064ced2a 100644 --- a/src/flash/nor/rp2040.c +++ b/src/flash/nor/rp2040.c @@ -510,11 +510,10 @@ static int rp2xxx_call_rom_func_batch(struct target *target, struct rp2040_flash } if (err != ERROR_OK) { LOG_ERROR("Failed to call ROM function batch\n"); - /* This case is hit when loading new ROM images on FPGA, but can also be - hit on real hardware if you swap two devices with different ROM - versions without restarting OpenOCD: */ - LOG_INFO("Repopulating ROM address cache after failed ROM call"); - /* We ignore the error because we have already failed, this is just + /* This case is hit when loading new ROM images on FPGA, but can also be hit on real + hardware if you swap two devices with different ROM versions without restarting OpenOCD: */ + LOG_ROM_SYMBOL_DEBUG("Repopulating ROM address cache after failed ROM call"); + /* We ignore the error on this next call because we have already failed, this is just recovery for the next attempt. */ (void)rp2xxx_populate_rom_pointer_cache(target, priv); return err; @@ -757,6 +756,7 @@ static int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, ui write_size /* count */ }; err = rp2xxx_call_rom_func(target, priv, priv->jump_flash_range_program, args, ARRAY_SIZE(args)); + keep_alive(); if (err != ERROR_OK) { LOG_ERROR("Failed to invoke flash programming code on target"); break; @@ -820,19 +820,50 @@ static int rp2040_flash_erase(struct flash_bank *bank, unsigned int first, unsig if (err != ERROR_OK) goto cleanup_and_return; - LOG_DEBUG("Remote call flash_range_erase"); + uint32_t offset_next = bank->sectors[first].offset; + uint32_t offset_last = bank->sectors[last].offset + bank->sectors[last].size - bank->sectors[first].offset; + + /* Break erase into multiple calls to avoid timeout on large erase. Choose 128k chunk which has + fairly low ROM call overhead and empirically seems to avoid the default keep_alive() limit + as well as our ROM call timeout. */ + const uint32_t erase_chunk_size = 128 * 1024; + + /* Promote log level for long erases to provide feedback */ + bool requires_loud_prints = offset_last - offset_next >= 2 * erase_chunk_size; + enum log_levels chunk_log_level = requires_loud_prints ? LOG_LVL_INFO : LOG_LVL_DEBUG; + + while (offset_next < offset_last) { + uint32_t remaining = offset_last - offset_next; + uint32_t call_size = remaining < erase_chunk_size ? remaining : erase_chunk_size; + /* Shorten the first call of a large erase if necessary to align subsequent calls */ + if (offset_next % erase_chunk_size != 0 && call_size == erase_chunk_size) + call_size = erase_chunk_size - offset_next % erase_chunk_size; + + LOG_CUSTOM_LEVEL(chunk_log_level, + " Erase chunk: 0x%08" PRIx32 " -> 0x%08" PRIx32, + offset_next, + offset_next + call_size - 1 + ); - uint32_t args[4] = { - bank->sectors[first].offset, /* addr */ - bank->sectors[last].offset + bank->sectors[last].size - bank->sectors[first].offset, /* count */ - 65536, /* block_size */ - 0xd8 /* block_cmd */ - }; + /* This ROM function uses the optimal mixture of 4k 20h and 64k D8h erases, without + over-erase. This is why we force the flash_bank sector size attribute to 4k even if + OpenOCD prefers to give the block size instead. */ + uint32_t args[4] = { + offset_next, + call_size, + 65536, /* block_size */ + 0xd8 /* block_cmd */ + }; + + err = rp2xxx_call_rom_func(bank->target, priv, priv->jump_flash_range_erase, args, ARRAY_SIZE(args)); + keep_alive(); + + if (err != ERROR_OK) + break; + + offset_next += call_size; + } - /* This ROM function will use the optimal mixture of 4k 20h and 64k D8h - erases, without over-erase, as long as you just tell OpenOCD that your - flash is made up of 4k sectors instead of letting it try to guess. */ - err = rp2xxx_call_rom_func(bank->target, priv, priv->jump_flash_range_erase, args, ARRAY_SIZE(args)); cleanup_and_return: cleanup_after_raw_flash_cmd(bank); --