OpenOCD
rp2040.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
6 
7 #include "imp.h"
8 #include <helper/binarybuffer.h>
9 #include <target/algorithm.h>
10 #include <target/armv7m.h>
11 #include "spi.h"
12 
13 /* NOTE THAT THIS CODE REQUIRES FLASH ROUTINES in BOOTROM WITH FUNCTION TABLE PTR AT 0x00000010
14  Your gdbinit should load the bootrom.elf if appropriate */
15 
16 /* this is 'M' 'u', 1 (version) */
17 #define BOOTROM_MAGIC 0x01754d
18 #define BOOTROM_MAGIC_ADDR 0x00000010
19 
20 /* Call a ROM function via the debug trampoline
21  Up to four arguments passed in r0...r3 as per ABI
22  Function address is passed in r7
23  the trampoline is needed because OpenOCD "algorithm" code insists on sw breakpoints. */
24 
25 #define MAKE_TAG(a, b) (((b)<<8) | a)
26 #define FUNC_DEBUG_TRAMPOLINE MAKE_TAG('D', 'T')
27 #define FUNC_DEBUG_TRAMPOLINE_END MAKE_TAG('D', 'E')
28 #define FUNC_FLASH_EXIT_XIP MAKE_TAG('E', 'X')
29 #define FUNC_CONNECT_INTERNAL_FLASH MAKE_TAG('I', 'F')
30 #define FUNC_FLASH_RANGE_ERASE MAKE_TAG('R', 'E')
31 #define FUNC_FLASH_RANGE_PROGRAM MAKE_TAG('R', 'P')
32 #define FUNC_FLASH_FLUSH_CACHE MAKE_TAG('F', 'C')
33 #define FUNC_FLASH_ENTER_CMD_XIP MAKE_TAG('C', 'X')
34 
36  /* flag indicating successful flash probe */
37  bool probed;
38  /* stack used by Boot ROM calls */
40  /* function jump table populated by rp2040_flash_probe() */
47  uint16_t jump_flush_cache;
49  /* detected model of SPI flash */
50  const struct flash_device *dev;
51 };
52 
53 /* guessed SPI flash description if autodetection disabled (same as win w25q16jv) */
54 static const struct flash_device rp2040_default_spi_device =
55  FLASH_ID("autodetect disabled", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0, 0x100, 0x10000, 0);
56 
57 static uint32_t rp2040_lookup_symbol(struct target *target, uint32_t tag, uint16_t *symbol)
58 {
59  uint32_t magic;
60  int err = target_read_u32(target, BOOTROM_MAGIC_ADDR, &magic);
61  if (err != ERROR_OK)
62  return err;
63 
64  magic &= 0xffffff; /* ignore bootrom version */
65  if (magic != BOOTROM_MAGIC) {
66  if (!((magic ^ BOOTROM_MAGIC)&0xffff))
67  LOG_ERROR("Incorrect RP2040 BOOT ROM version");
68  else
69  LOG_ERROR("RP2040 BOOT ROM not found");
70  return ERROR_FAIL;
71  }
72 
73  /* dereference the table pointer */
74  uint16_t table_entry;
75  err = target_read_u16(target, BOOTROM_MAGIC_ADDR + 4, &table_entry);
76  if (err != ERROR_OK)
77  return err;
78 
79  uint16_t entry_tag;
80  do {
81  err = target_read_u16(target, table_entry, &entry_tag);
82  if (err != ERROR_OK)
83  return err;
84  if (entry_tag == tag) {
85  /* 16 bit symbol is next */
86  return target_read_u16(target, table_entry + 2, symbol);
87  }
88  table_entry += 4;
89  } while (entry_tag);
90  return ERROR_FAIL;
91 }
92 
94  uint16_t func_offset, uint32_t argdata[], unsigned int n_args, unsigned int timeout_ms)
95 {
96  char *regnames[4] = { "r0", "r1", "r2", "r3" };
97 
98  assert(n_args <= ARRAY_SIZE(regnames)); /* only allow register arguments */
99 
100  if (!priv->stack) {
101  LOG_ERROR("no stack for flash programming code");
103  }
104  target_addr_t stacktop = priv->stack->address + priv->stack->size;
105 
106  LOG_TARGET_DEBUG(target, "Calling ROM func @0x%" PRIx16 " with %u arguments", func_offset, n_args);
107 
108  struct reg_param args[ARRAY_SIZE(regnames) + 2];
109  struct armv7m_algorithm alg_info;
110 
111  for (unsigned int i = 0; i < n_args; ++i) {
112  init_reg_param(&args[i], regnames[i], 32, PARAM_OUT);
113  buf_set_u32(args[i].value, 0, 32, argdata[i]);
114  }
115  /* Pass function pointer in r7 */
116  init_reg_param(&args[n_args], "r7", 32, PARAM_OUT);
117  buf_set_u32(args[n_args].value, 0, 32, func_offset);
118  /* Setup stack */
119  init_reg_param(&args[n_args + 1], "sp", 32, PARAM_OUT);
120  buf_set_u32(args[n_args + 1].value, 0, 32, stacktop);
121  unsigned int n_reg_params = n_args + 2; /* User arguments + r7 + sp */
122 
123  for (unsigned int i = 0; i < n_reg_params; ++i)
124  LOG_DEBUG("Set %s = 0x%" PRIx32, args[i].reg_name, buf_get_u32(args[i].value, 0, 32));
125 
126  /* Actually call the function */
128  alg_info.core_mode = ARM_MODE_THREAD;
129  int err = target_run_algorithm(
130  target,
131  0, NULL, /* No memory arguments */
132  n_reg_params, args, /* User arguments + r7 + sp */
133  priv->jump_debug_trampoline, priv->jump_debug_trampoline_end,
134  timeout_ms,
135  &alg_info
136  );
137 
138  for (unsigned int i = 0; i < n_reg_params; ++i)
139  destroy_reg_param(&args[i]);
140 
141  if (err != ERROR_OK)
142  LOG_ERROR("Failed to invoke ROM function @0x%" PRIx16, func_offset);
143 
144  return err;
145 }
146 
147 /* Finalize flash write/erase/read ID
148  * - flush cache
149  * - enters memory-mapped (XIP) mode to make flash data visible
150  * - deallocates target ROM func stack if previously allocated
151  */
153 {
154  struct rp2040_flash_bank *priv = bank->driver_priv;
155  struct target *target = bank->target;
156 
157  /* Always flush before returning to execute-in-place, to invalidate stale
158  * cache contents. The flush call also restores regular hardware-controlled
159  * chip select following a rp2040_flash_exit_xip().
160  */
161  LOG_DEBUG("Flushing flash cache after write behind");
162  int err = rp2040_call_rom_func(target, priv, priv->jump_flush_cache, NULL, 0, 1000);
163  if (err != ERROR_OK) {
164  LOG_ERROR("Failed to flush flash cache");
165  /* Intentionally continue after error and try to setup xip anyway */
166  }
167 
168  LOG_DEBUG("Configuring SSI for execute-in-place");
169  err = rp2040_call_rom_func(target, priv, priv->jump_enter_cmd_xip, NULL, 0, 1000);
170  if (err != ERROR_OK)
171  LOG_ERROR("Failed to set SSI to XIP mode");
172 
174  priv->stack = NULL;
175  return err;
176 }
177 
178 /* Prepare flash write/erase/read ID
179  * - allocates a stack for target ROM func
180  * - switches the SPI interface from memory-mapped mode to direct command mode
181  * Always pair with a call of rp2040_finalize_stack_free()
182  * after flash operation finishes or fails.
183  */
185 {
186  struct rp2040_flash_bank *priv = bank->driver_priv;
187  struct target *target = bank->target;
188 
189  /* target_alloc_working_area always allocates multiples of 4 bytes, so no worry about alignment */
190  const int STACK_SIZE = 256;
191  int err = target_alloc_working_area(target, STACK_SIZE, &priv->stack);
192  if (err != ERROR_OK) {
193  LOG_ERROR("Could not allocate stack for flash programming code");
195  }
196 
197  LOG_DEBUG("Connecting internal flash");
198  err = rp2040_call_rom_func(target, priv, priv->jump_connect_internal_flash, NULL, 0, 1000);
199  if (err != ERROR_OK) {
200  LOG_ERROR("Failed to connect internal flash");
201  return err;
202  }
203 
204  LOG_DEBUG("Kicking flash out of XIP mode");
205  err = rp2040_call_rom_func(target, priv, priv->jump_flash_exit_xip, NULL, 0, 1000);
206  if (err != ERROR_OK) {
207  LOG_ERROR("Failed to exit flash XIP mode");
208  return err;
209  }
210 
211  return ERROR_OK;
212 }
213 
214 static int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
215 {
216  LOG_DEBUG("Writing %d bytes starting at 0x%" PRIx32, count, offset);
217 
218  struct rp2040_flash_bank *priv = bank->driver_priv;
219  struct target *target = bank->target;
220 
221  if (target->state != TARGET_HALTED) {
222  LOG_ERROR("Target not halted");
224  }
225 
226  struct working_area *bounce = NULL;
227 
228  int err = rp2040_stack_grab_and_prep(bank);
229  if (err != ERROR_OK)
230  goto cleanup;
231 
232  unsigned int avail_pages = target_get_working_area_avail(target) / priv->dev->pagesize;
233  /* We try to allocate working area rounded down to device page size,
234  * al least 1 page, at most the write data size
235  */
236  unsigned int chunk_size = MIN(MAX(avail_pages, 1) * priv->dev->pagesize, count);
237  err = target_alloc_working_area(target, chunk_size, &bounce);
238  if (err != ERROR_OK) {
239  LOG_ERROR("Could not allocate bounce buffer for flash programming. Can't continue");
240  goto cleanup;
241  }
242 
243  LOG_DEBUG("Allocated flash bounce buffer @" TARGET_ADDR_FMT, bounce->address);
244 
245  while (count > 0) {
246  uint32_t write_size = count > chunk_size ? chunk_size : count;
247  LOG_DEBUG("Writing %d bytes to offset 0x%" PRIx32, write_size, offset);
248  err = target_write_buffer(target, bounce->address, write_size, buffer);
249  if (err != ERROR_OK) {
250  LOG_ERROR("Could not load data into target bounce buffer");
251  break;
252  }
253  uint32_t args[3] = {
254  offset, /* addr */
255  bounce->address, /* data */
256  write_size /* count */
257  };
258  err = rp2040_call_rom_func(target, priv, priv->jump_flash_range_program,
259  args, ARRAY_SIZE(args), 3000);
260  if (err != ERROR_OK) {
261  LOG_ERROR("Failed to invoke flash programming code on target");
262  break;
263  }
264 
265  buffer += write_size;
266  offset += write_size;
267  count -= write_size;
268  }
269 
270 cleanup:
272 
274 
275  return err;
276 }
277 
278 static int rp2040_flash_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
279 {
280  struct rp2040_flash_bank *priv = bank->driver_priv;
281  struct target *target = bank->target;
282 
283  if (target->state != TARGET_HALTED) {
284  LOG_ERROR("Target not halted");
286  }
287 
288  uint32_t start_addr = bank->sectors[first].offset;
289  uint32_t length = bank->sectors[last].offset + bank->sectors[last].size - start_addr;
290  LOG_DEBUG("RP2040 erase %d bytes starting at 0x%" PRIx32, length, start_addr);
291 
292  int err = rp2040_stack_grab_and_prep(bank);
293  if (err != ERROR_OK)
294  goto cleanup;
295 
296  LOG_DEBUG("Remote call flash_range_erase");
297 
298  uint32_t args[4] = {
299  bank->sectors[first].offset, /* addr */
300  bank->sectors[last].offset + bank->sectors[last].size - bank->sectors[first].offset, /* count */
301  priv->dev->sectorsize, /* block_size */
302  priv->dev->erase_cmd /* block_cmd */
303  };
304 
305  /*
306  The RP2040 Boot ROM provides a _flash_range_erase() API call documented in Section 2.8.3.1.3:
307  https://datasheets.raspberrypi.org/rp2040/rp2040-datasheet.pdf
308  and the particular source code for said Boot ROM function can be found here:
309  https://github.com/raspberrypi/pico-bootrom/blob/master/bootrom/program_flash_generic.c
310 
311  In theory, the function algorithm provides for erasing both a smaller "sector" (4096 bytes) and
312  an optional larger "block" (size and command provided in args).
313  */
314 
315  unsigned int timeout_ms = 2000 * (last - first) + 1000;
316  err = rp2040_call_rom_func(target, priv, priv->jump_flash_range_erase,
317  args, ARRAY_SIZE(args), timeout_ms);
318 
319 cleanup:
321 
322  return err;
323 }
324 
325 /* -----------------------------------------------------------------------------
326  Driver probing etc */
327 
328 static int rp2040_ssel_active(struct target *target, bool active)
329 {
330  const target_addr_t qspi_ctrl_addr = 0x4001800c;
331  const uint32_t qspi_ctrl_outover_low = 2UL << 8;
332  const uint32_t qspi_ctrl_outover_high = 3UL << 8;
333  uint32_t state = (active) ? qspi_ctrl_outover_low : qspi_ctrl_outover_high;
334  uint32_t val;
335 
336  int err = target_read_u32(target, qspi_ctrl_addr, &val);
337  if (err != ERROR_OK)
338  return err;
339 
340  val = (val & ~qspi_ctrl_outover_high) | state;
341 
342  err = target_write_u32(target, qspi_ctrl_addr, val);
343  if (err != ERROR_OK)
344  return err;
345 
346  return ERROR_OK;
347 }
348 
349 static int rp2040_spi_read_flash_id(struct target *target, uint32_t *devid)
350 {
351  uint32_t device_id = 0;
352  const target_addr_t ssi_dr0 = 0x18000060;
353 
354  int err = rp2040_ssel_active(target, true);
355 
356  /* write RDID request into SPI peripheral's FIFO */
357  for (int count = 0; (count < 4) && (err == ERROR_OK); count++)
358  err = target_write_u32(target, ssi_dr0, SPIFLASH_READ_ID);
359 
360  /* by this time, there is a receive FIFO entry for every write */
361  for (int count = 0; (count < 4) && (err == ERROR_OK); count++) {
362  uint32_t status;
363  err = target_read_u32(target, ssi_dr0, &status);
364 
365  device_id >>= 8;
366  device_id |= (status & 0xFF) << 24;
367  }
368 
369  if (err == ERROR_OK)
370  *devid = device_id >> 8;
371 
372  int err2 = rp2040_ssel_active(target, false);
373  if (err2 != ERROR_OK)
374  LOG_ERROR("SSEL inactive failed");
375 
376  return err;
377 }
378 
379 static int rp2040_flash_probe(struct flash_bank *bank)
380 {
381  struct rp2040_flash_bank *priv = bank->driver_priv;
382  struct target *target = bank->target;
383 
384  if (target->state != TARGET_HALTED) {
385  LOG_ERROR("Target not halted");
387  }
388 
389  int err = rp2040_lookup_symbol(target, FUNC_DEBUG_TRAMPOLINE, &priv->jump_debug_trampoline);
390  if (err != ERROR_OK) {
391  LOG_ERROR("Debug trampoline not found in RP2040 ROM.");
392  return err;
393  }
394  priv->jump_debug_trampoline &= ~1u; /* mask off thumb bit */
395 
396  err = rp2040_lookup_symbol(target, FUNC_DEBUG_TRAMPOLINE_END, &priv->jump_debug_trampoline_end);
397  if (err != ERROR_OK) {
398  LOG_ERROR("Debug trampoline end not found in RP2040 ROM.");
399  return err;
400  }
401  priv->jump_debug_trampoline_end &= ~1u; /* mask off thumb bit */
402 
403  err = rp2040_lookup_symbol(target, FUNC_FLASH_EXIT_XIP, &priv->jump_flash_exit_xip);
404  if (err != ERROR_OK) {
405  LOG_ERROR("Function FUNC_FLASH_EXIT_XIP not found in RP2040 ROM.");
406  return err;
407  }
408 
409  err = rp2040_lookup_symbol(target, FUNC_CONNECT_INTERNAL_FLASH, &priv->jump_connect_internal_flash);
410  if (err != ERROR_OK) {
411  LOG_ERROR("Function FUNC_CONNECT_INTERNAL_FLASH not found in RP2040 ROM.");
412  return err;
413  }
414 
415  err = rp2040_lookup_symbol(target, FUNC_FLASH_RANGE_ERASE, &priv->jump_flash_range_erase);
416  if (err != ERROR_OK) {
417  LOG_ERROR("Function FUNC_FLASH_RANGE_ERASE not found in RP2040 ROM.");
418  return err;
419  }
420 
421  err = rp2040_lookup_symbol(target, FUNC_FLASH_RANGE_PROGRAM, &priv->jump_flash_range_program);
422  if (err != ERROR_OK) {
423  LOG_ERROR("Function FUNC_FLASH_RANGE_PROGRAM not found in RP2040 ROM.");
424  return err;
425  }
426 
427  err = rp2040_lookup_symbol(target, FUNC_FLASH_FLUSH_CACHE, &priv->jump_flush_cache);
428  if (err != ERROR_OK) {
429  LOG_ERROR("Function FUNC_FLASH_FLUSH_CACHE not found in RP2040 ROM.");
430  return err;
431  }
432 
433  err = rp2040_lookup_symbol(target, FUNC_FLASH_ENTER_CMD_XIP, &priv->jump_enter_cmd_xip);
434  if (err != ERROR_OK) {
435  LOG_ERROR("Function FUNC_FLASH_ENTER_CMD_XIP not found in RP2040 ROM.");
436  return err;
437  }
438 
439  if (bank->size) {
440  /* size overridden, suppress reading SPI flash ID */
442  LOG_DEBUG("SPI flash autodetection disabled, using configured size");
443 
444  } else {
445  /* zero bank size in cfg, read SPI flash ID and autodetect */
447 
448  uint32_t device_id = 0;
449  if (err == ERROR_OK)
450  err = rp2040_spi_read_flash_id(target, &device_id);
451 
453 
454  if (err != ERROR_OK)
455  return err;
456 
457  /* search for a SPI flash Device ID match */
458  priv->dev = NULL;
459  for (const struct flash_device *p = flash_devices; p->name ; p++)
460  if (p->device_id == device_id) {
461  priv->dev = p;
462  break;
463  }
464 
465  if (!priv->dev) {
466  LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32 ")", device_id);
467  return ERROR_FAIL;
468  }
469  LOG_INFO("Found flash device '%s' (ID 0x%08" PRIx32 ")",
470  priv->dev->name, priv->dev->device_id);
471 
472  bank->size = priv->dev->size_in_bytes;
473  }
474 
475  /* the Boot ROM flash_range_program() routine requires page alignment */
476  bank->write_start_alignment = priv->dev->pagesize;
477  bank->write_end_alignment = priv->dev->pagesize;
478 
479  bank->num_sectors = bank->size / priv->dev->sectorsize;
480  LOG_INFO("RP2040 B0 Flash Probe: %" PRIu32 " bytes @" TARGET_ADDR_FMT ", in %u sectors\n",
481  bank->size, bank->base, bank->num_sectors);
482  bank->sectors = alloc_block_array(0, priv->dev->sectorsize, bank->num_sectors);
483  if (!bank->sectors)
484  return ERROR_FAIL;
485 
486  if (err == ERROR_OK)
487  priv->probed = true;
488 
489  return err;
490 }
491 
493 {
494  struct rp2040_flash_bank *priv = bank->driver_priv;
495 
496  if (priv->probed)
497  return ERROR_OK;
498 
499  return rp2040_flash_probe(bank);
500 }
501 
503 {
504  free(bank->driver_priv);
505  bank->driver_priv = NULL;
506 }
507 
508 /* -----------------------------------------------------------------------------
509  Driver boilerplate */
510 
511 FLASH_BANK_COMMAND_HANDLER(rp2040_flash_bank_command)
512 {
513  struct rp2040_flash_bank *priv;
514  priv = malloc(sizeof(struct rp2040_flash_bank));
515  priv->probed = false;
516 
517  /* Set up driver_priv */
518  bank->driver_priv = priv;
519 
520  return ERROR_OK;
521 }
522 
523 const struct flash_driver rp2040_flash = {
524  .name = "rp2040_flash",
525  .flash_bank_command = rp2040_flash_bank_command,
526  .erase = rp2040_flash_erase,
527  .write = rp2040_flash_write,
528  .read = default_flash_read,
529  .probe = rp2040_flash_probe,
530  .auto_probe = rp2040_flash_auto_probe,
531  .erase_check = default_flash_blank_check,
532  .free_driver_priv = rp2040_flash_free_driver_priv
533 };
void init_reg_param(struct reg_param *param, char *reg_name, uint32_t size, enum param_direction direction)
Definition: algorithm.c:29
void destroy_reg_param(struct reg_param *param)
Definition: algorithm.c:37
@ PARAM_OUT
Definition: algorithm.h:16
@ ARM_MODE_THREAD
Definition: arm.h:94
#define ARMV7M_COMMON_MAGIC
Definition: armv7m.h:220
Support functions to access arbitrary bits in a byte array.
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned int first, unsigned int num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 32-bit word.
Definition: binarybuffer.h:104
static void buf_set_u32(uint8_t *_buffer, unsigned int first, unsigned int num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
Definition: binarybuffer.h:34
uint8_t bank
Definition: esirisc.c:135
static struct esp_usb_jtag * priv
Definition: esp_usb_jtag.c:219
uint8_t length
Definition: esp_usb_jtag.c:1
struct flash_sector * alloc_block_array(uint32_t offset, uint32_t size, unsigned int num_blocks)
Allocate and fill an array of sectors or protection blocks.
int default_flash_blank_check(struct flash_bank *bank)
Provides default erased-bank check handling.
int default_flash_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
Provides default read implementation for flash memory.
#define ERROR_FAIL
Definition: log.h:170
#define LOG_TARGET_DEBUG(target, fmt_str,...)
Definition: log.h:149
#define LOG_ERROR(expr ...)
Definition: log.h:132
#define LOG_INFO(expr ...)
Definition: log.h:126
#define LOG_DEBUG(expr ...)
Definition: log.h:109
#define ERROR_OK
Definition: log.h:164
#define MIN(a, b)
Definition: replacements.h:22
#define MAX(a, b)
Definition: replacements.h:25
#define FUNC_FLASH_RANGE_ERASE
Definition: rp2040.c:30
static int rp2040_flash_auto_probe(struct flash_bank *bank)
Definition: rp2040.c:492
static int rp2040_flash_probe(struct flash_bank *bank)
Definition: rp2040.c:379
#define FUNC_FLASH_FLUSH_CACHE
Definition: rp2040.c:32
#define FUNC_DEBUG_TRAMPOLINE_END
Definition: rp2040.c:27
static int rp2040_finalize_stack_free(struct flash_bank *bank)
Definition: rp2040.c:152
#define BOOTROM_MAGIC
Definition: rp2040.c:17
#define FUNC_FLASH_EXIT_XIP
Definition: rp2040.c:28
const struct flash_driver rp2040_flash
Definition: rp2040.c:523
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)
Definition: rp2040.c:93
static int rp2040_flash_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
Definition: rp2040.c:278
static int rp2040_spi_read_flash_id(struct target *target, uint32_t *devid)
Definition: rp2040.c:349
#define FUNC_CONNECT_INTERNAL_FLASH
Definition: rp2040.c:29
FLASH_BANK_COMMAND_HANDLER(rp2040_flash_bank_command)
Definition: rp2040.c:511
static int rp2040_stack_grab_and_prep(struct flash_bank *bank)
Definition: rp2040.c:184
#define BOOTROM_MAGIC_ADDR
Definition: rp2040.c:18
static int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
Definition: rp2040.c:214
static const struct flash_device rp2040_default_spi_device
Definition: rp2040.c:54
static void rp2040_flash_free_driver_priv(struct flash_bank *bank)
Definition: rp2040.c:502
static uint32_t rp2040_lookup_symbol(struct target *target, uint32_t tag, uint16_t *symbol)
Definition: rp2040.c:57
#define FUNC_FLASH_RANGE_PROGRAM
Definition: rp2040.c:31
#define FUNC_DEBUG_TRAMPOLINE
Definition: rp2040.c:26
static int rp2040_ssel_active(struct target *target, bool active)
Definition: rp2040.c:328
#define FUNC_FLASH_ENTER_CMD_XIP
Definition: rp2040.c:33
const struct flash_device flash_devices[]
Definition: spi.c:24
#define FLASH_ID(n, re, qr, pp, es, ces, id, psize, ssize, size)
Definition: spi.h:33
#define SPIFLASH_READ_ID
Definition: spi.h:72
unsigned int common_magic
Definition: armv7m.h:295
enum arm_mode core_mode
Definition: armv7m.h:297
Provides details of a flash bank, available either on-chip or through a major interface.
Definition: nor/core.h:75
const char * name
Definition: spi.h:21
Provides the implementation-independent structure that defines all of the callbacks required by OpenO...
Definition: nor/driver.h:39
const char * name
Gives a human-readable name of this flash driver, This field is used to select and initialize the dri...
Definition: nor/driver.h:44
uint16_t jump_debug_trampoline_end
Definition: rp2040.c:42
uint16_t jump_flush_cache
Definition: rp2040.c:47
const struct flash_device * dev
Definition: rp2040.c:50
uint16_t jump_flash_range_program
Definition: rp2040.c:46
uint16_t jump_flash_range_erase
Definition: rp2040.c:45
struct working_area * stack
Definition: rp2040.c:39
uint16_t jump_flash_exit_xip
Definition: rp2040.c:43
uint16_t jump_connect_internal_flash
Definition: rp2040.c:44
uint16_t jump_enter_cmd_xip
Definition: rp2040.c:48
uint16_t jump_debug_trampoline
Definition: rp2040.c:41
Definition: target.h:116
enum target_state state
Definition: target.h:157
target_addr_t address
Definition: target.h:86
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
Definition: target.c:2342
int target_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_param, target_addr_t entry_point, target_addr_t exit_point, unsigned int timeout_ms, void *arch_info)
Downloads a target-specific native code algorithm to the target, and executes it.
Definition: target.c:773
uint32_t target_get_working_area_avail(struct target *target)
Definition: target.c:2164
int target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)
Definition: target.c:2060
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
Definition: target.c:2641
int target_free_working_area(struct target *target, struct working_area *area)
Free a working area.
Definition: target.c:2118
int target_read_u16(struct target *target, target_addr_t address, uint16_t *value)
Definition: target.c:2574
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
Definition: target.c:2550
#define ERROR_TARGET_NOT_HALTED
Definition: target.h:790
@ TARGET_HALTED
Definition: target.h:56
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
Definition: target.h:794
#define TARGET_ADDR_FMT
Definition: types.h:342
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.
Definition: types.h:57
uint64_t target_addr_t
Definition: types.h:335
#define NULL
Definition: usb.h:16
uint8_t status[4]
Definition: vdebug.c:17
uint8_t offset[4]
Definition: vdebug.c:9
uint8_t state[4]
Definition: vdebug.c:21
uint8_t count[4]
Definition: vdebug.c:22