mirror of
https://github.com/openocd-org/openocd.git
synced 2025-10-14 02:58:23 +08:00
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 <vanekt@fbl.cz> Signed-off-by: Luke Wren <luke@raspberrypi.com> Reviewed-on: https://review.openocd.org/c/openocd/+/8729 Tested-by: jenkins
This commit is contained in:
@@ -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");
|
||||
|
Reference in New Issue
Block a user