You can subscribe to this list here.
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(75) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2009 |
Jan
(70) |
Feb
(20) |
Mar
(52) |
Apr
(149) |
May
(387) |
Jun
(466) |
Jul
(133) |
Aug
(87) |
Sep
(122) |
Oct
(140) |
Nov
(185) |
Dec
(105) |
2010 |
Jan
(85) |
Feb
(45) |
Mar
(75) |
Apr
(17) |
May
(41) |
Jun
(52) |
Jul
(33) |
Aug
(29) |
Sep
(36) |
Oct
(15) |
Nov
(26) |
Dec
(34) |
2011 |
Jan
(26) |
Feb
(25) |
Mar
(26) |
Apr
(29) |
May
(20) |
Jun
(27) |
Jul
(15) |
Aug
(32) |
Sep
(13) |
Oct
(64) |
Nov
(60) |
Dec
(10) |
2012 |
Jan
(64) |
Feb
(63) |
Mar
(39) |
Apr
(43) |
May
(54) |
Jun
(11) |
Jul
(30) |
Aug
(45) |
Sep
(11) |
Oct
(70) |
Nov
(24) |
Dec
(23) |
2013 |
Jan
(17) |
Feb
(8) |
Mar
(35) |
Apr
(40) |
May
(20) |
Jun
(24) |
Jul
(36) |
Aug
(25) |
Sep
(42) |
Oct
(40) |
Nov
(9) |
Dec
(21) |
2014 |
Jan
(29) |
Feb
(24) |
Mar
(60) |
Apr
(22) |
May
(22) |
Jun
(46) |
Jul
(11) |
Aug
(23) |
Sep
(26) |
Oct
(10) |
Nov
(14) |
Dec
(2) |
2015 |
Jan
(28) |
Feb
(47) |
Mar
(33) |
Apr
(58) |
May
(5) |
Jun
(1) |
Jul
|
Aug
(8) |
Sep
(12) |
Oct
(25) |
Nov
(58) |
Dec
(21) |
2016 |
Jan
(12) |
Feb
(40) |
Mar
(2) |
Apr
(1) |
May
(67) |
Jun
(2) |
Jul
(5) |
Aug
(36) |
Sep
|
Oct
(24) |
Nov
(17) |
Dec
(50) |
2017 |
Jan
(14) |
Feb
(16) |
Mar
(2) |
Apr
(35) |
May
(14) |
Jun
(16) |
Jul
(3) |
Aug
(3) |
Sep
|
Oct
(19) |
Nov
|
Dec
(16) |
2018 |
Jan
(55) |
Feb
(11) |
Mar
(34) |
Apr
(14) |
May
(4) |
Jun
(20) |
Jul
(39) |
Aug
(16) |
Sep
(17) |
Oct
(16) |
Nov
(20) |
Dec
(30) |
2019 |
Jan
(29) |
Feb
(24) |
Mar
(37) |
Apr
(26) |
May
(19) |
Jun
(21) |
Jul
(2) |
Aug
(3) |
Sep
(9) |
Oct
(12) |
Nov
(12) |
Dec
(12) |
2020 |
Jan
(47) |
Feb
(36) |
Mar
(54) |
Apr
(44) |
May
(37) |
Jun
(19) |
Jul
(32) |
Aug
(13) |
Sep
(16) |
Oct
(24) |
Nov
(32) |
Dec
(11) |
2021 |
Jan
(14) |
Feb
(5) |
Mar
(40) |
Apr
(32) |
May
(42) |
Jun
(31) |
Jul
(29) |
Aug
(47) |
Sep
(38) |
Oct
(17) |
Nov
(74) |
Dec
(33) |
2022 |
Jan
(11) |
Feb
(15) |
Mar
(40) |
Apr
(21) |
May
(39) |
Jun
(44) |
Jul
(19) |
Aug
(46) |
Sep
(79) |
Oct
(35) |
Nov
(21) |
Dec
(15) |
2023 |
Jan
(56) |
Feb
(13) |
Mar
(43) |
Apr
(28) |
May
(60) |
Jun
(15) |
Jul
(29) |
Aug
(28) |
Sep
(32) |
Oct
(21) |
Nov
(42) |
Dec
(39) |
2024 |
Jan
(35) |
Feb
(17) |
Mar
(28) |
Apr
(7) |
May
(14) |
Jun
(35) |
Jul
(30) |
Aug
(35) |
Sep
(30) |
Oct
(28) |
Nov
(38) |
Dec
(18) |
2025 |
Jan
(21) |
Feb
(28) |
Mar
(36) |
Apr
(35) |
May
(34) |
Jun
(58) |
Jul
(9) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: openocd-gerrit <ope...@us...> - 2025-05-01 15:23:50
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via cbd7987c7ca2656b60bc8964bb1d9b7819e66ccb (commit) from 4d4c45cfd25703f39f9e2413b22d91a48c4b4565 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit cbd7987c7ca2656b60bc8964bb1d9b7819e66ccb Author: Antonio Borneo <bor...@gm...> Date: Sat Apr 19 11:03:46 2025 +0200 target: stm8: drop include file stm8.h The file stm8.h is only included by stm8.c and provides some basic declaration that can be simply part of the C file. Drop the file stm8.h and move its content in stm8.c Replace the macro 'STM8_NUM_CORE_REGS' with the existing macro 'STM8_NUM_REGS'. While there: - drop the useless include of "hello.h". Change-Id: Iecd1a27f0630cdbbfd51033d34aa3d468aa63464 Signed-off-by: Antonio Borneo <bor...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/8856 Tested-by: jenkins Reviewed-by: zapb <de...@za...> diff --git a/src/target/Makefile.am b/src/target/Makefile.am index 1fc7d2afa..1a7686418 100644 --- a/src/target/Makefile.am +++ b/src/target/Makefile.am @@ -224,7 +224,6 @@ ARC_SRC = \ %D%/avr32_mem.h \ %D%/avr32_regs.h \ %D%/semihosting_common.h \ - %D%/stm8.h \ %D%/lakemont.h \ %D%/x86_32_common.h \ %D%/arm_cti.h \ diff --git a/src/target/stm8.c b/src/target/stm8.c index c80ea0eb2..81c41f2b2 100644 --- a/src/target/stm8.c +++ b/src/target/stm8.c @@ -13,14 +13,12 @@ #include <helper/log.h> #include "target.h" #include "target_type.h" -#include "hello.h" #include "jtag/interface.h" #include "jtag/jtag.h" #include "jtag/swim.h" #include "register.h" #include "breakpoints.h" #include "algorithm.h" -#include "stm8.h" static struct reg_cache *stm8_build_reg_cache(struct target *target); static int stm8_read_core_reg(struct target *target, unsigned int num); @@ -54,6 +52,8 @@ static const struct { { 5, "cc", 8, REG_TYPE_UINT8, "general", "org.gnu.gdb.stm8.core", 0 }, }; +#define STM8_COMMON_MAGIC 0x53544D38U + #define STM8_NUM_REGS ARRAY_SIZE(stm8_regs) #define STM8_PC 0 #define STM8_A 1 @@ -168,6 +168,51 @@ struct stm8_comparator { enum hw_break_type type; }; +struct stm8_common { + unsigned int common_magic; + + void *arch_info; + struct reg_cache *core_cache; + uint32_t core_regs[STM8_NUM_REGS]; + + /* working area for fastdata access */ + struct working_area *fast_data_area; + + bool swim_configured; + bool bp_scanned; + uint8_t num_hw_bpoints; + uint8_t num_hw_bpoints_avail; + struct stm8_comparator *hw_break_list; + uint32_t blocksize; + uint32_t flashstart; + uint32_t flashend; + uint32_t eepromstart; + uint32_t eepromend; + uint32_t optionstart; + uint32_t optionend; + bool enable_step_irq; + + bool enable_stm8l; + uint32_t flash_cr2; + uint32_t flash_ncr2; + uint32_t flash_iapsr; + uint32_t flash_dukr; + uint32_t flash_pukr; + + /* cc value used for interrupt flags restore */ + uint32_t cc; + bool cc_valid; + + /* register cache to processor synchronization */ + int (*read_core_reg)(struct target *target, unsigned int num); + int (*write_core_reg)(struct target *target, unsigned int num); +}; + +static struct stm8_common *target_to_stm8(struct target *target) +{ + return target->arch_info; +} + static int stm8_adapter_read_memory(struct target *target, uint32_t addr, int size, int count, void *buf) { diff --git a/src/target/stm8.h b/src/target/stm8.h deleted file mode 100644 index 55e1071ab..000000000 --- a/src/target/stm8.h +++ /dev/null @@ -1,63 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/* -* OpenOCD STM8 target driver -* Copyright (C) 2017 Ake Rehnman -* ake.rehnman(at)gmail.com -*/ - -#ifndef OPENOCD_TARGET_STM8_H -#define OPENOCD_TARGET_STM8_H - -struct target; - -#define STM8_COMMON_MAGIC 0x53544D38U -#define STM8_NUM_CORE_REGS 6 - -struct stm8_common { - unsigned int common_magic; - - void *arch_info; - struct reg_cache *core_cache; - uint32_t core_regs[STM8_NUM_CORE_REGS]; - - /* working area for fastdata access */ - struct working_area *fast_data_area; - - bool swim_configured; - bool bp_scanned; - uint8_t num_hw_bpoints; - uint8_t num_hw_bpoints_avail; - struct stm8_comparator *hw_break_list; - uint32_t blocksize; - uint32_t flashstart; - uint32_t flashend; - uint32_t eepromstart; - uint32_t eepromend; - uint32_t optionstart; - uint32_t optionend; - bool enable_step_irq; - - bool enable_stm8l; - uint32_t flash_cr2; - uint32_t flash_ncr2; - uint32_t flash_iapsr; - uint32_t flash_dukr; - uint32_t flash_pukr; - - /* cc value used for interrupt flags restore */ - uint32_t cc; - bool cc_valid; - - /* register cache to processor synchronization */ - int (*read_core_reg)(struct target *target, unsigned int num); - int (*write_core_reg)(struct target *target, unsigned int num); -}; - -static inline struct stm8_common * -target_to_stm8(struct target *target) -{ - return target->arch_info; -} - -#endif /* OPENOCD_TARGET_STM8_H */ ----------------------------------------------------------------------- Summary of changes: src/target/Makefile.am | 1 - src/target/stm8.c | 49 +++++++++++++++++++++++++++++++++++++-- src/target/stm8.h | 63 -------------------------------------------------- 3 files changed, 47 insertions(+), 66 deletions(-) delete mode 100644 src/target/stm8.h hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2025-04-25 10:31:00
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 4d4c45cfd25703f39f9e2413b22d91a48c4b4565 (commit) via bf66d95be2db83da2694d20970c4b8db8e5de969 (commit) from 5bb7dbc2312f4ce84224720eb258ebcae2089e28 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4d4c45cfd25703f39f9e2413b22d91a48c4b4565 Author: Tomas Vanek <va...@fb...> Date: Fri Mar 21 21:56:39 2025 +0100 flash/nor/rp2xxx: define macro BOOTROM_MAGIC_MASK and use it instead of magic value. Change-Id: I5d006aaf990d4ef3a82e622b1e41cd2bfec359f7 Signed-off-by: Tomas Vanek <va...@fb...> Reported-by: Antonio Borneo <bor...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/8810 Reviewed-by: Antonio Borneo <bor...@gm...> Tested-by: jenkins diff --git a/src/flash/nor/rp2xxx.c b/src/flash/nor/rp2xxx.c index 2b22e52eb..85c591104 100644 --- a/src/flash/nor/rp2xxx.c +++ b/src/flash/nor/rp2xxx.c @@ -16,6 +16,7 @@ #define BOOTROM_RP2040_MAGIC 0x01754d /* this is 'M' 'u', 2 (version) */ #define BOOTROM_RP2350_MAGIC 0x02754d +#define BOOTROM_MAGIC_MASK 0xffffff #define BOOTROM_MAGIC_ADDR 0x00000010 #define MAKE_TAG(a, b) (((b)<<8) | a) @@ -368,7 +369,7 @@ static int rp2xxx_lookup_rom_symbol(struct target *target, uint16_t tag, uint16_ return err; /* Ignore version */ - magic &= 0xffffff; + magic &= BOOTROM_MAGIC_MASK; if (magic == BOOTROM_RP2350_MAGIC) { /* Distinguish old-style RP2350 ROM table (A0, and earlier A1 builds) commit bf66d95be2db83da2694d20970c4b8db8e5de969 Author: Tomas Vanek <va...@fb...> Date: Fri Mar 21 21:30:13 2025 +0100 flash/nor/rp2xxx: fix LOG_xxx messages Use proper format specifiers for uint16_t and uint32_t arguments. Use LOG_TARGET_DEBUG instead of target->cmd_name as a parameter. Use command_print() in command handler. Drop dots and new lines at end of messages. Change-Id: I37c7d3680a352210b1d7e69f2c9b4ba0efe6ec15 Signed-off-by: Tomas Vanek <va...@fb...> Reported-by: Antonio Borneo <bor...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/8809 Tested-by: jenkins diff --git a/src/flash/nor/rp2xxx.c b/src/flash/nor/rp2xxx.c index 280f077c1..2b22e52eb 100644 --- a/src/flash/nor/rp2xxx.c +++ b/src/flash/nor/rp2xxx.c @@ -242,7 +242,7 @@ static int rp2040_lookup_rom_symbol(struct target *target, uint16_t tag, uint16_ if (err != ERROR_OK) return err; - LOG_ROM_SYMBOL_DEBUG(" -> found: 0x%04x", *symbol_out); + LOG_ROM_SYMBOL_DEBUG(" -> found: 0x%04" PRIx16, *symbol_out); return ERROR_OK; } ptr_to_entry += 4; @@ -287,7 +287,7 @@ static int rp2350_a0_lookup_symbol(struct target *target, uint16_t tag, uint16_t if (err != ERROR_OK) return err; - LOG_ROM_SYMBOL_DEBUG(" -> found: 0x%04x", *symbol_out); + LOG_ROM_SYMBOL_DEBUG(" -> found: 0x%04" PRIx16, *symbol_out); return ERROR_OK; } ptr_to_entry += 6; @@ -347,7 +347,7 @@ static int rp2350_lookup_rom_symbol(struct target *target, uint32_t ptr_to_entry if (err != ERROR_OK) return err; - LOG_ROM_SYMBOL_DEBUG(" -> found: 0x%04x", *symbol_out); + LOG_ROM_SYMBOL_DEBUG(" -> found: 0x%04" PRIx16, *symbol_out); return ERROR_OK; } /* Skip past this entry */ @@ -398,38 +398,38 @@ static int rp2xxx_populate_rom_pointer_cache(struct target *target, struct rp2xx err = rp2xxx_lookup_rom_symbol(target, FUNC_FLASH_EXIT_XIP, symtype_func, &priv->jump_flash_exit_xip); if (err != ERROR_OK) { - LOG_ERROR("Function FUNC_FLASH_EXIT_XIP not found in RP2xxx ROM."); + LOG_ERROR("Function FUNC_FLASH_EXIT_XIP not found in RP2xxx ROM"); return err; } err = rp2xxx_lookup_rom_symbol(target, FUNC_CONNECT_INTERNAL_FLASH, symtype_func, &priv->jump_connect_internal_flash); if (err != ERROR_OK) { - LOG_ERROR("Function FUNC_CONNECT_INTERNAL_FLASH not found in RP2xxx ROM."); + LOG_ERROR("Function FUNC_CONNECT_INTERNAL_FLASH not found in RP2xxx ROM"); return err; } err = rp2xxx_lookup_rom_symbol(target, FUNC_FLASH_RANGE_ERASE, symtype_func, &priv->jump_flash_range_erase); if (err != ERROR_OK) { - LOG_ERROR("Function FUNC_FLASH_RANGE_ERASE not found in RP2xxx ROM."); + LOG_ERROR("Function FUNC_FLASH_RANGE_ERASE not found in RP2xxx ROM"); return err; } err = rp2xxx_lookup_rom_symbol(target, FUNC_FLASH_RANGE_PROGRAM, symtype_func, &priv->jump_flash_range_program); if (err != ERROR_OK) { - LOG_ERROR("Function FUNC_FLASH_RANGE_PROGRAM not found in RP2xxx ROM."); + LOG_ERROR("Function FUNC_FLASH_RANGE_PROGRAM not found in RP2xxx ROM"); return err; } err = rp2xxx_lookup_rom_symbol(target, FUNC_FLASH_FLUSH_CACHE, symtype_func, &priv->jump_flush_cache); if (err != ERROR_OK) { - LOG_ERROR("Function FUNC_FLASH_FLUSH_CACHE not found in RP2xxx ROM."); + LOG_ERROR("Function FUNC_FLASH_FLUSH_CACHE not found in RP2xxx ROM"); return err; } err = rp2xxx_lookup_rom_symbol(target, FUNC_FLASH_ENTER_CMD_XIP, symtype_func, &priv->jump_enter_cmd_xip); if (err != ERROR_OK) { - LOG_ERROR("Function FUNC_FLASH_ENTER_CMD_XIP not found in RP2xxx ROM."); + LOG_ERROR("Function FUNC_FLASH_ENTER_CMD_XIP not found in RP2xxx ROM"); return err; } @@ -480,18 +480,17 @@ static int rp2xxx_call_rom_func_batch(struct target *target, struct rp2xxx_flash return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } if (priv->ram_algo_space->size < batch_size) { - LOG_ERROR("RAM code space too small for call batch size of %u\n", n_calls); + LOG_ERROR("RAM code space too small for call batch size of %u", n_calls); return ERROR_BUF_TOO_SMALL; } - LOG_DEBUG("Calling batch of %u ROM functions:", n_calls); + LOG_TARGET_DEBUG(target, "Calling batch of %u ROM functions:", n_calls); for (unsigned int i = 0; i < n_calls; ++i) { LOG_DEBUG(" func @ %" PRIx32, calls[i].pc); LOG_DEBUG(" sp = %" PRIx32, calls[i].sp); for (unsigned int j = 0; j < 4; ++j) - LOG_DEBUG(" a%d = %" PRIx32, j, calls[i].args[j]); + LOG_DEBUG(" a%u = %" PRIx32, j, calls[i].args[j]); } - LOG_DEBUG("Calling on core \"%s\"", target->cmd_name); if (n_calls <= 0) { LOG_DEBUG("Returning early from call of 0 ROM functions"); @@ -534,7 +533,7 @@ static int rp2xxx_call_rom_func_batch(struct target *target, struct rp2xxx_flash free(batch_bf); if (err != ERROR_OK) { - LOG_ERROR("Failed to write ROM batch algorithm to RAM code space\n"); + LOG_ERROR("Failed to write ROM batch algorithm to RAM code space"); return err; } @@ -565,7 +564,7 @@ static int rp2xxx_call_rom_func_batch(struct target *target, struct rp2xxx_flash ); } if (err != ERROR_OK) { - LOG_ERROR("Failed to call ROM function batch\n"); + LOG_ERROR("Failed to call ROM function batch"); /* 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"); @@ -616,9 +615,9 @@ static int rp2350_init_accessctrl(struct target *target) return ERROR_FAIL; } if (accessctrl_lock_reg & ACCESSCTRL_LOCK_DEBUG_BITS) { - LOG_ERROR("ACCESSCTRL is locked, so can't reset permissions. Following steps might fail.\n"); + LOG_ERROR("ACCESSCTRL is locked, so can't reset permissions. Following steps might fail"); } else { - LOG_DEBUG("Reset ACCESSCTRL permissions via CFGRESET\n"); + LOG_DEBUG("Reset ACCESSCTRL permissions via CFGRESET"); return target_write_u32(target, ACCESSCTRL_CFGRESET_OFFSET, ACCESSCTRL_WRITE_PASSWORD | 1u); } return ERROR_OK; @@ -637,9 +636,9 @@ static int rp2350_init_arm_core0(struct target *target, struct rp2xxx_flash_bank return retval; } - LOG_DEBUG("DSCSR: %08x\n", dscsr); + LOG_DEBUG("DSCSR: 0x%08" PRIx32, dscsr); if (!(dscsr & DSCSR_CDS)) { - LOG_DEBUG("Setting Current Domain Secure in DSCSR\n"); + LOG_DEBUG("Setting Current Domain Secure in DSCSR"); retval = target_write_u32(target, DCB_DSCSR, (dscsr & ~DSCSR_CDSKEY) | DSCSR_CDS); if (retval != ERROR_OK) { LOG_ERROR("RP2350 init ARM core: DSCSR read failed"); @@ -664,12 +663,12 @@ static int rp2350_init_arm_core0(struct target *target, struct rp2xxx_flash_bank rcp_init_code ); if (err != ERROR_OK) { - LOG_ERROR("Failed to load rcp_init algorithm into RAM\n"); + LOG_ERROR("Failed to load rcp_init algorithm into RAM"); return ERROR_FAIL; } - LOG_DEBUG("Calling rcp_init on core \"%s\", code at 0x%" PRIx32 "\n", - target->cmd_name, (uint32_t)priv->ram_algo_space->address); + LOG_TARGET_DEBUG(target, "Calling rcp_init, code at " TARGET_ADDR_FMT, + priv->ram_algo_space->address); /* Actually call the function */ struct armv7m_algorithm alg_info; @@ -684,7 +683,7 @@ static int rp2350_init_arm_core0(struct target *target, struct rp2xxx_flash_bank &alg_info ); if (err != ERROR_OK) { - LOG_ERROR("Failed to invoke rcp_init\n"); + LOG_ERROR("Failed to invoke rcp_init"); return err; } @@ -729,7 +728,7 @@ static int setup_for_raw_flash_cmd(struct target *target, struct rp2xxx_flash_ba BOOTROM_STATE_RESET_CURRENT_CORE }; if (!priv->jump_bootrom_reset_state) { - LOG_WARNING("RP2350 flash: no bootrom_reset_method\n"); + LOG_WARNING("RP2350 flash: no bootrom_reset_method"); } 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 @@ -746,7 +745,7 @@ static int setup_for_raw_flash_cmd(struct target *target, struct rp2xxx_flash_ba /* 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"); + LOG_DEBUG("Enabling default Arm emulator stacks for RISC-V ROM calls"); 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) { @@ -771,7 +770,7 @@ static int setup_for_raw_flash_cmd(struct target *target, struct rp2xxx_flash_ba 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); + LOG_ERROR("Failed to initialise Arm emulation stacks for RISC-V"); return err; } } @@ -852,7 +851,7 @@ static void cleanup_after_raw_flash_cmd(struct target *target, struct rp2xxx_fla static int rp2xxx_flash_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { - LOG_DEBUG("Writing %d bytes starting at 0x%" PRIx32, count, offset); + LOG_DEBUG("Writing %" PRIu32 " bytes starting at 0x%" PRIx32, count, offset); struct rp2xxx_flash_bank *priv = bank->driver_priv; struct target *target = bank->target; @@ -882,7 +881,8 @@ static int rp2xxx_flash_write(struct flash_bank *bank, const uint8_t *buffer, ui while (count > 0) { uint32_t write_size = count > chunk_size ? chunk_size : count; - LOG_DEBUG("Writing %d bytes to offset 0x%" PRIx32, write_size, offset); + LOG_DEBUG("Writing %" PRIu32 " bytes to offset 0x%" PRIx32, + write_size, offset); err = target_write_buffer(target, bounce->address, write_size, buffer); if (err != ERROR_OK) { LOG_ERROR("Could not load data into target bounce buffer"); @@ -929,7 +929,8 @@ static int rp2xxx_flash_erase(struct flash_bank *bank, unsigned int first, unsig uint32_t offset_start = bank->sectors[first].offset; uint32_t offset_last = bank->sectors[last].offset + bank->sectors[last].size; uint32_t length = offset_last - offset_start; - LOG_DEBUG("erase %d bytes starting at 0x%" PRIx32, length, offset_start); + LOG_DEBUG("erase %" PRIu32 " bytes starting at 0x%" PRIx32, + length, offset_start); int err = setup_for_raw_flash_cmd(target, priv); if (err != ERROR_OK) @@ -1328,7 +1329,7 @@ COMMAND_HANDLER(rp2xxx_rom_api_call_handler) COMMAND_PARSE_NUMBER(u32, CMD_ARGV[i + 1], args[i]); if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); + command_print(CMD, "Target not halted"); return ERROR_TARGET_NOT_HALTED; } @@ -1343,7 +1344,7 @@ COMMAND_HANDLER(rp2xxx_rom_api_call_handler) uint16_t fc; retval = rp2xxx_lookup_rom_symbol(target, tag, symtype_func, &fc); if (retval != ERROR_OK) { - command_print(CMD, "Function %.2s not found in RP2xxx ROM.", + command_print(CMD, "Function %.2s not found in RP2xxx ROM", CMD_ARGV[0]); goto cleanup_and_return; } ----------------------------------------------------------------------- Summary of changes: src/flash/nor/rp2xxx.c | 66 ++++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 32 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2025-04-25 09:47:07
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 5bb7dbc2312f4ce84224720eb258ebcae2089e28 (commit) via 376d11c2e38303094976186d59502ab7d3073452 (commit) from f039fe7f9d1ecfc1ca25574d5527c35db119e77b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5bb7dbc2312f4ce84224720eb258ebcae2089e28 Author: Luke Wren <lu...@ra...> 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 <va...@fb...> Signed-off-by: Luke Wren <lu...@ra...> Reviewed-on: https://review.openocd.org/c/openocd/+/8729 Tested-by: jenkins diff --git a/src/flash/nor/rp2xxx.c b/src/flash/nor/rp2xxx.c index fce501703..280f077c1 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"); commit 376d11c2e38303094976186d59502ab7d3073452 Author: Tomas Vanek <va...@fb...> Date: Sat Aug 17 16:21:06 2024 +0200 tcl/target/rp2040: add flash size override and reset init event Allow flash size override and suppress flash size detection by setting FLASHSIZE Tcl variable. reset-init event calls 'connect XIP' ROM API function to make flash content accessible at the XIP mapping memory area. Ported from rp2350.cfg Change-Id: I9b352b1ef6d4c6d4b78a6b61e900ce01355c8eff Signed-off-by: Tomas Vanek <va...@fb...> Reviewed-on: https://review.openocd.org/c/openocd/+/8461 Reviewed-by: Jonathan Bell <jon...@ra...> Tested-by: jenkins diff --git a/tcl/target/rp2040.cfg b/tcl/target/rp2040.cfg index 5fae390b4..f64d4322b 100644 --- a/tcl/target/rp2040.cfg +++ b/tcl/target/rp2040.cfg @@ -20,6 +20,14 @@ if { [info exists WORKAREASIZE] } { set _WORKAREASIZE 0x10000 } +# Nonzero FLASHSIZE supresses QSPI flash size detection +if { [info exists FLASHSIZE] } { + set _FLASHSIZE $FLASHSIZE +} else { + # Detect QSPI flash size based on flash ID or SFDP + set _FLASHSIZE 0 +} + if { [info exists CPUTAPID] } { set _CPUTAPID $CPUTAPID } else { @@ -74,6 +82,10 @@ if { $_USE_CORE != 1 } { target create $_TARGETNAME_0 cortex_m -dap $_CHIPNAME.dap0 -coreid 0 # srst does not exist; use SYSRESETREQ to perform a soft reset $_TARGETNAME_0 cortex_m reset_config sysresetreq + + # After a rescue reset and fi BOOTSEL is halted connect the flash to enable + # reads from the XIP cached mapping area + $_TARGETNAME_0 configure -event reset-init { rp2xxx rom_api_call 0 CX } } # core 1 @@ -95,11 +107,11 @@ if { $_USE_CORE == 1 } { } else { set _FLASH_TARGET $_TARGETNAME_0 } -# Backup the work area. The flash probe runs an algorithm on the target CPU. -# The flash is probed during gdb connect if gdb memory_map is enabled (by default). -$_FLASH_TARGET configure -work-area-phys 0x20010000 -work-area-size $_WORKAREASIZE -work-area-backup 1 +# QSPI flash size detection during gdb connect requires to back-up RAM +set _WKA_BACKUP [expr { $_FLASHSIZE == 0 }] +$_FLASH_TARGET configure -work-area-phys 0x20010000 -work-area-size $_WORKAREASIZE -work-area-backup $_WKA_BACKUP set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME rp2xxx 0x10000000 0 0 0 $_FLASH_TARGET +flash bank $_FLASHNAME rp2xxx 0x10000000 $_FLASHSIZE 0 0 $_FLASH_TARGET if { $_BOTH_CORES } { # Alias to ensure gdb connecting to core 1 gets the correct memory map ----------------------------------------------------------------------- Summary of changes: src/flash/nor/rp2xxx.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ tcl/target/rp2040.cfg | 20 ++++++++++++++++---- 2 files changed, 63 insertions(+), 4 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2025-04-25 09:46:13
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via f039fe7f9d1ecfc1ca25574d5527c35db119e77b (commit) from a9608871692be6cda4d73ae837b4313747370ff8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f039fe7f9d1ecfc1ca25574d5527c35db119e77b Author: Tomas Vanek <va...@fb...> Date: Fri Aug 16 23:35:06 2024 +0200 flash/nor/rp2xxx: fix endianness error struct rp2xxx_rom_call_batch_record consists of uint32_t in the host endianness. Therefore it should be converted to the target endianness not just simply copied by target_write_buffer(). Concatenate algo code, converted batch records and terminator to the host resident buffer and copy it at once to the target and save some adapter turnaround times. While on it remove typedef rp2xxx_rom_call_batch_record_t Change-Id: I0e698396003869bee5dde4141d48ddd7d62b3cbc Signed-off-by: Tomas Vanek <va...@fb...> Reviewed-on: https://review.openocd.org/c/openocd/+/8460 Reviewed-by: Jonathan Bell <jon...@ra...> Tested-by: jenkins diff --git a/src/flash/nor/rp2xxx.c b/src/flash/nor/rp2xxx.c index 5d0255b61..fce501703 100644 --- a/src/flash/nor/rp2xxx.c +++ b/src/flash/nor/rp2xxx.c @@ -179,11 +179,11 @@ static const uint8_t rp2xxx_rom_call_batch_algo_riscv[ROM_CALL_BATCH_ALGO_SIZE_B // <_args>: }; -typedef struct rp2xxx_rom_call_batch_record { +struct rp2xxx_rom_call_batch_record { uint32_t pc; uint32_t sp; uint32_t args[4]; -} rp2xxx_rom_call_batch_record_t; +}; struct rp2xxx_flash_bank { bool probed; /* flag indicating successful flash probe */ @@ -457,18 +457,18 @@ static int rp2xxx_populate_rom_pointer_cache(struct target *target, struct rp2xx // Call a list of PC + SP + r0-r3 function call tuples with a single OpenOCD // algorithm invocation, to amortise the algorithm overhead over multiple calls: static int rp2xxx_call_rom_func_batch(struct target *target, struct rp2xxx_flash_bank *priv, - rp2xxx_rom_call_batch_record_t *calls, unsigned int n_calls) + struct rp2xxx_rom_call_batch_record *calls, unsigned int n_calls) { - // Note +1 is for the null terminator - unsigned int batch_words = 1 + (ROM_CALL_BATCH_ALGO_SIZE_BYTES + - n_calls * sizeof(rp2xxx_rom_call_batch_record_t) - ) / sizeof(uint32_t); + // Note + sizeof(uint32_t) is for the null terminator + unsigned int batch_size = ROM_CALL_BATCH_ALGO_SIZE_BYTES + + n_calls * sizeof(struct rp2xxx_rom_call_batch_record) + + sizeof(uint32_t); if (!priv->ram_algo_space) { LOG_ERROR("No RAM code space allocated for ROM call"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } - if (priv->ram_algo_space->size < batch_words * sizeof(uint32_t)) { + if (priv->ram_algo_space->size < batch_size) { LOG_ERROR("RAM code space too small for call batch size of %u\n", n_calls); return ERROR_BUF_TOO_SMALL; } @@ -501,32 +501,31 @@ static int rp2xxx_call_rom_func_batch(struct target *target, struct rp2xxx_flash algo_code = rp2xxx_rom_call_batch_algo_riscv; } + uint8_t *batch_bf = malloc(batch_size); + if (!batch_bf) { + LOG_ERROR("No memory for batch buffer"); + return ERROR_FAIL; + } + memcpy(batch_bf, algo_code, ROM_CALL_BATCH_ALGO_SIZE_BYTES); + unsigned int words = n_calls * sizeof(struct rp2xxx_rom_call_batch_record) + / sizeof(uint32_t); + target_buffer_set_u32_array(target, + &batch_bf[ROM_CALL_BATCH_ALGO_SIZE_BYTES], words, + (const uint32_t *)calls); + /* Null terminator */ + target_buffer_set_u32(target, &batch_bf[batch_size - sizeof(uint32_t)], 0); + int err = target_write_buffer(target, priv->ram_algo_space->address, - ROM_CALL_BATCH_ALGO_SIZE_BYTES, - algo_code + batch_size, + batch_bf ); + free(batch_bf); + if (err != ERROR_OK) { LOG_ERROR("Failed to write ROM batch algorithm to RAM code space\n"); return err; } - err = target_write_buffer(target, - priv->ram_algo_space->address + ROM_CALL_BATCH_ALGO_SIZE_BYTES, - n_calls * sizeof(rp2xxx_rom_call_batch_record_t), - (const uint8_t *)calls - ); - if (err != ERROR_OK) { - LOG_ERROR("Failed to write ROM batch records to RAM code space\n"); - return err; - } - err = target_write_u32(target, - priv->ram_algo_space->address + (batch_words - 1) * sizeof(uint32_t), - 0 - ); - if (err != ERROR_OK) { - LOG_ERROR("Failed to write null terminator for ROM batch records\n"); - return err; - } // Call into the ROM batch algorithm -- this will in turn call each ROM // call specified by the batch records. @@ -579,7 +578,7 @@ static int rp2xxx_call_rom_func(struct target *target, struct rp2xxx_flash_bank } target_addr_t stacktop = priv->stack->address + priv->stack->size; - rp2xxx_rom_call_batch_record_t call = { + struct rp2xxx_rom_call_batch_record call = { .pc = func_offset, .sp = stacktop }; @@ -732,7 +731,7 @@ static int setup_for_raw_flash_cmd(struct target *target, struct rp2xxx_flash_ba } LOG_DEBUG("Connecting flash IOs and issuing XIP exit sequence to flash"); - rp2xxx_rom_call_batch_record_t calls[2] = { + struct rp2xxx_rom_call_batch_record calls[2] = { { .pc = priv->jump_connect_internal_flash, .sp = priv->stack->address + priv->stack->size @@ -759,7 +758,7 @@ static int rp2xxx_invalidate_cache_restore_xip(struct target *target, struct rp2 LOG_DEBUG("Flushing flash cache after write behind"); - rp2xxx_rom_call_batch_record_t finishing_calls[2] = { + struct rp2xxx_rom_call_batch_record finishing_calls[2] = { { .pc = priv->jump_flush_cache, .sp = priv->stack->address + priv->stack->size ----------------------------------------------------------------------- Summary of changes: src/flash/nor/rp2xxx.c | 59 +++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 30 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2025-04-25 09:45:22
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via a9608871692be6cda4d73ae837b4313747370ff8 (commit) from d29c1c6d6df31f64ae5593babc65cfdffa312def (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a9608871692be6cda4d73ae837b4313747370ff8 Author: Tomas Vanek <va...@fb...> Date: Fri Aug 16 22:53:36 2024 +0200 flash/nor/rp2xxx: drop couple of Java-like const The compiler knows what variable remains constant during its lifetime and there is no need to emphasise constantness. Change-Id: Ib515f96a3c77afea87274f33b8ccac7a71bfb932 Signed-off-by: Tomas Vanek <va...@fb...> Reviewed-on: https://review.openocd.org/c/openocd/+/8459 Tested-by: jenkins Reviewed-by: Jonathan Bell <jon...@ra...> diff --git a/src/flash/nor/rp2xxx.c b/src/flash/nor/rp2xxx.c index 909d3f14d..5d0255b61 100644 --- a/src/flash/nor/rp2xxx.c +++ b/src/flash/nor/rp2xxx.c @@ -223,7 +223,7 @@ static int rp2040_lookup_rom_symbol(struct target *target, uint16_t tag, uint16_ } uint16_t ptr_to_entry; - const unsigned int offset_magic_to_table_ptr = flags == RT_FLAG_DATA ? 6 : 4; + unsigned int offset_magic_to_table_ptr = flags == RT_FLAG_DATA ? 6 : 4; int err = target_read_u16(target, BOOTROM_MAGIC_ADDR + offset_magic_to_table_ptr, &ptr_to_entry); if (err != ERROR_OK) return err; @@ -390,8 +390,8 @@ static int rp2xxx_lookup_rom_symbol(struct target *target, uint16_t tag, uint16_ static int rp2xxx_populate_rom_pointer_cache(struct target *target, struct rp2xxx_flash_bank *priv) { - const uint16_t symtype_func = is_arm(target_to_arm(target)) - ? RT_FLAG_FUNC_ARM_SEC : RT_FLAG_FUNC_RISCV; + uint16_t symtype_func = is_arm(target_to_arm(target)) + ? RT_FLAG_FUNC_ARM_SEC : RT_FLAG_FUNC_RISCV; int err; err = rp2xxx_lookup_rom_symbol(target, FUNC_FLASH_EXIT_XIP, symtype_func, &priv->jump_flash_exit_xip); ----------------------------------------------------------------------- Summary of changes: src/flash/nor/rp2xxx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2025-04-25 09:44:50
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via d29c1c6d6df31f64ae5593babc65cfdffa312def (commit) from 9fce121366c86e77e84b9d20c7d1c7dbb38710d5 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d29c1c6d6df31f64ae5593babc65cfdffa312def Author: Tomas Vanek <va...@fb...> Date: Wed Aug 14 17:43:13 2024 +0200 flash/nor/rp2xxx: minor code improvements Add error messages and proper error propagation. Type cleaning. Use saved chip id. Cosmetics: separating lines added. Signed-off-by: Tomas Vanek <va...@fb...> Change-Id: I151e684e1fbfc9476ec429036caf85f4c9329547 Reviewed-on: https://review.openocd.org/c/openocd/+/8457 Tested-by: jenkins Reviewed-by: Jonathan Bell <jon...@ra...> diff --git a/src/flash/nor/rp2xxx.c b/src/flash/nor/rp2xxx.c index e58fc8a29..909d3f14d 100644 --- a/src/flash/nor/rp2xxx.c +++ b/src/flash/nor/rp2xxx.c @@ -233,11 +233,13 @@ static int rp2040_lookup_rom_symbol(struct target *target, uint16_t tag, uint16_ err = target_read_u16(target, ptr_to_entry, &entry_tag); if (err != ERROR_OK) return err; + if (entry_tag == tag) { /* 16 bit symbol is next */ err = target_read_u16(target, ptr_to_entry + 2, symbol_out); if (err != ERROR_OK) return err; + LOG_ROM_SYMBOL_DEBUG(" -> found: 0x%04x", *symbol_out); return ERROR_OK; } @@ -277,10 +279,12 @@ static int rp2350_a0_lookup_symbol(struct target *target, uint16_t tag, uint16_t err = target_read_u16(target, ptr_to_entry, &entry_tag); if (err != ERROR_OK) return err; + if (entry_tag == tag) { err = target_read_u16(target, ptr_to_entry + 2, symbol_out); if (err != ERROR_OK) return err; + LOG_ROM_SYMBOL_DEBUG(" -> found: 0x%04x", *symbol_out); return ERROR_OK; } @@ -303,9 +307,10 @@ static int rp2350_lookup_rom_symbol(struct target *target, uint32_t ptr_to_entry while (true) { uint16_t entry_tag, entry_flags; - uint32_t err = target_read_u16(target, ptr_to_entry, &entry_tag); + int err = target_read_u16(target, ptr_to_entry, &entry_tag); if (err != ERROR_OK) return err; + if (entry_tag == 0) { *symbol_out = 0; return ERROR_FAIL; @@ -315,6 +320,7 @@ static int rp2350_lookup_rom_symbol(struct target *target, uint32_t ptr_to_entry err = target_read_u16(target, ptr_to_entry, &entry_flags); if (err != ERROR_OK) return err; + ptr_to_entry += 2; uint16_t matching_flags = flags & entry_flags; @@ -338,6 +344,7 @@ static int rp2350_lookup_rom_symbol(struct target *target, uint32_t ptr_to_entry err = target_read_u16(target, ptr_to_entry, symbol_out); if (err != ERROR_OK) return err; + LOG_ROM_SYMBOL_DEBUG(" -> found: 0x%04x", *symbol_out); return ERROR_OK; } @@ -426,18 +433,23 @@ static int rp2xxx_populate_rom_pointer_cache(struct target *target, struct rp2xx // From this point are optional functions which do not exist on e.g. RP2040 // or pre-production RP2350 ROM versions: + if (IS_RP2040(priv->id)) { + priv->jump_bootrom_reset_state = 0; + priv->jump_flash_reset_address_trans = 0; + return ERROR_OK; + } err = rp2xxx_lookup_rom_symbol(target, FUNC_BOOTROM_STATE_RESET, symtype_func, &priv->jump_bootrom_reset_state); if (err != ERROR_OK) { priv->jump_bootrom_reset_state = 0; - LOG_WARNING("Function FUNC_BOOTROM_STATE_RESET not found in RP2xxx ROM. (probably an RP2040 or an RP2350 A0)"); + LOG_WARNING("Function FUNC_BOOTROM_STATE_RESET 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) { priv->jump_flash_reset_address_trans = 0; - LOG_WARNING("Function FUNC_FLASH_RESET_ADDRESS_TRANS not found in RP2xxx ROM. (probably an RP2040 or an RP2350 A0)"); + LOG_WARNING("Function FUNC_FLASH_RESET_ADDRESS_TRANS not found in RP2xxx ROM. (probably an RP2350 A0)"); } return ERROR_OK; } @@ -465,7 +477,7 @@ static int rp2xxx_call_rom_func_batch(struct target *target, struct rp2xxx_flash for (unsigned int i = 0; i < n_calls; ++i) { LOG_DEBUG(" func @ %" PRIx32, calls[i].pc); LOG_DEBUG(" sp = %" PRIx32, calls[i].sp); - for (int j = 0; j < 4; ++j) + for (unsigned int j = 0; j < 4; ++j) LOG_DEBUG(" a%d = %" PRIx32, j, calls[i].args[j]); } LOG_DEBUG("Calling on core \"%s\"", target->cmd_name); @@ -607,14 +619,22 @@ static int rp2350_init_arm_core0(struct target *target, struct rp2xxx_flash_bank // Flash algorithms (and the RCP init stub called by this function) must // run in the Secure state, so flip the state now before attempting to // execute any code on the core. + int retval; uint32_t dscsr; - (void)target_read_u32(target, DCB_DSCSR, &dscsr); + retval = target_read_u32(target, DCB_DSCSR, &dscsr); + if (retval != ERROR_OK) { + LOG_ERROR("RP2350 init ARM core: DSCSR read failed"); + return retval; + } + LOG_DEBUG("DSCSR: %08x\n", dscsr); if (!(dscsr & DSCSR_CDS)) { LOG_DEBUG("Setting Current Domain Secure in DSCSR\n"); - (void)target_write_u32(target, DCB_DSCSR, (dscsr & ~DSCSR_CDSKEY) | DSCSR_CDS); - (void)target_read_u32(target, DCB_DSCSR, &dscsr); - LOG_DEBUG("DSCSR*: %08x\n", dscsr); + retval = target_write_u32(target, DCB_DSCSR, (dscsr & ~DSCSR_CDSKEY) | DSCSR_CDS); + if (retval != ERROR_OK) { + LOG_ERROR("RP2350 init ARM core: DSCSR read failed"); + return retval; + } } if (!priv->stack) { @@ -682,8 +702,7 @@ static int setup_for_raw_flash_cmd(struct target *target, struct rp2xxx_flash_ba } } - // hacky RP2350 check -- either RISC-V or v8-M - if (is_arm(target_to_arm(target)) ? target_to_arm(target)->arch == ARM_ARCH_V8M : true) { + if (IS_RP2350(priv->id)) { err = rp2350_init_accessctrl(target); if (err != ERROR_OK) { LOG_ERROR("Failed to init ACCESSCTRL before ROM call"); @@ -861,16 +880,16 @@ static int rp2xxx_flash_erase(struct flash_bank *bank, unsigned int first, unsig return ERROR_TARGET_NOT_HALTED; } - uint32_t start_addr = bank->sectors[first].offset; - uint32_t length = bank->sectors[last].offset + bank->sectors[last].size - start_addr; - LOG_DEBUG("erase %d bytes starting at 0x%" PRIx32, length, start_addr); + uint32_t offset_start = bank->sectors[first].offset; + uint32_t offset_last = bank->sectors[last].offset + bank->sectors[last].size; + uint32_t length = offset_last - offset_start; + LOG_DEBUG("erase %d bytes starting at 0x%" PRIx32, length, offset_start); int err = setup_for_raw_flash_cmd(target, priv); if (err != ERROR_OK) goto cleanup_and_return; - uint32_t offset_next = bank->sectors[first].offset; - uint32_t offset_last = bank->sectors[last].offset + bank->sectors[last].size; + uint32_t offset_next = offset_start; /* 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 ----------------------------------------------------------------------- Summary of changes: src/flash/nor/rp2xxx.c | 49 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 15 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2025-04-25 09:43:21
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 9fce121366c86e77e84b9d20c7d1c7dbb38710d5 (commit) from 63f94bbab864d78e19ff86eda0836a5ff35b4a1b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 9fce121366c86e77e84b9d20c7d1c7dbb38710d5 Author: Tomas Vanek <va...@fb...> Date: Wed Aug 14 17:14:17 2024 +0200 doc: document changes in rp2xxx flash driver Namely the driver name changed from rp2040_flash and added RP2350 support. Signed-off-by: Tomas Vanek <va...@fb...> Change-Id: I2ec9e62786002d71f655dbe0edc9f2e9ac4141b7 Reviewed-on: https://review.openocd.org/c/openocd/+/8456 Tested-by: jenkins diff --git a/doc/openocd.texi b/doc/openocd.texi index 9ff524b74..32a2895ec 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -7872,15 +7872,29 @@ locked, but can still mass erase the whole flash. @end deffn @end deffn -@deffn {Flash Driver} {rp2040} -Supports RP2040 "Raspberry Pi Pico" microcontroller. -RP2040 is a dual-core device with two CM0+ cores. Both cores share the same -Flash/RAM/MMIO address space. Non-volatile storage is achieved with an -external QSPI flash; a Boot ROM provides helper functions. +@deffn {Flash Driver} {rp2xxx} +Supports RP2040 "Raspberry Pi Pico" microcontroller and RP2350 Pico 2 +RP2040 is a dual-core device with two CM0+ cores. +RP2350 is a dual-core device with two slots switched to either Cortex-M33 +or Hazard3 RISC-V core. +Both cores share the same Flash/RAM/MMIO address space. +Non-volatile storage is achieved with an external QSPI flash; +a Boot ROM provides helper functions. @example -flash bank $_FLASHNAME rp2040_flash $_FLASHBASE $_FLASHSIZE 1 32 $_TARGETNAME +flash bank $_FLASHNAME rp2xxx $_FLASHBASE $_FLASHSIZE 0 0 $_TARGETNAME @end example + +@deffn {Command} {rp2xxx rom_api_call} fc [p0 [p1 [p2 [p3]]]] +A utility for calling ROM API function with two characters lookup code +@var{fc} and up to 4 optional parameters @var{p0 p1 p2 p3}. +The call is supported on the target where the flash bank is configured +(core0). +@end deffn + +@deffn {Command} {rp2xxx _switch_target} old_target new_target +A command used internally by rp2350.cfg when the core type is switched. +@end deffn @end deffn @deffn {Flash Driver} {rsl10} ----------------------------------------------------------------------- Summary of changes: doc/openocd.texi | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2025-04-25 09:42:38
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 63f94bbab864d78e19ff86eda0836a5ff35b4a1b (commit) from c914cfceab54245fae1aefd70e20d0ed549f9308 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 63f94bbab864d78e19ff86eda0836a5ff35b4a1b Author: Tomas Vanek <va...@fb...> Date: Wed Aug 14 11:29:21 2024 +0200 flash/nor/rp2040: refactoring: change rp2040 to rp2xxx While on it use calloc() instead of malloc()/memset() Drop useless implementation of rp2040_flash_free_driver_priv() - exactly same as default_flash_free_driver_priv() Code style fixes forced by checkpatch Signed-off-by: Tomas Vanek <va...@fb...> Change-Id: I5c56c4a7d586c0dcab164a45e8f6200ea9a3bd1d Reviewed-on: https://review.openocd.org/c/openocd/+/8455 Tested-by: jenkins diff --git a/src/flash/nor/Makefile.am b/src/flash/nor/Makefile.am index 147807fba..7a81b282b 100644 --- a/src/flash/nor/Makefile.am +++ b/src/flash/nor/Makefile.am @@ -59,7 +59,7 @@ NOR_DRIVERS = \ %D%/psoc6.c \ %D%/qn908x.c \ %D%/renesas_rpchf.c \ - %D%/rp2040.c \ + %D%/rp2xxx.c \ %D%/rsl10.c \ %D%/sfdp.c \ %D%/sh_qspi.c \ diff --git a/src/flash/nor/driver.h b/src/flash/nor/driver.h index 794566f12..3b57ef9ff 100644 --- a/src/flash/nor/driver.h +++ b/src/flash/nor/driver.h @@ -289,7 +289,7 @@ extern const struct flash_driver psoc5lp_nvl_flash; extern const struct flash_driver psoc6_flash; extern const struct flash_driver qn908x_flash; extern const struct flash_driver renesas_rpchf_flash; -extern const struct flash_driver rp2040_flash; +extern const struct flash_driver rp2xxx_flash; extern const struct flash_driver rsl10_flash; extern const struct flash_driver sh_qspi_flash; extern const struct flash_driver sim3x_flash; diff --git a/src/flash/nor/drivers.c b/src/flash/nor/drivers.c index 67d86243b..3770bfbd3 100644 --- a/src/flash/nor/drivers.c +++ b/src/flash/nor/drivers.c @@ -66,7 +66,7 @@ static const struct flash_driver * const flash_drivers[] = { &psoc6_flash, &qn908x_flash, &renesas_rpchf_flash, - &rp2040_flash, + &rp2xxx_flash, &sh_qspi_flash, &sim3x_flash, &stellaris_flash, diff --git a/src/flash/nor/rp2040.c b/src/flash/nor/rp2xxx.c similarity index 94% rename from src/flash/nor/rp2040.c rename to src/flash/nor/rp2xxx.c index 514cea8b6..e58fc8a29 100644 --- a/src/flash/nor/rp2040.c +++ b/src/flash/nor/rp2xxx.c @@ -185,14 +185,14 @@ typedef struct rp2xxx_rom_call_batch_record { uint32_t args[4]; } rp2xxx_rom_call_batch_record_t; -struct rp2040_flash_bank { +struct rp2xxx_flash_bank { bool probed; /* flag indicating successful flash probe */ uint32_t id; /* cached SYSINFO CHIP_ID */ struct working_area *stack; /* stack used by Boot ROM calls */ /* static code scratchpad used for RAM algorithms -- allocated in advance so that higher-level calls can just grab all remaining workarea: */ struct working_area *ram_algo_space; - /* function jump table populated by rp2040_flash_probe() */ + /* function jump table populated by rp2xxx_flash_probe() */ uint16_t jump_flash_exit_xip; uint16_t jump_connect_internal_flash; uint16_t jump_flash_range_erase; @@ -381,7 +381,7 @@ static int rp2xxx_lookup_rom_symbol(struct target *target, uint16_t tag, uint16_ return ERROR_FAIL; } -static int rp2xxx_populate_rom_pointer_cache(struct target *target, struct rp2040_flash_bank *priv) +static int rp2xxx_populate_rom_pointer_cache(struct target *target, struct rp2xxx_flash_bank *priv) { const uint16_t symtype_func = is_arm(target_to_arm(target)) ? RT_FLAG_FUNC_ARM_SEC : RT_FLAG_FUNC_RISCV; @@ -444,7 +444,7 @@ static int rp2xxx_populate_rom_pointer_cache(struct target *target, struct rp204 // Call a list of PC + SP + r0-r3 function call tuples with a single OpenOCD // algorithm invocation, to amortise the algorithm overhead over multiple calls: -static int rp2xxx_call_rom_func_batch(struct target *target, struct rp2040_flash_bank *priv, +static int rp2xxx_call_rom_func_batch(struct target *target, struct rp2xxx_flash_bank *priv, rp2xxx_rom_call_batch_record_t *calls, unsigned int n_calls) { // Note +1 is for the null terminator @@ -556,7 +556,7 @@ static int rp2xxx_call_rom_func_batch(struct target *target, struct rp2040_flash } // Call a single ROM function, using the default algorithm stack. -static int rp2xxx_call_rom_func(struct target *target, struct rp2040_flash_bank *priv, +static int rp2xxx_call_rom_func(struct target *target, struct rp2xxx_flash_bank *priv, uint16_t func_offset, uint32_t argdata[], unsigned int n_args) { assert(n_args <= 4); /* only allow register arguments -- capped at just 4 on Arm */ @@ -602,7 +602,7 @@ static int rp2350_init_accessctrl(struct target *target) return ERROR_OK; } -static int rp2350_init_arm_core0(struct target *target, struct rp2040_flash_bank *priv) +static int rp2350_init_arm_core0(struct target *target, struct rp2xxx_flash_bank *priv) { // Flash algorithms (and the RCP init stub called by this function) must // run in the Secure state, so flip the state now before attempting to @@ -661,7 +661,7 @@ static int rp2350_init_arm_core0(struct target *target, struct rp2040_flash_bank return err; } -static int setup_for_raw_flash_cmd(struct target *target, struct rp2040_flash_bank *priv) +static int setup_for_raw_flash_cmd(struct target *target, struct rp2xxx_flash_bank *priv) { int err = ERROR_OK; @@ -725,14 +725,14 @@ static int setup_for_raw_flash_cmd(struct target *target, struct rp2040_flash_ba }; err = rp2xxx_call_rom_func_batch(target, priv, calls, 2); if (err != ERROR_OK) { - LOG_ERROR("RP2040 flash: failed to exit flash XIP mode"); + LOG_ERROR("RP2xxx flash: failed to exit flash XIP mode"); return err; } return ERROR_OK; } -static int rp2xxx_invalidate_cache_restore_xip(struct target *target, struct rp2040_flash_bank *priv) +static int rp2xxx_invalidate_cache_restore_xip(struct target *target, struct rp2xxx_flash_bank *priv) { // Flash content has changed. We can now do a bit of poking to make // the new flash contents visible to us via memory-mapped (XIP) interface @@ -763,12 +763,12 @@ static int rp2xxx_invalidate_cache_restore_xip(struct target *target, struct rp2 int retval = rp2xxx_call_rom_func_batch(target, priv, finishing_calls, num_finishing_calls); if (retval != ERROR_OK) - LOG_ERROR("RP2040 write: failed to flush flash cache/restore XIP"); + LOG_ERROR("RP2xxx: failed to flush flash cache/restore XIP"); return retval; } -static void cleanup_after_raw_flash_cmd(struct target *target, struct rp2040_flash_bank *priv) +static void cleanup_after_raw_flash_cmd(struct target *target, struct rp2xxx_flash_bank *priv) { /* OpenOCD is prone to trashing work-area allocations on target state transitions, which leaves us with stale work area pointers in our @@ -785,11 +785,11 @@ static void cleanup_after_raw_flash_cmd(struct target *target, struct rp2040_fla } } -static int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) +static int rp2xxx_flash_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { LOG_DEBUG("Writing %d bytes starting at 0x%" PRIx32, count, offset); - struct rp2040_flash_bank *priv = bank->driver_priv; + struct rp2xxx_flash_bank *priv = bank->driver_priv; struct target *target = bank->target; if (target->state != TARGET_HALTED) { @@ -851,9 +851,9 @@ cleanup_and_return: return err; } -static int rp2040_flash_erase(struct flash_bank *bank, unsigned int first, unsigned int last) +static int rp2xxx_flash_erase(struct flash_bank *bank, unsigned int first, unsigned int last) { - struct rp2040_flash_bank *priv = bank->driver_priv; + struct rp2xxx_flash_bank *priv = bank->driver_priv; struct target *target = bank->target; if (target->state != TARGET_HALTED) { @@ -863,7 +863,7 @@ static int rp2040_flash_erase(struct flash_bank *bank, unsigned int first, unsig uint32_t start_addr = bank->sectors[first].offset; uint32_t length = bank->sectors[last].offset + bank->sectors[last].size - start_addr; - LOG_DEBUG("RP2040 erase %d bytes starting at 0x%" PRIx32, length, start_addr); + LOG_DEBUG("erase %d bytes starting at 0x%" PRIx32, length, start_addr); int err = setup_for_raw_flash_cmd(target, priv); if (err != ERROR_OK) @@ -1064,7 +1064,7 @@ static int rp2xxx_spi_tx_rx(struct flash_bank *bank, unsigned int dummy_len, uint8_t *rx, unsigned int rx_len) { - struct rp2040_flash_bank *priv = bank->driver_priv; + struct rp2xxx_flash_bank *priv = bank->driver_priv; struct target *target = bank->target; if (IS_RP2040(priv->id)) @@ -1078,7 +1078,7 @@ static int rp2xxx_spi_tx_rx(struct flash_bank *bank, static int rp2xxx_read_sfdp_block(struct flash_bank *bank, uint32_t addr, unsigned int words, uint32_t *buffer) { - struct rp2040_flash_bank *priv = bank->driver_priv; + struct rp2xxx_flash_bank *priv = bank->driver_priv; uint8_t cmd[4] = { SPIFLASH_READ_SFDP }; uint8_t data[4 * words + priv->sfdp_dummy_detect]; @@ -1106,9 +1106,9 @@ static int rp2xxx_read_sfdp_block(struct flash_bank *bank, uint32_t addr, return retval; } -static int rp2040_flash_probe(struct flash_bank *bank) +static int rp2xxx_flash_probe(struct flash_bank *bank) { - struct rp2040_flash_bank *priv = bank->driver_priv; + struct rp2xxx_flash_bank *priv = bank->driver_priv; struct target *target = bank->target; int retval = target_read_u32(target, RP2XXX_SYSINFO_CHIP_ID, &priv->id); @@ -1202,31 +1202,23 @@ static int rp2040_flash_probe(struct flash_bank *bank) return ERROR_OK; } -static int rp2040_flash_auto_probe(struct flash_bank *bank) +static int rp2xxx_flash_auto_probe(struct flash_bank *bank) { - struct rp2040_flash_bank *priv = bank->driver_priv; + struct rp2xxx_flash_bank *priv = bank->driver_priv; if (priv->probed) return ERROR_OK; - return rp2040_flash_probe(bank); -} - -static void rp2040_flash_free_driver_priv(struct flash_bank *bank) -{ - free(bank->driver_priv); - bank->driver_priv = NULL; + return rp2xxx_flash_probe(bank); } /* ----------------------------------------------------------------------------- Driver boilerplate */ -FLASH_BANK_COMMAND_HANDLER(rp2040_flash_bank_command) +FLASH_BANK_COMMAND_HANDLER(rp2xxx_flash_bank_command) { - struct rp2040_flash_bank *priv; - priv = malloc(sizeof(struct rp2040_flash_bank)); - memset(priv, 0, sizeof(struct rp2040_flash_bank)); - priv->probed = false; + struct rp2xxx_flash_bank *priv; + priv = calloc(1, sizeof(struct rp2xxx_flash_bank)); priv->size_override = bank->size != 0; /* Set up driver_priv */ @@ -1236,7 +1228,7 @@ FLASH_BANK_COMMAND_HANDLER(rp2040_flash_bank_command) } -COMMAND_HANDLER(rp2040_rom_api_call_handler) +COMMAND_HANDLER(rp2xxx_rom_api_call_handler) { if (CMD_ARGC < 1) return ERROR_COMMAND_SYNTAX_ERROR; @@ -1245,7 +1237,7 @@ COMMAND_HANDLER(rp2040_rom_api_call_handler) struct flash_bank *bank; for (bank = flash_bank_list(); bank; bank = bank->next) { - if (bank->driver != &rp2040_flash) + if (bank->driver != &rp2xxx_flash) continue; if (bank->target == target) @@ -1258,7 +1250,7 @@ COMMAND_HANDLER(rp2040_rom_api_call_handler) return ERROR_FAIL; } - int retval = rp2040_flash_auto_probe(bank); + int retval = rp2xxx_flash_auto_probe(bank); if (retval != ERROR_OK) { command_print(CMD, "auto_probe failed"); return retval; @@ -1275,7 +1267,7 @@ COMMAND_HANDLER(rp2040_rom_api_call_handler) return ERROR_TARGET_NOT_HALTED; } - struct rp2040_flash_bank *priv = bank->driver_priv; + struct rp2xxx_flash_bank *priv = bank->driver_priv; retval = setup_for_raw_flash_cmd(target, priv); if (retval != ERROR_OK) goto cleanup_and_return; @@ -1304,7 +1296,7 @@ cleanup_and_return: return retval; } -COMMAND_HANDLER(rp2040_switch_target_handler) +COMMAND_HANDLER(rp2xxx_switch_target_handler) { if (CMD_ARGC != 2) return ERROR_COMMAND_SYNTAX_ERROR; @@ -1323,10 +1315,10 @@ COMMAND_HANDLER(rp2040_switch_target_handler) struct flash_bank *bank; for (bank = flash_bank_list(); bank; bank = bank->next) { - if (bank->driver == &rp2040_flash) { + if (bank->driver == &rp2xxx_flash) { if (bank->target == old_target) { bank->target = new_target; - struct rp2040_flash_bank *priv = bank->driver_priv; + struct rp2xxx_flash_bank *priv = bank->driver_priv; priv->probed = false; return ERROR_OK; } else if (bank->target == new_target) { @@ -1340,44 +1332,44 @@ COMMAND_HANDLER(rp2040_switch_target_handler) return ERROR_FAIL; } -static const struct command_registration rp2040_exec_command_handlers[] = { +static const struct command_registration rp2xxx_exec_command_handlers[] = { { .name = "rom_api_call", .mode = COMMAND_EXEC, .help = "arbitrary ROM API call", .usage = "fc [p0 [p1 [p2 [p3]]]]", - .handler = rp2040_rom_api_call_handler, + .handler = rp2xxx_rom_api_call_handler, }, { .name = "_switch_target", .mode = COMMAND_EXEC, .help = "internal use", .usage = "old_target new_target", - .handler = rp2040_switch_target_handler, + .handler = rp2xxx_switch_target_handler, }, COMMAND_REGISTRATION_DONE }; -static const struct command_registration rp2040_command_handler[] = { +static const struct command_registration rp2xxx_command_handler[] = { { .name = "rp2xxx", .mode = COMMAND_ANY, .help = "rp2xxx flash controller commands", .usage = "", - .chain = rp2040_exec_command_handlers, + .chain = rp2xxx_exec_command_handlers, }, COMMAND_REGISTRATION_DONE }; -const struct flash_driver rp2040_flash = { - .name = "rp2040_flash", - .commands = rp2040_command_handler, - .flash_bank_command = rp2040_flash_bank_command, - .erase = rp2040_flash_erase, - .write = rp2040_flash_write, +const struct flash_driver rp2xxx_flash = { + .name = "rp2xxx", + .commands = rp2xxx_command_handler, + .flash_bank_command = rp2xxx_flash_bank_command, + .erase = rp2xxx_flash_erase, + .write = rp2xxx_flash_write, .read = default_flash_read, - .probe = rp2040_flash_probe, - .auto_probe = rp2040_flash_auto_probe, + .probe = rp2xxx_flash_probe, + .auto_probe = rp2xxx_flash_auto_probe, .erase_check = default_flash_blank_check, - .free_driver_priv = rp2040_flash_free_driver_priv + .free_driver_priv = default_flash_free_driver_priv }; diff --git a/tcl/target/rp2040.cfg b/tcl/target/rp2040.cfg index 5e78c6931..5fae390b4 100644 --- a/tcl/target/rp2040.cfg +++ b/tcl/target/rp2040.cfg @@ -99,7 +99,7 @@ if { $_USE_CORE == 1 } { # The flash is probed during gdb connect if gdb memory_map is enabled (by default). $_FLASH_TARGET configure -work-area-phys 0x20010000 -work-area-size $_WORKAREASIZE -work-area-backup 1 set _FLASHNAME $_CHIPNAME.flash -flash bank $_FLASHNAME rp2040_flash 0x10000000 0 0 0 $_FLASH_TARGET +flash bank $_FLASHNAME rp2xxx 0x10000000 0 0 0 $_FLASH_TARGET if { $_BOTH_CORES } { # Alias to ensure gdb connecting to core 1 gets the correct memory map diff --git a/tcl/target/rp2350.cfg b/tcl/target/rp2350.cfg index dc26cde19..b7617acd4 100644 --- a/tcl/target/rp2350.cfg +++ b/tcl/target/rp2350.cfg @@ -160,7 +160,7 @@ if { [info exists _FLASH_TARGET] } { echo "Info : $_CHIPNAME.flash will be handled by the active one of $_FLASH_TARGET and $_TARGETNAME_RV0 cores" } set _FLASHNAME $_CHIPNAME.flash - flash bank $_FLASHNAME rp2040_flash 0x10000000 $_FLASHSIZE 0 0 $_FLASH_TARGET + flash bank $_FLASHNAME rp2xxx 0x10000000 $_FLASHSIZE 0 0 $_FLASH_TARGET } if { [info exists _TARGETNAME_1] } { ----------------------------------------------------------------------- Summary of changes: src/flash/nor/Makefile.am | 2 +- src/flash/nor/driver.h | 2 +- src/flash/nor/drivers.c | 2 +- src/flash/nor/{rp2040.c => rp2xxx.c} | 102 ++++++++++++++++------------------- tcl/target/rp2040.cfg | 2 +- tcl/target/rp2350.cfg | 2 +- 6 files changed, 52 insertions(+), 60 deletions(-) rename src/flash/nor/{rp2040.c => rp2xxx.c} (94%) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2025-04-25 09:41:55
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via c914cfceab54245fae1aefd70e20d0ed549f9308 (commit) via 26729aa8b089230bf0896c32df9a4b7ae3ef6fee (commit) from 20d1d4405d73fe47efc07cb109454c088a8ecbc8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c914cfceab54245fae1aefd70e20d0ed549f9308 Author: Tomas Vanek <va...@fb...> Date: Wed Aug 14 10:47:36 2024 +0200 flash/nor/rp2040: refactor finalizing calls and use them after erase Invalidate cache and restore flash XIP mode after erase and also in error cleanup after write/erase. Signed-off-by: Tomas Vanek <va...@fb...> Change-Id: If7e0c2d75f50f923e6bcbf0aa7bab53fe91b6cc8 Reviewed-on: https://review.openocd.org/c/openocd/+/8454 Tested-by: jenkins diff --git a/src/flash/nor/rp2040.c b/src/flash/nor/rp2040.c index c28bc8509..514cea8b6 100644 --- a/src/flash/nor/rp2040.c +++ b/src/flash/nor/rp2040.c @@ -732,6 +732,42 @@ static int setup_for_raw_flash_cmd(struct target *target, struct rp2040_flash_ba return ERROR_OK; } +static int rp2xxx_invalidate_cache_restore_xip(struct target *target, struct rp2040_flash_bank *priv) +{ + // Flash content has changed. We can now do a bit of poking to make + // the new flash contents visible to us via memory-mapped (XIP) interface + // in the 0x1... memory region. + + LOG_DEBUG("Flushing flash cache after write behind"); + + rp2xxx_rom_call_batch_record_t finishing_calls[2] = { + { + .pc = priv->jump_flush_cache, + .sp = priv->stack->address + priv->stack->size + }, + { + .sp = priv->stack->address + priv->stack->size + }, + }; + + int num_finishing_calls = 1; + // Note on RP2350 it's not *required* to call flash_enter_cmd_xip, since + // the ROM leaves flash XIPable by default in between direct-mode + // accesses + if (IS_RP2040(priv->id)) { + finishing_calls[num_finishing_calls++].pc = priv->jump_enter_cmd_xip; + } else if (priv->jump_flash_reset_address_trans) { + // Note flash_reset_address_trans function does not exist on older devices + finishing_calls[num_finishing_calls++].pc = priv->jump_flash_reset_address_trans; + } + + int retval = rp2xxx_call_rom_func_batch(target, priv, finishing_calls, num_finishing_calls); + if (retval != ERROR_OK) + LOG_ERROR("RP2040 write: failed to flush flash cache/restore XIP"); + + return retval; +} + static void cleanup_after_raw_flash_cmd(struct target *target, struct rp2040_flash_bank *priv) { /* OpenOCD is prone to trashing work-area allocations on target state @@ -805,45 +841,12 @@ static int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, ui count -= write_size; } - if (err != ERROR_OK) - goto cleanup_and_return; - - // Flash is successfully programmed. We can now do a bit of poking to make - // the new flash contents visible to us via memory-mapped (XIP) interface - // in the 0x1... memory region. - // - // Note on RP2350 it's not *required* to call flash_enter_cmd_xip, since - // the ROM leaves flash XIPable by default in between direct-mode - // accesses, but there's no harm in calling it anyway. - - LOG_DEBUG("Flushing flash cache after write behind"); - err = rp2xxx_call_rom_func(target, priv, priv->jump_flush_cache, NULL, 0); - - rp2xxx_rom_call_batch_record_t finishing_calls[3] = { - { - .pc = priv->jump_flush_cache, - .sp = priv->stack->address + priv->stack->size - }, - { - .pc = priv->jump_enter_cmd_xip, - .sp = priv->stack->address + priv->stack->size - }, - { - .pc = priv->jump_flash_reset_address_trans, - .sp = priv->stack->address + priv->stack->size - } - }; - // Note the last function does not exist on older devices: - int num_finishing_calls = priv->jump_flash_reset_address_trans ? 3 : 2; - - err = rp2xxx_call_rom_func_batch(target, priv, finishing_calls, num_finishing_calls); - if (err != ERROR_OK) { - LOG_ERROR("RP2040 write: failed to flush flash cache"); - goto cleanup_and_return; - } cleanup_and_return: target_free_working_area(target, bounce); + /* Don't propagate error or user gets fooled the flash write failed */ + (void)rp2xxx_invalidate_cache_restore_xip(target, priv); + cleanup_after_raw_flash_cmd(target, priv); return err; } @@ -912,6 +915,9 @@ static int rp2040_flash_erase(struct flash_bank *bank, unsigned int first, unsig cleanup_and_return: + /* Don't propagate error or user gets fooled the flash erase failed */ + (void)rp2xxx_invalidate_cache_restore_xip(target, priv); + cleanup_after_raw_flash_cmd(target, priv); return err; } commit 26729aa8b089230bf0896c32df9a4b7ae3ef6fee Author: Tomas Vanek <va...@fb...> Date: Wed Aug 14 10:41:55 2024 +0200 flash/nor/rp2040: improve flash write buffer size computation While on it: Define the names for the fixed flash page/sector sizes and use them instead of magic values. Fix memory leak on error return. Partially backported from former upstream rp2040.c Signed-off-by: Tomas Vanek <va...@fb...> Change-Id: If51c912f4d381ee47756a70f616ecdbee1ac0da7 Reviewed-on: https://review.openocd.org/c/openocd/+/8453 Tested-by: jenkins diff --git a/src/flash/nor/rp2040.c b/src/flash/nor/rp2040.c index 65c1e095b..c28bc8509 100644 --- a/src/flash/nor/rp2040.c +++ b/src/flash/nor/rp2040.c @@ -73,6 +73,9 @@ #define RP2XXX_MAX_ALGO_STACK_USAGE 1024 #define RP2XXX_MAX_RAM_ALGO_SIZE 1024 +#define RP2XXX_ROM_API_FIXED_FLASH_PAGE 256 +#define RP2XXX_ROM_API_FIXED_FLASH_SECTOR 4096 + // Calling bootrom functions on Arm RP2350 requires the redundancy // coprocessor (RCP) to be initialised. Usually this is done first thing by // the bootrom, but the debugger may skip this, e.g. by resetting the cores @@ -758,17 +761,19 @@ static int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, ui return ERROR_TARGET_NOT_HALTED; } - struct working_area *bounce; + struct working_area *bounce = NULL; int err = setup_for_raw_flash_cmd(target, priv); if (err != ERROR_OK) goto cleanup_and_return; - // Allocate as much memory as possible, rounded down to a whole number of flash pages - const unsigned int chunk_size = target_get_working_area_avail(target) & ~0xffu; - if (chunk_size == 0 || target_alloc_working_area(target, chunk_size, &bounce) != ERROR_OK) { + unsigned int avail_pages = target_get_working_area_avail(target) / RP2XXX_ROM_API_FIXED_FLASH_PAGE; + /* We try to allocate working area rounded down to device page size, + * al least 1 page, at most the write data size */ + unsigned int chunk_size = MIN(MAX(avail_pages, 1) * RP2XXX_ROM_API_FIXED_FLASH_PAGE, count); + err = target_alloc_working_area(target, chunk_size, &bounce); + if (err != ERROR_OK) { LOG_ERROR("Could not allocate bounce buffer for flash programming. Can't continue"); - err = ERROR_TARGET_RESOURCE_NOT_AVAILABLE; goto cleanup_and_return; } @@ -787,7 +792,8 @@ static int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, ui bounce->address, /* data */ write_size /* count */ }; - err = rp2xxx_call_rom_func(target, priv, priv->jump_flash_range_program, args, ARRAY_SIZE(args)); + 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"); @@ -798,7 +804,6 @@ static int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, ui offset += write_size; count -= write_size; } - target_free_working_area(target, bounce); if (err != ERROR_OK) goto cleanup_and_return; @@ -837,6 +842,8 @@ static int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, ui goto cleanup_and_return; } cleanup_and_return: + target_free_working_area(target, bounce); + cleanup_after_raw_flash_cmd(target, priv); return err; } @@ -1113,8 +1120,8 @@ static int rp2040_flash_probe(struct flash_bank *bank) return retval; /* the Boot ROM flash_range_program() routine requires page alignment */ - bank->write_start_alignment = 256; - bank->write_end_alignment = 256; + bank->write_start_alignment = RP2XXX_ROM_API_FIXED_FLASH_PAGE; + bank->write_end_alignment = RP2XXX_ROM_API_FIXED_FLASH_PAGE; uint32_t flash_id = 0; if (priv->size_override) { @@ -1168,7 +1175,7 @@ static int rp2040_flash_probe(struct flash_bank *bank) return ERROR_FLASH_BANK_INVALID; } - bank->num_sectors = bank->size / 4096; + bank->num_sectors = bank->size / RP2XXX_ROM_API_FIXED_FLASH_SECTOR; if (priv->size_override) { LOG_INFO("%s, QSPI Flash size override = %u KiB in %u sectors", @@ -1180,7 +1187,7 @@ static int rp2040_flash_probe(struct flash_bank *bank) } free(bank->sectors); - bank->sectors = alloc_block_array(0, 4096, bank->num_sectors); + bank->sectors = alloc_block_array(0, RP2XXX_ROM_API_FIXED_FLASH_SECTOR, bank->num_sectors); if (!bank->sectors) return ERROR_FAIL; ----------------------------------------------------------------------- Summary of changes: src/flash/nor/rp2040.c | 105 +++++++++++++++++++++++++++---------------------- 1 file changed, 59 insertions(+), 46 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2025-04-25 09:41:14
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 20d1d4405d73fe47efc07cb109454c088a8ecbc8 (commit) from 2e1a76368eed7aac8054e6ccb7c8104bad421a70 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 20d1d4405d73fe47efc07cb109454c088a8ecbc8 Author: Tomas Vanek <va...@fb...> Date: Wed Aug 14 09:39:42 2024 +0200 flash/nor/rp2040: add missing TARGET_HALTED checks Flash erase and write require this guard, unfortunately it is also partially needed in the flash probe. Partially backported from former upstream rp2040.c Signed-off-by: Tomas Vanek <va...@fb...> Change-Id: Ie8a240e66c3ed68e08f872cbbfdd90a6d80e1f1e Reviewed-on: https://review.openocd.org/c/openocd/+/8452 Tested-by: jenkins diff --git a/src/flash/nor/rp2040.c b/src/flash/nor/rp2040.c index 0e592f912..65c1e095b 100644 --- a/src/flash/nor/rp2040.c +++ b/src/flash/nor/rp2040.c @@ -752,6 +752,12 @@ static int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, ui struct rp2040_flash_bank *priv = bank->driver_priv; struct target *target = bank->target; + + if (target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + struct working_area *bounce; int err = setup_for_raw_flash_cmd(target, priv); @@ -839,6 +845,12 @@ static int rp2040_flash_erase(struct flash_bank *bank, unsigned int first, unsig { struct rp2040_flash_bank *priv = bank->driver_priv; struct target *target = bank->target; + + if (target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + uint32_t start_addr = bank->sectors[first].offset; uint32_t length = bank->sectors[last].offset + bank->sectors[last].size - start_addr; LOG_DEBUG("RP2040 erase %d bytes starting at 0x%" PRIx32, length, start_addr); @@ -1109,6 +1121,11 @@ static int rp2040_flash_probe(struct flash_bank *bank) priv->spi_dev.name = "size override"; LOG_DEBUG("SPI flash autodetection disabled, using configured size"); } else { + if (target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + bank->size = 0; (void)setup_for_raw_flash_cmd(target, priv); @@ -1240,6 +1257,11 @@ COMMAND_HANDLER(rp2040_rom_api_call_handler) for (unsigned int i = 0; i + 1 < CMD_ARGC && i < ARRAY_SIZE(args); i++) COMMAND_PARSE_NUMBER(u32, CMD_ARGV[i + 1], args[i]); + if (target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + struct rp2040_flash_bank *priv = bank->driver_priv; retval = setup_for_raw_flash_cmd(target, priv); if (retval != ERROR_OK) ----------------------------------------------------------------------- Summary of changes: src/flash/nor/rp2040.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2025-04-25 09:37:20
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 2e1a76368eed7aac8054e6ccb7c8104bad421a70 (commit) from 22dfd0efaddaa70baf9e65aff661554c4497909a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2e1a76368eed7aac8054e6ccb7c8104bad421a70 Author: Tomas Vanek <va...@fb...> Date: Wed Aug 14 09:10:31 2024 +0200 flash/nor/rp2040: detect flash size including SFDP Also keep size override by FLASHSIZE Tcl variable possible. Partially backported from former upstream rp2040.c Signed-off-by: Tomas Vanek <va...@fb...> Change-Id: I224c3644450e8b46e35714bfc5436219ffdee563 Reviewed-on: https://review.openocd.org/c/openocd/+/8451 Tested-by: jenkins diff --git a/src/flash/nor/rp2040.c b/src/flash/nor/rp2040.c index 15a04fbb0..0e592f912 100644 --- a/src/flash/nor/rp2040.c +++ b/src/flash/nor/rp2040.c @@ -9,6 +9,7 @@ #include <target/algorithm.h> #include <target/armv7m.h> #include "spi.h" +#include "sfdp.h" #include <target/cortex_m.h> /* this is 'M' 'u', 1 (version) */ @@ -43,6 +44,32 @@ #define ACCESSCTRL_CFGRESET_OFFSET 0x40060008u #define ACCESSCTRL_WRITE_PASSWORD 0xacce0000u +#define RP2040_SSI_DR0 0x18000060 +#define RP2040_QSPI_CTRL 0x4001800c + +#define RP2040_QSPI_CTRL_OUTOVER_MASK (3ul << 8) +#define RP2040_QSPI_CTRL_OUTOVER_LOW (2ul << 8) +#define RP2040_QSPI_CTRL_OUTOVER_HIGH (3ul << 8) + +#define RP2350_QMI_DIRECT_CSR 0x400d0000 +#define RP2350_QMI_DIRECT_TX 0x400d0004 +#define RP2350_QMI_DIRECT_RX 0x400d0008 + +#define RP2350_QMI_DIRECT_CSR_EN BIT(0) +#define RP2350_QMI_DIRECT_CSR_ASSERT_CS0N BIT(2) +#define RP2350_QMI_DIRECT_TX_NOPUSH BIT(20) +#define RP2350_QMI_DIRECT_TX_OE BIT(19) + +#define RP2XXX_SYSINFO_CHIP_ID 0x40000000 +#define RP2XXX_CHIP_ID_PART_MANUFACTURER(id) ((id) & 0x0fffffff) +#define RP2XXX_CHIP_ID_MANUFACTURER 0x493 +#define RP2XXX_MK_PART(part) (((part) << 12) | (RP2XXX_CHIP_ID_MANUFACTURER << 1) | 1) +#define RP2040_CHIP_ID_PART 0x0002 +#define IS_RP2040(id) (RP2XXX_CHIP_ID_PART_MANUFACTURER(id) == RP2XXX_MK_PART(RP2040_CHIP_ID_PART)) +#define RP2350_CHIP_ID_PART 0x0004 +#define IS_RP2350(id) (RP2XXX_CHIP_ID_PART_MANUFACTURER(id) == RP2XXX_MK_PART(RP2350_CHIP_ID_PART)) +#define RP2XXX_CHIP_ID_REVISION(id) ((id) >> 28) + #define RP2XXX_MAX_ALGO_STACK_USAGE 1024 #define RP2XXX_MAX_RAM_ALGO_SIZE 1024 @@ -156,10 +183,9 @@ typedef struct rp2xxx_rom_call_batch_record { } rp2xxx_rom_call_batch_record_t; struct rp2040_flash_bank { - /* flag indicating successful flash probe */ - bool probed; - /* stack used by Boot ROM calls */ - struct working_area *stack; + bool probed; /* flag indicating successful flash probe */ + uint32_t id; /* cached SYSINFO CHIP_ID */ + struct working_area *stack; /* stack used by Boot ROM calls */ /* static code scratchpad used for RAM algorithms -- allocated in advance so that higher-level calls can just grab all remaining workarea: */ struct working_area *ram_algo_space; @@ -172,6 +198,11 @@ struct rp2040_flash_bank { uint16_t jump_flash_reset_address_trans; uint16_t jump_enter_cmd_xip; uint16_t jump_bootrom_reset_state; + + char dev_name[20]; + bool size_override; + struct flash_device spi_dev; /* detected model of SPI flash */ + unsigned int sfdp_dummy, sfdp_dummy_detect; }; #ifndef LOG_ROM_SYMBOL_DEBUG @@ -869,37 +900,276 @@ cleanup_and_return: /* ----------------------------------------------------------------------------- Driver probing etc */ + +static int rp2040_ssel_active(struct target *target, bool active) +{ + uint32_t state = active ? RP2040_QSPI_CTRL_OUTOVER_LOW : RP2040_QSPI_CTRL_OUTOVER_HIGH; + uint32_t val; + + int err = target_read_u32(target, RP2040_QSPI_CTRL, &val); + if (err != ERROR_OK) + return err; + + val = (val & ~RP2040_QSPI_CTRL_OUTOVER_MASK) | state; + + err = target_write_u32(target, RP2040_QSPI_CTRL, val); + if (err != ERROR_OK) + return err; + + return ERROR_OK; +} + +static int rp2040_spi_tx_rx(struct target *target, + const uint8_t *tx, unsigned int tx_len, + unsigned int dummy_len, + uint8_t *rx, unsigned int rx_len) +{ + int retval, retval2; + + retval = rp2040_ssel_active(target, true); + if (retval != ERROR_OK) { + LOG_ERROR("QSPI select failed"); + goto deselect; + } + + unsigned int tx_cnt = 0; + unsigned int rx_cnt = 0; + unsigned int xfer_len = tx_len + dummy_len + rx_len; + while (rx_cnt < xfer_len) { + int in_flight = tx_cnt - rx_cnt; + if (tx_cnt < xfer_len && in_flight < 14) { + uint32_t dr = tx_cnt < tx_len ? tx[tx_cnt] : 0; + retval = target_write_u32(target, RP2040_SSI_DR0, dr); + if (retval != ERROR_OK) + break; + + tx_cnt++; + continue; + } + uint32_t dr; + retval = target_read_u32(target, RP2040_SSI_DR0, &dr); + if (retval != ERROR_OK) + break; + + if (rx_cnt >= tx_len + dummy_len) + rx[rx_cnt - tx_len - dummy_len] = (uint8_t)dr; + + rx_cnt++; + } + +deselect: + retval2 = rp2040_ssel_active(target, false); + + if (retval != ERROR_OK) { + LOG_ERROR("QSPI Tx/Rx failed"); + return retval; + } + if (retval2 != ERROR_OK) + LOG_ERROR("QSPI deselect failed"); + + return retval2; +} + +static int rp2350_spi_tx_rx(struct target *target, + const uint8_t *tx, unsigned int tx_len, + unsigned int dummy_len, + uint8_t *rx, unsigned int rx_len) +{ + uint32_t direct_csr; + int retval = target_read_u32(target, RP2350_QMI_DIRECT_CSR, &direct_csr); + if (retval != ERROR_OK) { + LOG_ERROR("QMI DIRECT_CSR read failed"); + return retval; + } + direct_csr |= RP2350_QMI_DIRECT_CSR_EN | RP2350_QMI_DIRECT_CSR_ASSERT_CS0N; + retval = target_write_u32(target, RP2350_QMI_DIRECT_CSR, direct_csr); + if (retval != ERROR_OK) { + LOG_ERROR("QMI DIRECT mode enable failed"); + goto deselect; + } + + unsigned int tx_cnt = 0; + unsigned int rx_cnt = 0; + unsigned int xfer_len = tx_len + dummy_len + rx_len; + while (tx_cnt < xfer_len || rx_cnt < rx_len) { + int in_flight = tx_cnt - tx_len - dummy_len - rx_cnt; + if (tx_cnt < xfer_len && in_flight < 4) { + uint32_t tx_cmd; + if (tx_cnt < tx_len) + tx_cmd = tx[tx_cnt] | RP2350_QMI_DIRECT_TX_NOPUSH | RP2350_QMI_DIRECT_TX_OE; + else if (tx_cnt < tx_len + dummy_len) + tx_cmd = RP2350_QMI_DIRECT_TX_NOPUSH; + else + tx_cmd = 0; + + retval = target_write_u32(target, RP2350_QMI_DIRECT_TX, tx_cmd); + if (retval != ERROR_OK) + break; + + tx_cnt++; + continue; + } + if (rx_cnt < rx_len) { + uint32_t dr; + retval = target_read_u32(target, RP2350_QMI_DIRECT_RX, &dr); + if (retval != ERROR_OK) + break; + + rx[rx_cnt] = (uint8_t)dr; + rx_cnt++; + } + } + +deselect: + direct_csr &= ~(RP2350_QMI_DIRECT_CSR_EN | RP2350_QMI_DIRECT_CSR_ASSERT_CS0N); + int retval2 = target_write_u32(target, RP2350_QMI_DIRECT_CSR, direct_csr); + + if (retval != ERROR_OK) { + LOG_ERROR("QSPI Tx/Rx failed"); + return retval; + } + if (retval2 != ERROR_OK) + LOG_ERROR("QMI DIRECT mode disable failed"); + + return retval2; +} + +static int rp2xxx_spi_tx_rx(struct flash_bank *bank, + const uint8_t *tx, unsigned int tx_len, + unsigned int dummy_len, + uint8_t *rx, unsigned int rx_len) +{ + struct rp2040_flash_bank *priv = bank->driver_priv; + struct target *target = bank->target; + + if (IS_RP2040(priv->id)) + return rp2040_spi_tx_rx(target, tx, tx_len, dummy_len, rx, rx_len); + else if (IS_RP2350(priv->id)) + return rp2350_spi_tx_rx(target, tx, tx_len, dummy_len, rx, rx_len); + else + return ERROR_FAIL; +} + +static int rp2xxx_read_sfdp_block(struct flash_bank *bank, uint32_t addr, + unsigned int words, uint32_t *buffer) +{ + struct rp2040_flash_bank *priv = bank->driver_priv; + + uint8_t cmd[4] = { SPIFLASH_READ_SFDP }; + uint8_t data[4 * words + priv->sfdp_dummy_detect]; + + h_u24_to_be(&cmd[1], addr); + + int retval = rp2xxx_spi_tx_rx(bank, cmd, sizeof(cmd), priv->sfdp_dummy, + data, 4 * words + priv->sfdp_dummy_detect); + if (retval != ERROR_OK) + return retval; + + if (priv->sfdp_dummy_detect) { + for (unsigned int i = 0; i < priv->sfdp_dummy_detect; i++) + if (le_to_h_u32(&data[i]) == SFDP_MAGIC) { + priv->sfdp_dummy_detect = 0; + priv->sfdp_dummy = i; + break; + } + for (unsigned int i = 0; i < words; i++) + buffer[i] = le_to_h_u32(&data[4 * i + priv->sfdp_dummy]); + } else { + for (unsigned int i = 0; i < words; i++) + buffer[i] = le_to_h_u32(&data[4 * i]); + } + return retval; +} + static int rp2040_flash_probe(struct flash_bank *bank) { struct rp2040_flash_bank *priv = bank->driver_priv; struct target *target = bank->target; - int err = rp2xxx_populate_rom_pointer_cache(target, priv); - if (err != ERROR_OK) - return err; + int retval = target_read_u32(target, RP2XXX_SYSINFO_CHIP_ID, &priv->id); + if (retval != ERROR_OK) { + LOG_ERROR("SYSINFO CHIP_ID read failed"); + return retval; + } + if (!IS_RP2040(priv->id) && !IS_RP2350(priv->id)) { + LOG_ERROR("Unknown SYSINFO CHIP_ID 0x%08" PRIx32, priv->id); + return ERROR_FLASH_BANK_INVALID; + } + + retval = rp2xxx_populate_rom_pointer_cache(target, priv); + if (retval != ERROR_OK) + return retval; /* the Boot ROM flash_range_program() routine requires page alignment */ bank->write_start_alignment = 256; bank->write_end_alignment = 256; - // Max size -- up to two devices (two chip selects) in adjacent 24-bit address windows + uint32_t flash_id = 0; + if (priv->size_override) { + priv->spi_dev.name = "size override"; + LOG_DEBUG("SPI flash autodetection disabled, using configured size"); + } else { + bank->size = 0; + + (void)setup_for_raw_flash_cmd(target, priv); + /* ignore error, flash size detection could work anyway */ + + const uint8_t cmd[] = { SPIFLASH_READ_ID }; + uint8_t data[3]; + retval = rp2xxx_spi_tx_rx(bank, cmd, sizeof(cmd), 0, data, sizeof(data)); + if (retval == ERROR_OK) { + flash_id = le_to_h_u24(data); + + /* search for a SPI flash Device ID match */ + for (const struct flash_device *p = flash_devices; p->name ; p++) { + if (p->device_id == flash_id) { + priv->spi_dev = *p; + bank->size = p->size_in_bytes; + break; + } + } + } + + if (bank->size == 0) { + priv->sfdp_dummy_detect = 8; + priv->sfdp_dummy = 0; + retval = spi_sfdp(bank, &priv->spi_dev, &rp2xxx_read_sfdp_block); + if (retval == ERROR_OK) + bank->size = priv->spi_dev.size_in_bytes; + } + + cleanup_after_raw_flash_cmd(target, priv); + } + + snprintf(priv->dev_name, sizeof(priv->dev_name), "%s rev %u", + IS_RP2350(priv->id) ? "RP2350" : "RP2040", + RP2XXX_CHIP_ID_REVISION(priv->id)); + if (bank->size == 0) { - /* TODO: get real flash size */ - bank->size = 32 * 1024 * 1024; + LOG_ERROR("%s, QSPI Flash id = 0x%06" PRIx32 " not recognised", + priv->dev_name, flash_id); + return ERROR_FLASH_BANK_INVALID; } bank->num_sectors = bank->size / 4096; - LOG_INFO("RP2040 Flash Probe: %d bytes @" TARGET_ADDR_FMT ", in %d sectors\n", - bank->size, bank->base, bank->num_sectors); + if (priv->size_override) { + LOG_INFO("%s, QSPI Flash size override = %u KiB in %u sectors", + priv->dev_name, bank->size / 1024, bank->num_sectors); + } else { + LOG_INFO("%s, QSPI Flash %s id = 0x%06" PRIx32 " size = %u KiB in %u sectors", + priv->dev_name, priv->spi_dev.name, flash_id, + bank->size / 1024, bank->num_sectors); + } + + free(bank->sectors); bank->sectors = alloc_block_array(0, 4096, bank->num_sectors); if (!bank->sectors) return ERROR_FAIL; - if (err == ERROR_OK) - priv->probed = true; + priv->probed = true; - return err; + return ERROR_OK; } static int rp2040_flash_auto_probe(struct flash_bank *bank) @@ -927,6 +1197,7 @@ FLASH_BANK_COMMAND_HANDLER(rp2040_flash_bank_command) priv = malloc(sizeof(struct rp2040_flash_bank)); memset(priv, 0, sizeof(struct rp2040_flash_bank)); priv->probed = false; + priv->size_override = bank->size != 0; /* Set up driver_priv */ bank->driver_priv = priv; diff --git a/tcl/target/rp2350.cfg b/tcl/target/rp2350.cfg index d2465bd2f..dc26cde19 100644 --- a/tcl/target/rp2350.cfg +++ b/tcl/target/rp2350.cfg @@ -19,6 +19,14 @@ if { [info exists WORKAREASIZE] } { set _WORKAREASIZE 0x10000 } +# Nonzero FLASHSIZE supresses QSPI flash size detection +if { [info exists FLASHSIZE] } { + set _FLASHSIZE $FLASHSIZE +} else { + # Detect QSPI flash size based on flash ID or SFDP + set _FLASHSIZE 0 +} + if { [info exists CPUTAPID] } { set _CPUTAPID $CPUTAPID } else { @@ -143,13 +151,15 @@ if { ![info exists _FLASH_TARGET] && [info exists _TARGETNAME_1] } { } } if { [info exists _FLASH_TARGET] } { - $_FLASH_TARGET configure -work-area-phys 0x20010000 -work-area-size $_WORKAREASIZE + # QSPI flash size detection during gdb connect requires to back-up RAM + set _WKA_BACKUP [expr { $_FLASHSIZE == 0 }] + $_FLASH_TARGET configure -work-area-phys 0x20010000 -work-area-size $_WORKAREASIZE -work-area-backup $_WKA_BACKUP if { [info exists _TARGETNAME_CM0] && [info exists _TARGETNAME_RV0] } { - $_TARGETNAME_RV0 configure -work-area-phys 0x20010000 -work-area-size $_WORKAREASIZE + $_TARGETNAME_RV0 configure -work-area-phys 0x20010000 \ + -work-area-size $_WORKAREASIZE -work-area-backup $_WKA_BACKUP echo "Info : $_CHIPNAME.flash will be handled by the active one of $_FLASH_TARGET and $_TARGETNAME_RV0 cores" } set _FLASHNAME $_CHIPNAME.flash - set _FLASHSIZE 0x00400000 flash bank $_FLASHNAME rp2040_flash 0x10000000 $_FLASHSIZE 0 0 $_FLASH_TARGET } ----------------------------------------------------------------------- Summary of changes: src/flash/nor/rp2040.c | 301 ++++++++++++++++++++++++++++++++++++++++++++++--- tcl/target/rp2350.cfg | 16 ++- 2 files changed, 299 insertions(+), 18 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2025-04-25 09:36:27
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 22dfd0efaddaa70baf9e65aff661554c4497909a (commit) from 69ee4457864af2657ce1b634887b26b838fc916f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 22dfd0efaddaa70baf9e65aff661554c4497909a Author: Tomas Vanek <va...@fb...> Date: Tue Aug 13 16:23:20 2024 +0200 tcl/target/rp2350: workarounds for ROM API issues A0 chip: remove pad isolation A2 chip: instead of reset init fixes we will fix the flash driver with the following patch by Luke Wren: 8729: flash/nor/rp2xxx: fix flash operation after halt in RISC-V bootsel https://review.openocd.org/c/openocd/+/8729 I don't have A1 version to test. Signed-off-by: Tomas Vanek <va...@fb...> Change-Id: I9e9fab04ead929fe6e0a17c6c2f32a6f02e9beb9 Reviewed-on: https://review.openocd.org/c/openocd/+/8450 Tested-by: jenkins diff --git a/tcl/target/rp2350.cfg b/tcl/target/rp2350.cfg index 775561f06..d2465bd2f 100644 --- a/tcl/target/rp2350.cfg +++ b/tcl/target/rp2350.cfg @@ -94,8 +94,7 @@ if { [info exists _TARGETNAME_RV0] } { target create $_TARGETNAME_RV0 riscv -dap $_CHIPNAME.dap -ap-num 0xa000 -coreid 0 $_TARGETNAME_RV0 riscv set_enable_virt2phys off - # Workaround for stray IO_QSPI: GPIO_QSPI_SD1_CTRL: INOVER bit in RISC-V BOOTSEL - $_TARGETNAME_RV0 configure -event reset-init { mww 0x4003002c 0 } + $_TARGETNAME_RV0 configure -event reset-init "_rv_reset_init" if { [info exists _TARGETNAME_CM0] } { # just for setting after init when the event become-available is not fired @@ -204,3 +203,22 @@ if { $_RESCUE } { init rescue_reset } + +proc _rv_reset_init { } { + set chip_id [format 0x%08x [read_memory 0x40000000 32 1]] + + # Version related workarounds + switch $chip_id { + 0x00004927 { # A0 + # remove IO_QSPI isolation + mww 0x40030014 0 + mww 0x4003001c 0 + mww 0x40030024 0 + mww 0x4003002c 0 + mww 0x40030034 0 + mww 0x4003003c 0 + } + } + + rp2xxx rom_api_call FC +} ----------------------------------------------------------------------- Summary of changes: tcl/target/rp2350.cfg | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2025-04-25 09:34:47
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 69ee4457864af2657ce1b634887b26b838fc916f (commit) from 2e49c99b1f919c2496c2d0140ada4ea5134c20a0 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 69ee4457864af2657ce1b634887b26b838fc916f Author: Tomas Vanek <va...@fb...> Date: Sun Aug 11 15:03:05 2024 +0200 tcl/target/rp2350: universal config for any combination of CM/RV cores RP2350 has 2 slots where either Cortex-M33 or RISC-V can be selected. Tcl variable USE_CORE selects what cores will be configured for debug. Signed-off-by: Tomas Vanek <va...@fb...> Change-Id: I56fe1aa94304bdfd1ec98bba57cc3fa792a35f69 Reviewed-on: https://review.openocd.org/c/openocd/+/8449 Tested-by: jenkins diff --git a/tcl/target/rp2350.cfg b/tcl/target/rp2350.cfg new file mode 100644 index 000000000..775561f06 --- /dev/null +++ b/tcl/target/rp2350.cfg @@ -0,0 +1,206 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +# RP2350 is a microcontroller with dual Cortex-M33 cores or dual Hazard3 RISC-V cores. +# https://www.raspberrypi.com/documentation/microcontrollers/rp2350.html + +transport select swd + +source [find target/swj-dp.tcl] + +if { [info exists CHIPNAME] } { + set _CHIPNAME $CHIPNAME +} else { + set _CHIPNAME rp2350 +} + +if { [info exists WORKAREASIZE] } { + set _WORKAREASIZE $WORKAREASIZE +} else { + set _WORKAREASIZE 0x10000 +} + +if { [info exists CPUTAPID] } { + set _CPUTAPID $CPUTAPID +} else { + set _CPUTAPID 0x00040927 +} + +# Set to '1' to start rescue mode +if { [info exists RESCUE] } { + set _RESCUE $RESCUE +} else { + set _RESCUE 0 +} + +# Set to 'cm0' or 'cm1' for Cortex-M33 single core configuration +# To keep compatibility with RP2040 aliases '0' and '1' are provided for Cortex-M33 cores +# Use 'rv0' or 'rv1' for RISC-V single core configuration +# List more for a multicore configuration +if { [info exists USE_CORE] } { + set _USE_CORE $USE_CORE +} else { + # defaults to both Cortex-M33 cores + set _USE_CORE { cm0 cm1 } +} + +swj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID + +if { [info exists SWD_MULTIDROP] } { + dap create $_CHIPNAME.dap -adiv6 -chain-position $_CHIPNAME.cpu -dp-id 0x0040927 -instance-id 0 +} else { + dap create $_CHIPNAME.dap -adiv6 -chain-position $_CHIPNAME.cpu +} + +# Cortex-M33 core 0 +if { [lsearch $_USE_CORE cm0] >= 0 || [lsearch $_USE_CORE 0] >= 0 } { + set _TARGETNAME_CM0 $_CHIPNAME.cm0 + set _TARGETNAME_0 $_TARGETNAME_CM0 +} + +# RISC-V core 0 +if { [lsearch $_USE_CORE rv0] >= 0 } { + set _TARGETNAME_RV0 $_CHIPNAME.rv0 + if { ![info exists _TARGETNAME_0] } { + set _TARGETNAME_0 $_TARGETNAME_RV0 + } +} + +# Cortex-M33 core 1 +if { [lsearch $_USE_CORE cm1] >= 0 || [lsearch $_USE_CORE 1] >= 0 } { + set _TARGETNAME_CM1 $_CHIPNAME.cm1 + set _TARGETNAME_1 $_TARGETNAME_CM1 +} + +# RISC-V core 1 +if { [lsearch $_USE_CORE rv1] >= 0 } { + set _TARGETNAME_RV1 $_CHIPNAME.rv1 + if { ![info exists _TARGETNAME_1] } { + set _TARGETNAME_1 $_TARGETNAME_RV1 + } +} + + +if { [info exists _TARGETNAME_CM0] } { + target create $_TARGETNAME_CM0 cortex_m -dap $_CHIPNAME.dap -ap-num 0x2000 + # srst does not exist; use SYSRESETREQ to perform a soft reset + $_TARGETNAME_CM0 cortex_m reset_config sysresetreq + + # After a rescue reset the cache requires invalidate to allow SPI flash + # reads from the XIP cached mapping area + $_TARGETNAME_CM0 configure -event reset-init { rp2xxx rom_api_call FC } +} + +if { [info exists _TARGETNAME_RV0] } { + target create $_TARGETNAME_RV0 riscv -dap $_CHIPNAME.dap -ap-num 0xa000 -coreid 0 + $_TARGETNAME_RV0 riscv set_enable_virt2phys off + + # Workaround for stray IO_QSPI: GPIO_QSPI_SD1_CTRL: INOVER bit in RISC-V BOOTSEL + $_TARGETNAME_RV0 configure -event reset-init { mww 0x4003002c 0 } + + if { [info exists _TARGETNAME_CM0] } { + # just for setting after init when the event become-available is not fired + $_TARGETNAME_RV0 configure -event examine-end "rp2xxx _switch_target $_TARGETNAME_CM0 $_TARGETNAME_RV0" + } +} + +if { [info exists _TARGETNAME_CM1] } { + target create $_TARGETNAME_CM1 cortex_m -dap $_CHIPNAME.dap -ap-num 0x4000 + $_TARGETNAME_CM1 cortex_m reset_config sysresetreq +} + +if { [info exists _TARGETNAME_RV1] } { + target create $_TARGETNAME_RV1 riscv -dap $_CHIPNAME.dap -ap-num 0xa000 -coreid 1 + $_TARGETNAME_RV1 riscv set_enable_virt2phys off +} + +if { [info exists USE_SMP] } { + set _USE_SMP $USE_SMP +} elseif { [info exists _TARGETNAME_CM0] == [info exists _TARGETNAME_CM1] + && [info exists _TARGETNAME_RV0] == [info exists _TARGETNAME_RV1] } { + set _USE_SMP 1 +} else { + set _USE_SMP 0 +} +if { $_USE_SMP } { + if { [info exists _TARGETNAME_CM0] && [info exists _TARGETNAME_CM1] } { + $_TARGETNAME_CM0 configure -rtos hwthread + $_TARGETNAME_CM1 configure -rtos hwthread + target smp $_TARGETNAME_CM0 $_TARGETNAME_CM1 + } + if { [info exists _TARGETNAME_RV0] && [info exists _TARGETNAME_RV1] } { + $_TARGETNAME_RV0 configure -rtos hwthread + $_TARGETNAME_RV1 configure -rtos hwthread + target smp $_TARGETNAME_RV0 $_TARGETNAME_RV1 + } +} + +if { [info exists _TARGETNAME_0] } { + set _FLASH_TARGET $_TARGETNAME_0 +} +if { ![info exists _FLASH_TARGET] && [info exists _TARGETNAME_1] } { + set _FLASH_TARGET $_TARGETNAME_1 + if { [info exists _TARGETNAME_CM1] && [info exists _TARGETNAME_RV1] } { + echo "Info : $_CHIPNAME.flash will be handled by $_TARGETNAME_1 without switching" + } +} +if { [info exists _FLASH_TARGET] } { + $_FLASH_TARGET configure -work-area-phys 0x20010000 -work-area-size $_WORKAREASIZE + if { [info exists _TARGETNAME_CM0] && [info exists _TARGETNAME_RV0] } { + $_TARGETNAME_RV0 configure -work-area-phys 0x20010000 -work-area-size $_WORKAREASIZE + echo "Info : $_CHIPNAME.flash will be handled by the active one of $_FLASH_TARGET and $_TARGETNAME_RV0 cores" + } + set _FLASHNAME $_CHIPNAME.flash + set _FLASHSIZE 0x00400000 + flash bank $_FLASHNAME rp2040_flash 0x10000000 $_FLASHSIZE 0 0 $_FLASH_TARGET +} + +if { [info exists _TARGETNAME_1] } { + # Alias to ensure gdb connecting to core 1 gets the correct memory map + flash bank $_CHIPNAME.alias virtual 0x10000000 0 0 0 $_TARGETNAME_1 $_FLASHNAME +} + +if { [info exists _TARGETNAME_0] } { + # Select core 0 + targets $_TARGETNAME_0 +} + +# Cold reset resets everything except DP +proc cold_reset { { __CHIPNAME "" } } { + if { $__CHIPNAME == "" } { + global _CHIPNAME + set __CHIPNAME $_CHIPNAME + } + poll off + # set CDBGRSTREQ (and keep set CSYSPWRUPREQ and CDBGPWRUPREQ) + $__CHIPNAME.dap dpreg 4 0x54000000 + set dpstat [$__CHIPNAME.dap dpreg 4] + if { [expr { $dpstat & 0xcc000000 }] != 0xcc000000 } { + echo "Warn : dpstat_reset failed, DP STAT $dpstat" + } + $__CHIPNAME.dap dpreg 4 0x50000000 + dap init + poll on +} + +# Rescue reset resets everything except DP and RP_AP +# Both Cortex-M33 cores stop in bootrom +proc rescue_reset { { __CHIPNAME "" } } { + if { $__CHIPNAME == "" } { + global _CHIPNAME + set __CHIPNAME $_CHIPNAME + } + poll off + # set bit RESCUE_RESTART in RP_AP: CTRL register + $__CHIPNAME.dap apreg 0x80000 0 0x80000000 + $__CHIPNAME.dap apreg 0x80000 0 0 + dap init + poll on + if { [lsearch [target names] $__CHIPNAME.cm0] < 0 } { + echo "Info : restart OpenOCD with 'set USE_CORE { cm0 cm1 }' to debug after rescue" + } +} + +if { $_RESCUE } { + init + rescue_reset +} ----------------------------------------------------------------------- Summary of changes: tcl/target/rp2350.cfg | 206 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 tcl/target/rp2350.cfg hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2025-04-25 09:33:23
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 2e49c99b1f919c2496c2d0140ada4ea5134c20a0 (commit) from 15d92076b0c2d6198e2f60381e4dcb645ec9a110 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2e49c99b1f919c2496c2d0140ada4ea5134c20a0 Author: Tomas Vanek <va...@fb...> Date: Sat Aug 10 16:10:43 2024 +0200 flash/nor/rp2040: flash bank target switching for RP2350 RP2350 can switch either core to Cortex-M33 or RISC-V. The different architectures have to be supported as distinct targets in OpenOCD. Introduce 'rp2xxx _switch target' Tcl command to adapt flash bank to architecture changes. Keep the target and priv pointers intact until a flash operation is finished to prevent sudden change in the middle of write/erase. Signed-off-by: Tomas Vanek <va...@fb...> Change-Id: I764354ab469e253042128958dfe70c09d04d6411 Reviewed-on: https://review.openocd.org/c/openocd/+/8448 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/src/flash/nor/rp2040.c b/src/flash/nor/rp2040.c index df9284d96..15a04fbb0 100644 --- a/src/flash/nor/rp2040.c +++ b/src/flash/nor/rp2040.c @@ -627,16 +627,13 @@ static int rp2350_init_arm_core0(struct target *target, struct rp2040_flash_bank return err; } -static int setup_for_raw_flash_cmd(struct flash_bank *bank) +static int setup_for_raw_flash_cmd(struct target *target, struct rp2040_flash_bank *priv) { - struct rp2040_flash_bank *priv = bank->driver_priv; - struct target *target = bank->target; - int err = ERROR_OK; if (!priv->stack) { /* target_alloc_working_area always allocates multiples of 4 bytes, so no worry about alignment */ - err = target_alloc_working_area(bank->target, RP2XXX_MAX_ALGO_STACK_USAGE, &priv->stack); + err = target_alloc_working_area(target, RP2XXX_MAX_ALGO_STACK_USAGE, &priv->stack); if (err != ERROR_OK) { LOG_ERROR("Could not allocate stack for flash programming code -- insufficient space"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; @@ -644,7 +641,7 @@ static int setup_for_raw_flash_cmd(struct flash_bank *bank) } if (!priv->ram_algo_space) { - err = target_alloc_working_area(bank->target, RP2XXX_MAX_RAM_ALGO_SIZE, &priv->ram_algo_space); + err = target_alloc_working_area(target, RP2XXX_MAX_RAM_ALGO_SIZE, &priv->ram_algo_space); if (err != ERROR_OK) { LOG_ERROR("Could not allocate RAM code space for ROM calls -- insufficient space"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; @@ -692,7 +689,7 @@ static int setup_for_raw_flash_cmd(struct flash_bank *bank) .sp = priv->stack->address + priv->stack->size } }; - err = rp2xxx_call_rom_func_batch(bank->target, priv, calls, 2); + err = rp2xxx_call_rom_func_batch(target, priv, calls, 2); if (err != ERROR_OK) { LOG_ERROR("RP2040 flash: failed to exit flash XIP mode"); return err; @@ -701,15 +698,13 @@ static int setup_for_raw_flash_cmd(struct flash_bank *bank) return ERROR_OK; } -static void cleanup_after_raw_flash_cmd(struct flash_bank *bank) +static void cleanup_after_raw_flash_cmd(struct target *target, struct rp2040_flash_bank *priv) { /* OpenOCD is prone to trashing work-area allocations on target state transitions, which leaves us with stale work area pointers in our driver state. Best to clean up our allocations manually after completing each flash call, so we know to make fresh ones next time. */ LOG_DEBUG("Cleaning up after flash operations"); - struct rp2040_flash_bank *priv = bank->driver_priv; - struct target *target = bank->target; if (priv->stack) { target_free_working_area(target, priv->stack); priv->stack = 0; @@ -728,7 +723,7 @@ static int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, ui struct target *target = bank->target; struct working_area *bounce; - int err = setup_for_raw_flash_cmd(bank); + int err = setup_for_raw_flash_cmd(target, priv); if (err != ERROR_OK) goto cleanup_and_return; @@ -780,7 +775,7 @@ static int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, ui // accesses, but there's no harm in calling it anyway. LOG_DEBUG("Flushing flash cache after write behind"); - err = rp2xxx_call_rom_func(bank->target, priv, priv->jump_flush_cache, NULL, 0); + err = rp2xxx_call_rom_func(target, priv, priv->jump_flush_cache, NULL, 0); rp2xxx_rom_call_batch_record_t finishing_calls[3] = { { @@ -805,18 +800,19 @@ static int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, ui goto cleanup_and_return; } cleanup_and_return: - cleanup_after_raw_flash_cmd(bank); + cleanup_after_raw_flash_cmd(target, priv); return err; } static int rp2040_flash_erase(struct flash_bank *bank, unsigned int first, unsigned int last) { struct rp2040_flash_bank *priv = bank->driver_priv; + struct target *target = bank->target; uint32_t start_addr = bank->sectors[first].offset; uint32_t length = bank->sectors[last].offset + bank->sectors[last].size - start_addr; LOG_DEBUG("RP2040 erase %d bytes starting at 0x%" PRIx32, length, start_addr); - int err = setup_for_raw_flash_cmd(bank); + int err = setup_for_raw_flash_cmd(target, priv); if (err != ERROR_OK) goto cleanup_and_return; @@ -855,7 +851,7 @@ static int rp2040_flash_erase(struct flash_bank *bank, unsigned int first, unsig 0xd8 /* block_cmd */ }; - err = rp2xxx_call_rom_func(bank->target, priv, priv->jump_flash_range_erase, args, ARRAY_SIZE(args)); + err = rp2xxx_call_rom_func(target, priv, priv->jump_flash_range_erase, args, ARRAY_SIZE(args)); keep_alive(); if (err != ERROR_OK) @@ -866,7 +862,7 @@ static int rp2040_flash_erase(struct flash_bank *bank, unsigned int first, unsig cleanup_and_return: - cleanup_after_raw_flash_cmd(bank); + cleanup_after_raw_flash_cmd(target, priv); return err; } @@ -973,7 +969,8 @@ COMMAND_HANDLER(rp2040_rom_api_call_handler) for (unsigned int i = 0; i + 1 < CMD_ARGC && i < ARRAY_SIZE(args); i++) COMMAND_PARSE_NUMBER(u32, CMD_ARGV[i + 1], args[i]); - retval = setup_for_raw_flash_cmd(bank); + struct rp2040_flash_bank *priv = bank->driver_priv; + retval = setup_for_raw_flash_cmd(target, priv); if (retval != ERROR_OK) goto cleanup_and_return; @@ -992,16 +989,51 @@ COMMAND_HANDLER(rp2040_rom_api_call_handler) * in an event handler, use LOG_INFO instead */ LOG_INFO("RP2xxx ROM API function %.2s @ %04" PRIx16, CMD_ARGV[0], fc); - struct rp2040_flash_bank *priv = bank->driver_priv; retval = rp2xxx_call_rom_func(target, priv, fc, args, ARRAY_SIZE(args)); if (retval != ERROR_OK) command_print(CMD, "RP2xxx ROM API call failed"); cleanup_and_return: - cleanup_after_raw_flash_cmd(bank); + cleanup_after_raw_flash_cmd(target, priv); return retval; } +COMMAND_HANDLER(rp2040_switch_target_handler) +{ + if (CMD_ARGC != 2) + return ERROR_COMMAND_SYNTAX_ERROR; + + struct target *old_target = get_target(CMD_ARGV[0]); + if (!old_target) { + command_print(CMD, "Unrecognised old target %s", CMD_ARGV[0]); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + + struct target *new_target = get_target(CMD_ARGV[1]); + if (!new_target) { + command_print(CMD, "Unrecognised new target %s", CMD_ARGV[1]); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + + struct flash_bank *bank; + for (bank = flash_bank_list(); bank; bank = bank->next) { + if (bank->driver == &rp2040_flash) { + if (bank->target == old_target) { + bank->target = new_target; + struct rp2040_flash_bank *priv = bank->driver_priv; + priv->probed = false; + return ERROR_OK; + } else if (bank->target == new_target) { + return ERROR_OK; + } + } + } + + command_print(CMD, "Neither old nor new target %s found in flash bank list", + CMD_ARGV[0]); + return ERROR_FAIL; +} + static const struct command_registration rp2040_exec_command_handlers[] = { { .name = "rom_api_call", @@ -1010,6 +1042,13 @@ static const struct command_registration rp2040_exec_command_handlers[] = { .usage = "fc [p0 [p1 [p2 [p3]]]]", .handler = rp2040_rom_api_call_handler, }, + { + .name = "_switch_target", + .mode = COMMAND_EXEC, + .help = "internal use", + .usage = "old_target new_target", + .handler = rp2040_switch_target_handler, + }, COMMAND_REGISTRATION_DONE }; ----------------------------------------------------------------------- Summary of changes: src/flash/nor/rp2040.c | 77 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 19 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2025-04-25 09:31:22
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 15d92076b0c2d6198e2f60381e4dcb645ec9a110 (commit) from ba03d13c29fba9f5e4e97121c47eb3b7857aa92d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 15d92076b0c2d6198e2f60381e4dcb645ec9a110 Author: Tomas Vanek <va...@fb...> Date: Wed Jul 17 11:49:55 2024 +0200 flash/nor/rp2040: allow arbitrary ROM API call from Tcl The new flash command could be handy for a reboot to BOOTSEL mode and for making (Q)SPI flash content visible at 0x10xxxxxx address mapping area after a rescue reset. Signed-off-by: Tomas Vanek <va...@fb...> Change-Id: I1b532afcc41a4051298313e685658e86c02c53f9 Reviewed-on: https://review.openocd.org/c/openocd/+/8447 Reviewed-by: Antonio Borneo <bor...@gm...> Tested-by: jenkins diff --git a/src/flash/nor/rp2040.c b/src/flash/nor/rp2040.c index 5faba57a0..df9284d96 100644 --- a/src/flash/nor/rp2040.c +++ b/src/flash/nor/rp2040.c @@ -938,8 +938,95 @@ FLASH_BANK_COMMAND_HANDLER(rp2040_flash_bank_command) return ERROR_OK; } + +COMMAND_HANDLER(rp2040_rom_api_call_handler) +{ + if (CMD_ARGC < 1) + return ERROR_COMMAND_SYNTAX_ERROR; + + struct target *target = get_current_target(CMD->ctx); + + struct flash_bank *bank; + for (bank = flash_bank_list(); bank; bank = bank->next) { + if (bank->driver != &rp2040_flash) + continue; + + if (bank->target == target) + break; + } + + if (!bank) { + command_print(CMD, "[%s] No associated RP2xxx flash bank found", + target_name(target)); + return ERROR_FAIL; + } + + int retval = rp2040_flash_auto_probe(bank); + if (retval != ERROR_OK) { + command_print(CMD, "auto_probe failed"); + return retval; + } + + uint16_t tag = MAKE_TAG(CMD_ARGV[0][0], CMD_ARGV[0][1]); + + uint32_t args[4] = { 0 }; + for (unsigned int i = 0; i + 1 < CMD_ARGC && i < ARRAY_SIZE(args); i++) + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[i + 1], args[i]); + + retval = setup_for_raw_flash_cmd(bank); + if (retval != ERROR_OK) + goto cleanup_and_return; + + uint16_t symtype_func = is_arm(target_to_arm(target)) + ? RT_FLAG_FUNC_ARM_SEC : RT_FLAG_FUNC_RISCV; + + uint16_t fc; + retval = rp2xxx_lookup_rom_symbol(target, tag, symtype_func, &fc); + if (retval != ERROR_OK) { + command_print(CMD, "Function %.2s not found in RP2xxx ROM.", + CMD_ARGV[0]); + goto cleanup_and_return; + } + + /* command_print() output gets lost if the command is called + * in an event handler, use LOG_INFO instead */ + LOG_INFO("RP2xxx ROM API function %.2s @ %04" PRIx16, CMD_ARGV[0], fc); + + struct rp2040_flash_bank *priv = bank->driver_priv; + retval = rp2xxx_call_rom_func(target, priv, fc, args, ARRAY_SIZE(args)); + if (retval != ERROR_OK) + command_print(CMD, "RP2xxx ROM API call failed"); + +cleanup_and_return: + cleanup_after_raw_flash_cmd(bank); + return retval; +} + +static const struct command_registration rp2040_exec_command_handlers[] = { + { + .name = "rom_api_call", + .mode = COMMAND_EXEC, + .help = "arbitrary ROM API call", + .usage = "fc [p0 [p1 [p2 [p3]]]]", + .handler = rp2040_rom_api_call_handler, + }, + COMMAND_REGISTRATION_DONE +}; + +static const struct command_registration rp2040_command_handler[] = { + { + .name = "rp2xxx", + .mode = COMMAND_ANY, + .help = "rp2xxx flash controller commands", + .usage = "", + .chain = rp2040_exec_command_handlers, + }, + COMMAND_REGISTRATION_DONE +}; + const struct flash_driver rp2040_flash = { .name = "rp2040_flash", + .commands = rp2040_command_handler, .flash_bank_command = rp2040_flash_bank_command, .erase = rp2040_flash_erase, .write = rp2040_flash_write, ----------------------------------------------------------------------- Summary of changes: src/flash/nor/rp2040.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2025-04-25 09:28:58
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via ba03d13c29fba9f5e4e97121c47eb3b7857aa92d (commit) from 8f92e520bbd76917fd3ed18b9b9bb4099044da14 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ba03d13c29fba9f5e4e97121c47eb3b7857aa92d Author: Tomas Vanek <va...@fb...> Date: Tue Aug 6 17:39:44 2024 +0200 flash/nor/rp2040: allow flash size override from cfg Do not enforce hard-wired size 32 MiB Signed-off-by: Tomas Vanek <va...@fb...> Change-Id: I54608f75cc13996fda38ebd5d330e3b1893c2fd9 Reviewed-on: https://review.openocd.org/c/openocd/+/8446 Tested-by: jenkins Reviewed-by: Jonathan Bell <jon...@ra...> Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/src/flash/nor/rp2040.c b/src/flash/nor/rp2040.c index ed8341d1f..5faba57a0 100644 --- a/src/flash/nor/rp2040.c +++ b/src/flash/nor/rp2040.c @@ -887,7 +887,10 @@ static int rp2040_flash_probe(struct flash_bank *bank) bank->write_end_alignment = 256; // Max size -- up to two devices (two chip selects) in adjacent 24-bit address windows - bank->size = 32 * 1024 * 1024; + if (bank->size == 0) { + /* TODO: get real flash size */ + bank->size = 32 * 1024 * 1024; + } bank->num_sectors = bank->size / 4096; ----------------------------------------------------------------------- Summary of changes: src/flash/nor/rp2040.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2025-04-25 09:28:22
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 8f92e520bbd76917fd3ed18b9b9bb4099044da14 (commit) via ca966d3d7f28875e4872e691c3fdce27867ddab0 (commit) from 2e8e1a3da386685a2a572bcc85f043505a7b3d94 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8f92e520bbd76917fd3ed18b9b9bb4099044da14 Author: Luke Wren <lu...@ra...> Date: Tue Aug 6 11:57:04 2024 +0100 flash/nor/rp2040: Fix incorrect erase bounds calculation when erase region does not start at 0 Signed-off-by: Tomas Vanek <va...@fb...> Signed-off-by: Luke Wren <lu...@ra...> Change-Id: I2b9db61e8ac837b6c6431aacf3b73ed3a1772fbc Reviewed-on: https://review.openocd.org/c/openocd/+/8445 Tested-by: jenkins Reviewed-by: Jonathan Bell <jon...@ra...> diff --git a/src/flash/nor/rp2040.c b/src/flash/nor/rp2040.c index 9151b6878..ed8341d1f 100644 --- a/src/flash/nor/rp2040.c +++ b/src/flash/nor/rp2040.c @@ -821,7 +821,7 @@ static int rp2040_flash_erase(struct flash_bank *bank, unsigned int first, unsig goto cleanup_and_return; uint32_t offset_next = bank->sectors[first].offset; - uint32_t offset_last = bank->sectors[last].offset + bank->sectors[last].size - bank->sectors[first].offset; + uint32_t offset_last = bank->sectors[last].offset + bank->sectors[last].size; /* 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 commit ca966d3d7f28875e4872e691c3fdce27867ddab0 Author: Luke Wren <lu...@ra...> 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 <va...@fb...> Signed-off-by: Luke Wren <lu...@ra...> Change-Id: Ibb18775aeed192361ae1585bfdaad03760583cf3 Reviewed-on: https://review.openocd.org/c/openocd/+/8444 Tested-by: jenkins Reviewed-by: Jonathan Bell <jon...@ra...> diff --git a/src/flash/nor/rp2040.c b/src/flash/nor/rp2040.c index a9995f8c6..9151b6878 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); ----------------------------------------------------------------------- Summary of changes: src/flash/nor/rp2040.c | 63 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 16 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2025-04-25 09:27:45
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 2e8e1a3da386685a2a572bcc85f043505a7b3d94 (commit) via eb4a6342485a433ad01a18ef115236c2a29de900 (commit) via 1ed49addc5030f6df414657ead6bfc70a0deabd9 (commit) from ea775d49fc71253a95986eb5b1254b4861bdeb97 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2e8e1a3da386685a2a572bcc85f043505a7b3d94 Author: Luke Wren <lu...@ra...> Date: Fri Jun 28 16:41:48 2024 +0100 flash/nor/rp2040: Fix up ROM table lookup for RP2350 A2 which has 16-bit well-known pointers. Change-Id: Ia0838a0b062f73a9c5751abb48f1b4d55100bd1d Signed-off-by: Tomas Vanek <va...@fb...> Signed-off-by: Luke Wren <lu...@ra...> Reviewed-on: https://review.openocd.org/c/openocd/+/8443 Reviewed-by: Jonathan Bell <jon...@ra...> Tested-by: jenkins diff --git a/src/flash/nor/rp2040.c b/src/flash/nor/rp2040.c index 764a034c6..a9995f8c6 100644 --- a/src/flash/nor/rp2040.c +++ b/src/flash/nor/rp2040.c @@ -331,8 +331,8 @@ static int rp2xxx_lookup_rom_symbol(struct target *target, uint16_t tag, uint16_ /* Distinguish old-style RP2350 ROM table (A0, and earlier A1 builds) based on position of table -- a high address means it is shared with RISC-V, i.e. new-style. */ - uint32_t table_ptr; - err = target_read_u32(target, BOOTROM_MAGIC_ADDR + 4, &table_ptr); + uint16_t table_ptr; + err = target_read_u16(target, BOOTROM_MAGIC_ADDR + 4, &table_ptr); if (err != ERROR_OK) return err; if (table_ptr < 0x7c00) commit eb4a6342485a433ad01a18ef115236c2a29de900 Author: graham sanderson <gra...@ra...> Date: Sun Mar 24 18:33:24 2024 -0500 flash/nor/rp2040: RP2350 A1 changes TV: cortex_m.c changes removed. Change-Id: I85830f2d64f8afb86690737f9ae70dde5e6143e1 Signed-off-by: Tomas Vanek <va...@fb...> Signed-off-by: graham sanderson <gra...@ra...> Reviewed-on: https://review.openocd.org/c/openocd/+/8442 Tested-by: jenkins diff --git a/src/flash/nor/rp2040.c b/src/flash/nor/rp2040.c index 1e582b433..764a034c6 100644 --- a/src/flash/nor/rp2040.c +++ b/src/flash/nor/rp2040.c @@ -256,13 +256,10 @@ static int rp2350_a0_lookup_symbol(struct target *target, uint16_t tag, uint16_t return ERROR_FAIL; } -static int rp2350_lookup_rom_symbol(struct target *target, uint16_t tag, uint16_t flags, uint16_t *symbol_out) +static int rp2350_lookup_rom_symbol(struct target *target, uint32_t ptr_to_entry, + uint16_t tag, uint16_t flags, uint16_t *symbol_out) { LOG_ROM_SYMBOL_DEBUG("Looking up ROM symbol '%c%c' in RP2350 A1 table", tag & 0xff, (tag >> 8) & 0xff); - uint32_t ptr_to_entry; - int err = target_read_u32(target, BOOTROM_MAGIC_ADDR + 4, &ptr_to_entry); - if (err != ERROR_OK) - return err; /* On RP2350 A1, Each entry has a flag bitmap identifying the type of its contents. The entry contains one halfword of data for each set flag @@ -272,7 +269,7 @@ static int rp2350_lookup_rom_symbol(struct target *target, uint16_t tag, uint16_ while (true) { uint16_t entry_tag, entry_flags; - err = target_read_u16(target, ptr_to_entry, &entry_tag); + uint32_t err = target_read_u16(target, ptr_to_entry, &entry_tag); if (err != ERROR_OK) return err; if (entry_tag == 0) { @@ -341,7 +338,7 @@ static int rp2xxx_lookup_rom_symbol(struct target *target, uint16_t tag, uint16_ if (table_ptr < 0x7c00) return rp2350_a0_lookup_symbol(target, tag, flags, symbol_out); else - return rp2350_lookup_rom_symbol(target, tag, flags, symbol_out); + return rp2350_lookup_rom_symbol(target, table_ptr, tag, flags, symbol_out); } else if (magic == BOOTROM_RP2040_MAGIC) { return rp2040_lookup_rom_symbol(target, tag, flags, symbol_out); commit 1ed49addc5030f6df414657ead6bfc70a0deabd9 Author: Luke Wren <wre...@gm...> Date: Wed Jul 14 16:36:13 2021 +0100 flash/nor/rp2040: Add RISC-V ROM algorithm batch call support And add support for A1 ROM table. TV: cortex_m smp change removed. Fixed style problems. 'uint' replaced by unsigned int Change-Id: Iff2710fa0734dc7074d8d490d8fae43dc27c0c2a Signed-off-by: Tomas Vanek <va...@fb...> Signed-off-by: Luke Wren <wre...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/8441 Tested-by: jenkins diff --git a/src/flash/nor/rp2040.c b/src/flash/nor/rp2040.c index c53b54754..1e582b433 100644 --- a/src/flash/nor/rp2040.c +++ b/src/flash/nor/rp2040.c @@ -11,32 +11,27 @@ #include "spi.h" #include <target/cortex_m.h> -/* NOTE THAT THIS CODE REQUIRES FLASH ROUTINES in BOOTROM WITH FUNCTION TABLE PTR AT 0x00000010 - Your gdbinit should load the bootrom.elf if appropriate */ - /* this is 'M' 'u', 1 (version) */ #define BOOTROM_RP2040_MAGIC 0x01754d /* this is 'M' 'u', 2 (version) */ #define BOOTROM_RP2350_MAGIC 0x02754d #define BOOTROM_MAGIC_ADDR 0x00000010 -#define RT_ARM_FUNC 0x1 - -/* Call a ROM function via the debug trampoline - Up to four arguments passed in r0...r3 as per ABI - Function address is passed in r7 - the trampoline is needed because OpenOCD "algorithm" code insists on sw breakpoints. */ - #define MAKE_TAG(a, b) (((b)<<8) | a) -#define FUNC_DEBUG_TRAMPOLINE MAKE_TAG('D', 'T') -#define FUNC_DEBUG_TRAMPOLINE_END MAKE_TAG('D', 'E') -#define FUNC_FLASH_EXIT_XIP MAKE_TAG('E', 'X') -#define FUNC_CONNECT_INTERNAL_FLASH MAKE_TAG('I', 'F') -#define FUNC_FLASH_RANGE_ERASE MAKE_TAG('R', 'E') -#define FUNC_FLASH_RANGE_PROGRAM MAKE_TAG('R', 'P') -#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_FLASH_EXIT_XIP MAKE_TAG('E', 'X') +#define FUNC_CONNECT_INTERNAL_FLASH MAKE_TAG('I', 'F') +#define FUNC_FLASH_RANGE_ERASE MAKE_TAG('R', 'E') +#define FUNC_FLASH_RANGE_PROGRAM MAKE_TAG('R', 'P') +#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_FLASH_RESET_ADDRESS_TRANS MAKE_TAG('R', 'A') + +/* ROM table flags for RP2350 A1 ROM onwards */ +#define RT_FLAG_FUNC_RISCV 0x01 +#define RT_FLAG_FUNC_ARM_SEC 0x04 +#define RT_FLAG_FUNC_ARM_NONSEC 0x10 +#define RT_FLAG_DATA 0x40 // these form a bit set #define BOOTROM_STATE_RESET_CURRENT_CORE 0x01 @@ -48,10 +43,14 @@ #define ACCESSCTRL_CFGRESET_OFFSET 0x40060008u #define ACCESSCTRL_WRITE_PASSWORD 0xacce0000u -// Calling bootrom functions requires the redundancy coprocessor (RCP) to be -// initialised. Usually this is done first thing by the bootrom, but the -// debugger may skip this, e.g. by resetting the cores and then running a -// NO_FLASH binary, or by reset-halting the cores before flash programming. +#define RP2XXX_MAX_ALGO_STACK_USAGE 1024 +#define RP2XXX_MAX_RAM_ALGO_SIZE 1024 + +// Calling bootrom functions on Arm RP2350 requires the redundancy +// coprocessor (RCP) to be initialised. Usually this is done first thing by +// the bootrom, but the debugger may skip this, e.g. by resetting the cores +// and then running a NO_FLASH binary, or by reset-halting the cores before +// flash programming. // // The first case can be handled by a stub in the binary itself to initialise // the RCP with dummy values if the bootrom has not already initialised it. @@ -59,186 +58,500 @@ // requires the debugger itself to initialise the RCP, using this stub code: static const int rcp_init_code_bkpt_offset = 24; -static const uint16_t rcp_init_code[] = { +static const uint8_t rcp_init_code[] = { // Just enable the RCP which is fine if it already was (we assume no other // co-processors are enabled at this point to save space) - 0x4806, // ldr r0, = PPB_BASE + M33_CPACR_OFFSET - 0xf45f, 0x4140, // movs r1, #M33_CPACR_CP7_BITS - 0x6001, // str r1, [r0] + 0x06, 0x48, // ldr r0, = PPB_BASE + M33_CPACR_OFFSET + 0x5f, 0xf4, 0x40, 0x41, // movs r1, #M33_CPACR_CP7_BITS + 0x01, 0x60, // str r1, [r0] // Only initialize canary seeds if they haven't been (as to do so twice is a fault) - 0xee30, 0xf710, // mrc p7, #1, r15, c0, c0, #0 - 0xd404, // bmi 1f + 0x30, 0xee, 0x10, 0xf7, // mrc p7, #1, r15, c0, c0, #0 + 0x04, 0xd4, // bmi 1f // Todo should we use something random here and pass it into the algorithm? - 0xec40, 0x0780, // mcrr p7, #8, r0, r0, c0 - 0xec40, 0x0781, // mcrr p7, #8, r0, r0, c1 + 0x40, 0xec, 0x80, 0x07, // mcrr p7, #8, r0, r0, c0 + 0x40, 0xec, 0x81, 0x07, // mcrr p7, #8, r0, r0, c1 // Let other core know - 0xbf40, // sev + 0x40, 0xbf, // sev // 1: - 0xbe00, // bkpt (end of algorithm) - 0x0000, // pad - 0xed88, 0xe000 // PPB_BASE + M33_CPACR_OFFSET + 0x00, 0xbe, // bkpt (end of algorithm) + 0x00, 0x00, // pad + 0x88, 0xed, 0x00, 0xe0 // PPB_BASE + M33_CPACR_OFFSET }; +// An algorithm stub that can be concatenated with a null-terminated list of +// (PC, SP, r0-r3) records to perform a batch of ROM calls under a single +// OpenOCD algorithm call, to save on algorithm overhead: +#define ROM_CALL_BATCH_ALGO_SIZE_BYTES 32 +static const int rp2xxx_rom_call_batch_algo_bkpt_offset = ROM_CALL_BATCH_ALGO_SIZE_BYTES - 2; +static const uint8_t rp2xxx_rom_call_batch_algo_armv6m[ROM_CALL_BATCH_ALGO_SIZE_BYTES] = { +// <_start>: + 0x07, 0xa7, // add r7, pc, #28 ; (adr r7, 20 <_args>) +// <_do_next>: + 0x10, 0xcf, // ldmia r7!, {r4} + 0x00, 0x2c, // cmp r4, #0 + 0x0a, 0xd0, // beq.n 1e <_done> + 0x20, 0xcf, // ldmia r7!, {r5} + 0xad, 0x46, // mov sp, r5 + 0x0f, 0xcf, // ldmia r7!, {r0, r1, r2, r3} + 0xa0, 0x47, // blx r4 + 0xf7, 0xe7, // b.n 2 <_do_next> + 0xc0, 0x46, // nop + 0xc0, 0x46, // nop + 0xc0, 0x46, // nop + 0xc0, 0x46, // nop + 0xc0, 0x46, // nop + 0xc0, 0x46, // nop +// <_done>: + 0x00, 0xbe, // bkpt 0x0000 +// <_args>: +}; + +// The same as rom_call_batch_algo_armv6m, but clearing stack limits before setting stack: +static const uint8_t rp2xxx_rom_call_batch_algo_armv8m[ROM_CALL_BATCH_ALGO_SIZE_BYTES] = { +// <_start>: + 0x07, 0xa7, // add r7, pc, #28 ; (adr r7, 20 <_args>) + 0x00, 0x20, // movs r0, #0 + 0x80, 0xf3, 0x0a, 0x88, // msr MSPLIM, r0 + 0x80, 0xf3, 0x0b, 0x88, // msr PSPLIM, r0 +// <_do_next>: + 0x10, 0xcf, // ldmia r7!, {r4} + 0x00, 0x2c, // cmp r4, #0 + 0x05, 0xd0, // beq.n 1e <_done> + 0x20, 0xcf, // ldmia r7!, {r5} + 0xad, 0x46, // mov sp, r5 + 0x0f, 0xcf, // ldmia r7!, {r0, r1, r2, r3} + 0xa0, 0x47, // blx r4 + 0xf7, 0xe7, // b.n c <_do_next> + 0xc0, 0x46, // nop +// <_done>: + 0x00, 0xbe, // bkpt 0x0000 +// <_args>: +}; + +// The same as rom_call_batch_algo_armv6m, but placing arguments in a0-a3 on RISC-V: +static const uint8_t rp2xxx_rom_call_batch_algo_riscv[ROM_CALL_BATCH_ALGO_SIZE_BYTES] = { +// <_start>: + 0x97, 0x04, 0x00, 0x00, // auipc s1,0 + 0x93, 0x84, 0x04, 0x02, // add s1,s1,32 # 20 <_args> +// <_do_next>: + 0x98, 0x40, // lw a4,0(s1) + 0x11, 0xcb, // beqz a4,1e <_done> + 0x03, 0xa1, 0x44, 0x00, // lw sp,4(s1) + 0x88, 0x44, // lw a0,8(s1) + 0xcc, 0x44, // lw a1,12(s1) + 0x90, 0x48, // lw a2,16(s1) + 0xd4, 0x48, // lw a3,20(s1) + 0xe1, 0x04, // add s1,s1,24 + 0x02, 0x97, // jalr a4 + 0xf5, 0xb7, // j 8 <_do_next> +// <_done>: + 0x02, 0x90, // ebreak +// <_args>: +}; + +typedef struct rp2xxx_rom_call_batch_record { + uint32_t pc; + uint32_t sp; + uint32_t args[4]; +} rp2xxx_rom_call_batch_record_t; + struct rp2040_flash_bank { /* flag indicating successful flash probe */ bool probed; /* stack used by Boot ROM calls */ struct working_area *stack; + /* static code scratchpad used for RAM algorithms -- allocated in advance + so that higher-level calls can just grab all remaining workarea: */ + struct working_area *ram_algo_space; /* function jump table populated by rp2040_flash_probe() */ - uint16_t jump_debug_trampoline; - uint16_t jump_debug_trampoline_end; uint16_t jump_flash_exit_xip; uint16_t jump_connect_internal_flash; uint16_t jump_flash_range_erase; uint16_t jump_flash_range_program; uint16_t jump_flush_cache; + uint16_t jump_flash_reset_address_trans; uint16_t jump_enter_cmd_xip; uint16_t jump_bootrom_reset_state; }; -static uint32_t rp2040_lookup_symbol(struct target *target, uint32_t tag, uint16_t *symbol) +#ifndef LOG_ROM_SYMBOL_DEBUG +#define LOG_ROM_SYMBOL_DEBUG LOG_DEBUG +#endif + +static int rp2040_lookup_rom_symbol(struct target *target, uint16_t tag, uint16_t flags, uint16_t *symbol_out) { - uint32_t magic, magic_addr; - bool found_rp2040_magic, found_rp2350_magic; - magic_addr = BOOTROM_MAGIC_ADDR; - int err = target_read_u32(target, BOOTROM_MAGIC_ADDR, &magic); + LOG_ROM_SYMBOL_DEBUG("Looking up ROM symbol '%c%c' in RP2040 table", tag & 0xff, (tag >> 8) & 0xff); + if (flags != RT_FLAG_FUNC_ARM_SEC && flags != RT_FLAG_DATA) { + /* Note RT flags do not exist on RP2040, so just sanity check that we + are asked for a type of thing that actually exists in the ROM table */ + LOG_ERROR("Only data and Secure Arm functions can be looked up in RP2040 ROM table"); + return ERROR_FAIL; + } + + uint16_t ptr_to_entry; + const unsigned int offset_magic_to_table_ptr = flags == RT_FLAG_DATA ? 6 : 4; + int err = target_read_u16(target, BOOTROM_MAGIC_ADDR + offset_magic_to_table_ptr, &ptr_to_entry); if (err != ERROR_OK) return err; - magic &= 0xffffff; /* ignore bootrom version */ - - found_rp2040_magic = magic == BOOTROM_RP2040_MAGIC; - found_rp2350_magic = magic == BOOTROM_RP2350_MAGIC; + uint16_t entry_tag; + do { + err = target_read_u16(target, ptr_to_entry, &entry_tag); + if (err != ERROR_OK) + return err; + if (entry_tag == tag) { + /* 16 bit symbol is next */ + err = target_read_u16(target, ptr_to_entry + 2, symbol_out); + if (err != ERROR_OK) + return err; + LOG_ROM_SYMBOL_DEBUG(" -> found: 0x%04x", *symbol_out); + return ERROR_OK; + } + ptr_to_entry += 4; + } while (entry_tag); + *symbol_out = 0; + return ERROR_FAIL; +} - if (!(found_rp2040_magic || found_rp2350_magic)) { - LOG_ERROR("RP2040/RP2350 BOOT ROM not found"); - return ERROR_FAIL; +static int rp2350_a0_lookup_symbol(struct target *target, uint16_t tag, uint16_t flags, uint16_t *symbol_out) +{ + LOG_ROM_SYMBOL_DEBUG("Looking up ROM symbol '%c%c' in RP2350 A0 table", tag & 0xff, (tag >> 8) & 0xff); + + /* RP2350 A0 table format is the same as RP2040 except with 16 bits of + flags after each 16-bit pointer. We ignore the flags, as each symbol + only has one datum associated with it. */ + + uint32_t magic_ptr = BOOTROM_MAGIC_ADDR; + if (flags == RT_FLAG_FUNC_RISCV) { + /* RP2350 A0 used split function tables for Arm/RISC-V -- not used on + any other device or any other version of this device. There is a + well-known RISC-V table at the top of ROM, matching the well-known + Arm table at the bottom of ROM. */ + magic_ptr = 0x7decu; + } else if (flags != RT_FLAG_FUNC_ARM_SEC) { + LOG_WARNING("Ignoring non-default flags for RP2350 A0 lookup, hope you like Secure Arm functions"); } - /* dereference the table pointer */ - uint16_t table_entry; - err = target_read_u16(target, magic_addr + 4, &table_entry); + uint16_t ptr_to_entry; + const unsigned int offset_magic_to_table_ptr = 4; + int err = target_read_u16(target, magic_ptr + offset_magic_to_table_ptr, &ptr_to_entry); if (err != ERROR_OK) return err; uint16_t entry_tag; do { - err = target_read_u16(target, table_entry, &entry_tag); + err = target_read_u16(target, ptr_to_entry, &entry_tag); if (err != ERROR_OK) return err; if (entry_tag == tag) { - if (found_rp2350_magic) { - uint16_t flags; - /* flags are next */ - err = target_read_u16(target, table_entry + 4, &flags); - if (err != ERROR_OK) - return err; - // - if (flags & RT_ARM_FUNC) { - /* 16 bit symbol */ - return target_read_u16(target, table_entry + 2, symbol); - } - } else { - /* 16 bit symbol is next */ - return target_read_u16(target, table_entry + 2, symbol); - } + err = target_read_u16(target, ptr_to_entry + 2, symbol_out); + if (err != ERROR_OK) + return err; + LOG_ROM_SYMBOL_DEBUG(" -> found: 0x%04x", *symbol_out); + return ERROR_OK; } - table_entry += found_rp2350_magic ? 6 : 4; + ptr_to_entry += 6; } while (entry_tag); + *symbol_out = 0; return ERROR_FAIL; } -static int rp2040_call_rom_func(struct target *target, struct rp2040_flash_bank *priv, - uint16_t func_offset, uint32_t argdata[], unsigned int n_args) +static int rp2350_lookup_rom_symbol(struct target *target, uint16_t tag, uint16_t flags, uint16_t *symbol_out) { - char *regnames[4] = { "r0", "r1", "r2", "r3" }; + LOG_ROM_SYMBOL_DEBUG("Looking up ROM symbol '%c%c' in RP2350 A1 table", tag & 0xff, (tag >> 8) & 0xff); + uint32_t ptr_to_entry; + int err = target_read_u32(target, BOOTROM_MAGIC_ADDR + 4, &ptr_to_entry); + if (err != ERROR_OK) + return err; - assert(n_args <= ARRAY_SIZE(regnames)); /* only allow register arguments */ + /* On RP2350 A1, Each entry has a flag bitmap identifying the type of its + contents. The entry contains one halfword of data for each set flag + bit. There may be both Arm and RISC-V entries under the same tag, or + separate Arm Secure/NonSecure entries (or all three, why not). */ - if (!priv->stack) { - LOG_ERROR("no stack for flash programming code"); + while (true) { + uint16_t entry_tag, entry_flags; + + err = target_read_u16(target, ptr_to_entry, &entry_tag); + if (err != ERROR_OK) + return err; + if (entry_tag == 0) { + *symbol_out = 0; + return ERROR_FAIL; + } + ptr_to_entry += 2; + + err = target_read_u16(target, ptr_to_entry, &entry_flags); + if (err != ERROR_OK) + return err; + ptr_to_entry += 2; + + uint16_t matching_flags = flags & entry_flags; + + if (tag == entry_tag && matching_flags != 0) { + /* This is our entry, seek to the correct data item and return it. */ + bool is_riscv_func = matching_flags & RT_FLAG_FUNC_RISCV; + while (!(matching_flags & 1)) { + if (entry_flags & 1) + ptr_to_entry += 2; + + matching_flags >>= 1; + entry_flags >>= 1; + } + if (is_riscv_func) { + /* For RISC-V, the table entry itself is the entry point -- trick + to make shared function implementations smaller */ + *symbol_out = ptr_to_entry; + return ERROR_OK; + } + err = target_read_u16(target, ptr_to_entry, symbol_out); + if (err != ERROR_OK) + return err; + LOG_ROM_SYMBOL_DEBUG(" -> found: 0x%04x", *symbol_out); + return ERROR_OK; + } + /* Skip past this entry */ + while (entry_flags) { + if (entry_flags & 1) + ptr_to_entry += 2; + + entry_flags >>= 1; + } + } +} + +static int rp2xxx_lookup_rom_symbol(struct target *target, uint16_t tag, uint16_t flags, uint16_t *symbol_out) +{ + uint32_t magic; + int err = target_read_u32(target, BOOTROM_MAGIC_ADDR, &magic); + if (err != ERROR_OK) + return err; + + /* Ignore version */ + magic &= 0xffffff; + + if (magic == BOOTROM_RP2350_MAGIC) { + /* Distinguish old-style RP2350 ROM table (A0, and earlier A1 builds) + based on position of table -- a high address means it is shared with + RISC-V, i.e. new-style. */ + uint32_t table_ptr; + err = target_read_u32(target, BOOTROM_MAGIC_ADDR + 4, &table_ptr); + if (err != ERROR_OK) + return err; + if (table_ptr < 0x7c00) + return rp2350_a0_lookup_symbol(target, tag, flags, symbol_out); + else + return rp2350_lookup_rom_symbol(target, tag, flags, symbol_out); + + } else if (magic == BOOTROM_RP2040_MAGIC) { + return rp2040_lookup_rom_symbol(target, tag, flags, symbol_out); + } + LOG_ERROR("RP2040/RP2350 BOOT ROM not found"); + return ERROR_FAIL; +} + +static int rp2xxx_populate_rom_pointer_cache(struct target *target, struct rp2040_flash_bank *priv) +{ + const uint16_t symtype_func = is_arm(target_to_arm(target)) + ? RT_FLAG_FUNC_ARM_SEC : RT_FLAG_FUNC_RISCV; + int err; + err = rp2xxx_lookup_rom_symbol(target, FUNC_FLASH_EXIT_XIP, + symtype_func, &priv->jump_flash_exit_xip); + if (err != ERROR_OK) { + LOG_ERROR("Function FUNC_FLASH_EXIT_XIP not found in RP2xxx ROM."); + return err; + } + + err = rp2xxx_lookup_rom_symbol(target, FUNC_CONNECT_INTERNAL_FLASH, + symtype_func, &priv->jump_connect_internal_flash); + if (err != ERROR_OK) { + LOG_ERROR("Function FUNC_CONNECT_INTERNAL_FLASH not found in RP2xxx ROM."); + return err; + } + + err = rp2xxx_lookup_rom_symbol(target, FUNC_FLASH_RANGE_ERASE, symtype_func, &priv->jump_flash_range_erase); + if (err != ERROR_OK) { + LOG_ERROR("Function FUNC_FLASH_RANGE_ERASE not found in RP2xxx ROM."); + return err; + } + + err = rp2xxx_lookup_rom_symbol(target, FUNC_FLASH_RANGE_PROGRAM, symtype_func, &priv->jump_flash_range_program); + if (err != ERROR_OK) { + LOG_ERROR("Function FUNC_FLASH_RANGE_PROGRAM not found in RP2xxx ROM."); + return err; + } + + err = rp2xxx_lookup_rom_symbol(target, FUNC_FLASH_FLUSH_CACHE, symtype_func, &priv->jump_flush_cache); + if (err != ERROR_OK) { + LOG_ERROR("Function FUNC_FLASH_FLUSH_CACHE not found in RP2xxx ROM."); + return err; + } + + err = rp2xxx_lookup_rom_symbol(target, FUNC_FLASH_ENTER_CMD_XIP, symtype_func, &priv->jump_enter_cmd_xip); + if (err != ERROR_OK) { + LOG_ERROR("Function FUNC_FLASH_ENTER_CMD_XIP not found in RP2xxx ROM."); + return err; + } + + // From this point are optional functions which do not exist on e.g. RP2040 + // or pre-production RP2350 ROM versions: + + err = rp2xxx_lookup_rom_symbol(target, FUNC_BOOTROM_STATE_RESET, symtype_func, &priv->jump_bootrom_reset_state); + if (err != ERROR_OK) { + priv->jump_bootrom_reset_state = 0; + LOG_WARNING("Function FUNC_BOOTROM_STATE_RESET not found in RP2xxx ROM. (probably an RP2040 or 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) { + priv->jump_flash_reset_address_trans = 0; + LOG_WARNING("Function FUNC_FLASH_RESET_ADDRESS_TRANS not found in RP2xxx ROM. (probably an RP2040 or an RP2350 A0)"); + } + return ERROR_OK; +} + +// Call a list of PC + SP + r0-r3 function call tuples with a single OpenOCD +// algorithm invocation, to amortise the algorithm overhead over multiple calls: +static int rp2xxx_call_rom_func_batch(struct target *target, struct rp2040_flash_bank *priv, + rp2xxx_rom_call_batch_record_t *calls, unsigned int n_calls) +{ + // Note +1 is for the null terminator + unsigned int batch_words = 1 + (ROM_CALL_BATCH_ALGO_SIZE_BYTES + + n_calls * sizeof(rp2xxx_rom_call_batch_record_t) + ) / sizeof(uint32_t); + + if (!priv->ram_algo_space) { + LOG_ERROR("No RAM code space allocated for ROM call"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } - target_addr_t stacktop = priv->stack->address + priv->stack->size; + if (priv->ram_algo_space->size < batch_words * sizeof(uint32_t)) { + LOG_ERROR("RAM code space too small for call batch size of %u\n", n_calls); + return ERROR_BUF_TOO_SMALL; + } - LOG_DEBUG("Calling ROM func @0x%" PRIx16 " with %d arguments", func_offset, n_args); + LOG_DEBUG("Calling batch of %u ROM functions:", n_calls); + for (unsigned int i = 0; i < n_calls; ++i) { + LOG_DEBUG(" func @ %" PRIx32, calls[i].pc); + LOG_DEBUG(" sp = %" PRIx32, calls[i].sp); + for (int j = 0; j < 4; ++j) + LOG_DEBUG(" a%d = %" PRIx32, j, calls[i].args[j]); + } LOG_DEBUG("Calling on core \"%s\"", target->cmd_name); - struct reg_param args[ARRAY_SIZE(regnames) + 12]; - struct armv7m_algorithm alg_info; + if (n_calls <= 0) { + LOG_DEBUG("Returning early from call of 0 ROM functions"); + return ERROR_OK; + } - for (unsigned int i = 0; i < n_args; ++i) { - init_reg_param(&args[i], regnames[i], 32, PARAM_OUT); - buf_set_u32(args[i].value, 0, 32, argdata[i]); - } - /* Pass function pointer in r7 */ - unsigned int extra_args = 0; - init_reg_param(&args[n_args + extra_args], "r7", 32, PARAM_OUT); - buf_set_u32(args[n_args + extra_args++].value, 0, 32, func_offset); - /* Set stack pointer, have seen the caching get confused by the aliases of sp so - take the shotgun approach*/ - init_reg_param(&args[n_args + extra_args], "msp_s", 32, PARAM_OUT); - buf_set_u32(args[n_args + extra_args++].value, 0, 32, stacktop); - init_reg_param(&args[n_args + extra_args], "msp_ns", 32, PARAM_OUT); - buf_set_u32(args[n_args + extra_args++].value, 0, 32, stacktop); - init_reg_param(&args[n_args + extra_args], "psp_s", 32, PARAM_OUT); - buf_set_u32(args[n_args + extra_args++].value, 0, 32, stacktop); - init_reg_param(&args[n_args + extra_args], "psp_ns", 32, PARAM_OUT); - buf_set_u32(args[n_args + extra_args++].value, 0, 32, stacktop); - init_reg_param(&args[n_args + extra_args], "msp", 32, PARAM_OUT); - buf_set_u32(args[n_args + extra_args++].value, 0, 32, stacktop); - init_reg_param(&args[n_args + extra_args], "psp", 32, PARAM_OUT); - buf_set_u32(args[n_args + extra_args++].value, 0, 32, stacktop); - init_reg_param(&args[n_args + extra_args], "sp", 32, PARAM_OUT); - buf_set_u32(args[n_args + extra_args++].value, 0, 32, stacktop); - /* Clear stack pointer limits, as they may be above the algorithm stack */ - init_reg_param(&args[n_args + extra_args], "msplim_s", 32, PARAM_OUT); - buf_set_u32(args[n_args + extra_args++].value, 0, 32, 0); - init_reg_param(&args[n_args + extra_args], "psplim_s", 32, PARAM_OUT); - buf_set_u32(args[n_args + extra_args++].value, 0, 32, 0); - init_reg_param(&args[n_args + extra_args], "msplim_ns", 32, PARAM_OUT); - buf_set_u32(args[n_args + extra_args++].value, 0, 32, 0); - init_reg_param(&args[n_args + extra_args], "psplim_ns", 32, PARAM_OUT); - buf_set_u32(args[n_args + extra_args++].value, 0, 32, 0); - - for (unsigned int i = 0; i < n_args + extra_args; ++i) - LOG_DEBUG("Set %s = 0x%" PRIx32, args[i].reg_name, buf_get_u32(args[i].value, 0, 32)); + const uint8_t *algo_code; + if (is_arm(target_to_arm(target))) { + if (target_to_arm(target)->arch == ARM_ARCH_V8M) { + LOG_DEBUG("Using algo: rp2xxx_rom_call_batch_algo_armv8m"); + algo_code = rp2xxx_rom_call_batch_algo_armv8m; + } else { + LOG_DEBUG("Using algo: rp2xxx_rom_call_batch_algo_armv6m"); + algo_code = rp2xxx_rom_call_batch_algo_armv6m; + } + } else { + LOG_DEBUG("Using algo: rp2xxx_rom_call_batch_algo_riscv"); + algo_code = rp2xxx_rom_call_batch_algo_riscv; + } - /* Actually call the function */ - alg_info.common_magic = ARMV7M_COMMON_MAGIC; - alg_info.core_mode = ARM_MODE_THREAD; - int err = target_run_algorithm( - target, - 0, NULL, /* No memory arguments */ - n_args + extra_args, args, /* User arguments + r7 + SPs */ - priv->jump_debug_trampoline, priv->jump_debug_trampoline_end, - 3000, /* 3s timeout */ - &alg_info + int err = target_write_buffer(target, + priv->ram_algo_space->address, + ROM_CALL_BATCH_ALGO_SIZE_BYTES, + algo_code ); - for (unsigned int i = 0; i < n_args + extra_args; ++i) - destroy_reg_param(&args[i]); - if (err != ERROR_OK) - LOG_ERROR("Failed to invoke ROM function @0x%" PRIx16 "\n", func_offset); - return err; + if (err != ERROR_OK) { + LOG_ERROR("Failed to write ROM batch algorithm to RAM code space\n"); + return err; + } + err = target_write_buffer(target, + priv->ram_algo_space->address + ROM_CALL_BATCH_ALGO_SIZE_BYTES, + n_calls * sizeof(rp2xxx_rom_call_batch_record_t), + (const uint8_t *)calls + ); + if (err != ERROR_OK) { + LOG_ERROR("Failed to write ROM batch records to RAM code space\n"); + return err; + } + err = target_write_u32(target, + priv->ram_algo_space->address + (batch_words - 1) * sizeof(uint32_t), + 0 + ); + if (err != ERROR_OK) { + LOG_ERROR("Failed to write null terminator for ROM batch records\n"); + return err; + } + + // Call into the ROM batch algorithm -- this will in turn call each ROM + // call specified by the batch records. + target_addr_t algo_start_addr = priv->ram_algo_space->address; + target_addr_t algo_end_addr = priv->ram_algo_space->address + rp2xxx_rom_call_batch_algo_bkpt_offset; + unsigned int algo_timeout_ms = 3000; + if (is_arm(target_to_arm(target))) { + struct armv7m_algorithm alg_info; + alg_info.common_magic = ARMV7M_COMMON_MAGIC; + alg_info.core_mode = ARM_MODE_THREAD; + err = target_run_algorithm(target, + 0, NULL, /* No memory arguments */ + 0, NULL, /* No register arguments */ + algo_start_addr, algo_end_addr, + algo_timeout_ms, + &alg_info + ); + } else { + // Presumed RISC-V -- there is no RISCV_COMMON_MAGIC on older OpenOCD + err = target_run_algorithm(target, + 0, NULL, /* No memory arguments */ + 0, NULL, /* No register arguments */ + algo_start_addr, algo_end_addr, + algo_timeout_ms, + NULL /* Currently no RISC-V-specific algorithm info */ + ); + } + 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 + recovery for the next attempt. */ + (void)rp2xxx_populate_rom_pointer_cache(target, priv); + return err; + } + return ERROR_OK; } -static int rp2350_init_core(struct target *target, struct rp2040_flash_bank *priv) +// Call a single ROM function, using the default algorithm stack. +static int rp2xxx_call_rom_func(struct target *target, struct rp2040_flash_bank *priv, + uint16_t func_offset, uint32_t argdata[], unsigned int n_args) { + assert(n_args <= 4); /* only allow register arguments -- capped at just 4 on Arm */ + if (!priv->stack) { LOG_ERROR("no stack for flash programming code"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } + target_addr_t stacktop = priv->stack->address + priv->stack->size; - struct armv7m_algorithm alg_info; + rp2xxx_rom_call_batch_record_t call = { + .pc = func_offset, + .sp = stacktop + }; + for (unsigned int i = 0; i < n_args; ++i) + call.args[i] = argdata[i]; - // copy rcp_init code onto stack, as we don't actually need any stack during the call - if (priv->stack->size < sizeof(rcp_init_code)) { - LOG_ERROR("Working area too small for rcp_init"); - return ERROR_BUF_TOO_SMALL; - } + return rp2xxx_call_rom_func_batch(target, priv, &call, 1); +} - // Attempt to reset ACCESSCTRL before running RCP init, in case Secure - // access to SRAM has been blocked. (Also ROM, QMI regs are needed later) +static int rp2350_init_accessctrl(struct target *target) +{ + // Attempt to reset ACCESSCTRL, in case Secure access to SRAM has been + // blocked, which will stop us from loading/running algorithms such as RCP + // init. (Also ROM, QMI regs are needed later) uint32_t accessctrl_lock_reg; if (target_read_u32(target, ACCESSCTRL_LOCK_OFFSET, &accessctrl_lock_reg) != ERROR_OK) { LOG_ERROR("Failed to read ACCESSCTRL lock register"); @@ -254,30 +567,59 @@ static int rp2350_init_core(struct target *target, struct rp2040_flash_bank *pri LOG_ERROR("ACCESSCTRL is locked, so can't reset permissions. Following steps might fail.\n"); } else { LOG_DEBUG("Reset ACCESSCTRL permissions via CFGRESET\n"); - target_write_u32(target, ACCESSCTRL_CFGRESET_OFFSET, ACCESSCTRL_WRITE_PASSWORD | 1u); + return target_write_u32(target, ACCESSCTRL_CFGRESET_OFFSET, ACCESSCTRL_WRITE_PASSWORD | 1u); + } + return ERROR_OK; +} + +static int rp2350_init_arm_core0(struct target *target, struct rp2040_flash_bank *priv) +{ + // Flash algorithms (and the RCP init stub called by this function) must + // run in the Secure state, so flip the state now before attempting to + // execute any code on the core. + uint32_t dscsr; + (void)target_read_u32(target, DCB_DSCSR, &dscsr); + LOG_DEBUG("DSCSR: %08x\n", dscsr); + if (!(dscsr & DSCSR_CDS)) { + LOG_DEBUG("Setting Current Domain Secure in DSCSR\n"); + (void)target_write_u32(target, DCB_DSCSR, (dscsr & ~DSCSR_CDSKEY) | DSCSR_CDS); + (void)target_read_u32(target, DCB_DSCSR, &dscsr); + LOG_DEBUG("DSCSR*: %08x\n", dscsr); + } + + if (!priv->stack) { + LOG_ERROR("No stack for flash programming code"); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } + + if (!priv->ram_algo_space || priv->ram_algo_space->size < sizeof(rcp_init_code)) { + LOG_ERROR("No algorithm space for rcp_init code"); + return ERROR_BUF_TOO_SMALL; } int err = target_write_memory(target, - priv->stack->address, + priv->ram_algo_space->address, 1, sizeof(rcp_init_code), - (const uint8_t *)rcp_init_code + rcp_init_code ); if (err != ERROR_OK) { LOG_ERROR("Failed to load rcp_init algorithm into RAM\n"); return ERROR_FAIL; } - LOG_DEBUG("Calling rcp_init core \"%s\" code at 0x%" PRIx16 "\n", target->cmd_name, (uint32_t)priv->stack->address); + LOG_DEBUG("Calling rcp_init on core \"%s\", code at 0x%" PRIx32 "\n", + target->cmd_name, (uint32_t)priv->ram_algo_space->address); /* Actually call the function */ + struct armv7m_algorithm alg_info; alg_info.common_magic = ARMV7M_COMMON_MAGIC; alg_info.core_mode = ARM_MODE_THREAD; err = target_run_algorithm(target, 0, NULL, /* No memory arguments */ 0, NULL, /* No register arguments */ - priv->stack->address, - priv->stack->address + rcp_init_code_bkpt_offset, + priv->ram_algo_space->address, + priv->ram_algo_space->address + rcp_init_code_bkpt_offset, 1000, /* 1s timeout */ &alg_info ); @@ -286,80 +628,75 @@ static int rp2350_init_core(struct target *target, struct rp2040_flash_bank *pri return err; } - uint32_t reset_args[1] = { - BOOTROM_STATE_RESET_CURRENT_CORE - }; - if (!priv->jump_bootrom_reset_state) { - LOG_WARNING("RP2350 flash: no bootrom_reset_method\n"); - } else { - err = rp2040_call_rom_func(target, priv, priv->jump_bootrom_reset_state, reset_args, ARRAY_SIZE(reset_args)); - if (err != ERROR_OK) { - LOG_ERROR("RP2040 flash: failed to call reset core state"); - return err; - } - } - return err; } -static int setup_for_rom_call(struct flash_bank *bank) +static int setup_for_raw_flash_cmd(struct flash_bank *bank) { struct rp2040_flash_bank *priv = bank->driver_priv; - struct target *target = bank->target; int err = ERROR_OK; + if (!priv->stack) { /* target_alloc_working_area always allocates multiples of 4 bytes, so no worry about alignment */ - const int STACK_SIZE = 256; - target_alloc_working_area(bank->target, STACK_SIZE, &priv->stack); + err = target_alloc_working_area(bank->target, RP2XXX_MAX_ALGO_STACK_USAGE, &priv->stack); if (err != ERROR_OK) { - LOG_ERROR("Could not allocate stack for flash programming code"); + LOG_ERROR("Could not allocate stack for flash programming code -- insufficient space"); return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } } - // Flash algorithms must run in Secure state - uint32_t dscsr; - (void)target_read_u32(target, DCB_DSCSR, &dscsr); - LOG_DEBUG("DSCSR: %08x\n", dscsr); - if (!(dscsr & DSCSR_CDS)) { - LOG_DEBUG("Setting Current Domain Secure in DSCSR\n"); - (void)target_write_u32(target, DCB_DSCSR, (dscsr & ~DSCSR_CDSKEY) | DSCSR_CDS); - (void)target_read_u32(target, DCB_DSCSR, &dscsr); - LOG_DEBUG("DSCSR*: %08x\n", dscsr); + if (!priv->ram_algo_space) { + err = target_alloc_working_area(bank->target, RP2XXX_MAX_RAM_ALGO_SIZE, &priv->ram_algo_space); + if (err != ERROR_OK) { + LOG_ERROR("Could not allocate RAM code space for ROM calls -- insufficient space"); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } } - // hacky RP2350 check - if (target_to_arm(target)->arch == ARM_ARCH_V8M) { - err = rp2350_init_core(target, priv); + // hacky RP2350 check -- either RISC-V or v8-M + if (is_arm(target_to_arm(target)) ? target_to_arm(target)->arch == ARM_ARCH_V8M : true) { + err = rp2350_init_accessctrl(target); if (err != ERROR_OK) { - LOG_ERROR("RP2350 flash: failed to init core"); + LOG_ERROR("Failed to init ACCESSCTRL before ROM call"); return err; } - } - return err; -} - -static int setup_for_raw_flash_cmd(struct flash_bank *bank) -{ - struct rp2040_flash_bank *priv = bank->driver_priv; - int err = setup_for_rom_call(bank); - err = rp2040_call_rom_func(bank->target, priv, priv->jump_connect_internal_flash, NULL, 0); - if (err != ERROR_OK) { - LOG_ERROR("RP2040 flash: failed to setup for rom call"); - return err; - } - - LOG_DEBUG("Connecting internal flash"); - err = rp2040_call_rom_func(bank->target, priv, priv->jump_connect_internal_flash, NULL, 0); - if (err != ERROR_OK) { - LOG_ERROR("RP2040 flash: failed to connect internal flash"); - return err; + if (is_arm(target_to_arm(target))) { + err = rp2350_init_arm_core0(target, priv); + if (err != ERROR_OK) { + LOG_ERROR("Failed to init Arm core 0 before ROM call"); + return err; + } + } + uint32_t reset_args[1] = { + BOOTROM_STATE_RESET_CURRENT_CORE + }; + if (!priv->jump_bootrom_reset_state) { + LOG_WARNING("RP2350 flash: no bootrom_reset_method\n"); + } else { + 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)); + if (err != ERROR_OK) { + LOG_ERROR("RP2350 flash: failed to call reset core state"); + return err; + } + } } - LOG_DEBUG("Kicking flash out of XIP mode"); - err = rp2040_call_rom_func(bank->target, priv, priv->jump_flash_exit_xip, NULL, 0); + LOG_DEBUG("Connecting flash IOs and issuing XIP exit sequence to flash"); + rp2xxx_rom_call_batch_record_t calls[2] = { + { + .pc = priv->jump_connect_internal_flash, + .sp = priv->stack->address + priv->stack->size + }, + { + .pc = priv->jump_flash_exit_xip, + .sp = priv->stack->address + priv->stack->size + } + }; + err = rp2xxx_call_rom_func_batch(bank->target, priv, calls, 2); if (err != ERROR_OK) { LOG_ERROR("RP2040 flash: failed to exit flash XIP mode"); return err; @@ -368,6 +705,25 @@ static int setup_for_raw_flash_cmd(struct flash_bank *bank) return ERROR_OK; } +static void cleanup_after_raw_flash_cmd(struct flash_bank *bank) +{ + /* OpenOCD is prone to trashing work-area allocations on target state + transitions, which leaves us with stale work area pointers in our + driver state. Best to clean up our allocations manually after + completing each flash call, so we know to make fresh ones next time. */ + LOG_DEBUG("Cleaning up after flash operations"); + struct rp2040_flash_bank *priv = bank->driver_priv; + struct target *target = bank->target; + if (priv->stack) { + target_free_working_area(target, priv->stack); + priv->stack = 0; + } + if (priv->ram_algo_space) { + target_free_working_area(target, priv->ram_algo_space); + priv->ram_algo_space = 0; + } +} + static int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { LOG_DEBUG("Writing %d bytes starting at 0x%" PRIx32, count, offset); @@ -378,13 +734,14 @@ static int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, ui int err = setup_for_raw_flash_cmd(bank); if (err != ERROR_OK) - return err; + goto cleanup_and_return; // Allocate as much memory as possible, rounded down to a whole number of flash pages const unsigned int chunk_size = target_get_working_area_avail(target) & ~0xffu; if (chunk_size == 0 || target_alloc_working_area(target, chunk_size, &bounce) != ERROR_OK) { LOG_ERROR("Could not allocate bounce buffer for flash programming. Can't continue"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + err = ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + goto cleanup_and_return; } LOG_DEBUG("Allocated flash bounce buffer @" TARGET_ADDR_FMT, bounce->address); @@ -402,7 +759,7 @@ static int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, ui bounce->address, /* data */ write_size /* count */ }; - err = rp2040_call_rom_func(target, priv, priv->jump_flash_range_program, args, ARRAY_SIZE(args)); + err = rp2xxx_call_rom_func(target, priv, priv->jump_flash_range_program, args, ARRAY_SIZE(args)); if (err != ERROR_OK) { LOG_ERROR("Failed to invoke flash programming code on target"); break; @@ -415,20 +772,43 @@ static int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, ui target_free_working_area(target, bounce); if (err != ERROR_OK) - return err; + goto cleanup_and_return; + + // Flash is successfully programmed. We can now do a bit of poking to make + // the new flash contents visible to us via memory-mapped (XIP) interface + // in the 0x1... memory region. + // + // Note on RP2350 it's not *required* to call flash_enter_cmd_xip, since + // the ROM leaves flash XIPable by default in between direct-mode + // accesses, but there's no harm in calling it anyway. - /* Flash is successfully programmed. We can now do a bit of poking to make the flash - contents visible to us via memory-mapped (XIP) interface in the 0x1... memory region */ LOG_DEBUG("Flushing flash cache after write behind"); - err = rp2040_call_rom_func(bank->target, priv, priv->jump_flush_cache, NULL, 0); + err = rp2xxx_call_rom_func(bank->target, priv, priv->jump_flush_cache, NULL, 0); + + rp2xxx_rom_call_batch_record_t finishing_calls[3] = { + { + .pc = priv->jump_flush_cache, + .sp = priv->stack->address + priv->stack->size + }, + { + .pc = priv->jump_enter_cmd_xip, + .sp = priv->stack->address + priv->stack->size + }, + { + .pc = priv->jump_flash_reset_address_trans, + .sp = priv->stack->address + priv->stack->size + } + }; + // Note the last function does not exist on older devices: + int num_finishing_calls = priv->jump_flash_reset_address_trans ? 3 : 2; + + err = rp2xxx_call_rom_func_batch(target, priv, finishing_calls, num_finishing_calls); if (err != ERROR_OK) { LOG_ERROR("RP2040 write: failed to flush flash cache"); - return err; + goto cleanup_and_return; } - LOG_DEBUG("Configuring SSI for execute-in-place"); - err = rp2040_call_rom_func(bank->target, priv, priv->jump_enter_cmd_xip, NULL, 0); - if (err != ERROR_OK) - LOG_ERROR("RP2040 write: failed to flush flash cache"); +cleanup_and_return: + cleanup_after_raw_flash_cmd(bank); return err; } @@ -441,7 +821,7 @@ static int rp2040_flash_erase(struct flash_bank *bank, unsigned int first, unsig int err = setup_for_raw_flash_cmd(bank); if (err != ERROR_OK) - return err; + goto cleanup_and_return; LOG_DEBUG("Remote call flash_range_erase"); @@ -452,18 +832,13 @@ static int rp2040_flash_erase(struct flash_bank *bank, unsigned int first, unsig 0xd8 /* block_cmd */ }; - /* - The RP2040 Boot ROM provides a _flash_range_erase() API call documented in Section 2.8.3.1.3: - https://datasheets.raspberrypi.org/rp2040/rp2040-datasheet.pdf - and the particular source code for said Boot ROM function can be found here: - https://github.com/raspberrypi/pico-bootrom/blob/master/bootrom/program_flash_generic.c - - In theory, the function algorithm provides for erasing both a smaller "sector" (4096 bytes) and - an optional larger "block" (size and command provided in args). OpenOCD's spi.c only uses "block" sizes. - */ - - err = rp2040_call_rom_func(bank->target, priv, priv->jump_flash_range_erase, args, ARRAY_SIZE(args)); + /* 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); return err; } @@ -475,63 +850,9 @@ static int rp2040_flash_probe(struct flash_bank *bank) struct rp2040_flash_bank *priv = bank->driver_priv; struct target *target = bank->target; - int err = rp2040_lookup_symbol(target, FUNC_DEBUG_TRAMPOLINE, &priv->jump_debug_trampoline); - if (err != ERROR_OK) { - LOG_ERROR("Debug trampoline not found in RP2040 ROM."); - return err; - } - priv->jump_debug_trampoline &= ~1u; /* mask off thumb bit */ - - err = rp2040_lookup_symbol(target, FUNC_DEBUG_TRAMPOLINE_END, &priv->jump_debug_trampoline_end); - if (err != ERROR_OK) { - LOG_ERROR("Debug trampoline end not found in RP2040 ROM."); - return err; - } - priv->jump_debug_trampoline_end &= ~1u; /* mask off thumb bit */ - - err = rp2040_lookup_symbol(target, FUNC_FLASH_EXIT_XIP, &priv->jump_flash_exit_xip); - if (err != ERROR_OK) { - LOG_ERROR("Function FUNC_FLASH_EXIT_XIP not found in RP2040 ROM."); - return err; - } - - err = rp2040_lookup_symbol(target, FUNC_CONNECT_INTERNAL_FLASH, &priv->jump_connect_internal_flash); - if (err != ERROR_OK) { - LOG_ERROR("Function FUNC_CONNECT_INTERNAL_FLASH not found in RP2040 ROM."); - return err; - } - - err = rp2040_lookup_symbol(target, FUNC_FLASH_RANGE_ERASE, &priv->jump_flash_range_erase); - if (err != ERROR_OK) { - LOG_ERROR("Function FUNC_FLASH_RANGE_ERASE not found in RP2040 ROM."); - return err; - } - LOG_WARNING("GOT FLASH ERASE AT %08x\n", (int)priv->jump_flash_range_erase); - - err = rp2040_lookup_symbol(target, FUNC_FLASH_RANGE_PROGRAM, &priv->jump_flash_range_program); - if (err != ERROR_OK) { - LOG_ERROR("Function FUNC_FLASH_RANGE_PROGRAM not found in RP2040 ROM."); - return err; - } - - err = rp2040_lookup_symbol(target, FUNC_FLASH_FLUSH_CACHE, &priv->jump_flush_cache); - if (err != ERROR_OK) { - LOG_ERROR("Function FUNC_FLASH_FLUSH_CACHE not found in RP2040 ROM."); - return err; - } - - err = rp2040_lookup_symbol(target, FUNC_FLASH_ENTER_CMD_XIP, &priv->jump_enter_cmd_xip); - if (err != ERROR_OK) { - LOG_ERROR("Function FUNC_FLASH_ENTER_CMD_XIP not found in RP2040 ROM."); + int err = rp2xxx_populate_rom_pointer_cache(target, priv); + if (err != ERROR_OK) return err; - } - - err = rp2040_lookup_symbol(target, FUNC_BOOTROM_STATE_RESET, &priv->jump_bootrom_reset_state); - if (err != ERROR_OK) { - priv->jump_bootrom_reset_state = 0; -// LOG_ERROR("Function FUNC_BOOTROM_STATE_RESET not found in RP2040 ROM."); -// return err; - } /* the Boot ROM flash_range_program() routine requires page alignment */ bank->write_start_alignment = 256; @@ -577,6 +898,7 @@ FLASH_BANK_COMMAND_HANDLER(rp2040_flash_bank_command) { struct rp2040_flash_bank *priv; priv = malloc(sizeof(struct rp2040_flash_bank)); + memset(priv, 0, sizeof(struct rp2040_flash_bank)); priv->probed = false; /* Set up driver_priv */ ----------------------------------------------------------------------- Summary of changes: src/flash/nor/rp2040.c | 873 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 596 insertions(+), 277 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2025-04-25 09:27:01
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via ea775d49fc71253a95986eb5b1254b4861bdeb97 (commit) from 2aa0592e0fd90218ff55446ebb3a9233017e59f7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ea775d49fc71253a95986eb5b1254b4861bdeb97 Author: graham sanderson <gra...@ra...> Date: Fri Nov 3 15:55:41 2023 -0500 flash/nor/rp2040: add RP2350 support TV: Extracted RP2040/2350 flash driver part only. Fixed style problems. Change-Id: I88a7d5aa0a239ae93d72bd5671686b19c6ca11ad Signed-off-by: Tomas Vanek <va...@fb...> Signed-off-by: graham sanderson <gra...@ra...> Reviewed-on: https://review.openocd.org/c/openocd/+/8440 Tested-by: jenkins diff --git a/src/flash/nor/rp2040.c b/src/flash/nor/rp2040.c index b2ebd9c49..c53b54754 100644 --- a/src/flash/nor/rp2040.c +++ b/src/flash/nor/rp2040.c @@ -9,14 +9,19 @@ #include <target/algorithm.h> #include <target/armv7m.h> #include "spi.h" +#include <target/cortex_m.h> /* NOTE THAT THIS CODE REQUIRES FLASH ROUTINES in BOOTROM WITH FUNCTION TABLE PTR AT 0x00000010 Your gdbinit should load the bootrom.elf if appropriate */ /* this is 'M' 'u', 1 (version) */ -#define BOOTROM_MAGIC 0x01754d +#define BOOTROM_RP2040_MAGIC 0x01754d +/* this is 'M' 'u', 2 (version) */ +#define BOOTROM_RP2350_MAGIC 0x02754d #define BOOTROM_MAGIC_ADDR 0x00000010 +#define RT_ARM_FUNC 0x1 + /* Call a ROM function via the debug trampoline Up to four arguments passed in r0...r3 as per ABI Function address is passed in r7 @@ -31,6 +36,48 @@ #define FUNC_FLASH_RANGE_PROGRAM MAKE_TAG('R', 'P') #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') + +// these form a bit set +#define BOOTROM_STATE_RESET_CURRENT_CORE 0x01 +#define BOOTROM_STATE_RESET_OTHER_CORE 0x02 +#define BOOTROM_STATE_RESET_GLOBAL_STATE 0x04 + +#define ACCESSCTRL_LOCK_OFFSET 0x40060000u +#define ACCESSCTRL_LOCK_DEBUG_BITS 0x00000008u +#define ACCESSCTRL_CFGRESET_OFFSET 0x40060008u +#define ACCESSCTRL_WRITE_PASSWORD 0xacce0000u + +// Calling bootrom functions requires the redundancy coprocessor (RCP) to be +// initialised. Usually this is done first thing by the bootrom, but the +// debugger may skip this, e.g. by resetting the cores and then running a +// NO_FLASH binary, or by reset-halting the cores before flash programming. +// +// The first case can be handled by a stub in the binary itself to initialise +// the RCP with dummy values if the bootrom has not already initialised it. +// (Note this case is only reachable via the debugger.) The second case +// requires the debugger itself to initialise the RCP, using this stub code: + +static const int rcp_init_code_bkpt_offset = 24; +static const uint16_t rcp_init_code[] = { + // Just enable the RCP which is fine if it already was (we assume no other + // co-processors are enabled at this point to save space) + 0x4806, // ldr r0, = PPB_BASE + M33_CPACR_OFFSET + 0xf45f, 0x4140, // movs r1, #M33_CPACR_CP7_BITS + 0x6001, // str r1, [r0] + // Only initialize canary seeds if they haven't been (as to do so twice is a fault) + 0xee30, 0xf710, // mrc p7, #1, r15, c0, c0, #0 + 0xd404, // bmi 1f + // Todo should we use something random here and pass it into the algorithm? + 0xec40, 0x0780, // mcrr p7, #8, r0, r0, c0 + 0xec40, 0x0781, // mcrr p7, #8, r0, r0, c1 + // Let other core know + 0xbf40, // sev + // 1: + 0xbe00, // bkpt (end of algorithm) + 0x0000, // pad + 0xed88, 0xe000 // PPB_BASE + M33_CPACR_OFFSET +}; struct rp2040_flash_bank { /* flag indicating successful flash probe */ @@ -46,33 +93,31 @@ struct rp2040_flash_bank { uint16_t jump_flash_range_program; uint16_t jump_flush_cache; uint16_t jump_enter_cmd_xip; - /* detected model of SPI flash */ - const struct flash_device *dev; + uint16_t jump_bootrom_reset_state; }; -/* guessed SPI flash description if autodetection disabled (same as win w25q16jv) */ -static const struct flash_device rp2040_default_spi_device = - FLASH_ID("autodetect disabled", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0, 0x100, 0x10000, 0); - static uint32_t rp2040_lookup_symbol(struct target *target, uint32_t tag, uint16_t *symbol) { - uint32_t magic; + uint32_t magic, magic_addr; + bool found_rp2040_magic, found_rp2350_magic; + magic_addr = BOOTROM_MAGIC_ADDR; int err = target_read_u32(target, BOOTROM_MAGIC_ADDR, &magic); if (err != ERROR_OK) return err; magic &= 0xffffff; /* ignore bootrom version */ - if (magic != BOOTROM_MAGIC) { - if (!((magic ^ BOOTROM_MAGIC)&0xffff)) - LOG_ERROR("Incorrect RP2040 BOOT ROM version"); - else - LOG_ERROR("RP2040 BOOT ROM not found"); + + found_rp2040_magic = magic == BOOTROM_RP2040_MAGIC; + found_rp2350_magic = magic == BOOTROM_RP2350_MAGIC; + + if (!(found_rp2040_magic || found_rp2350_magic)) { + LOG_ERROR("RP2040/RP2350 BOOT ROM not found"); return ERROR_FAIL; } /* dereference the table pointer */ uint16_t table_entry; - err = target_read_u16(target, BOOTROM_MAGIC_ADDR + 4, &table_entry); + err = target_read_u16(target, magic_addr + 4, &table_entry); if (err != ERROR_OK) return err; @@ -82,16 +127,29 @@ static uint32_t rp2040_lookup_symbol(struct target *target, uint32_t tag, uint16 if (err != ERROR_OK) return err; if (entry_tag == tag) { - /* 16 bit symbol is next */ - return target_read_u16(target, table_entry + 2, symbol); + if (found_rp2350_magic) { + uint16_t flags; + /* flags are next */ + err = target_read_u16(target, table_entry + 4, &flags); + if (err != ERROR_OK) + return err; + // + if (flags & RT_ARM_FUNC) { + /* 16 bit symbol */ + return target_read_u16(target, table_entry + 2, symbol); + } + } else { + /* 16 bit symbol is next */ + return target_read_u16(target, table_entry + 2, symbol); + } } - table_entry += 4; + table_entry += found_rp2350_magic ? 6 : 4; } while (entry_tag); return ERROR_FAIL; } static int rp2040_call_rom_func(struct target *target, struct rp2040_flash_bank *priv, - uint16_t func_offset, uint32_t argdata[], unsigned int n_args, unsigned int timeout_ms) + uint16_t func_offset, uint32_t argdata[], unsigned int n_args) { char *regnames[4] = { "r0", "r1", "r2", "r3" }; @@ -103,9 +161,10 @@ static int rp2040_call_rom_func(struct target *target, struct rp2040_flash_bank } target_addr_t stacktop = priv->stack->address + priv->stack->size; - LOG_TARGET_DEBUG(target, "Calling ROM func @0x%" PRIx16 " with %u arguments", func_offset, n_args); + LOG_DEBUG("Calling ROM func @0x%" PRIx16 " with %d arguments", func_offset, n_args); + LOG_DEBUG("Calling on core \"%s\"", target->cmd_name); - struct reg_param args[ARRAY_SIZE(regnames) + 2]; + struct reg_param args[ARRAY_SIZE(regnames) + 12]; struct armv7m_algorithm alg_info; for (unsigned int i = 0; i < n_args; ++i) { @@ -113,14 +172,36 @@ static int rp2040_call_rom_func(struct target *target, struct rp2040_flash_bank buf_set_u32(args[i].value, 0, 32, argdata[i]); } /* Pass function pointer in r7 */ - init_reg_param(&args[n_args], "r7", 32, PARAM_OUT); - buf_set_u32(args[n_args].value, 0, 32, func_offset); - /* Setup stack */ - init_reg_param(&args[n_args + 1], "sp", 32, PARAM_OUT); - buf_set_u32(args[n_args + 1].value, 0, 32, stacktop); - unsigned int n_reg_params = n_args + 2; /* User arguments + r7 + sp */ - - for (unsigned int i = 0; i < n_reg_params; ++i) + unsigned int extra_args = 0; + init_reg_param(&args[n_args + extra_args], "r7", 32, PARAM_OUT); + buf_set_u32(args[n_args + extra_args++].value, 0, 32, func_offset); + /* Set stack pointer, have seen the caching get confused by the aliases of sp so + take the shotgun approach*/ + init_reg_param(&args[n_args + extra_args], "msp_s", 32, PARAM_OUT); + buf_set_u32(args[n_args + extra_args++].value, 0, 32, stacktop); + init_reg_param(&args[n_args + extra_args], "msp_ns", 32, PARAM_OUT); + buf_set_u32(args[n_args + extra_args++].value, 0, 32, stacktop); + init_reg_param(&args[n_args + extra_args], "psp_s", 32, PARAM_OUT); + buf_set_u32(args[n_args + extra_args++].value, 0, 32, stacktop); + init_reg_param(&args[n_args + extra_args], "psp_ns", 32, PARAM_OUT); + buf_set_u32(args[n_args + extra_args++].value, 0, 32, stacktop); + init_reg_param(&args[n_args + extra_args], "msp", 32, PARAM_OUT); + buf_set_u32(args[n_args + extra_args++].value, 0, 32, stacktop); + init_reg_param(&args[n_args + extra_args], "psp", 32, PARAM_OUT); + buf_set_u32(args[n_args + extra_args++].value, 0, 32, stacktop); + init_reg_param(&args[n_args + extra_args], "sp", 32, PARAM_OUT); + buf_set_u32(args[n_args + extra_args++].value, 0, 32, stacktop); + /* Clear stack pointer limits, as they may be above the algorithm stack */ + init_reg_param(&args[n_args + extra_args], "msplim_s", 32, PARAM_OUT); + buf_set_u32(args[n_args + extra_args++].value, 0, 32, 0); + init_reg_param(&args[n_args + extra_args], "psplim_s", 32, PARAM_OUT); + buf_set_u32(args[n_args + extra_args++].value, 0, 32, 0); + init_reg_param(&args[n_args + extra_args], "msplim_ns", 32, PARAM_OUT); + buf_set_u32(args[n_args + extra_args++].value, 0, 32, 0); + init_reg_param(&args[n_args + extra_args], "psplim_ns", 32, PARAM_OUT); + buf_set_u32(args[n_args + extra_args++].value, 0, 32, 0); + + for (unsigned int i = 0; i < n_args + extra_args; ++i) LOG_DEBUG("Set %s = 0x%" PRIx32, args[i].reg_name, buf_get_u32(args[i].value, 0, 32)); /* Actually call the function */ @@ -129,82 +210,158 @@ static int rp2040_call_rom_func(struct target *target, struct rp2040_flash_bank int err = target_run_algorithm( target, 0, NULL, /* No memory arguments */ - n_reg_params, args, /* User arguments + r7 + sp */ + n_args + extra_args, args, /* User arguments + r7 + SPs */ priv->jump_debug_trampoline, priv->jump_debug_trampoline_end, - timeout_ms, + 3000, /* 3s timeout */ &alg_info ); - - for (unsigned int i = 0; i < n_reg_params; ++i) + for (unsigned int i = 0; i < n_args + extra_args; ++i) destroy_reg_param(&args[i]); - if (err != ERROR_OK) - LOG_ERROR("Failed to invoke ROM function @0x%" PRIx16, func_offset); - + LOG_ERROR("Failed to invoke ROM function @0x%" PRIx16 "\n", func_offset); return err; } -/* Finalize flash write/erase/read ID - * - flush cache - * - enters memory-mapped (XIP) mode to make flash data visible - * - deallocates target ROM func stack if previously allocated - */ -static int rp2040_finalize_stack_free(struct flash_bank *bank) +static int rp2350_init_core(struct target *target, struct rp2040_flash_bank *priv) { - struct rp2040_flash_bank *priv = bank->driver_priv; - struct target *target = bank->target; + if (!priv->stack) { + LOG_ERROR("no stack for flash programming code"); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } - /* Always flush before returning to execute-in-place, to invalidate stale - * cache contents. The flush call also restores regular hardware-controlled - * chip select following a rp2040_flash_exit_xip(). - */ - LOG_DEBUG("Flushing flash cache after write behind"); - int err = rp2040_call_rom_func(target, priv, priv->jump_flush_cache, NULL, 0, 1000); + struct armv7m_algorithm alg_info; + + // copy rcp_init code onto stack, as we don't actually need any stack during the call + if (priv->stack->size < sizeof(rcp_init_code)) { + LOG_ERROR("Working area too small for rcp_init"); + return ERROR_BUF_TOO_SMALL; + } + + // Attempt to reset ACCESSCTRL before running RCP init, in case Secure + // access to SRAM has been blocked. (Also ROM, QMI regs are needed later) + uint32_t accessctrl_lock_reg; + if (target_read_u32(target, ACCESSCTRL_LOCK_OFFSET, &accessctrl_lock_reg) != ERROR_OK) { + LOG_ERROR("Failed to read ACCESSCTRL lock register"); + // Failed to read an APB register which should always be readable from + // any security/privilege level. Something fundamental is wrong. E.g.: + // + // - The debugger is attempting to perform Secure bus accesses on a + // system where Secure debug has been disabled + // - clk_sys or busfabric clock are stopped (try doing a rescue reset) + return ERROR_FAIL; + } + if (accessctrl_lock_reg & ACCESSCTRL_LOCK_DEBUG_BITS) { + LOG_ERROR("ACCESSCTRL is locked, so can't reset permissions. Following steps might fail.\n"); + } else { + LOG_DEBUG("Reset ACCESSCTRL permissions via CFGRESET\n"); + target_write_u32(target, ACCESSCTRL_CFGRESET_OFFSET, ACCESSCTRL_WRITE_PASSWORD | 1u); + } + + int err = target_write_memory(target, + priv->stack->address, + 1, + sizeof(rcp_init_code), + (const uint8_t *)rcp_init_code + ); if (err != ERROR_OK) { - LOG_ERROR("Failed to flush flash cache"); - /* Intentionally continue after error and try to setup xip anyway */ + LOG_ERROR("Failed to load rcp_init algorithm into RAM\n"); + return ERROR_FAIL; } - LOG_DEBUG("Configuring SSI for execute-in-place"); - err = rp2040_call_rom_func(target, priv, priv->jump_enter_cmd_xip, NULL, 0, 1000); - if (err != ERROR_OK) - LOG_ERROR("Failed to set SSI to XIP mode"); + LOG_DEBUG("Calling rcp_init core \"%s\" code at 0x%" PRIx16 "\n", target->cmd_name, (uint32_t)priv->stack->address); + + /* Actually call the function */ + alg_info.common_magic = ARMV7M_COMMON_MAGIC; + alg_info.core_mode = ARM_MODE_THREAD; + err = target_run_algorithm(target, + 0, NULL, /* No memory arguments */ + 0, NULL, /* No register arguments */ + priv->stack->address, + priv->stack->address + rcp_init_code_bkpt_offset, + 1000, /* 1s timeout */ + &alg_info + ); + if (err != ERROR_OK) { + LOG_ERROR("Failed to invoke rcp_init\n"); + return err; + } + + uint32_t reset_args[1] = { + BOOTROM_STATE_RESET_CURRENT_CORE + }; + if (!priv->jump_bootrom_reset_state) { + LOG_WARNING("RP2350 flash: no bootrom_reset_method\n"); + } else { + err = rp2040_call_rom_func(target, priv, priv->jump_bootrom_reset_state, reset_args, ARRAY_SIZE(reset_args)); + if (err != ERROR_OK) { + LOG_ERROR("RP2040 flash: failed to call reset core state"); + return err; + } + } - target_free_working_area(target, priv->stack); - priv->stack = NULL; return err; } -/* Prepare flash write/erase/read ID - * - allocates a stack for target ROM func - * - switches the SPI interface from memory-mapped mode to direct command mode - * Always pair with a call of rp2040_finalize_stack_free() - * after flash operation finishes or fails. - */ -static int rp2040_stack_grab_and_prep(struct flash_bank *bank) +static int setup_for_rom_call(struct flash_bank *bank) { struct rp2040_flash_bank *priv = bank->driver_priv; + struct target *target = bank->target; - /* target_alloc_working_area always allocates multiples of 4 bytes, so no worry about alignment */ - const int STACK_SIZE = 256; - int err = target_alloc_working_area(target, STACK_SIZE, &priv->stack); + int err = ERROR_OK; + if (!priv->stack) { + /* target_alloc_working_area always allocates multiples of 4 bytes, so no worry about alignment */ + const int STACK_SIZE = 256; + target_alloc_working_area(bank->target, STACK_SIZE, &priv->stack); + if (err != ERROR_OK) { + LOG_ERROR("Could not allocate stack for flash programming code"); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } + } + + // Flash algorithms must run in Secure state + uint32_t dscsr; + (void)target_read_u32(target, DCB_DSCSR, &dscsr); + LOG_DEBUG("DSCSR: %08x\n", dscsr); + if (!(dscsr & DSCSR_CDS)) { + LOG_DEBUG("Setting Current Domain Secure in DSCSR\n"); + (void)target_write_u32(target, DCB_DSCSR, (dscsr & ~DSCSR_CDSKEY) | DSCSR_CDS); + (void)target_read_u32(target, DCB_DSCSR, &dscsr); + LOG_DEBUG("DSCSR*: %08x\n", dscsr); + } + + // hacky RP2350 check + if (target_to_arm(target)->arch == ARM_ARCH_V8M) { + err = rp2350_init_core(target, priv); + if (err != ERROR_OK) { + LOG_ERROR("RP2350 flash: failed to init core"); + return err; + } + } + return err; +} + +static int setup_for_raw_flash_cmd(struct flash_bank *bank) +{ + struct rp2040_flash_bank *priv = bank->driver_priv; + int err = setup_for_rom_call(bank); + err = rp2040_call_rom_func(bank->target, priv, priv->jump_connect_internal_flash, NULL, 0); if (err != ERROR_OK) { - LOG_ERROR("Could not allocate stack for flash programming code"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + LOG_ERROR("RP2040 flash: failed to setup for rom call"); + return err; } LOG_DEBUG("Connecting internal flash"); - err = rp2040_call_rom_func(target, priv, priv->jump_connect_internal_flash, NULL, 0, 1000); + err = rp2040_call_rom_func(bank->target, priv, priv->jump_connect_internal_flash, NULL, 0); if (err != ERROR_OK) { - LOG_ERROR("Failed to connect internal flash"); + LOG_ERROR("RP2040 flash: failed to connect internal flash"); return err; } LOG_DEBUG("Kicking flash out of XIP mode"); - err = rp2040_call_rom_func(target, priv, priv->jump_flash_exit_xip, NULL, 0, 1000); + err = rp2040_call_rom_func(bank->target, priv, priv->jump_flash_exit_xip, NULL, 0); if (err != ERROR_OK) { - LOG_ERROR("Failed to exit flash XIP mode"); + LOG_ERROR("RP2040 flash: failed to exit flash XIP mode"); return err; } @@ -217,27 +374,17 @@ static int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, ui struct rp2040_flash_bank *priv = bank->driver_priv; struct target *target = bank->target; + struct working_area *bounce; - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - - struct working_area *bounce = NULL; - - int err = rp2040_stack_grab_and_prep(bank); + int err = setup_for_raw_flash_cmd(bank); if (err != ERROR_OK) - goto cleanup; - - unsigned int avail_pages = target_get_working_area_avail(target) / priv->dev->pagesize; - /* We try to allocate working area rounded down to device page size, - * al least 1 page, at most the write data size - */ - unsigned int chunk_size = MIN(MAX(avail_pages, 1) * priv->dev->pagesize, count); - err = target_alloc_working_area(target, chunk_size, &bounce); - if (err != ERROR_OK) { + return err; + + // Allocate as much memory as possible, rounded down to a whole number of flash pages + const unsigned int chunk_size = target_get_working_area_avail(target) & ~0xffu; + if (chunk_size == 0 || target_alloc_working_area(target, chunk_size, &bounce) != ERROR_OK) { LOG_ERROR("Could not allocate bounce buffer for flash programming. Can't continue"); - goto cleanup; + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } LOG_DEBUG("Allocated flash bounce buffer @" TARGET_ADDR_FMT, bounce->address); @@ -255,8 +402,7 @@ static int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, ui bounce->address, /* data */ write_size /* count */ }; - err = rp2040_call_rom_func(target, priv, priv->jump_flash_range_program, - args, ARRAY_SIZE(args), 3000); + err = rp2040_call_rom_func(target, priv, priv->jump_flash_range_program, args, ARRAY_SIZE(args)); if (err != ERROR_OK) { LOG_ERROR("Failed to invoke flash programming code on target"); break; @@ -266,40 +412,44 @@ static int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, ui offset += write_size; count -= write_size; } - -cleanup: target_free_working_area(target, bounce); - rp2040_finalize_stack_free(bank); + if (err != ERROR_OK) + return err; + /* Flash is successfully programmed. We can now do a bit of poking to make the flash + contents visible to us via memory-mapped (XIP) interface in the 0x1... memory region */ + LOG_DEBUG("Flushing flash cache after write behind"); + err = rp2040_call_rom_func(bank->target, priv, priv->jump_flush_cache, NULL, 0); + if (err != ERROR_OK) { + LOG_ERROR("RP2040 write: failed to flush flash cache"); + return err; + } + LOG_DEBUG("Configuring SSI for execute-in-place"); + err = rp2040_call_rom_func(bank->target, priv, priv->jump_enter_cmd_xip, NULL, 0); + if (err != ERROR_OK) + LOG_ERROR("RP2040 write: failed to flush flash cache"); return err; } static int rp2040_flash_erase(struct flash_bank *bank, unsigned int first, unsigned int last) { struct rp2040_flash_bank *priv = bank->driver_priv; - struct target *target = bank->target; - - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - uint32_t start_addr = bank->sectors[first].offset; uint32_t length = bank->sectors[last].offset + bank->sectors[last].size - start_addr; LOG_DEBUG("RP2040 erase %d bytes starting at 0x%" PRIx32, length, start_addr); - int err = rp2040_stack_grab_and_prep(bank); + int err = setup_for_raw_flash_cmd(bank); if (err != ERROR_OK) - goto cleanup; + return err; LOG_DEBUG("Remote call flash_range_erase"); uint32_t args[4] = { bank->sectors[first].offset, /* addr */ bank->sectors[last].offset + bank->sectors[last].size - bank->sectors[first].offset, /* count */ - priv->dev->sectorsize, /* block_size */ - priv->dev->erase_cmd /* block_cmd */ + 65536, /* block_size */ + 0xd8 /* block_cmd */ }; /* @@ -309,15 +459,10 @@ static int rp2040_flash_erase(struct flash_bank *bank, unsigned int first, unsig https://github.com/raspberrypi/pico-bootrom/blob/master/bootrom/program_flash_generic.c In theory, the function algorithm provides for erasing both a smaller "sector" (4096 bytes) and - an optional larger "block" (size and command provided in args). + an optional larger "block" (size and command provided in args). OpenOCD's spi.c only uses "block" sizes. */ - unsigned int timeout_ms = 2000 * (last - first) + 1000; - err = rp2040_call_rom_func(target, priv, priv->jump_flash_range_erase, - args, ARRAY_SIZE(args), timeout_ms); - -cleanup: - rp2040_finalize_stack_free(bank); + err = rp2040_call_rom_func(bank->target, priv, priv->jump_flash_range_erase, args, ARRAY_SIZE(args)); return err; } @@ -325,67 +470,11 @@ cleanup: /* ----------------------------------------------------------------------------- Driver probing etc */ -static int rp2040_ssel_active(struct target *target, bool active) -{ - const target_addr_t qspi_ctrl_addr = 0x4001800c; - const uint32_t qspi_ctrl_outover_low = 2UL << 8; - const uint32_t qspi_ctrl_outover_high = 3UL << 8; - uint32_t state = (active) ? qspi_ctrl_outover_low : qspi_ctrl_outover_high; - uint32_t val; - - int err = target_read_u32(target, qspi_ctrl_addr, &val); - if (err != ERROR_OK) - return err; - - val = (val & ~qspi_ctrl_outover_high) | state; - - err = target_write_u32(target, qspi_ctrl_addr, val); - if (err != ERROR_OK) - return err; - - return ERROR_OK; -} - -static int rp2040_spi_read_flash_id(struct target *target, uint32_t *devid) -{ - uint32_t device_id = 0; - const target_addr_t ssi_dr0 = 0x18000060; - - int err = rp2040_ssel_active(target, true); - - /* write RDID request into SPI peripheral's FIFO */ - for (int count = 0; (count < 4) && (err == ERROR_OK); count++) - err = target_write_u32(target, ssi_dr0, SPIFLASH_READ_ID); - - /* by this time, there is a receive FIFO entry for every write */ - for (int count = 0; (count < 4) && (err == ERROR_OK); count++) { - uint32_t status; - err = target_read_u32(target, ssi_dr0, &status); - - device_id >>= 8; - device_id |= (status & 0xFF) << 24; - } - - if (err == ERROR_OK) - *devid = device_id >> 8; - - int err2 = rp2040_ssel_active(target, false); - if (err2 != ERROR_OK) - LOG_ERROR("SSEL inactive failed"); - - return err; -} - static int rp2040_flash_probe(struct flash_bank *bank) { struct rp2040_flash_bank *priv = bank->driver_priv; struct target *target = bank->target; - if (target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - int err = rp2040_lookup_symbol(target, FUNC_DEBUG_TRAMPOLINE, &priv->jump_debug_trampoline); if (err != ERROR_OK) { LOG_ERROR("Debug trampoline not found in RP2040 ROM."); @@ -417,6 +506,7 @@ static int rp2040_flash_probe(struct flash_bank *bank) LOG_ERROR("Function FUNC_FLASH_RANGE_ERASE not found in RP2040 ROM."); return err; } + LOG_WARNING("GOT FLASH ERASE AT %08x\n", (int)priv->jump_flash_range_erase); err = rp2040_lookup_symbol(target, FUNC_FLASH_RANGE_PROGRAM, &priv->jump_flash_range_program); if (err != ERROR_OK) { @@ -436,50 +526,25 @@ static int rp2040_flash_probe(struct flash_bank *bank) return err; } - if (bank->size) { - /* size overridden, suppress reading SPI flash ID */ - priv->dev = &rp2040_default_spi_device; - LOG_DEBUG("SPI flash autodetection disabled, using configured size"); - - } else { - /* zero bank size in cfg, read SPI flash ID and autodetect */ - err = rp2040_stack_grab_and_prep(bank); - - uint32_t device_id = 0; - if (err == ERROR_OK) - err = rp2040_spi_read_flash_id(target, &device_id); - - rp2040_finalize_stack_free(bank); - - if (err != ERROR_OK) - return err; - - /* search for a SPI flash Device ID match */ - priv->dev = NULL; - for (const struct flash_device *p = flash_devices; p->name ; p++) - if (p->device_id == device_id) { - priv->dev = p; - break; - } - - if (!priv->dev) { - LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32 ")", device_id); - return ERROR_FAIL; - } - LOG_INFO("Found flash device '%s' (ID 0x%08" PRIx32 ")", - priv->dev->name, priv->dev->device_id); - - bank->size = priv->dev->size_in_bytes; + err = rp2040_lookup_symbol(target, FUNC_BOOTROM_STATE_RESET, &priv->jump_bootrom_reset_state); + if (err != ERROR_OK) { + priv->jump_bootrom_reset_state = 0; +// LOG_ERROR("Function FUNC_BOOTROM_STATE_RESET not found in RP2040 ROM."); +// return err; } /* the Boot ROM flash_range_program() routine requires page alignment */ - bank->write_start_alignment = priv->dev->pagesize; - bank->write_end_alignment = priv->dev->pagesize; + bank->write_start_alignment = 256; + bank->write_end_alignment = 256; + + // Max size -- up to two devices (two chip selects) in adjacent 24-bit address windows + bank->size = 32 * 1024 * 1024; + + bank->num_sectors = bank->size / 4096; - bank->num_sectors = bank->size / priv->dev->sectorsize; - LOG_INFO("RP2040 B0 Flash Probe: %" PRIu32 " bytes @" TARGET_ADDR_FMT ", in %u sectors\n", + LOG_INFO("RP2040 Flash Probe: %d bytes @" TARGET_ADDR_FMT ", in %d sectors\n", bank->size, bank->base, bank->num_sectors); - bank->sectors = alloc_block_array(0, priv->dev->sectorsize, bank->num_sectors); + bank->sectors = alloc_block_array(0, 4096, bank->num_sectors); if (!bank->sectors) return ERROR_FAIL; ----------------------------------------------------------------------- Summary of changes: src/flash/nor/rp2040.c | 483 ++++++++++++++++++++++++++++--------------------- 1 file changed, 274 insertions(+), 209 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2025-04-19 09:25:57
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 2aa0592e0fd90218ff55446ebb3a9233017e59f7 (commit) from 498e5590297e11a9c952d4210c6236fe8105241f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2aa0592e0fd90218ff55446ebb3a9233017e59f7 Author: Antonio Borneo <bor...@gm...> Date: Sun Apr 6 14:59:50 2025 +0200 flash: stellaris: fix deprecated command The driver directly runs a TCL command that has been renamed with commit 4d99e77419e3 ("jtag/hla: Restructure commands"), while the original name has been deprecated. Update the TCL command to the new syntax. Change-Id: I2fc9ef9a209bae1d78951e253d54164b2ac00cdd Signed-off-by: Antonio Borneo <bor...@gm...> Fixes: 4d99e77419e3 ("jtag/hla: Restructure commands") Reviewed-on: https://review.openocd.org/c/openocd/+/8832 Reviewed-by: zapb <de...@za...> Tested-by: jenkins diff --git a/src/flash/nor/stellaris.c b/src/flash/nor/stellaris.c index 1f53b2f35..f7dcc6f0e 100644 --- a/src/flash/nor/stellaris.c +++ b/src/flash/nor/stellaris.c @@ -1342,7 +1342,7 @@ COMMAND_HANDLER(stellaris_handle_recover_command) * cycle to recover. */ - Jim_Eval_Named(CMD_CTX->interp, "catch { hla_command \"debug unlock\" }", NULL, 0); + Jim_Eval_Named(CMD_CTX->interp, "catch { hla command \"debug unlock\" }", NULL, 0); if (!strcmp(Jim_GetString(Jim_GetResult(CMD_CTX->interp), NULL), "0")) { retval = ERROR_OK; goto user_action; ----------------------------------------------------------------------- Summary of changes: src/flash/nor/stellaris.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2025-04-19 09:25:34
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 498e5590297e11a9c952d4210c6236fe8105241f (commit) from 797dc7aba74152115898084dd00a50757b20c985 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 498e5590297e11a9c952d4210c6236fe8105241f Author: Junhui Liu <junhui.liu@pigmoral.tech> Date: Wed Mar 26 23:05:39 2025 +0800 tcl/target: Add RCPU support for Spacemit K1 Add support for the Real-Time CPU (RCPU) of K1, which is a 32-bit RISC-V N308 High-Efficiency Processor Core designed by Nuclei System Technology Co. Ltd. The JTAG interface can be configured to connect to either X60s or RCPU processors. To enable JTAG for RCPU, set TARGET to "rcpu". For example: openocd -c "set TARGET rcpu" -f interface/cmsis-dap.cfg \ -f target/spacemit-k1.cfg Change-Id: I9cd62fac332137afac17efa52702818de8f0b6f5 Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech> Reviewed-on: https://review.openocd.org/c/openocd/+/8821 Reviewed-by: liangzhen <zhe...@sp...> Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/tcl/target/spacemit-k1.cfg b/tcl/target/spacemit-k1.cfg index ef5d7833d..e57d1adbc 100644 --- a/tcl/target/spacemit-k1.cfg +++ b/tcl/target/spacemit-k1.cfg @@ -10,6 +10,21 @@ transport select jtag adapter speed 2000 +# Set TARGET to "rcpu" to enable JTAG for RCPU +if { [info exists TARGET] } { + set _TARGET $TARGET +} else { + set _TARGET x60 +} + +if { $_TARGET == "rcpu" } { + set CPUTAPID 0x10308A6D + set DRVAL 0xe +} else { + set CPUTAPID 0x10000E21 + set DRVAL 0xa +} + if { [info exists CHIPNAME] } { set _CHIPNAME $CHIPNAME } else { @@ -23,44 +38,49 @@ if { [info exists CORES] } { } if { [info exists SECJTAG] } { - jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10000E21 + jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $CPUTAPID } else { jtag newtap pre unknown -irlen 1 -expected-id 0x00000000 -disable jtag configure pre.unknown -event tap-enable "" - jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10000E21 -disable + jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $CPUTAPID -disable jtag configure $_CHIPNAME.cpu -event tap-enable "" jtag newtap post unknown -irlen 9 -expected-id 0x08501C0D -ignore-version jtag configure post.unknown -event setup { - global _CHIPNAME + global _CHIPNAME DRVAL irscan post.unknown 0x98 - drscan post.unknown 16 0xa + drscan post.unknown 16 $DRVAL jtag tapenable pre.unknown jtag tapenable $_CHIPNAME.cpu } } -set _TARGETNAME $_CHIPNAME.cpu -set DBGBASE {0x0 0x400} -set _smp_command "target smp" +set _TARGETNAME $_CHIPNAME.cpu_$_TARGET + +if { $_TARGET == "rcpu" } { + target create $_TARGETNAME.0 riscv -chain-position $_CHIPNAME.cpu +} else { + set DBGBASE {0x0 0x400} + set _smp_command "target smp" -for { set _core 0 } { $_core < $_cores } { incr _core } { - target create $_TARGETNAME.$_core riscv -chain-position $_TARGETNAME \ - -coreid [expr {$_core % 4}] -dbgbase [lindex $DBGBASE [expr {$_core / 4}]] + for { set _core 0 } { $_core < $_cores } { incr _core } { + target create $_TARGETNAME.$_core riscv -chain-position $_CHIPNAME.cpu \ + -coreid [expr {$_core % 4}] -dbgbase [lindex $DBGBASE [expr {$_core / 4}]] - if { [expr {$_core % 4}] == 0 } { - $_TARGETNAME.$_core configure -rtos hwthread + if { [expr {$_core % 4}] == 0 } { + $_TARGETNAME.$_core configure -rtos hwthread + } + + set _smp_command "$_smp_command $_TARGETNAME.$_core" } - set _smp_command "$_smp_command $_TARGETNAME.$_core" + eval $_smp_command } -eval $_smp_command - set _SPEED 8000 $_TARGETNAME.0 configure -event examine-start { ----------------------------------------------------------------------- Summary of changes: tcl/target/spacemit-k1.cfg | 50 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 15 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2025-04-19 09:25:01
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 797dc7aba74152115898084dd00a50757b20c985 (commit) from 9a09d38478e2fbe7a9482af11b0fafb04689355d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 797dc7aba74152115898084dd00a50757b20c985 Author: HAOUES Ahmed <ahm...@st...> Date: Tue Mar 25 14:29:30 2025 +0100 flash/stm32l4x: support STM32C05/09x devices STM32C05/09x devices are similar to STM32C03/07x devices Change-Id: I77c803356c32f06699c14622828585609c90a136 Signed-off-by: HAOUES Ahmed <ahm...@st...> Reviewed-on: https://review.openocd.org/c/openocd/+/8618 Reviewed-by: Tomas Vanek <va...@fb...> Reviewed-by: Antonio Borneo <bor...@gm...> Tested-by: jenkins diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c index fa57db8bb..f16333201 100644 --- a/src/flash/nor/stm32l4x.c +++ b/src/flash/nor/stm32l4x.c @@ -303,10 +303,18 @@ static const struct stm32l4_rev stm32c03xx_revs[] = { { 0x1000, "A" }, { 0x1001, "Z" }, }; +static const struct stm32l4_rev stm32c05xx_revs[] = { + { 0x1000, "A" }, +}; + static const struct stm32l4_rev stm32c071xx_revs[] = { { 0x1001, "Z" }, }; +static const struct stm32l4_rev stm32c09xx_revs[] = { + { 0x1000, "A" }, +}; + static const struct stm32l4_rev stm32g05_g06xx_revs[] = { { 0x1000, "A" }, }; @@ -450,6 +458,18 @@ static const struct stm32l4_part_info stm32l4_parts[] = { .otp_base = 0x1FFF7000, .otp_size = 1024, }, + { + .id = DEVID_STM32C05XX, + .revs = stm32c05xx_revs, + .num_revs = ARRAY_SIZE(stm32c05xx_revs), + .device_str = "STM32C05xx", + .max_flash_size_kb = 64, + .flags = F_NONE, + .flash_regs_base = 0x40022000, + .fsize_addr = 0x1FFF75A0, + .otp_base = 0x1FFF7000, + .otp_size = 1024, + }, { .id = DEVID_STM32C071XX, .revs = stm32c071xx_revs, @@ -462,6 +482,18 @@ static const struct stm32l4_part_info stm32l4_parts[] = { .otp_base = 0x1FFF7000, .otp_size = 1024, }, + { + .id = DEVID_STM32C09XX, + .revs = stm32c09xx_revs, + .num_revs = ARRAY_SIZE(stm32c09xx_revs), + .device_str = "STM32C09xx", + .max_flash_size_kb = 256, + .flags = F_NONE, + .flash_regs_base = 0x40022000, + .fsize_addr = 0x1FFF75A0, + .otp_base = 0x1FFF7000, + .otp_size = 1024, + }, { .id = DEVID_STM32U53_U54XX, .revs = stm32u53_u54xx_revs, @@ -2021,7 +2053,9 @@ static int stm32l4_probe(struct flash_bank *bank) case DEVID_STM32L43_L44XX: case DEVID_STM32C01XX: case DEVID_STM32C03XX: + case DEVID_STM32C05XX: case DEVID_STM32C071XX: + case DEVID_STM32C09XX: case DEVID_STM32G05_G06XX: case DEVID_STM32G07_G08XX: case DEVID_STM32U031XX: diff --git a/src/flash/nor/stm32l4x.h b/src/flash/nor/stm32l4x.h index 3199d4f6d..07b3615a2 100644 --- a/src/flash/nor/stm32l4x.h +++ b/src/flash/nor/stm32l4x.h @@ -88,6 +88,8 @@ #define DEVID_STM32L47_L48XX 0x415 #define DEVID_STM32L43_L44XX 0x435 #define DEVID_STM32C01XX 0x443 +#define DEVID_STM32C05XX 0x44C +#define DEVID_STM32C09XX 0x44D #define DEVID_STM32C03XX 0x453 #define DEVID_STM32U53_U54XX 0x455 #define DEVID_STM32G05_G06XX 0x456 ----------------------------------------------------------------------- Summary of changes: src/flash/nor/stm32l4x.c | 34 ++++++++++++++++++++++++++++++++++ src/flash/nor/stm32l4x.h | 2 ++ 2 files changed, 36 insertions(+) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2025-04-19 09:24:26
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 9a09d38478e2fbe7a9482af11b0fafb04689355d (commit) from 61890e3dc3201ce38e5af7f6b561389a123448e0 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 9a09d38478e2fbe7a9482af11b0fafb04689355d Author: Antonio Borneo <bor...@gm...> Date: Sun Apr 6 14:10:28 2025 +0200 target: drop unused parameter to target_create() The parameter Jim_Interp to the target API target_create() is not used by any target. Drop it. Change-Id: I67c492078a6c808db974505f9e297c45165f64d0 Signed-off-by: Antonio Borneo <bor...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/8831 Tested-by: jenkins Reviewed-by: Tomas Vanek <va...@fb...> diff --git a/src/target/aarch64.c b/src/target/aarch64.c index ce7808e3a..101cb1440 100644 --- a/src/target/aarch64.c +++ b/src/target/aarch64.c @@ -2814,7 +2814,7 @@ static int aarch64_init_arch_info(struct target *target, return ERROR_OK; } -static int armv8r_target_create(struct target *target, Jim_Interp *interp) +static int armv8r_target_create(struct target *target) { struct aarch64_private_config *pc = target->private_config; struct aarch64_common *aarch64; @@ -2833,7 +2833,7 @@ static int armv8r_target_create(struct target *target, Jim_Interp *interp) return aarch64_init_arch_info(target, aarch64, pc->adiv5_config.dap); } -static int aarch64_target_create(struct target *target, Jim_Interp *interp) +static int aarch64_target_create(struct target *target) { struct aarch64_private_config *pc = target->private_config; struct aarch64_common *aarch64; diff --git a/src/target/arc.c b/src/target/arc.c index 8757cafed..f2482c25e 100644 --- a/src/target/arc.c +++ b/src/target/arc.c @@ -1424,7 +1424,7 @@ static void arc_deinit_target(struct target *target) } -static int arc_target_create(struct target *target, Jim_Interp *interp) +static int arc_target_create(struct target *target) { struct arc_common *arc = calloc(1, sizeof(*arc)); diff --git a/src/target/arm11.c b/src/target/arm11.c index 756b36b95..583830f94 100644 --- a/src/target/arm11.c +++ b/src/target/arm11.c @@ -1079,7 +1079,7 @@ static int arm11_remove_breakpoint(struct target *target, return ERROR_OK; } -static int arm11_target_create(struct target *target, Jim_Interp *interp) +static int arm11_target_create(struct target *target) { struct arm11_common *arm11; diff --git a/src/target/arm720t.c b/src/target/arm720t.c index beab632c2..d1433dde7 100644 --- a/src/target/arm720t.c +++ b/src/target/arm720t.c @@ -412,7 +412,7 @@ static int arm720t_init_arch_info(struct target *target, return ERROR_OK; } -static int arm720t_target_create(struct target *target, Jim_Interp *interp) +static int arm720t_target_create(struct target *target) { struct arm720t_common *arm720t = calloc(1, sizeof(*arm720t)); diff --git a/src/target/arm7tdmi.c b/src/target/arm7tdmi.c index 393d3b46a..2f59254af 100644 --- a/src/target/arm7tdmi.c +++ b/src/target/arm7tdmi.c @@ -669,7 +669,7 @@ int arm7tdmi_init_arch_info(struct target *target, return ERROR_OK; } -static int arm7tdmi_target_create(struct target *target, Jim_Interp *interp) +static int arm7tdmi_target_create(struct target *target) { struct arm7_9_common *arm7_9; diff --git a/src/target/arm920t.c b/src/target/arm920t.c index 53b4d9d15..95cfd7ceb 100644 --- a/src/target/arm920t.c +++ b/src/target/arm920t.c @@ -833,7 +833,7 @@ static int arm920t_init_arch_info(struct target *target, return ERROR_OK; } -static int arm920t_target_create(struct target *target, Jim_Interp *interp) +static int arm920t_target_create(struct target *target) { struct arm920t_common *arm920t; diff --git a/src/target/arm926ejs.c b/src/target/arm926ejs.c index add90c997..053110656 100644 --- a/src/target/arm926ejs.c +++ b/src/target/arm926ejs.c @@ -702,7 +702,7 @@ int arm926ejs_init_arch_info(struct target *target, struct arm926ejs_common *arm return ERROR_OK; } -static int arm926ejs_target_create(struct target *target, Jim_Interp *interp) +static int arm926ejs_target_create(struct target *target) { struct arm926ejs_common *arm926ejs = calloc(1, sizeof(struct arm926ejs_common)); diff --git a/src/target/arm946e.c b/src/target/arm946e.c index 03f7e443f..828e70f4b 100644 --- a/src/target/arm946e.c +++ b/src/target/arm946e.c @@ -79,7 +79,7 @@ static int arm946e_init_arch_info(struct target *target, return ERROR_OK; } -static int arm946e_target_create(struct target *target, Jim_Interp *interp) +static int arm946e_target_create(struct target *target) { struct arm946e_common *arm946e = calloc(1, sizeof(struct arm946e_common)); diff --git a/src/target/arm966e.c b/src/target/arm966e.c index 8598d29d9..b6bcc8ba9 100644 --- a/src/target/arm966e.c +++ b/src/target/arm966e.c @@ -38,7 +38,7 @@ int arm966e_init_arch_info(struct target *target, struct arm966e_common *arm966e return ERROR_OK; } -static int arm966e_target_create(struct target *target, Jim_Interp *interp) +static int arm966e_target_create(struct target *target) { struct arm966e_common *arm966e = calloc(1, sizeof(struct arm966e_common)); diff --git a/src/target/arm9tdmi.c b/src/target/arm9tdmi.c index 7e31306b6..8ab12de32 100644 --- a/src/target/arm9tdmi.c +++ b/src/target/arm9tdmi.c @@ -765,7 +765,7 @@ int arm9tdmi_init_arch_info(struct target *target, return ERROR_OK; } -static int arm9tdmi_target_create(struct target *target, Jim_Interp *interp) +static int arm9tdmi_target_create(struct target *target) { struct arm7_9_common *arm7_9 = calloc(1, sizeof(struct arm7_9_common)); diff --git a/src/target/avr32_ap7k.c b/src/target/avr32_ap7k.c index 1b051dc01..94962c205 100644 --- a/src/target/avr32_ap7k.c +++ b/src/target/avr32_ap7k.c @@ -510,7 +510,7 @@ static int avr32_ap7k_init_target(struct command_context *cmd_ctx, return ERROR_OK; } -static int avr32_ap7k_target_create(struct target *target, Jim_Interp *interp) +static int avr32_ap7k_target_create(struct target *target) { struct avr32_ap7k_common *ap7k = calloc(1, sizeof(struct avr32_ap7k_common)); diff --git a/src/target/avrt.c b/src/target/avrt.c index 3afe32015..e25718bcc 100644 --- a/src/target/avrt.c +++ b/src/target/avrt.c @@ -16,7 +16,7 @@ #define AVR_JTAG_INS_LEN 4 /* forward declarations */ -static int avr_target_create(struct target *target, Jim_Interp *interp); +static int avr_target_create(struct target *target); static int avr_init_target(struct command_context *cmd_ctx, struct target *target); static int avr_arch_state(struct target *target); @@ -68,7 +68,7 @@ struct target_type avr_target = { .init_target = avr_init_target, }; -static int avr_target_create(struct target *target, Jim_Interp *interp) +static int avr_target_create(struct target *target) { struct avr_common *avr = calloc(1, sizeof(struct avr_common)); diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index 9c6064558..ee27e1b21 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -3126,7 +3126,7 @@ static int cortex_a_init_arch_info(struct target *target, return ERROR_OK; } -static int cortex_a_target_create(struct target *target, Jim_Interp *interp) +static int cortex_a_target_create(struct target *target) { struct cortex_a_common *cortex_a; struct adiv5_private_config *pc; @@ -3148,7 +3148,7 @@ static int cortex_a_target_create(struct target *target, Jim_Interp *interp) return cortex_a_init_arch_info(target, cortex_a, pc->dap); } -static int cortex_r4_target_create(struct target *target, Jim_Interp *interp) +static int cortex_r4_target_create(struct target *target) { struct cortex_a_common *cortex_a; struct adiv5_private_config *pc; diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c index e17f23c1d..ba9d83d79 100644 --- a/src/target/cortex_m.c +++ b/src/target/cortex_m.c @@ -2916,7 +2916,7 @@ static int cortex_m_init_arch_info(struct target *target, return ERROR_OK; } -static int cortex_m_target_create(struct target *target, Jim_Interp *interp) +static int cortex_m_target_create(struct target *target) { struct adiv5_private_config *pc; diff --git a/src/target/dsp563xx.c b/src/target/dsp563xx.c index 9b6f4756c..dc85a2180 100644 --- a/src/target/dsp563xx.c +++ b/src/target/dsp563xx.c @@ -880,7 +880,7 @@ static void dsp563xx_invalidate_x_context(struct target *target, } } -static int dsp563xx_target_create(struct target *target, Jim_Interp *interp) +static int dsp563xx_target_create(struct target *target) { struct dsp563xx_common *dsp563xx = calloc(1, sizeof(struct dsp563xx_common)); diff --git a/src/target/dsp5680xx.c b/src/target/dsp5680xx.c index 3f9a6742c..65efbae32 100644 --- a/src/target/dsp5680xx.c +++ b/src/target/dsp5680xx.c @@ -855,7 +855,7 @@ static int eonce_pc_store(struct target *target) return ERROR_OK; } -static int dsp5680xx_target_create(struct target *target, Jim_Interp *interp) +static int dsp5680xx_target_create(struct target *target) { struct dsp5680xx_common *dsp5680xx = calloc(1, sizeof(struct dsp5680xx_common)); diff --git a/src/target/esirisc.c b/src/target/esirisc.c index da40928da..fac5dc72e 100644 --- a/src/target/esirisc.c +++ b/src/target/esirisc.c @@ -1575,7 +1575,7 @@ static int esirisc_identify(struct target *target) return ERROR_OK; } -static int esirisc_target_create(struct target *target, Jim_Interp *interp) +static int esirisc_target_create(struct target *target) { struct jtag_tap *tap = target->tap; struct esirisc_common *esirisc; diff --git a/src/target/espressif/esp32.c b/src/target/espressif/esp32.c index 4deb5e070..399ba8e7c 100644 --- a/src/target/espressif/esp32.c +++ b/src/target/espressif/esp32.c @@ -326,7 +326,7 @@ static const struct esp_semihost_ops esp32_semihost_ops = { .prepare = esp32_disable_wdts }; -static int esp32_target_create(struct target *target, Jim_Interp *interp) +static int esp32_target_create(struct target *target) { struct xtensa_debug_module_config esp32_dm_cfg = { .dbg_ops = &esp32_dbg_ops, diff --git a/src/target/espressif/esp32s2.c b/src/target/espressif/esp32s2.c index 4f3914f66..b86e43e62 100644 --- a/src/target/espressif/esp32s2.c +++ b/src/target/espressif/esp32s2.c @@ -445,7 +445,7 @@ static const struct esp_semihost_ops esp32s2_semihost_ops = { .prepare = esp32s2_disable_wdts }; -static int esp32s2_target_create(struct target *target, Jim_Interp *interp) +static int esp32s2_target_create(struct target *target) { struct xtensa_debug_module_config esp32s2_dm_cfg = { .dbg_ops = &esp32s2_dbg_ops, diff --git a/src/target/espressif/esp32s3.c b/src/target/espressif/esp32s3.c index 7507c11c2..82413f77f 100644 --- a/src/target/espressif/esp32s3.c +++ b/src/target/espressif/esp32s3.c @@ -320,7 +320,7 @@ static const struct esp_semihost_ops esp32s3_semihost_ops = { .prepare = esp32s3_disable_wdts }; -static int esp32s3_target_create(struct target *target, Jim_Interp *interp) +static int esp32s3_target_create(struct target *target) { struct xtensa_debug_module_config esp32s3_dm_cfg = { .dbg_ops = &esp32s3_dbg_ops, diff --git a/src/target/fa526.c b/src/target/fa526.c index 38b7ab2e9..d832d3e7d 100644 --- a/src/target/fa526.c +++ b/src/target/fa526.c @@ -329,7 +329,7 @@ static int fa526_init_arch_info(struct target *target, return ERROR_OK; } -static int fa526_target_create(struct target *target, Jim_Interp *interp) +static int fa526_target_create(struct target *target) { struct arm920t_common *arm920t = calloc(1, sizeof(struct arm920t_common)); diff --git a/src/target/feroceon.c b/src/target/feroceon.c index 840ca1b62..cf2c838b7 100644 --- a/src/target/feroceon.c +++ b/src/target/feroceon.c @@ -622,7 +622,7 @@ static void feroceon_common_setup(struct target *target) arm7_9->wp1_used_default = -1; } -static int feroceon_target_create(struct target *target, Jim_Interp *interp) +static int feroceon_target_create(struct target *target) { struct arm926ejs_common *arm926ejs = calloc(1, sizeof(struct arm926ejs_common)); @@ -640,7 +640,7 @@ static int feroceon_target_create(struct target *target, Jim_Interp *interp) return ERROR_OK; } -static int dragonite_target_create(struct target *target, Jim_Interp *interp) +static int dragonite_target_create(struct target *target) { struct arm966e_common *arm966e = calloc(1, sizeof(struct arm966e_common)); diff --git a/src/target/hla_target.c b/src/target/hla_target.c index ef05df202..983cd8739 100644 --- a/src/target/hla_target.c +++ b/src/target/hla_target.c @@ -187,8 +187,7 @@ static int adapter_init_target(struct command_context *cmd_ctx, return ERROR_OK; } -static int adapter_target_create(struct target *target, - Jim_Interp *interp) +static int adapter_target_create(struct target *target) { LOG_DEBUG("%s", __func__); struct adiv5_private_config *pc = target->private_config; diff --git a/src/target/ls1_sap.c b/src/target/ls1_sap.c index 692f4cc9e..49335a8b9 100644 --- a/src/target/ls1_sap.c +++ b/src/target/ls1_sap.c @@ -17,7 +17,7 @@ struct ls1_sap { struct jtag_tap *tap; }; -static int ls1_sap_target_create(struct target *target, Jim_Interp *interp) +static int ls1_sap_target_create(struct target *target) { struct ls1_sap *ls1_sap = calloc(1, sizeof(struct ls1_sap)); diff --git a/src/target/mem_ap.c b/src/target/mem_ap.c index fdc52c307..c5618c9cc 100644 --- a/src/target/mem_ap.c +++ b/src/target/mem_ap.c @@ -24,7 +24,7 @@ struct mem_ap { uint64_t ap_num; }; -static int mem_ap_target_create(struct target *target, Jim_Interp *interp) +static int mem_ap_target_create(struct target *target) { struct mem_ap *mem_ap; struct adiv5_private_config *pc; diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c index dc7450108..4e27914a9 100644 --- a/src/target/mips_m4k.c +++ b/src/target/mips_m4k.c @@ -1158,7 +1158,7 @@ static int mips_m4k_init_arch_info(struct target *target, return ERROR_OK; } -static int mips_m4k_target_create(struct target *target, Jim_Interp *interp) +static int mips_m4k_target_create(struct target *target) { struct mips_m4k_common *mips_m4k = calloc(1, sizeof(struct mips_m4k_common)); diff --git a/src/target/mips_mips64.c b/src/target/mips_mips64.c index 85e377937..a181a154e 100644 --- a/src/target/mips_mips64.c +++ b/src/target/mips_mips64.c @@ -1082,7 +1082,7 @@ static int mips_mips64_init_target(struct command_context *cmd_ctx, return mips64_build_reg_cache(target); } -static int mips_mips64_target_create(struct target *target, Jim_Interp *interp) +static int mips_mips64_target_create(struct target *target) { struct mips_mips64_common *mips_mips64; struct mips64_common *mips64; diff --git a/src/target/openrisc/or1k.c b/src/target/openrisc/or1k.c index 4b9d3bca6..4aa2bd734 100644 --- a/src/target/openrisc/or1k.c +++ b/src/target/openrisc/or1k.c @@ -1097,7 +1097,7 @@ static int or1k_init_target(struct command_context *cmd_ctx, return ERROR_OK; } -static int or1k_target_create(struct target *target, Jim_Interp *interp) +static int or1k_target_create(struct target *target) { if (!target->tap) return ERROR_FAIL; diff --git a/src/target/quark_d20xx.c b/src/target/quark_d20xx.c index 90cf6670e..931f0dab7 100644 --- a/src/target/quark_d20xx.c +++ b/src/target/quark_d20xx.c @@ -32,7 +32,7 @@ #include "lakemont.h" #include "x86_32_common.h" -static int quark_d20xx_target_create(struct target *t, Jim_Interp *interp) +static int quark_d20xx_target_create(struct target *t) { struct x86_32_common *x86_32 = calloc(1, sizeof(struct x86_32_common)); if (!x86_32) { diff --git a/src/target/quark_x10xx.c b/src/target/quark_x10xx.c index 0daa642b8..2abc32ab7 100644 --- a/src/target/quark_x10xx.c +++ b/src/target/quark_x10xx.c @@ -40,7 +40,7 @@ #include "lakemont.h" #include "x86_32_common.h" -static int quark_x10xx_target_create(struct target *t, Jim_Interp *interp) +static int quark_x10xx_target_create(struct target *t) { struct x86_32_common *x86_32 = calloc(1, sizeof(*x86_32)); diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c index 6a8577f5c..11ef8f9b9 100644 --- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -427,7 +427,7 @@ static struct target_type *get_target_type(struct target *target) } } -static int riscv_create_target(struct target *target, Jim_Interp *interp) +static int riscv_create_target(struct target *target) { LOG_DEBUG("riscv_create_target()"); target->arch_info = calloc(1, sizeof(struct riscv_info)); diff --git a/src/target/stm8.c b/src/target/stm8.c index 76482e878..c80ea0eb2 100644 --- a/src/target/stm8.c +++ b/src/target/stm8.c @@ -1106,8 +1106,7 @@ static int stm8_init_arch_info(struct target *target, return ERROR_OK; } -static int stm8_target_create(struct target *target, - Jim_Interp *interp) +static int stm8_target_create(struct target *target) { struct stm8_common *stm8 = calloc(1, sizeof(struct stm8_common)); diff --git a/src/target/target.c b/src/target/target.c index 99481622d..40c8d3ed3 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -5865,7 +5865,7 @@ COMMAND_HANDLER(handle_target_create) } if (target->type->target_create) { - retval = (*target->type->target_create)(target, CMD_CTX->interp); + retval = (*target->type->target_create)(target); if (retval != ERROR_OK) { LOG_DEBUG("target_create failed"); free(target->cmd_name); diff --git a/src/target/target_type.h b/src/target/target_type.h index ce98cbad2..eddedbf34 100644 --- a/src/target/target_type.h +++ b/src/target/target_type.h @@ -194,7 +194,7 @@ struct target_type { const struct command_registration *commands; /* called when target is created */ - int (*target_create)(struct target *target, Jim_Interp *interp); + int (*target_create)(struct target *target); /* called for various config parameters */ /* returns JIM_CONTINUE - if option not understood */ diff --git a/src/target/xscale.c b/src/target/xscale.c index 5cc790a31..84318a905 100644 --- a/src/target/xscale.c +++ b/src/target/xscale.c @@ -3012,7 +3012,7 @@ static int xscale_init_arch_info(struct target *target, return ERROR_OK; } -static int xscale_target_create(struct target *target, Jim_Interp *interp) +static int xscale_target_create(struct target *target) { struct xscale_common *xscale; diff --git a/src/target/xtensa/xtensa_chip.c b/src/target/xtensa/xtensa_chip.c index ce6d35cab..aab7ee37c 100644 --- a/src/target/xtensa/xtensa_chip.c +++ b/src/target/xtensa/xtensa_chip.c @@ -81,7 +81,7 @@ static const struct xtensa_power_ops xtensa_chip_dm_pwr_ops = { .queue_reg_write = xtensa_dm_queue_pwr_reg_write }; -static int xtensa_chip_target_create(struct target *target, Jim_Interp *interp) +static int xtensa_chip_target_create(struct target *target) { struct xtensa_debug_module_config xtensa_chip_dm_cfg = { .dbg_ops = &xtensa_chip_dm_dbg_ops, ----------------------------------------------------------------------- Summary of changes: src/target/aarch64.c | 4 ++-- src/target/arc.c | 2 +- src/target/arm11.c | 2 +- src/target/arm720t.c | 2 +- src/target/arm7tdmi.c | 2 +- src/target/arm920t.c | 2 +- src/target/arm926ejs.c | 2 +- src/target/arm946e.c | 2 +- src/target/arm966e.c | 2 +- src/target/arm9tdmi.c | 2 +- src/target/avr32_ap7k.c | 2 +- src/target/avrt.c | 4 ++-- src/target/cortex_a.c | 4 ++-- src/target/cortex_m.c | 2 +- src/target/dsp563xx.c | 2 +- src/target/dsp5680xx.c | 2 +- src/target/esirisc.c | 2 +- src/target/espressif/esp32.c | 2 +- src/target/espressif/esp32s2.c | 2 +- src/target/espressif/esp32s3.c | 2 +- src/target/fa526.c | 2 +- src/target/feroceon.c | 4 ++-- src/target/hla_target.c | 3 +-- src/target/ls1_sap.c | 2 +- src/target/mem_ap.c | 2 +- src/target/mips_m4k.c | 2 +- src/target/mips_mips64.c | 2 +- src/target/openrisc/or1k.c | 2 +- src/target/quark_d20xx.c | 2 +- src/target/quark_x10xx.c | 2 +- src/target/riscv/riscv.c | 2 +- src/target/stm8.c | 3 +-- src/target/target.c | 2 +- src/target/target_type.h | 2 +- src/target/xscale.c | 2 +- src/target/xtensa/xtensa_chip.c | 2 +- 36 files changed, 40 insertions(+), 42 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2025-04-19 09:23:42
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 61890e3dc3201ce38e5af7f6b561389a123448e0 (commit) from 1d9b34baa3c5087f2a3387523c6c556b4e4f1afb (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 61890e3dc3201ce38e5af7f6b561389a123448e0 Author: Antonio Borneo <bor...@gm...> Date: Sun Dec 3 15:41:27 2023 +0100 target: rewrite function target_configure() as COMMAND_HELPER The function target_configure() is used by the commands 'target create', 'configure' and 'cget', already rewritten as COMMAND_HANDLER. Rewrite the common function as COMMAND_HELPER. While there: - fix the check on arguments, even if it should be coded better; - keep jimtcl code for target_type::target_jim_configure() and for rtos_create(); these would be rewritten later on. Change-Id: I7e5699ca6d124e34d3b2199714e3ce584bfcce80 Signed-off-by: Antonio Borneo <bor...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/8829 Tested-by: jenkins diff --git a/src/target/target.c b/src/target/target.c index 4bd2f24cc..99481622d 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -214,8 +214,6 @@ static const struct nvp nvp_target_event[] = { { .name = NULL, .value = -1 } }; -static const struct jim_nvp *jim_nvp_target_event = (const struct jim_nvp *)nvp_target_event; - static const struct nvp nvp_target_state[] = { { .name = "unknown", .value = TARGET_UNKNOWN }, { .name = "running", .value = TARGET_RUNNING }, @@ -238,7 +236,7 @@ static const struct nvp nvp_target_debug_reason[] = { { .name = NULL, .value = -1 }, }; -static const struct jim_nvp nvp_target_endian[] = { +static const struct nvp nvp_target_endian[] = { { .name = "big", .value = TARGET_BIG_ENDIAN }, { .name = "little", .value = TARGET_LITTLE_ENDIAN }, { .name = "be", .value = TARGET_BIG_ENDIAN }, @@ -2844,8 +2842,7 @@ COMMAND_HANDLER(handle_targets_command) marker, target_name(target), target_type_name(target), - jim_nvp_value2name_simple(nvp_target_endian, - target->endianness)->name, + nvp_value2name(nvp_target_endian, target->endianness)->name, target->tap->dotted_name, state); } @@ -4859,7 +4856,7 @@ enum target_cfg_param { TCFG_GDB_MAX_CONNECTIONS, }; -static struct jim_nvp nvp_config_opts[] = { +static struct nvp nvp_config_opts[] = { { .name = "-type", .value = TCFG_TYPE }, { .name = "-event", .value = TCFG_EVENT }, { .name = "-work-area-virt", .value = TCFG_WORK_AREA_VIRT }, @@ -4877,78 +4874,71 @@ static struct jim_nvp nvp_config_opts[] = { { .name = NULL, .value = -1 } }; -static int target_configure(struct jim_getopt_info *goi, struct target *target) +static COMMAND_HELPER(target_configure, struct target *target, unsigned int index, bool is_configure) { - struct jim_nvp *n; - Jim_Obj *o; - jim_wide w; - int e; + const struct nvp *n; + int retval; /* parse config or cget options ... */ - while (goi->argc > 0) { - Jim_SetEmptyResult(goi->interp); - /* jim_getopt_debug(goi); */ - + while (index < CMD_ARGC) { if (target->type->target_jim_configure) { /* target defines a configure function */ /* target gets first dibs on parameters */ - e = (*(target->type->target_jim_configure))(target, goi); + struct jim_getopt_info goi; + jim_getopt_setup(&goi, CMD_CTX->interp, CMD_ARGC - index, CMD_JIMTCL_ARGV + index); + goi.is_configure = is_configure; + int e = (*target->type->target_jim_configure)(target, &goi); + index = CMD_ARGC - goi.argc; if (e == JIM_OK) { /* more? */ continue; } if (e == JIM_ERR) { /* An error */ - return e; + int reslen; + const char *result = Jim_GetString(Jim_GetResult(CMD_CTX->interp), &reslen); + if (reslen > 0) + command_print(CMD, "%s", result); + return ERROR_FAIL; } /* otherwise we 'continue' below */ } - e = jim_getopt_nvp(goi, nvp_config_opts, &n); - if (e != JIM_OK) { - jim_getopt_nvp_unknown(goi, nvp_config_opts, 0); - return e; + n = nvp_name2value(nvp_config_opts, CMD_ARGV[index]); + if (!n->name) { + nvp_unknown_command_print(CMD, nvp_config_opts, NULL, CMD_ARGV[index]); + return ERROR_COMMAND_ARGUMENT_INVALID; } + index++; switch (n->value) { case TCFG_TYPE: /* not settable */ - if (goi->is_configure) { - Jim_SetResultFormatted(goi->interp, - "not settable: %s", n->name); - return JIM_ERR; - } else { -no_params: - if (goi->argc != 0) { - Jim_WrongNumArgs(goi->interp, - goi->argc, goi->argv, - "NO PARAMS"); - return JIM_ERR; - } + if (is_configure) { + command_print(CMD, "not settable: %s", n->name); + return ERROR_COMMAND_ARGUMENT_INVALID; } - Jim_SetResultString(goi->interp, - target_type_name(target), -1); + if (index != CMD_ARGC) + return ERROR_COMMAND_SYNTAX_ERROR; + command_print(CMD, "%s", target_type_name(target)); /* loop for more */ break; + case TCFG_EVENT: - if (goi->argc == 0) { - Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event ?event-name? ..."); - return JIM_ERR; + if (index == CMD_ARGC) { + command_print(CMD, "missing event-name"); + return ERROR_COMMAND_ARGUMENT_INVALID; } - e = jim_getopt_nvp(goi, jim_nvp_target_event, &n); - if (e != JIM_OK) { - jim_getopt_nvp_unknown(goi, jim_nvp_target_event, 1); - return e; + n = nvp_name2value(nvp_target_event, CMD_ARGV[index]); + if (!n->name) { + nvp_unknown_command_print(CMD, nvp_target_event, CMD_ARGV[index - 1], CMD_ARGV[index]); + return ERROR_COMMAND_ARGUMENT_INVALID; } + index++; - if (goi->is_configure) { - if (goi->argc != 1) { - Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event ?event-name? ?EVENT-BODY?"); - return JIM_ERR; - } - } else { - if (goi->argc != 0) { - Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-event ?event-name?"); - return JIM_ERR; + if (is_configure) { + if (index == CMD_ARGC) { + command_print(CMD, "missing event-body"); + return ERROR_COMMAND_ARGUMENT_INVALID; } } @@ -4964,20 +4954,20 @@ no_params: if (&teap->list == &target->events_action) teap = NULL; - if (goi->is_configure) { + if (is_configure) { /* START_DEPRECATED_TPIU */ if (n->value == TARGET_EVENT_TRACE_CONFIG) LOG_INFO("DEPRECATED target event %s; use TPIU events {pre,post}-{enable,disable}", n->name); /* END_DEPRECATED_TPIU */ - jim_getopt_obj(goi, &o); - if (Jim_Length(o) == 0) { + if (strlen(CMD_ARGV[index]) == 0) { /* empty action, drop existing one */ if (teap) { list_del(&teap->list); Jim_DecrRefCount(teap->interp, teap->body); free(teap); } + index++; break; } @@ -4988,10 +4978,12 @@ no_params: replace = false; } teap->event = n->value; - teap->interp = goi->interp; + teap->interp = CMD_CTX->interp; if (teap->body) Jim_DecrRefCount(teap->interp, teap->body); - teap->body = Jim_DuplicateObj(goi->interp, o); + /* use jim object to keep its reference on tcl file and line */ + /* TODO: need duplicate? isn't IncrRefCount enough? */ + teap->body = Jim_DuplicateObj(teap->interp, CMD_JIMTCL_ARGV[index++]); /* * FIXME: * Tcl/TK - "tk events" have a nice feature. @@ -5008,219 +5000,266 @@ no_params: /* add to head of event list */ list_add(&teap->list, &target->events_action); } - Jim_SetEmptyResult(goi->interp); } else { - /* get */ - if (!teap) - Jim_SetEmptyResult(goi->interp); - else - Jim_SetResult(goi->interp, Jim_DuplicateObj(goi->interp, teap->body)); + /* cget */ + if (index != CMD_ARGC) + return ERROR_COMMAND_SYNTAX_ERROR; + + if (teap) + command_print(CMD, "%s", Jim_GetString(teap->body, NULL)); } } /* loop for more */ break; case TCFG_WORK_AREA_VIRT: - if (goi->is_configure) { - target_free_all_working_areas(target); - e = jim_getopt_wide(goi, &w); - if (e != JIM_OK) - return e; - target->working_area_virt = w; + if (is_configure) { + if (index == CMD_ARGC) { + command_print(CMD, "missing argument to %s", CMD_ARGV[index - 1]); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + COMMAND_PARSE_NUMBER(u64, CMD_ARGV[index], target->working_area_virt); + index++; target->working_area_virt_spec = true; + target_free_all_working_areas(target); } else { - if (goi->argc != 0) - goto no_params; + if (index != CMD_ARGC) + return ERROR_COMMAND_SYNTAX_ERROR; + command_print(CMD, TARGET_ADDR_FMT, target->working_area_virt); } - Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->working_area_virt)); /* loop for more */ break; case TCFG_WORK_AREA_PHYS: - if (goi->is_configure) { - target_free_all_working_areas(target); - e = jim_getopt_wide(goi, &w); - if (e != JIM_OK) - return e; - target->working_area_phys = w; + if (is_configure) { + if (index == CMD_ARGC) { + command_print(CMD, "missing argument to %s", CMD_ARGV[index - 1]); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + COMMAND_PARSE_NUMBER(u64, CMD_ARGV[index], target->working_area_phys); + index++; target->working_area_phys_spec = true; + target_free_all_working_areas(target); } else { - if (goi->argc != 0) - goto no_params; + if (index != CMD_ARGC) + return ERROR_COMMAND_SYNTAX_ERROR; + command_print(CMD, TARGET_ADDR_FMT, target->working_area_phys); } - Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->working_area_phys)); /* loop for more */ break; case TCFG_WORK_AREA_SIZE: - if (goi->is_configure) { + if (is_configure) { + if (index == CMD_ARGC) { + command_print(CMD, "missing argument to %s", CMD_ARGV[index - 1]); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[index], target->working_area_size); + index++; target_free_all_working_areas(target); - e = jim_getopt_wide(goi, &w); - if (e != JIM_OK) - return e; - target->working_area_size = w; } else { - if (goi->argc != 0) - goto no_params; + if (index != CMD_ARGC) + return ERROR_COMMAND_SYNTAX_ERROR; + command_print(CMD, "0x%08" PRIx32, target->working_area_size); } - Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->working_area_size)); /* loop for more */ break; case TCFG_WORK_AREA_BACKUP: - if (goi->is_configure) { + if (is_configure) { + if (index == CMD_ARGC) { + command_print(CMD, "missing argument to %s", CMD_ARGV[index - 1]); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + retval = command_parse_bool_arg(CMD_ARGV[index], &target->backup_working_area); + if (retval != ERROR_OK) + return retval; + index++; target_free_all_working_areas(target); - e = jim_getopt_wide(goi, &w); - if (e != JIM_OK) - return e; - /* make this boolean */ - target->backup_working_area = (w != 0); } else { - if (goi->argc != 0) - goto no_params; + if (index != CMD_ARGC) + return ERROR_COMMAND_SYNTAX_ERROR; + command_print(CMD, target->backup_working_area ? "1" : "0"); } - Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->backup_working_area ? 1 : 0)); - /* loop for more e*/ + /* loop for more */ break; - case TCFG_ENDIAN: - if (goi->is_configure) { - e = jim_getopt_nvp(goi, nvp_target_endian, &n); - if (e != JIM_OK) { - jim_getopt_nvp_unknown(goi, nvp_target_endian, 1); - return e; + if (is_configure) { + if (index == CMD_ARGC) { + command_print(CMD, "missing argument to %s", CMD_ARGV[index - 1]); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + n = nvp_name2value(nvp_target_endian, CMD_ARGV[index]); + if (!n->name) { + nvp_unknown_command_print(CMD, nvp_target_endian, CMD_ARGV[index - 1], CMD_ARGV[index]); + return ERROR_COMMAND_ARGUMENT_INVALID; } + index++; target->endianness = n->value; } else { - if (goi->argc != 0) - goto no_params; - } - n = jim_nvp_value2name_simple(nvp_target_endian, target->endianness); - if (!n->name) { - target->endianness = TARGET_LITTLE_ENDIAN; - n = jim_nvp_value2name_simple(nvp_target_endian, target->endianness); + if (index != CMD_ARGC) + return ERROR_COMMAND_SYNTAX_ERROR; + n = nvp_value2name(nvp_target_endian, target->endianness); + if (!n->name) { + target->endianness = TARGET_LITTLE_ENDIAN; + n = nvp_value2name(nvp_target_endian, target->endianness); + } + command_print(CMD, "%s", n->name); } - Jim_SetResultString(goi->interp, n->name, -1); /* loop for more */ break; case TCFG_COREID: - if (goi->is_configure) { - e = jim_getopt_wide(goi, &w); - if (e != JIM_OK) - return e; - target->coreid = (int32_t)w; + if (is_configure) { + if (index == CMD_ARGC) { + command_print(CMD, "missing argument to %s", CMD_ARGV[index - 1]); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + COMMAND_PARSE_NUMBER(s32, CMD_ARGV[index], target->coreid); + index++; } else { - if (goi->argc != 0) - goto no_params; + if (index != CMD_ARGC) + return ERROR_COMMAND_SYNTAX_ERROR; + command_print(CMD, "%" PRIi32, target->coreid); } - Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->coreid)); /* loop for more */ break; case TCFG_CHAIN_POSITION: - if (goi->is_configure) { - Jim_Obj *o_t; - struct jtag_tap *tap; - + if (is_configure) { if (target->has_dap) { - Jim_SetResultString(goi->interp, - "target requires -dap parameter instead of -chain-position!", -1); - return JIM_ERR; + command_print(CMD, "target requires -dap parameter instead of -chain-position!"); + return ERROR_COMMAND_ARGUMENT_INVALID; } - e = jim_getopt_obj(goi, &o_t); - if (e != JIM_OK) - return e; - tap = jtag_tap_by_jim_obj(goi->interp, o_t); - if (!tap) - return JIM_ERR; + if (index == CMD_ARGC) { + command_print(CMD, "missing argument to %s", CMD_ARGV[index - 1]); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + struct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[index]); + if (!tap) { + command_print(CMD, "Tap '%s' could not be found", CMD_ARGV[index]); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + index++; target->tap = tap; target->tap_configured = true; } else { - if (goi->argc != 0) - goto no_params; + if (index != CMD_ARGC) + return ERROR_COMMAND_SYNTAX_ERROR; + command_print(CMD, "%s", target->tap->dotted_name); } - Jim_SetResultString(goi->interp, target->tap->dotted_name, -1); - /* loop for more e*/ + /* loop for more */ break; + case TCFG_DBGBASE: - if (goi->is_configure) { - e = jim_getopt_wide(goi, &w); - if (e != JIM_OK) - return e; - target->dbgbase = (uint32_t)w; + if (is_configure) { + if (index == CMD_ARGC) { + command_print(CMD, "missing argument to %s", CMD_ARGV[index - 1]); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + COMMAND_PARSE_NUMBER(u32, CMD_ARGV[index], target->dbgbase); + index++; target->dbgbase_set = true; } else { - if (goi->argc != 0) - goto no_params; + if (index != CMD_ARGC) + return ERROR_COMMAND_SYNTAX_ERROR; + command_print(CMD, "0x%08" PRIx32, target->dbgbase); } - Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->dbgbase)); /* loop for more */ break; + case TCFG_RTOS: - /* RTOS */ - { - int result = rtos_create(goi, target); - if (result != JIM_OK) - return result; + if (is_configure) { + if (index == CMD_ARGC) { + command_print(CMD, "missing argument to %s", CMD_ARGV[index - 1]); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + struct jim_getopt_info goi; + jim_getopt_setup(&goi, CMD_CTX->interp, CMD_ARGC - index, CMD_JIMTCL_ARGV + index); + index++; + goi.is_configure = true; + int resval = rtos_create(&goi, target); + int reslen; + const char *result = Jim_GetString(Jim_GetResult(CMD_CTX->interp), &reslen); + if (reslen > 0) + command_print(CMD, "%s", result); + if (resval != JIM_OK) + return ERROR_FAIL; + } else { + if (index != CMD_ARGC) + return ERROR_COMMAND_SYNTAX_ERROR; + if (target->rtos) + command_print(CMD, "%s", target->rtos->type->name); } /* loop for more */ break; case TCFG_DEFER_EXAMINE: - /* DEFER_EXAMINE */ - target->defer_examine = true; + if (is_configure) + target->defer_examine = true; + else + command_print(CMD, "%s", target->defer_examine ? "true" : "false"); /* loop for more */ break; case TCFG_GDB_PORT: - if (goi->is_configure) { - struct command_context *cmd_ctx = current_command_context(goi->interp); - if (cmd_ctx->mode != COMMAND_CONFIG) { - Jim_SetResultString(goi->interp, "-gdb-port must be configured before 'init'", -1); - return JIM_ERR; + if (is_configure) { + if (index == CMD_ARGC) { + command_print(CMD, "missing argument to %s", CMD_ARGV[index - 1]); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + + /* TODO: generalize test of COMMAND_CONFIG */ + if (CMD_CTX->mode != COMMAND_CONFIG) { + command_print(CMD, "-gdb-port must be configured before 'init'"); + return ERROR_COMMAND_ARGUMENT_INVALID; } - const char *s; - e = jim_getopt_string(goi, &s, NULL); - if (e != JIM_OK) - return e; + char *s = strdup(CMD_ARGV[index]); + if (!s) { + LOG_ERROR("Out of memory"); + return ERROR_FAIL; + } free(target->gdb_port_override); - target->gdb_port_override = strdup(s); + target->gdb_port_override = s; + index++; } else { - if (goi->argc != 0) - goto no_params; + if (index != CMD_ARGC) + return ERROR_COMMAND_SYNTAX_ERROR; + command_print(CMD, "%s", target->gdb_port_override ? target->gdb_port_override : "undefined"); } - Jim_SetResultString(goi->interp, target->gdb_port_override ? target->gdb_port_override : "undefined", -1); /* loop for more */ break; case TCFG_GDB_MAX_CONNECTIONS: - if (goi->is_configure) { - struct command_context *cmd_ctx = current_command_context(goi->interp); - if (cmd_ctx->mode != COMMAND_CONFIG) { - Jim_SetResultString(goi->interp, "-gdb-max-connections must be configured before 'init'", -1); - return JIM_ERR; + if (is_configure) { + if (index == CMD_ARGC) { + command_print(CMD, "missing argument to %s", CMD_ARGV[index - 1]); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + + if (CMD_CTX->mode != COMMAND_CONFIG) { + command_print(CMD, "-gdb-max-connections must be configured before 'init'"); + return ERROR_COMMAND_ARGUMENT_INVALID; } - e = jim_getopt_wide(goi, &w); - if (e != JIM_OK) - return e; - target->gdb_max_connections = (w < 0) ? CONNECTION_LIMIT_UNLIMITED : (int)w; + COMMAND_PARSE_NUMBER(int, CMD_ARGV[index], target->gdb_max_connections); + index++; + if (target->gdb_max_connections < 0) + target->gdb_max_connections = CONNECTION_LIMIT_UNLIMITED; } else { - if (goi->argc != 0) - goto no_params; + if (index != CMD_ARGC) + return ERROR_COMMAND_SYNTAX_ERROR; + command_print(CMD, "%d", target->gdb_max_connections); } - Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->gdb_max_connections)); + /* loop for more */ break; } - } /* while (goi->argc) */ - + } - /* done - we return */ - return JIM_OK; + return ERROR_OK; } COMMAND_HANDLER(handle_target_configure) @@ -5228,23 +5267,11 @@ COMMAND_HANDLER(handle_target_configure) if (!CMD_ARGC) return ERROR_COMMAND_SYNTAX_ERROR; - struct jim_getopt_info goi; - - jim_getopt_setup(&goi, CMD_CTX->interp, CMD_ARGC, CMD_JIMTCL_ARGV); - goi.is_configure = !strcmp(CMD_NAME, "configure"); + bool is_configure = !strcmp(CMD_NAME, "configure"); struct target *target = get_current_target(CMD_CTX); - int e = target_configure(&goi, target); - - int reslen; - const char *result = Jim_GetString(Jim_GetResult(CMD_CTX->interp), &reslen); - if (reslen > 0) - command_print(CMD, "%s", result); - - if (e != JIM_OK) - return ERROR_FAIL; - return ERROR_OK; + return CALL_COMMAND_HANDLER(target_configure, target, 0, is_configure); } COMMAND_HANDLER(handle_target_examine) @@ -5803,18 +5830,9 @@ COMMAND_HANDLER(handle_target_create) } /* Do the rest as "configure" options */ - struct jim_getopt_info goi; - jim_getopt_setup(&goi, CMD_CTX->interp, CMD_ARGC - 2, CMD_JIMTCL_ARGV + 2); - - goi.is_configure = 1; - int e = target_configure(&goi, target); - - int reslen; - const char *result = Jim_GetString(Jim_GetResult(CMD_CTX->interp), &reslen); - if (reslen > 0) - command_print(CMD, "%s", result); - - if (e == JIM_OK) { + bool is_configure = true; + retval = CALL_COMMAND_HANDLER(target_configure, target, 2, is_configure); + if (retval == ERROR_OK) { if (target->has_dap) { if (!target->dap_configured) { command_print(CMD, "-dap ?name? required when creating target"); @@ -5829,8 +5847,6 @@ COMMAND_HANDLER(handle_target_create) /* tap must be set after target was configured */ if (!target->tap) retval = ERROR_COMMAND_ARGUMENT_INVALID; - } else { - retval = ERROR_FAIL; } if (retval != ERROR_OK) { ----------------------------------------------------------------------- Summary of changes: src/target/target.c | 434 +++++++++++++++++++++++++++------------------------- 1 file changed, 225 insertions(+), 209 deletions(-) hooks/post-receive -- Main OpenOCD repository |
From: openocd-gerrit <ope...@us...> - 2025-04-19 09:23:16
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 1d9b34baa3c5087f2a3387523c6c556b4e4f1afb (commit) from 29e4a366222b96aac89dbec11e5f4a83a6a83bbe (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1d9b34baa3c5087f2a3387523c6c556b4e4f1afb Author: Antonio Borneo <bor...@gm...> Date: Sat Dec 2 23:40:56 2023 +0100 target: rewrite commands 'configure' and 'cget' as COMMAND_HANDLER Rewrite only the command, but still use the old jimtcl specific code shared with 'target create'. Change-Id: Ie5e1c9eb237531121c2d143d1732cf281dfdc9ff Signed-off-by: Antonio Borneo <bor...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/8828 Tested-by: jenkins diff --git a/src/target/target.c b/src/target/target.c index 9d9d73a28..4bd2f24cc 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -5223,22 +5223,28 @@ no_params: return JIM_OK; } -static int jim_target_configure(Jim_Interp *interp, int argc, Jim_Obj * const *argv) +COMMAND_HANDLER(handle_target_configure) { - struct command *c = jim_to_command(interp); + if (!CMD_ARGC) + return ERROR_COMMAND_SYNTAX_ERROR; + struct jim_getopt_info goi; - jim_getopt_setup(&goi, interp, argc - 1, argv + 1); - goi.is_configure = !strcmp(c->name, "configure"); - if (goi.argc < 1) { - Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv, - "missing: -option ..."); - return JIM_ERR; - } - struct command_context *cmd_ctx = current_command_context(interp); - assert(cmd_ctx); - struct target *target = get_current_target(cmd_ctx); - return target_configure(&goi, target); + jim_getopt_setup(&goi, CMD_CTX->interp, CMD_ARGC, CMD_JIMTCL_ARGV); + goi.is_configure = !strcmp(CMD_NAME, "configure"); + + struct target *target = get_current_target(CMD_CTX); + int e = target_configure(&goi, target); + + int reslen; + const char *result = Jim_GetString(Jim_GetResult(CMD_CTX->interp), &reslen); + if (reslen > 0) + command_print(CMD, "%s", result); + + if (e != JIM_OK) + return ERROR_FAIL; + + return ERROR_OK; } COMMAND_HANDLER(handle_target_examine) @@ -5491,14 +5497,14 @@ static const struct command_registration target_instance_command_handlers[] = { { .name = "configure", .mode = COMMAND_ANY, - .jim_handler = jim_target_configure, + .handler = handle_target_configure, .help = "configure a new target for use", .usage = "[target_attribute ...]", }, { .name = "cget", .mode = COMMAND_ANY, - .jim_handler = jim_target_configure, + .handler = handle_target_configure, .help = "returns the specified target attribute", .usage = "target_attribute", }, ----------------------------------------------------------------------- Summary of changes: src/target/target.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) hooks/post-receive -- Main OpenOCD repository |