This is an automated email from Gerrit.

"Tomas Vanek <van...@fbl.cz>" just uploaded a new patch set to Gerrit, which 
you can find at https://review.openocd.org/c/openocd/+/8448

-- gerrit

commit 605630b0d32590e429203fa93ac59c9cccfe7565
Author: Tomas Vanek <van...@fbl.cz>
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 <van...@fbl.cz>
    Change-Id: I764354ab469e253042128958dfe70c09d04d6411

diff --git a/src/flash/nor/rp2040.c b/src/flash/nor/rp2040.c
index 5b43c8eeb9..e5028303c0 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;
 }
 
@@ -949,11 +945,12 @@ COMMAND_HANDLER(rp2040_rom_api_call_handler)
        if (retval != ERROR_OK)
                return retval;
 
-       retval = setup_for_raw_flash_cmd(bank);
+       struct rp2040_flash_bank *priv = bank->driver_priv;
+       struct target *target = bank->target;
+       retval = setup_for_raw_flash_cmd(target, priv);
        if (retval != ERROR_OK)
                goto cleanup_and_return;
 
-       struct target *target = bank->target;
        uint16_t symtype_func = is_arm(target_to_arm(target))
                                 ? RT_FLAG_FUNC_ARM_SEC : RT_FLAG_FUNC_RISCV;
 
@@ -971,16 +968,50 @@ COMMAND_HANDLER(rp2040_rom_api_call_handler)
 
        LOG_INFO("RP2xxx ROM API function %.2s @ %04" PRIx16, CMD_ARGV[1], fc);
 
-       struct rp2040_flash_bank *priv = bank->driver_priv;
-       retval = rp2xxx_call_rom_func(bank->target, priv, fc, args, 
ARRAY_SIZE(args));
+       retval = rp2xxx_call_rom_func(target, priv, fc, args, ARRAY_SIZE(args));
        if (retval != ERROR_OK)
                LOG_ERROR("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) {
+               LOG_ERROR("Unrecognised old target %s", CMD_ARGV[0]);
+               return ERROR_FAIL;
+       }
+
+       struct target *new_target = get_target(CMD_ARGV[1]);
+       if (!new_target) {
+               LOG_ERROR("Unrecognised new target %s", CMD_ARGV[1]);
+               return ERROR_FAIL;
+       }
+
+       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;
+                       }
+               }
+       }
+
+       LOG_ERROR("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",
@@ -989,6 +1020,13 @@ static const struct command_registration 
rp2040_exec_command_handlers[] = {
                .usage = "bank 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
 };
 

-- 

Reply via email to