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/+/8729
-- gerrit commit 8a39855cfcbc6e19bcdf2deb7d90381ee06ea9c6 Author: Luke Wren <l...@raspberrypi.com> Date: Fri Dec 13 21:56:45 2024 +0100 flash/nor/rp2xxx: fix flash operation after halt in RISC-V bootsel Calling ROM API set_bootrom_stack() function allows ROM API functionality after OpenOCD halt or reset halt in RISC-V bootloder (emulated ARM code) Change-Id: I3b255738d61876e876a94207804d9cbe1a7593c2 Signed-off-by: Tomas Vanek <van...@fbl.cz> diff --git a/src/flash/nor/rp2xxx.c b/src/flash/nor/rp2xxx.c index e4465ec43f..b36321b155 100644 --- a/src/flash/nor/rp2xxx.c +++ b/src/flash/nor/rp2xxx.c @@ -26,6 +26,7 @@ #define FUNC_FLASH_FLUSH_CACHE MAKE_TAG('F', 'C') #define FUNC_FLASH_ENTER_CMD_XIP MAKE_TAG('C', 'X') #define FUNC_BOOTROM_STATE_RESET MAKE_TAG('S', 'R') +#define FUNC_BOOTROM_SET_STACK MAKE_TAG('S', 'S') #define FUNC_FLASH_RESET_ADDRESS_TRANS MAKE_TAG('R', 'A') /* ROM table flags for RP2350 A1 ROM onwards */ @@ -201,6 +202,7 @@ struct rp2xxx_flash_bank { uint16_t jump_flash_reset_address_trans; uint16_t jump_enter_cmd_xip; uint16_t jump_bootrom_reset_state; + uint16_t jump_bootrom_set_varm_stack; char dev_name[20]; bool size_override; @@ -445,6 +447,15 @@ static int rp2xxx_populate_rom_pointer_cache(struct target *target, struct rp2xx LOG_WARNING("Function FUNC_BOOTROM_STATE_RESET not found in RP2xxx ROM. (probably an RP2350 A0)"); } + if (!is_arm(target_to_arm(target))) { + err = rp2xxx_lookup_rom_symbol(target, FUNC_BOOTROM_SET_STACK, symtype_func, + &priv->jump_bootrom_set_varm_stack); + if (err != ERROR_OK) { + priv->jump_bootrom_set_varm_stack = 0; + LOG_WARNING("Function FUNC_BOOTROM_SET_STACK not found in RP2xxx ROM. (probably an RP2350 A0)"); + } + } + err = rp2xxx_lookup_rom_symbol(target, FUNC_FLASH_RESET_ADDRESS_TRANS, symtype_func, &priv->jump_flash_reset_address_trans); if (err != ERROR_OK) { @@ -720,6 +731,9 @@ static int setup_for_raw_flash_cmd(struct target *target, struct rp2xxx_flash_ba if (!priv->jump_bootrom_reset_state) { LOG_WARNING("RP2350 flash: no bootrom_reset_method\n"); } else { + /* This is mainly required to clear varmulet_enclosing_cpu pointers on RISC-V, in case + an Arm -> RISC-V call has been interrupted (these pointers are used to handle + reentrant calls to the ROM emulator) */ LOG_DEBUG("Clearing core 0 ROM state"); err = rp2xxx_call_rom_func(target, priv, priv->jump_bootrom_reset_state, reset_args, ARRAY_SIZE(reset_args)); @@ -728,6 +742,39 @@ static int setup_for_raw_flash_cmd(struct target *target, struct rp2xxx_flash_ba return err; } } + if (!is_arm(target_to_arm(target)) && priv->jump_bootrom_set_varm_stack) { + /* Pass {0, 0} to set_varmulet_user_stack() to enable automatic emulation of Arm APIs + using the ROM's default stacks. Usually the bootrom does this before exiting to user + code, but it needs to be done manually when the USB bootloader has been interrupted. */ + LOG_DEBUG("Enabling default Arm emulator stacks for RISC-V ROM calls\n"); + struct working_area *set_stack_mem_args; + err = target_alloc_working_area(target, 2 * sizeof(uint32_t), &set_stack_mem_args); + if (err != ERROR_OK) { + LOG_ERROR("Failed to allocate memory for arguments to set_varmulet_user_stack()"); + return err; + } + + err = target_write_u32(target, set_stack_mem_args->address, 0); + if (err == ERROR_OK) + err = target_write_u32(target, set_stack_mem_args->address + 4, 0); + + if (err != ERROR_OK) { + LOG_ERROR("Failed to initialise memory arguments for set_varmulet_user_stack()"); + target_free_working_area(target, set_stack_mem_args); + return err; + } + + uint32_t set_stack_register_args[1] = { + set_stack_mem_args->address + }; + err = rp2xxx_call_rom_func(target, priv, priv->jump_bootrom_set_varm_stack, + set_stack_register_args, ARRAY_SIZE(set_stack_register_args)); + target_free_working_area(target, set_stack_mem_args); + if (err != ERROR_OK) { + LOG_ERROR("Failed to initialise Arm emulation stacks for RISC-V: 0x%08" PRIx32, err); + return err; + } + } } LOG_DEBUG("Connecting flash IOs and issuing XIP exit sequence to flash"); --