jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / flash / nor / at91sam4l.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4 * Copyright (C) 2013 by Andrey Yurovsky *
5 * Andrey Yurovsky <yurovsky@gmail.com> *
6 ***************************************************************************/
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
12 #include "imp.h"
13
14 #include <jtag/jtag.h>
15 #include <target/cortex_m.h>
16
17 /* At this time, the SAM4L Flash is available in these capacities:
18 * ATSAM4Lx4xx: 256KB (512 pages)
19 * ATSAM4Lx2xx: 128KB (256 pages)
20 * ATSAM4Lx8xx: 512KB (1024 pages)
21 */
22
23 /* There are 16 lockable regions regardless of overall capacity. The number
24 * of pages per sector is therefore dependant on capacity. */
25 #define SAM4L_NUM_SECTORS 16
26
27 /* Locations in memory map */
28 #define SAM4L_FLASH ((uint32_t)0x00000000) /* Flash region */
29 #define SAM4L_FLASH_USER 0x00800000 /* Flash user page region */
30 #define SAM4L_FLASHCALW 0x400A0000 /* Flash controller */
31 #define SAM4L_CHIPID 0x400E0740 /* Chip Identification */
32
33 /* Offsets from SAM4L_FLASHCALW */
34 #define SAM4L_FCR 0x00 /* Flash Control Register (RW) */
35 #define SAM4L_FCMD 0x04 /* Flash Command Register (RW) */
36 #define SAM4L_FSR 0x08 /* Flash Status Register (RO) */
37 #define SAM4L_FPR 0x0C /* Flash Parameter Register (RO) */
38 #define SAM4L_FVR 0x10 /* Flash Version Register (RO) */
39 #define SAM4L_FGPFRHI 0x14 /* Flash General Purpose Register High (RO) */
40 #define SAM4L_FGPFRLO 0x18 /* Flash General Purpose Register Low (RO) */
41
42 /* Offsets from SAM4L_CHIPID */
43 #define SAM4L_CIDR 0x00 /* Chip ID Register (RO) */
44 #define SAM4L_EXID 0x04 /* Chip ID Extension Register (RO) */
45
46 /* Flash commands (for SAM4L_FCMD), see Table 14-5 */
47 #define SAM4L_FCMD_NOP 0 /* No Operation */
48 #define SAM4L_FCMD_WP 1 /* Write Page */
49 #define SAM4L_FCMD_EP 2 /* Erase Page */
50 #define SAM4L_FCMD_CPB 3 /* Clear Page Buffer */
51 #define SAM4L_FCMD_LP 4 /* Lock region containing given page */
52 #define SAM4L_FCMD_UP 5 /* Unlock region containing given page */
53 #define SAM4L_FCMD_EA 6 /* Erase All */
54 #define SAM4L_FCMD_WGPB 7 /* Write general-purpose fuse bit */
55 #define SAM4L_FCMD_EGPB 8 /* Erase general-purpose fuse bit */
56 #define SAM4L_FCMD_SSB 9 /* Set security fuses */
57 #define SAM4L_FCMD_PGPFB 10 /* Program general-purpose fuse byte */
58 #define SAM4L_FCMD_EAGPF 11 /* Erase all general-purpose fuse bits */
59 #define SAM4L_FCMD_QPR 12 /* Quick page read */
60 #define SAM4L_FCMD_WUP 13 /* Write user page */
61 #define SAM4L_FCMD_EUP 14 /* Erase user page */
62 #define SAM4L_FCMD_QPRUP 15 /* Quick page read (user page) */
63 #define SAM4L_FCMD_HSEN 16 /* High speed mode enable */
64 #define SAM4L_FCMD_HSDIS 17 /* High speed mode disable */
65
66 #define SAM4L_FMCD_CMDKEY 0xA5UL /* 'key' to issue commands, see 14.10.2 */
67
68
69 /* SMAP registers and bits */
70 #define SMAP_BASE 0x400A3000
71
72 #define SMAP_SCR (SMAP_BASE + 8)
73 #define SMAP_SCR_HCR (1 << 1)
74
75
76 struct sam4l_chip_info {
77 uint32_t id;
78 uint32_t exid;
79 const char *name;
80 };
81
82 /* These are taken from Table 9-1 in 42023E-SAM-07/2013 */
83 static const struct sam4l_chip_info sam4l_known_chips[] = {
84 { 0xAB0B0AE0, 0x1400000F, "ATSAM4LC8C" },
85 { 0xAB0A09E0, 0x0400000F, "ATSAM4LC4C" },
86 { 0xAB0A07E0, 0x0400000F, "ATSAM4LC2C" },
87 { 0xAB0B0AE0, 0x1300000F, "ATSAM4LC8B" },
88 { 0xAB0A09E0, 0x0300000F, "ATSAM4LC4B" },
89 { 0xAB0A07E0, 0x0300000F, "ATSAM4LC2B" },
90 { 0xAB0B0AE0, 0x1200000F, "ATSAM4LC8A" },
91 { 0xAB0A09E0, 0x0200000F, "ATSAM4LC4A" },
92 { 0xAB0A07E0, 0x0200000F, "ATSAM4LC2A" },
93 { 0xAB0B0AE0, 0x14000002, "ATSAM4LS8C" },
94 { 0xAB0A09E0, 0x04000002, "ATSAM4LS4C" },
95 { 0xAB0A07E0, 0x04000002, "ATSAM4LS2C" },
96 { 0xAB0B0AE0, 0x13000002, "ATSAM4LS8B" },
97 { 0xAB0A09E0, 0x03000002, "ATSAM4LS4B" },
98 { 0xAB0A07E0, 0x03000002, "ATSAM4LS2B" },
99 { 0xAB0B0AE0, 0x12000002, "ATSAM4LS8A" },
100 { 0xAB0A09E0, 0x02000002, "ATSAM4LS4A" },
101 { 0xAB0A07E0, 0x02000002, "ATSAM4LS2A" },
102 };
103
104 /* Meaning of SRAMSIZ field in CHIPID, see 9.3.1 in 42023E-SAM-07/2013 */
105 static const uint16_t sam4l_ram_sizes[16] = { 48, 1, 2, 6, 24, 4, 80, 160, 8, 16, 32, 64, 128, 256, 96, 512 };
106
107 /* Meaning of PSZ field in FPR, see 14.10.4 in 42023E-SAM-07/2013 */
108 static const uint16_t sam4l_page_sizes[8] = { 32, 64, 128, 256, 512, 1024, 2048, 4096 };
109
110 struct sam4l_info {
111 const struct sam4l_chip_info *details;
112
113 uint32_t flash_kb;
114 uint32_t ram_kb;
115 uint32_t page_size;
116 int num_pages;
117 int sector_size;
118 unsigned int pages_per_sector;
119
120 bool probed;
121 struct target *target;
122 };
123
124
125 static int sam4l_flash_wait_until_ready(struct target *target)
126 {
127 volatile unsigned int t = 0;
128 uint32_t st;
129 int res;
130
131 /* Poll the status register until the FRDY bit is set */
132 do {
133 res = target_read_u32(target, SAM4L_FLASHCALW + SAM4L_FSR, &st);
134 } while (res == ERROR_OK && !(st & (1<<0)) && ++t < 10);
135
136 return res;
137 }
138
139 static int sam4l_flash_check_error(struct target *target, uint32_t *err)
140 {
141 uint32_t st;
142 int res;
143
144 res = target_read_u32(target, SAM4L_FLASHCALW + SAM4L_FSR, &st);
145
146 if (res == ERROR_OK)
147 *err = st & ((1<<3) | (1<<2)); /* grab PROGE and LOCKE bits */
148
149 return res;
150 }
151
152 static int sam4l_flash_command(struct target *target, uint8_t cmd, int page)
153 {
154 int res;
155 uint32_t fcmd;
156 uint32_t err;
157
158 res = sam4l_flash_wait_until_ready(target);
159 if (res != ERROR_OK)
160 return res;
161
162 if (page >= 0) {
163 /* Set the page number. For some commands, the page number is just an
164 * argument (ex: fuse bit number). */
165 fcmd = (SAM4L_FMCD_CMDKEY << 24) | ((page & 0xFFFF) << 8) | (cmd & 0x3F);
166 } else {
167 /* Reuse the page number that was read from the flash command register. */
168 res = target_read_u32(target, SAM4L_FLASHCALW + SAM4L_FCMD, &fcmd);
169 if (res != ERROR_OK)
170 return res;
171
172 fcmd &= ~0x3F; /* clear out the command code */
173 fcmd |= (SAM4L_FMCD_CMDKEY << 24) | (cmd & 0x3F);
174 }
175
176 /* Send the command */
177 res = target_write_u32(target, SAM4L_FLASHCALW + SAM4L_FCMD, fcmd);
178 if (res != ERROR_OK)
179 return res;
180
181 res = sam4l_flash_check_error(target, &err);
182 if (res != ERROR_OK)
183 return res;
184
185 if (err != 0)
186 LOG_ERROR("%s got error status 0x%08" PRIx32, __func__, err);
187
188 res = sam4l_flash_wait_until_ready(target);
189
190 return res;
191 }
192
193 FLASH_BANK_COMMAND_HANDLER(sam4l_flash_bank_command)
194 {
195 if (bank->base != SAM4L_FLASH) {
196 LOG_ERROR("Address " TARGET_ADDR_FMT
197 " invalid bank address (try 0x%08" PRIx32
198 "[at91sam4l series] )",
199 bank->base, SAM4L_FLASH);
200 return ERROR_FAIL;
201 }
202
203 struct sam4l_info *chip;
204 chip = calloc(1, sizeof(*chip));
205 if (!chip) {
206 LOG_ERROR("No memory for flash bank chip info");
207 return ERROR_FAIL;
208 }
209
210 chip->target = bank->target;
211 chip->probed = false;
212
213 bank->driver_priv = chip;
214
215 return ERROR_OK;
216 }
217
218 static const struct sam4l_chip_info *sam4l_find_chip_name(uint32_t id, uint32_t exid)
219 {
220 unsigned int i;
221
222 id &= ~0xF;
223
224 for (i = 0; i < ARRAY_SIZE(sam4l_known_chips); i++) {
225 if (sam4l_known_chips[i].id == id && sam4l_known_chips[i].exid == exid)
226 return &sam4l_known_chips[i];
227 }
228
229 return NULL;
230 }
231
232 static int sam4l_check_page_erased(struct flash_bank *bank, uint32_t pn,
233 bool *is_erased_p)
234 {
235 int res;
236 uint32_t st;
237
238 /* Issue a quick page read to verify that we've erased this page */
239 res = sam4l_flash_command(bank->target, SAM4L_FCMD_QPR, pn);
240 if (res != ERROR_OK) {
241 LOG_ERROR("Quick page read %" PRIu32 " failed", pn);
242 return res;
243 }
244
245 /* Retrieve the flash status */
246 res = target_read_u32(bank->target, SAM4L_FLASHCALW + SAM4L_FSR, &st);
247 if (res != ERROR_OK) {
248 LOG_ERROR("Couldn't read erase status");
249 return res;
250 }
251
252 /* Is the page in question really erased? */
253 *is_erased_p = !!(st & (1<<5));
254
255 return ERROR_OK;
256 }
257
258 static int sam4l_probe(struct flash_bank *bank)
259 {
260 uint32_t id, exid, param;
261 int res;
262 struct sam4l_info *chip = (struct sam4l_info *)bank->driver_priv;
263
264 if (chip->probed)
265 return ERROR_OK;
266
267 res = target_read_u32(bank->target, SAM4L_CHIPID + SAM4L_CIDR, &id);
268 if (res != ERROR_OK) {
269 LOG_ERROR("Couldn't read chip ID");
270 return res;
271 }
272
273 res = target_read_u32(bank->target, SAM4L_CHIPID + SAM4L_EXID, &exid);
274 if (res != ERROR_OK) {
275 LOG_ERROR("Couldn't read extended chip ID");
276 return res;
277 }
278
279 chip->details = sam4l_find_chip_name(id, exid);
280
281 /* The RAM capacity is in a lookup table. */
282 chip->ram_kb = sam4l_ram_sizes[0xF & (id >> 16)];
283
284 switch (0xF & (id >> 8)) {
285 case 0x07:
286 chip->flash_kb = 128;
287 break;
288 case 0x09:
289 chip->flash_kb = 256;
290 break;
291 case 0x0A:
292 chip->flash_kb = 512;
293 break;
294 default:
295 LOG_ERROR("Unknown flash size (chip ID is %08" PRIx32 "), assuming 128K", id);
296 chip->flash_kb = 128;
297 break;
298 }
299
300 /* Retrieve the Flash parameters */
301 res = target_read_u32(bank->target, SAM4L_FLASHCALW + SAM4L_FPR, &param);
302 if (res != ERROR_OK) {
303 LOG_ERROR("Couldn't read Flash parameters");
304 return res;
305 }
306
307 /* Fetch the page size from the parameter register. Technically the flash
308 * capacity is there too though the manual mentions that not all parts will
309 * have it set so we use the Chip ID capacity information instead. */
310 chip->page_size = sam4l_page_sizes[0x7 & (param >> 8)];
311 assert(chip->page_size);
312 chip->num_pages = chip->flash_kb * 1024 / chip->page_size;
313
314 chip->sector_size = (chip->flash_kb * 1024) / SAM4L_NUM_SECTORS;
315 chip->pages_per_sector = chip->sector_size / chip->page_size;
316
317 /* Make sure the bank size is correct */
318 bank->size = chip->flash_kb * 1024;
319
320 /* Allocate the sector table. */
321 bank->num_sectors = SAM4L_NUM_SECTORS;
322 bank->sectors = calloc(bank->num_sectors, (sizeof((bank->sectors)[0])));
323 if (!bank->sectors)
324 return ERROR_FAIL;
325
326 /* Fill out the sector information: all SAM4L sectors are the same size and
327 * there is always a fixed number of them. */
328 for (unsigned int i = 0; i < bank->num_sectors; i++) {
329 bank->sectors[i].size = chip->sector_size;
330 bank->sectors[i].offset = i * chip->sector_size;
331 /* mark as unknown */
332 bank->sectors[i].is_erased = -1;
333 bank->sectors[i].is_protected = -1;
334 }
335
336 /* Done */
337 chip->probed = true;
338
339 LOG_INFO("SAM4L MCU: %s (Rev %c) (%" PRIu32 "KB Flash with %d %" PRIu32 "B pages, %" PRIu32 "KB RAM)",
340 chip->details ? chip->details->name : "unknown", (char)('A' + (id & 0xF)),
341 chip->flash_kb, chip->num_pages, chip->page_size, chip->ram_kb);
342
343 return ERROR_OK;
344 }
345
346 static int sam4l_protect_check(struct flash_bank *bank)
347 {
348 int res;
349 uint32_t st;
350 struct sam4l_info *chip = (struct sam4l_info *)bank->driver_priv;
351
352 if (bank->target->state != TARGET_HALTED) {
353 LOG_ERROR("Target not halted");
354
355 return ERROR_TARGET_NOT_HALTED;
356 }
357
358 if (!chip->probed) {
359 if (sam4l_probe(bank) != ERROR_OK)
360 return ERROR_FLASH_BANK_NOT_PROBED;
361 }
362
363 res = target_read_u32(bank->target, SAM4L_FLASHCALW + SAM4L_FSR, &st);
364 if (res != ERROR_OK)
365 return res;
366
367 st >>= 16; /* There are 16 lock region bits in the upper half word */
368 for (unsigned int i = 0; i < bank->num_sectors; i++)
369 bank->sectors[i].is_protected = !!(st & (1<<i));
370
371 return ERROR_OK;
372 }
373
374 static int sam4l_protect(struct flash_bank *bank, int set, unsigned int first,
375 unsigned int last)
376 {
377 struct sam4l_info *chip = (struct sam4l_info *)bank->driver_priv;
378
379 if (bank->target->state != TARGET_HALTED) {
380 LOG_ERROR("Target not halted");
381
382 return ERROR_TARGET_NOT_HALTED;
383 }
384
385 if (!chip->probed) {
386 if (sam4l_probe(bank) != ERROR_OK)
387 return ERROR_FLASH_BANK_NOT_PROBED;
388 }
389
390 /* Make sure the pages make sense. */
391 if (first >= bank->num_sectors || last >= bank->num_sectors) {
392 LOG_ERROR("Protect range %u - %u not valid (%u sectors total)", first, last,
393 bank->num_sectors);
394 return ERROR_FAIL;
395 }
396
397 /* Try to lock or unlock each sector in the range. This is done by locking
398 * a region containing one page in that sector, we arbitrarily choose the 0th
399 * page in the sector. */
400 for (unsigned int i = first; i <= last; i++) {
401 int res;
402
403 res = sam4l_flash_command(bank->target,
404 set ? SAM4L_FCMD_LP : SAM4L_FCMD_UP, i * chip->pages_per_sector);
405 if (res != ERROR_OK) {
406 LOG_ERROR("Can't %slock region containing page %d", set ? "" : "un", i);
407 return res;
408 }
409 }
410
411 return ERROR_OK;
412 }
413
414 static int sam4l_erase(struct flash_bank *bank, unsigned int first,
415 unsigned int last)
416 {
417 int ret;
418 struct sam4l_info *chip = (struct sam4l_info *)bank->driver_priv;
419
420 if (bank->target->state != TARGET_HALTED) {
421 LOG_ERROR("Target not halted");
422
423 return ERROR_TARGET_NOT_HALTED;
424 }
425
426 if (!chip->probed) {
427 if (sam4l_probe(bank) != ERROR_OK)
428 return ERROR_FLASH_BANK_NOT_PROBED;
429 }
430
431 /* Make sure the pages make sense. */
432 if (first >= bank->num_sectors || last >= bank->num_sectors) {
433 LOG_ERROR("Erase range %u - %u not valid (%u sectors total)", first, last,
434 bank->num_sectors);
435 return ERROR_FAIL;
436 }
437
438 /* Erase */
439 if ((first == 0) && ((last + 1) == bank->num_sectors)) {
440 LOG_DEBUG("Erasing the whole chip");
441
442 ret = sam4l_flash_command(bank->target, SAM4L_FCMD_EA, -1);
443 if (ret != ERROR_OK) {
444 LOG_ERROR("Erase All failed");
445 return ret;
446 }
447 } else {
448 LOG_DEBUG("Erasing sectors %u through %u...\n", first, last);
449
450 /* For each sector... */
451 for (unsigned int i = first; i <= last; i++) {
452 /* For each page in that sector... */
453 for (unsigned int j = 0; j < chip->pages_per_sector; j++) {
454 unsigned int pn = i * chip->pages_per_sector + j;
455 bool is_erased = false;
456
457 /* Issue the page erase */
458 ret = sam4l_flash_command(bank->target, SAM4L_FCMD_EP, pn);
459 if (ret != ERROR_OK) {
460 LOG_ERROR("Erasing page %u failed", pn);
461 return ret;
462 }
463
464 ret = sam4l_check_page_erased(bank, pn, &is_erased);
465 if (ret != ERROR_OK)
466 return ret;
467
468 if (!is_erased) {
469 LOG_DEBUG("Page %u was not erased.", pn);
470 return ERROR_FAIL;
471 }
472 }
473 }
474 }
475
476 return ERROR_OK;
477 }
478
479 /* Write an entire page from host buffer 'buf' to page-aligned 'address' in the
480 * Flash. */
481 static int sam4l_write_page(struct sam4l_info *chip, struct target *target,
482 uint32_t address, const uint8_t *buf)
483 {
484 int res;
485
486 LOG_DEBUG("sam4l_write_page address=%08" PRIx32, address);
487
488 /* Clear the page buffer before we write to it */
489 res = sam4l_flash_command(target, SAM4L_FCMD_CPB, -1);
490 if (res != ERROR_OK) {
491 LOG_ERROR("%s: can't clear page buffer", __func__);
492 return res;
493 }
494
495 /* Write the modified page back to the target's page buffer */
496 res = target_write_memory(target, address, 4, chip->page_size / 4, buf);
497
498 if (res != ERROR_OK) {
499 LOG_ERROR("%s: %d", __func__, __LINE__);
500 return res;
501 }
502
503 /* Commit the page contents to Flash: erase the current page and then
504 * write it out. */
505 res = sam4l_flash_command(target, SAM4L_FCMD_EP, -1);
506 if (res != ERROR_OK)
507 return res;
508 res = sam4l_flash_command(target, SAM4L_FCMD_WP, -1);
509
510 return res;
511 }
512
513 /* Write partial contents into page-aligned 'address' on the Flash from host
514 * buffer 'buf' by writing 'nb' of 'buf' at 'offset' into the Flash page. */
515 static int sam4l_write_page_partial(struct sam4l_info *chip,
516 struct flash_bank *bank, uint32_t address, const uint8_t *buf,
517 uint32_t page_offset, uint32_t nb)
518 {
519 int res;
520 uint8_t *pg = malloc(chip->page_size);
521 if (!pg)
522 return ERROR_FAIL;
523
524 LOG_DEBUG("sam4l_write_page_partial address=%08" PRIx32 " nb=%08" PRIx32, address, nb);
525
526 assert(page_offset + nb < chip->page_size);
527 assert((address % chip->page_size) == 0);
528
529 /* Retrieve the full page contents from Flash */
530 res = target_read_memory(bank->target, address, 4,
531 chip->page_size / 4, pg);
532 if (res != ERROR_OK) {
533 free(pg);
534 return res;
535 }
536
537 /* Insert our partial page over the data from Flash */
538 memcpy(pg + (page_offset % chip->page_size), buf, nb);
539
540 /* Write the page back out */
541 res = sam4l_write_page(chip, bank->target, address, pg);
542 free(pg);
543
544 return res;
545 }
546
547 static int sam4l_write(struct flash_bank *bank, const uint8_t *buffer,
548 uint32_t offset, uint32_t count)
549 {
550 int res;
551 uint32_t nb = 0;
552 struct sam4l_info *chip = (struct sam4l_info *)bank->driver_priv;
553
554 LOG_DEBUG("sam4l_write offset=%08" PRIx32 " count=%08" PRIx32, offset, count);
555
556 if (bank->target->state != TARGET_HALTED) {
557 LOG_ERROR("Target not halted");
558
559 return ERROR_TARGET_NOT_HALTED;
560 }
561
562 if (!chip->probed) {
563 if (sam4l_probe(bank) != ERROR_OK)
564 return ERROR_FLASH_BANK_NOT_PROBED;
565 }
566
567 if (offset % chip->page_size) {
568 /* We're starting at an unaligned offset so we'll write a partial page
569 * comprising that offset and up to the end of that page. */
570 nb = chip->page_size - (offset % chip->page_size);
571 if (nb > count)
572 nb = count;
573 } else if (count < chip->page_size) {
574 /* We're writing an aligned but partial page. */
575 nb = count;
576 }
577
578 if (nb > 0) {
579 res = sam4l_write_page_partial(chip, bank,
580 (offset / chip->page_size) * chip->page_size + bank->base,
581 buffer,
582 offset % chip->page_size, nb);
583 if (res != ERROR_OK)
584 return res;
585
586 /* We're done with the page contents */
587 count -= nb;
588 offset += nb;
589 }
590
591 /* There's at least one aligned page to write out. */
592 if (count >= chip->page_size) {
593 assert(chip->page_size > 0);
594 int np = count / chip->page_size + ((count % chip->page_size) ? 1 : 0);
595
596 for (int i = 0; i < np; i++) {
597 if (count >= chip->page_size) {
598 res = sam4l_write_page(chip, bank->target,
599 bank->base + offset,
600 buffer + (i * chip->page_size));
601 /* Advance one page */
602 offset += chip->page_size;
603 count -= chip->page_size;
604 } else {
605 res = sam4l_write_page_partial(chip, bank,
606 bank->base + offset,
607 buffer + (i * chip->page_size), 0, count);
608 /* We're done after this. */
609 offset += count;
610 count = 0;
611 }
612
613 if (res != ERROR_OK)
614 return res;
615 }
616 }
617
618 return ERROR_OK;
619 }
620
621
622 COMMAND_HANDLER(sam4l_handle_reset_deassert)
623 {
624 struct target *target = get_current_target(CMD_CTX);
625 int retval = ERROR_OK;
626 enum reset_types jtag_reset_config = jtag_get_reset_config();
627
628 /* If the target has been unresponsive before, try to re-establish
629 * communication now - CPU is held in reset by DSU, DAP is working */
630 if (!target_was_examined(target))
631 target_examine_one(target);
632 target_poll(target);
633
634 /* In case of sysresetreq, debug retains state set in cortex_m_assert_reset()
635 * so we just release reset held by SMAP
636 *
637 * n_RESET (srst) clears the DP, so reenable debug and set vector catch here
638 *
639 * After vectreset SMAP release is not needed however makes no harm
640 */
641 if (target->reset_halt && (jtag_reset_config & RESET_HAS_SRST)) {
642 retval = target_write_u32(target, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN);
643 if (retval == ERROR_OK)
644 retval = target_write_u32(target, DCB_DEMCR,
645 TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
646 /* do not return on error here, releasing SMAP reset is more important */
647 }
648
649 int retval2 = target_write_u32(target, SMAP_SCR, SMAP_SCR_HCR);
650 if (retval2 != ERROR_OK)
651 return retval2;
652
653 return retval;
654 }
655
656 static const struct command_registration at91sam4l_exec_command_handlers[] = {
657 {
658 .name = "smap_reset_deassert",
659 .handler = sam4l_handle_reset_deassert,
660 .mode = COMMAND_EXEC,
661 .help = "deassert internal reset held by SMAP",
662 .usage = "",
663 },
664 COMMAND_REGISTRATION_DONE
665 };
666
667 static const struct command_registration at91sam4l_command_handlers[] = {
668 {
669 .name = "at91sam4l",
670 .mode = COMMAND_ANY,
671 .help = "at91sam4l flash command group",
672 .usage = "",
673 .chain = at91sam4l_exec_command_handlers,
674 },
675 COMMAND_REGISTRATION_DONE
676 };
677
678 const struct flash_driver at91sam4l_flash = {
679 .name = "at91sam4l",
680 .commands = at91sam4l_command_handlers,
681 .flash_bank_command = sam4l_flash_bank_command,
682 .erase = sam4l_erase,
683 .protect = sam4l_protect,
684 .write = sam4l_write,
685 .read = default_flash_read,
686 .probe = sam4l_probe,
687 .auto_probe = sam4l_probe,
688 .erase_check = default_flash_blank_check,
689 .protect_check = sam4l_protect_check,
690 .free_driver_priv = default_flash_free_driver_priv,
691 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)