const struct flash_device *dev;
};
+/* 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;
}
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, int timeout_ms)
+ uint16_t func_offset, uint32_t argdata[], unsigned int n_args, unsigned int timeout_ms)
{
char *regnames[4] = { "r0", "r1", "r2", "r3" };
/* 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_args + 2; ++i)
+ for (unsigned int i = 0; i < n_reg_params; ++i)
LOG_DEBUG("Set %s = 0x%" PRIx32, args[i].reg_name, buf_get_u32(args[i].value, 0, 32));
/* Actually call the function */
int err = target_run_algorithm(
target,
0, NULL, /* No memory arguments */
- n_args + 1, args, /* User arguments + r7 */
+ n_reg_params, args, /* User arguments + r7 + sp */
priv->jump_debug_trampoline, priv->jump_debug_trampoline_end,
timeout_ms,
&alg_info
);
- for (unsigned int i = 0; i < n_args + 2; ++i)
+
+ for (unsigned int i = 0; i < n_reg_params; ++i)
destroy_reg_param(&args[i]);
+
if (err != ERROR_OK)
- LOG_ERROR("Failed to invoke ROM function @0x%" PRIx16 "\n", func_offset);
- return err;
+ LOG_ERROR("Failed to invoke ROM function @0x%" PRIx16, func_offset);
+ return err;
}
/* Finalize flash write/erase/read ID
an optional larger "block" (size and command provided in args).
*/
- int timeout_ms = 2000 * (last - first) + 1000;
+ 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);
return err;
}
- err = rp2040_stack_grab_and_prep(bank);
+ 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");
- uint32_t device_id = 0;
- if (err == ERROR_OK)
- err = rp2040_spi_read_flash_id(target, &device_id);
+ } else {
+ /* zero bank size in cfg, read SPI flash ID and autodetect */
+ err = rp2040_stack_grab_and_prep(bank);
- rp2040_finalize_stack_free(bank);
+ uint32_t device_id = 0;
+ if (err == ERROR_OK)
+ err = rp2040_spi_read_flash_id(target, &device_id);
- if (err != ERROR_OK)
- return err;
+ rp2040_finalize_stack_free(bank);
- /* 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 (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);
- if (!priv->dev) {
- LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32 ")", device_id);
- return ERROR_FAIL;
+ bank->size = priv->dev->size_in_bytes;
}
- LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32 ")",
- priv->dev->name, priv->dev->device_id);
-
/* 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->size = priv->dev->size_in_bytes;
-
bank->num_sectors = bank->size / priv->dev->sectorsize;
- LOG_INFO("RP2040 B0 Flash Probe: %d bytes @" TARGET_ADDR_FMT ", in %d sectors\n",
+ LOG_INFO("RP2040 B0 Flash Probe: %" PRIu32 " bytes @" TARGET_ADDR_FMT ", in %u sectors\n",
bank->size, bank->base, bank->num_sectors);
bank->sectors = alloc_block_array(0, priv->dev->sectorsize, bank->num_sectors);
if (!bank->sectors)
return ERROR_OK;
}
-struct flash_driver rp2040_flash = {
+const struct flash_driver rp2040_flash = {
.name = "rp2040_flash",
.flash_bank_command = rp2040_flash_bank_command,
.erase = rp2040_flash_erase,