]> www.infradead.org Git - users/borneoa/openocd-next.git/commitdiff
flash/nor/rp2040: allow arbitrary ROM API call from Tcl
authorTomas Vanek <vanekt@fbl.cz>
Wed, 17 Jul 2024 09:49:55 +0000 (11:49 +0200)
committerTomas Vanek <vanekt@fbl.cz>
Fri, 25 Apr 2025 09:30:21 +0000 (09:30 +0000)
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 <vanekt@fbl.cz>
Change-Id: I1b532afcc41a4051298313e685658e86c02c53f9
Reviewed-on: https://review.openocd.org/c/openocd/+/8447
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
Tested-by: jenkins
src/flash/nor/rp2040.c

index 5faba57a0814aedcfece1e2b8f240e333290e719..df9284d96890d187579732cbbc9570a6a0f40543 100644 (file)
@@ -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,