flash/nor/rp2040: remove new line from error message
[fw/openocd] / src / flash / nor / rp2040.c
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
35 struct rp2040_flash_bank {
36         /* flag indicating successful flash probe */
37         bool probed;
38         /* stack used by Boot ROM calls */
39         struct working_area *stack;
40         /* function jump table populated by rp2040_flash_probe() */
41         uint16_t jump_debug_trampoline;
42         uint16_t jump_debug_trampoline_end;
43         uint16_t jump_flash_exit_xip;
44         uint16_t jump_connect_internal_flash;
45         uint16_t jump_flash_range_erase;
46         uint16_t jump_flash_range_program;
47         uint16_t jump_flush_cache;
48         uint16_t jump_enter_cmd_xip;
49         /* detected model of SPI flash */
50         const struct flash_device *dev;
51 };
52
53 static uint32_t rp2040_lookup_symbol(struct target *target, uint32_t tag, uint16_t *symbol)
54 {
55         uint32_t magic;
56         int err = target_read_u32(target, BOOTROM_MAGIC_ADDR, &magic);
57         if (err != ERROR_OK)
58                 return err;
59
60         magic &= 0xffffff; /* ignore bootrom version */
61         if (magic != BOOTROM_MAGIC) {
62                 if (!((magic ^ BOOTROM_MAGIC)&0xffff))
63                         LOG_ERROR("Incorrect RP2040 BOOT ROM version");
64                 else
65                         LOG_ERROR("RP2040 BOOT ROM not found");
66                 return ERROR_FAIL;
67         }
68
69         /* dereference the table pointer */
70         uint16_t table_entry;
71         err = target_read_u16(target, BOOTROM_MAGIC_ADDR + 4, &table_entry);
72         if (err != ERROR_OK)
73                 return err;
74
75         uint16_t entry_tag;
76         do {
77                 err = target_read_u16(target, table_entry, &entry_tag);
78                 if (err != ERROR_OK)
79                         return err;
80                 if (entry_tag == tag) {
81                         /* 16 bit symbol is next */
82                         return target_read_u16(target, table_entry + 2, symbol);
83                 }
84                 table_entry += 4;
85         } while (entry_tag);
86         return ERROR_FAIL;
87 }
88
89 static int rp2040_call_rom_func(struct target *target, struct rp2040_flash_bank *priv,
90                 uint16_t func_offset, uint32_t argdata[], unsigned int n_args, int timeout_ms)
91 {
92         char *regnames[4] = { "r0", "r1", "r2", "r3" };
93
94         assert(n_args <= ARRAY_SIZE(regnames)); /* only allow register arguments */
95
96         if (!priv->stack) {
97                 LOG_ERROR("no stack for flash programming code");
98                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
99         }
100         target_addr_t stacktop = priv->stack->address + priv->stack->size;
101
102         LOG_TARGET_DEBUG(target, "Calling ROM func @0x%" PRIx16 " with %u arguments", func_offset, n_args);
103
104         struct reg_param args[ARRAY_SIZE(regnames) + 2];
105         struct armv7m_algorithm alg_info;
106
107         for (unsigned int i = 0; i < n_args; ++i) {
108                 init_reg_param(&args[i], regnames[i], 32, PARAM_OUT);
109                 buf_set_u32(args[i].value, 0, 32, argdata[i]);
110         }
111         /* Pass function pointer in r7 */
112         init_reg_param(&args[n_args], "r7", 32, PARAM_OUT);
113         buf_set_u32(args[n_args].value, 0, 32, func_offset);
114         init_reg_param(&args[n_args + 1], "sp", 32, PARAM_OUT);
115         buf_set_u32(args[n_args + 1].value, 0, 32, stacktop);
116
117
118         for (unsigned int i = 0; i < n_args + 2; ++i)
119                 LOG_DEBUG("Set %s = 0x%" PRIx32, args[i].reg_name, buf_get_u32(args[i].value, 0, 32));
120
121         /* Actually call the function */
122         alg_info.common_magic = ARMV7M_COMMON_MAGIC;
123         alg_info.core_mode = ARM_MODE_THREAD;
124         int err = target_run_algorithm(
125                 target,
126                 0, NULL,          /* No memory arguments */
127                 n_args + 1, args, /* User arguments + r7 */
128                 priv->jump_debug_trampoline, priv->jump_debug_trampoline_end,
129                 timeout_ms,
130                 &alg_info
131         );
132         for (unsigned int i = 0; i < n_args + 2; ++i)
133                 destroy_reg_param(&args[i]);
134         if (err != ERROR_OK)
135                 LOG_ERROR("Failed to invoke ROM function @0x%" PRIx16, func_offset);
136         return err;
137
138 }
139
140 /* Finalize flash write/erase/read ID
141  * - flush cache
142  * - enters memory-mapped (XIP) mode to make flash data visible
143  * - deallocates target ROM func stack if previously allocated
144  */
145 static int rp2040_finalize_stack_free(struct flash_bank *bank)
146 {
147         struct rp2040_flash_bank *priv = bank->driver_priv;
148         struct target *target = bank->target;
149
150         /* Always flush before returning to execute-in-place, to invalidate stale
151          * cache contents. The flush call also restores regular hardware-controlled
152          * chip select following a rp2040_flash_exit_xip().
153          */
154         LOG_DEBUG("Flushing flash cache after write behind");
155         int err = rp2040_call_rom_func(target, priv, priv->jump_flush_cache, NULL, 0, 1000);
156         if (err != ERROR_OK) {
157                 LOG_ERROR("Failed to flush flash cache");
158                 /* Intentionally continue after error and try to setup xip anyway */
159         }
160
161         LOG_DEBUG("Configuring SSI for execute-in-place");
162         err = rp2040_call_rom_func(target, priv, priv->jump_enter_cmd_xip, NULL, 0, 1000);
163         if (err != ERROR_OK)
164                 LOG_ERROR("Failed to set SSI to XIP mode");
165
166         target_free_working_area(target, priv->stack);
167         priv->stack = NULL;
168         return err;
169 }
170
171 /* Prepare flash write/erase/read ID
172  * - allocates a stack for target ROM func
173  * - switches the SPI interface from memory-mapped mode to direct command mode
174  * Always pair with a call of rp2040_finalize_stack_free()
175  * after flash operation finishes or fails.
176  */
177 static int rp2040_stack_grab_and_prep(struct flash_bank *bank)
178 {
179         struct rp2040_flash_bank *priv = bank->driver_priv;
180         struct target *target = bank->target;
181
182         /* target_alloc_working_area always allocates multiples of 4 bytes, so no worry about alignment */
183         const int STACK_SIZE = 256;
184         int err = target_alloc_working_area(target, STACK_SIZE, &priv->stack);
185         if (err != ERROR_OK) {
186                 LOG_ERROR("Could not allocate stack for flash programming code");
187                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
188         }
189
190         LOG_DEBUG("Connecting internal flash");
191         err = rp2040_call_rom_func(target, priv, priv->jump_connect_internal_flash, NULL, 0, 1000);
192         if (err != ERROR_OK) {
193                 LOG_ERROR("Failed to connect internal flash");
194                 return err;
195         }
196
197         LOG_DEBUG("Kicking flash out of XIP mode");
198         err = rp2040_call_rom_func(target, priv, priv->jump_flash_exit_xip, NULL, 0, 1000);
199         if (err != ERROR_OK) {
200                 LOG_ERROR("Failed to exit flash XIP mode");
201                 return err;
202         }
203
204         return ERROR_OK;
205 }
206
207 static int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
208 {
209         LOG_DEBUG("Writing %d bytes starting at 0x%" PRIx32, count, offset);
210
211         struct rp2040_flash_bank *priv = bank->driver_priv;
212         struct target *target = bank->target;
213
214         if (target->state != TARGET_HALTED) {
215                 LOG_ERROR("Target not halted");
216                 return ERROR_TARGET_NOT_HALTED;
217         }
218
219         struct working_area *bounce = NULL;
220
221         int err = rp2040_stack_grab_and_prep(bank);
222         if (err != ERROR_OK)
223                 goto cleanup;
224
225         unsigned int avail_pages = target_get_working_area_avail(target) / priv->dev->pagesize;
226         /* We try to allocate working area rounded down to device page size,
227          * al least 1 page, at most the write data size
228          */
229         unsigned int chunk_size = MIN(MAX(avail_pages, 1) * priv->dev->pagesize, count);
230         err = target_alloc_working_area(target, chunk_size, &bounce);
231         if (err != ERROR_OK) {
232                 LOG_ERROR("Could not allocate bounce buffer for flash programming. Can't continue");
233                 goto cleanup;
234         }
235
236         LOG_DEBUG("Allocated flash bounce buffer @" TARGET_ADDR_FMT, bounce->address);
237
238         while (count > 0) {
239                 uint32_t write_size = count > chunk_size ? chunk_size : count;
240                 LOG_DEBUG("Writing %d bytes to offset 0x%" PRIx32, write_size, offset);
241                 err = target_write_buffer(target, bounce->address, write_size, buffer);
242                 if (err != ERROR_OK) {
243                         LOG_ERROR("Could not load data into target bounce buffer");
244                         break;
245                 }
246                 uint32_t args[3] = {
247                         offset, /* addr */
248                         bounce->address, /* data */
249                         write_size /* count */
250                 };
251                 err = rp2040_call_rom_func(target, priv, priv->jump_flash_range_program,
252                                                                  args, ARRAY_SIZE(args), 3000);
253                 if (err != ERROR_OK) {
254                         LOG_ERROR("Failed to invoke flash programming code on target");
255                         break;
256                 }
257
258                 buffer += write_size;
259                 offset += write_size;
260                 count -= write_size;
261         }
262
263 cleanup:
264         target_free_working_area(target, bounce);
265
266         rp2040_finalize_stack_free(bank);
267
268         return err;
269 }
270
271 static int rp2040_flash_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
272 {
273         struct rp2040_flash_bank *priv = bank->driver_priv;
274         struct target *target = bank->target;
275
276         if (target->state != TARGET_HALTED) {
277                 LOG_ERROR("Target not halted");
278                 return ERROR_TARGET_NOT_HALTED;
279         }
280
281         uint32_t start_addr = bank->sectors[first].offset;
282         uint32_t length = bank->sectors[last].offset + bank->sectors[last].size - start_addr;
283         LOG_DEBUG("RP2040 erase %d bytes starting at 0x%" PRIx32, length, start_addr);
284
285         int err = rp2040_stack_grab_and_prep(bank);
286         if (err != ERROR_OK)
287                 goto cleanup;
288
289         LOG_DEBUG("Remote call flash_range_erase");
290
291         uint32_t args[4] = {
292                 bank->sectors[first].offset, /* addr */
293                 bank->sectors[last].offset + bank->sectors[last].size - bank->sectors[first].offset, /* count */
294                 priv->dev->sectorsize, /* block_size */
295                 priv->dev->erase_cmd /* block_cmd */
296         };
297
298         /*
299         The RP2040 Boot ROM provides a _flash_range_erase() API call documented in Section 2.8.3.1.3:
300         https://datasheets.raspberrypi.org/rp2040/rp2040-datasheet.pdf
301         and the particular source code for said Boot ROM function can be found here:
302         https://github.com/raspberrypi/pico-bootrom/blob/master/bootrom/program_flash_generic.c
303
304         In theory, the function algorithm provides for erasing both a smaller "sector" (4096 bytes) and
305         an optional larger "block" (size and command provided in args).
306         */
307
308         int timeout_ms = 2000 * (last - first) + 1000;
309         err = rp2040_call_rom_func(target, priv, priv->jump_flash_range_erase,
310                                                         args, ARRAY_SIZE(args), timeout_ms);
311
312 cleanup:
313         rp2040_finalize_stack_free(bank);
314
315         return err;
316 }
317
318 /* -----------------------------------------------------------------------------
319    Driver probing etc */
320
321 static int rp2040_ssel_active(struct target *target, bool active)
322 {
323         const target_addr_t qspi_ctrl_addr = 0x4001800c;
324         const uint32_t qspi_ctrl_outover_low  = 2UL << 8;
325         const uint32_t qspi_ctrl_outover_high = 3UL << 8;
326         uint32_t state = (active) ? qspi_ctrl_outover_low : qspi_ctrl_outover_high;
327         uint32_t val;
328
329         int err = target_read_u32(target, qspi_ctrl_addr, &val);
330         if (err != ERROR_OK)
331                 return err;
332
333         val = (val & ~qspi_ctrl_outover_high) | state;
334
335         err = target_write_u32(target, qspi_ctrl_addr, val);
336         if (err != ERROR_OK)
337                 return err;
338
339         return ERROR_OK;
340 }
341
342 static int rp2040_spi_read_flash_id(struct target *target, uint32_t *devid)
343 {
344         uint32_t device_id = 0;
345         const target_addr_t ssi_dr0 = 0x18000060;
346
347         int err = rp2040_ssel_active(target, true);
348
349         /* write RDID request into SPI peripheral's FIFO */
350         for (int count = 0; (count < 4) && (err == ERROR_OK); count++)
351                 err = target_write_u32(target, ssi_dr0, SPIFLASH_READ_ID);
352
353         /* by this time, there is a receive FIFO entry for every write */
354         for (int count = 0; (count < 4) && (err == ERROR_OK); count++) {
355                 uint32_t status;
356                 err = target_read_u32(target, ssi_dr0, &status);
357
358                 device_id >>= 8;
359                 device_id |= (status & 0xFF) << 24;
360         }
361
362         if (err == ERROR_OK)
363                 *devid = device_id >> 8;
364
365         int err2 = rp2040_ssel_active(target, false);
366         if (err2 != ERROR_OK)
367                 LOG_ERROR("SSEL inactive failed");
368
369         return err;
370 }
371
372 static int rp2040_flash_probe(struct flash_bank *bank)
373 {
374         struct rp2040_flash_bank *priv = bank->driver_priv;
375         struct target *target = bank->target;
376
377         if (target->state != TARGET_HALTED) {
378                 LOG_ERROR("Target not halted");
379                 return ERROR_TARGET_NOT_HALTED;
380         }
381
382         int err = rp2040_lookup_symbol(target, FUNC_DEBUG_TRAMPOLINE, &priv->jump_debug_trampoline);
383         if (err != ERROR_OK) {
384                 LOG_ERROR("Debug trampoline not found in RP2040 ROM.");
385                 return err;
386         }
387         priv->jump_debug_trampoline &= ~1u; /* mask off thumb bit */
388
389         err = rp2040_lookup_symbol(target, FUNC_DEBUG_TRAMPOLINE_END, &priv->jump_debug_trampoline_end);
390         if (err != ERROR_OK) {
391                 LOG_ERROR("Debug trampoline end not found in RP2040 ROM.");
392                 return err;
393         }
394         priv->jump_debug_trampoline_end &= ~1u; /* mask off thumb bit */
395
396         err = rp2040_lookup_symbol(target, FUNC_FLASH_EXIT_XIP, &priv->jump_flash_exit_xip);
397         if (err != ERROR_OK) {
398                 LOG_ERROR("Function FUNC_FLASH_EXIT_XIP not found in RP2040 ROM.");
399                 return err;
400         }
401
402         err = rp2040_lookup_symbol(target, FUNC_CONNECT_INTERNAL_FLASH, &priv->jump_connect_internal_flash);
403         if (err != ERROR_OK) {
404                 LOG_ERROR("Function FUNC_CONNECT_INTERNAL_FLASH not found in RP2040 ROM.");
405                 return err;
406         }
407
408         err = rp2040_lookup_symbol(target, FUNC_FLASH_RANGE_ERASE, &priv->jump_flash_range_erase);
409         if (err != ERROR_OK) {
410                 LOG_ERROR("Function FUNC_FLASH_RANGE_ERASE not found in RP2040 ROM.");
411                 return err;
412         }
413
414         err = rp2040_lookup_symbol(target, FUNC_FLASH_RANGE_PROGRAM, &priv->jump_flash_range_program);
415         if (err != ERROR_OK) {
416                 LOG_ERROR("Function FUNC_FLASH_RANGE_PROGRAM not found in RP2040 ROM.");
417                 return err;
418         }
419
420         err = rp2040_lookup_symbol(target, FUNC_FLASH_FLUSH_CACHE, &priv->jump_flush_cache);
421         if (err != ERROR_OK) {
422                 LOG_ERROR("Function FUNC_FLASH_FLUSH_CACHE not found in RP2040 ROM.");
423                 return err;
424         }
425
426         err = rp2040_lookup_symbol(target, FUNC_FLASH_ENTER_CMD_XIP, &priv->jump_enter_cmd_xip);
427         if (err != ERROR_OK) {
428                 LOG_ERROR("Function FUNC_FLASH_ENTER_CMD_XIP not found in RP2040 ROM.");
429                 return err;
430         }
431
432         err = rp2040_stack_grab_and_prep(bank);
433
434         uint32_t device_id = 0;
435         if (err == ERROR_OK)
436                 err = rp2040_spi_read_flash_id(target, &device_id);
437
438         rp2040_finalize_stack_free(bank);
439
440         if (err != ERROR_OK)
441                 return err;
442
443         /* search for a SPI flash Device ID match */
444         priv->dev = NULL;
445         for (const struct flash_device *p = flash_devices; p->name ; p++)
446                 if (p->device_id == device_id) {
447                         priv->dev = p;
448                         break;
449                 }
450
451         if (!priv->dev) {
452                 LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32 ")", device_id);
453                 return ERROR_FAIL;
454         }
455
456         LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32 ")",
457                 priv->dev->name, priv->dev->device_id);
458
459         /* the Boot ROM flash_range_program() routine requires page alignment */
460         bank->write_start_alignment = priv->dev->pagesize;
461         bank->write_end_alignment = priv->dev->pagesize;
462
463         bank->size = priv->dev->size_in_bytes;
464
465         bank->num_sectors = bank->size / priv->dev->sectorsize;
466         LOG_INFO("RP2040 B0 Flash Probe: %d bytes @" TARGET_ADDR_FMT ", in %d sectors\n",
467                 bank->size, bank->base, bank->num_sectors);
468         bank->sectors = alloc_block_array(0, priv->dev->sectorsize, bank->num_sectors);
469         if (!bank->sectors)
470                 return ERROR_FAIL;
471
472         if (err == ERROR_OK)
473                 priv->probed = true;
474
475         return err;
476 }
477
478 static int rp2040_flash_auto_probe(struct flash_bank *bank)
479 {
480         struct rp2040_flash_bank *priv = bank->driver_priv;
481
482         if (priv->probed)
483                 return ERROR_OK;
484
485         return rp2040_flash_probe(bank);
486 }
487
488 static void rp2040_flash_free_driver_priv(struct flash_bank *bank)
489 {
490         free(bank->driver_priv);
491         bank->driver_priv = NULL;
492 }
493
494 /* -----------------------------------------------------------------------------
495    Driver boilerplate */
496
497 FLASH_BANK_COMMAND_HANDLER(rp2040_flash_bank_command)
498 {
499         struct rp2040_flash_bank *priv;
500         priv = malloc(sizeof(struct rp2040_flash_bank));
501         priv->probed = false;
502
503         /* Set up driver_priv */
504         bank->driver_priv = priv;
505
506         return ERROR_OK;
507 }
508
509 struct flash_driver rp2040_flash = {
510         .name = "rp2040_flash",
511         .flash_bank_command = rp2040_flash_bank_command,
512         .erase =  rp2040_flash_erase,
513         .write = rp2040_flash_write,
514         .read = default_flash_read,
515         .probe = rp2040_flash_probe,
516         .auto_probe = rp2040_flash_auto_probe,
517         .erase_check = default_flash_blank_check,
518         .free_driver_priv = rp2040_flash_free_driver_priv
519 };