at91sam4: Add flash description and chipid for SAM4Cxx variants.
[openocd.git] / src / flash / nor / at91sam4.c
1 /***************************************************************************
2 * Copyright (C) 2009 by Duane Ellis *
3 * openocd@duaneellis.com *
4 * *
5 * Copyright (C) 2010 by Olaf Lüke (at91sam3s* support) *
6 * olaf@uni-paderborn.de *
7 * *
8 * Copyright (C) 2011 by Olivier Schonken, Jim Norris *
9 * (at91sam3x* & at91sam4 support)* *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
20 * *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
23 ****************************************************************************/
24
25 /* Some of the the lower level code was based on code supplied by
26 * ATMEL under this copyright. */
27
28 /* BEGIN ATMEL COPYRIGHT */
29 /* ----------------------------------------------------------------------------
30 * ATMEL Microcontroller Software Support
31 * ----------------------------------------------------------------------------
32 * Copyright (c) 2009, Atmel Corporation
33 *
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions are met:
38 *
39 * - Redistributions of source code must retain the above copyright notice,
40 * this list of conditions and the disclaimer below.
41 *
42 * Atmel's name may not be used to endorse or promote products derived from
43 * this software without specific prior written permission.
44 *
45 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
46 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
47 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
48 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
49 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
50 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
51 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
52 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
53 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
54 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55 * ----------------------------------------------------------------------------
56 */
57 /* END ATMEL COPYRIGHT */
58
59 #ifdef HAVE_CONFIG_H
60 #include "config.h"
61 #endif
62
63 #include "imp.h"
64 #include <helper/time_support.h>
65
66 #define REG_NAME_WIDTH (12)
67
68 /* at91sam4s/at91sam4e/at91sam4c series (has always one flash bank)*/
69 #define FLASH_BANK_BASE_S 0x00400000
70 #define FLASH_BANK_BASE_C 0x01000000
71
72 /* at91sam4sd series (two one flash banks), first bank address */
73 #define FLASH_BANK0_BASE_SD FLASH_BANK_BASE_S
74 /* at91sam4sd16x, second bank address */
75 #define FLASH_BANK1_BASE_1024K_SD (FLASH_BANK0_BASE_SD+(1024*1024/2))
76 /* at91sam4sd32x, second bank address */
77 #define FLASH_BANK1_BASE_2048K_SD (FLASH_BANK0_BASE_SD+(2048*1024/2))
78
79 /* at91sam4c32x, first and second bank address */
80 #define FLASH_BANK0_BASE_C32 FLASH_BANK_BASE_C
81 #define FLASH_BANK1_BASE_C32 (FLASH_BANK_BASE_C+(2048*1024/2))
82
83 #define AT91C_EFC_FCMD_GETD (0x0) /* (EFC) Get Flash Descriptor */
84 #define AT91C_EFC_FCMD_WP (0x1) /* (EFC) Write Page */
85 #define AT91C_EFC_FCMD_WPL (0x2) /* (EFC) Write Page and Lock */
86 #define AT91C_EFC_FCMD_EWP (0x3) /* (EFC) Erase Page and Write Page */
87 #define AT91C_EFC_FCMD_EWPL (0x4) /* (EFC) Erase Page and Write Page then Lock */
88 #define AT91C_EFC_FCMD_EA (0x5) /* (EFC) Erase All */
89 /* cmd6 is not present in the at91sam4u4/2/1 data sheet table 19-2 */
90 /* #define AT91C_EFC_FCMD_EPL (0x6) // (EFC) Erase plane? */
91 #define AT91C_EFC_FCMD_EPA (0x7) /* (EFC) Erase pages */
92 #define AT91C_EFC_FCMD_SLB (0x8) /* (EFC) Set Lock Bit */
93 #define AT91C_EFC_FCMD_CLB (0x9) /* (EFC) Clear Lock Bit */
94 #define AT91C_EFC_FCMD_GLB (0xA) /* (EFC) Get Lock Bit */
95 #define AT91C_EFC_FCMD_SFB (0xB) /* (EFC) Set Fuse Bit */
96 #define AT91C_EFC_FCMD_CFB (0xC) /* (EFC) Clear Fuse Bit */
97 #define AT91C_EFC_FCMD_GFB (0xD) /* (EFC) Get Fuse Bit */
98 #define AT91C_EFC_FCMD_STUI (0xE) /* (EFC) Start Read Unique ID */
99 #define AT91C_EFC_FCMD_SPUI (0xF) /* (EFC) Stop Read Unique ID */
100
101 #define offset_EFC_FMR 0
102 #define offset_EFC_FCR 4
103 #define offset_EFC_FSR 8
104 #define offset_EFC_FRR 12
105
106 extern struct flash_driver at91sam4_flash;
107
108 static float _tomhz(uint32_t freq_hz)
109 {
110 float f;
111
112 f = ((float)(freq_hz)) / 1000000.0;
113 return f;
114 }
115
116 /* How the chip is configured. */
117 struct sam4_cfg {
118 uint32_t unique_id[4];
119
120 uint32_t slow_freq;
121 uint32_t rc_freq;
122 uint32_t mainosc_freq;
123 uint32_t plla_freq;
124 uint32_t mclk_freq;
125 uint32_t cpu_freq;
126 uint32_t fclk_freq;
127 uint32_t pclk0_freq;
128 uint32_t pclk1_freq;
129 uint32_t pclk2_freq;
130
131
132 #define SAM4_CHIPID_CIDR (0x400E0740)
133 uint32_t CHIPID_CIDR;
134 #define SAM4_CHIPID_EXID (0x400E0744)
135 uint32_t CHIPID_EXID;
136
137 #define SAM4_PMC_BASE (0x400E0400)
138 #define SAM4_PMC_SCSR (SAM4_PMC_BASE + 0x0008)
139 uint32_t PMC_SCSR;
140 #define SAM4_PMC_PCSR (SAM4_PMC_BASE + 0x0018)
141 uint32_t PMC_PCSR;
142 #define SAM4_CKGR_UCKR (SAM4_PMC_BASE + 0x001c)
143 uint32_t CKGR_UCKR;
144 #define SAM4_CKGR_MOR (SAM4_PMC_BASE + 0x0020)
145 uint32_t CKGR_MOR;
146 #define SAM4_CKGR_MCFR (SAM4_PMC_BASE + 0x0024)
147 uint32_t CKGR_MCFR;
148 #define SAM4_CKGR_PLLAR (SAM4_PMC_BASE + 0x0028)
149 uint32_t CKGR_PLLAR;
150 #define SAM4_PMC_MCKR (SAM4_PMC_BASE + 0x0030)
151 uint32_t PMC_MCKR;
152 #define SAM4_PMC_PCK0 (SAM4_PMC_BASE + 0x0040)
153 uint32_t PMC_PCK0;
154 #define SAM4_PMC_PCK1 (SAM4_PMC_BASE + 0x0044)
155 uint32_t PMC_PCK1;
156 #define SAM4_PMC_PCK2 (SAM4_PMC_BASE + 0x0048)
157 uint32_t PMC_PCK2;
158 #define SAM4_PMC_SR (SAM4_PMC_BASE + 0x0068)
159 uint32_t PMC_SR;
160 #define SAM4_PMC_IMR (SAM4_PMC_BASE + 0x006c)
161 uint32_t PMC_IMR;
162 #define SAM4_PMC_FSMR (SAM4_PMC_BASE + 0x0070)
163 uint32_t PMC_FSMR;
164 #define SAM4_PMC_FSPR (SAM4_PMC_BASE + 0x0074)
165 uint32_t PMC_FSPR;
166 };
167
168 struct sam4_bank_private {
169 int probed;
170 /* DANGER: THERE ARE DRAGONS HERE.. */
171 /* NOTE: If you add more 'ghost' pointers */
172 /* be aware that you must *manually* update */
173 /* these pointers in the function sam4_GetDetails() */
174 /* See the comment "Here there be dragons" */
175
176 /* so we can find the chip we belong to */
177 struct sam4_chip *pChip;
178 /* so we can find the original bank pointer */
179 struct flash_bank *pBank;
180 unsigned bank_number;
181 uint32_t controller_address;
182 uint32_t base_address;
183 uint32_t flash_wait_states;
184 bool present;
185 unsigned size_bytes;
186 unsigned nsectors;
187 unsigned sector_size;
188 unsigned page_size;
189 };
190
191 struct sam4_chip_details {
192 /* THERE ARE DRAGONS HERE.. */
193 /* note: If you add pointers here */
194 /* be careful about them as they */
195 /* may need to be updated inside */
196 /* the function: "sam4_GetDetails() */
197 /* which copy/overwrites the */
198 /* 'runtime' copy of this structure */
199 uint32_t chipid_cidr;
200 const char *name;
201
202 unsigned n_gpnvms;
203 #define SAM4_N_NVM_BITS 3
204 unsigned gpnvm[SAM4_N_NVM_BITS];
205 unsigned total_flash_size;
206 unsigned total_sram_size;
207 unsigned n_banks;
208 #define SAM4_MAX_FLASH_BANKS 2
209 /* these are "initialized" from the global const data */
210 struct sam4_bank_private bank[SAM4_MAX_FLASH_BANKS];
211 };
212
213 struct sam4_chip {
214 struct sam4_chip *next;
215 int probed;
216
217 /* this is "initialized" from the global const structure */
218 struct sam4_chip_details details;
219 struct target *target;
220 struct sam4_cfg cfg;
221 };
222
223
224 struct sam4_reg_list {
225 uint32_t address; size_t struct_offset; const char *name;
226 void (*explain_func)(struct sam4_chip *pInfo);
227 };
228
229 static struct sam4_chip *all_sam4_chips;
230
231 static struct sam4_chip *get_current_sam4(struct command_context *cmd_ctx)
232 {
233 struct target *t;
234 static struct sam4_chip *p;
235
236 t = get_current_target(cmd_ctx);
237 if (!t) {
238 command_print(cmd_ctx, "No current target?");
239 return NULL;
240 }
241
242 p = all_sam4_chips;
243 if (!p) {
244 /* this should not happen */
245 /* the command is not registered until the chip is created? */
246 command_print(cmd_ctx, "No SAM4 chips exist?");
247 return NULL;
248 }
249
250 while (p) {
251 if (p->target == t)
252 return p;
253 p = p->next;
254 }
255 command_print(cmd_ctx, "Cannot find SAM4 chip?");
256 return NULL;
257 }
258
259 /*The actual sector size of the SAM4S flash memory is 65536 bytes. 16 sectors for a 1024KB device*/
260 /*The lockregions are 8KB per lock region, with a 1024KB device having 128 lock regions. */
261 /*For the best results, nsectors are thus set to the amount of lock regions, and the sector_size*/
262 /*set to the lock region size. Page erases are used to erase 8KB sections when programming*/
263
264 /* these are used to *initialize* the "pChip->details" structure. */
265 static const struct sam4_chip_details all_sam4_details[] = {
266 /* Start at91sam4c* series */
267 /* at91sam4c32e - LQFP144 */
268 {
269 .chipid_cidr = 0xA66D0EE0,
270 .name = "at91sam4c32e",
271 .total_flash_size = 2024 * 1024,
272 .total_sram_size = 256 * 1024,
273 .n_gpnvms = 3,
274 .n_banks = 2,
275 /* .bank[0] = { */
276 {
277 {
278 .probed = 0,
279 .pChip = NULL,
280 .pBank = NULL,
281 .bank_number = 0,
282 .base_address = FLASH_BANK0_BASE_C32,
283 .controller_address = 0x400e0a00,
284 .flash_wait_states = 5,
285 .present = 1,
286 .size_bytes = 1024 * 1024,
287 .nsectors = 128,
288 .sector_size = 8192,
289 .page_size = 512,
290 },
291 /* .bank[1] = { */
292 {
293 .probed = 0,
294 .pChip = NULL,
295 .pBank = NULL,
296 .bank_number = 1,
297 .base_address = FLASH_BANK1_BASE_C32,
298 .controller_address = 0x400e0c00,
299 .flash_wait_states = 5,
300 .present = 1,
301 .size_bytes = 1024 * 1024,
302 .nsectors = 128,
303 .sector_size = 8192,
304 .page_size = 512,
305 },
306 },
307 },
308 /* at91sam4c32c - LQFP100 */
309 {
310 .chipid_cidr = 0xA64D0EE0,
311 .name = "at91sam4c32c",
312 .total_flash_size = 2024 * 1024,
313 .total_sram_size = 256 * 1024,
314 .n_gpnvms = 3,
315 .n_banks = 2,
316 /* .bank[0] = { */
317 {
318 {
319 .probed = 0,
320 .pChip = NULL,
321 .pBank = NULL,
322 .bank_number = 0,
323 .base_address = FLASH_BANK0_BASE_C32,
324 .controller_address = 0x400e0a00,
325 .flash_wait_states = 5,
326 .present = 1,
327 .size_bytes = 1024 * 1024,
328 .nsectors = 128,
329 .sector_size = 8192,
330 .page_size = 512,
331 },
332 /* .bank[1] = { */
333 {
334 .probed = 0,
335 .pChip = NULL,
336 .pBank = NULL,
337 .bank_number = 1,
338 .base_address = FLASH_BANK1_BASE_C32,
339 .controller_address = 0x400e0c00,
340 .flash_wait_states = 5,
341 .present = 1,
342 .size_bytes = 1024 * 1024,
343 .nsectors = 128,
344 .sector_size = 8192,
345 .page_size = 512,
346 },
347 },
348 },
349 /* at91sam4c16c - LQFP100 */
350 {
351 .chipid_cidr = 0xA64C0CE0,
352 .name = "at91sam4c16c",
353 .total_flash_size = 1024 * 1024,
354 .total_sram_size = 128 * 1024,
355 .n_gpnvms = 2,
356 .n_banks = 1,
357 {
358 /* .bank[0] = {*/
359 {
360 .probed = 0,
361 .pChip = NULL,
362 .pBank = NULL,
363 .bank_number = 0,
364 .base_address = FLASH_BANK_BASE_C,
365 .controller_address = 0x400e0a00,
366 .flash_wait_states = 5,
367 .present = 1,
368 .size_bytes = 1024 * 1024,
369 .nsectors = 128,
370 .sector_size = 8192,
371 .page_size = 512,
372 },
373 /* .bank[1] = {*/
374 {
375 .present = 0,
376 .probed = 0,
377 .bank_number = 1,
378
379 },
380 },
381 },
382 /* at91sam4c8c - LQFP100 */
383 {
384 .chipid_cidr = 0xA64C0AE0,
385 .name = "at91sam4c8c",
386 .total_flash_size = 512 * 1024,
387 .total_sram_size = 128 * 1024,
388 .n_gpnvms = 2,
389 .n_banks = 1,
390 {
391 /* .bank[0] = {*/
392 {
393 .probed = 0,
394 .pChip = NULL,
395 .pBank = NULL,
396 .bank_number = 0,
397 .base_address = FLASH_BANK_BASE_C,
398 .controller_address = 0x400e0a00,
399 .flash_wait_states = 5,
400 .present = 1,
401 .size_bytes = 512 * 1024,
402 .nsectors = 64,
403 .sector_size = 8192,
404 .page_size = 512,
405 },
406 /* .bank[1] = {*/
407 {
408 .present = 0,
409 .probed = 0,
410 .bank_number = 1,
411
412 },
413 },
414 },
415 /* at91sam4c4c (rev B) - LQFP100 */
416 {
417 .chipid_cidr = 0xA64C0CE5,
418 .name = "at91sam4c4c",
419 .total_flash_size = 256 * 1024,
420 .total_sram_size = 128 * 1024,
421 .n_gpnvms = 2,
422 .n_banks = 1,
423 {
424 /* .bank[0] = {*/
425 {
426 .probed = 0,
427 .pChip = NULL,
428 .pBank = NULL,
429 .bank_number = 0,
430 .base_address = FLASH_BANK_BASE_C,
431 .controller_address = 0x400e0a00,
432 .flash_wait_states = 5,
433 .present = 1,
434 .size_bytes = 256 * 1024,
435 .nsectors = 32,
436 .sector_size = 8192,
437 .page_size = 512,
438 },
439 /* .bank[1] = {*/
440 {
441 .present = 0,
442 .probed = 0,
443 .bank_number = 1,
444
445 },
446 },
447 },
448
449 /* Start at91sam4e* series */
450 /*atsam4e16e - LQFP144/LFBGA144*/
451 {
452 .chipid_cidr = 0xA3CC0CE0,
453 .name = "at91sam4e16e",
454 .total_flash_size = 1024 * 1024,
455 .total_sram_size = 128 * 1024,
456 .n_gpnvms = 2,
457 .n_banks = 1,
458 {
459 /* .bank[0] = {*/
460 {
461 .probed = 0,
462 .pChip = NULL,
463 .pBank = NULL,
464 .bank_number = 0,
465 .base_address = FLASH_BANK_BASE_S,
466 .controller_address = 0x400e0a00,
467 .flash_wait_states = 6, /* workaround silicon bug */
468 .present = 1,
469 .size_bytes = 1024 * 1024,
470 .nsectors = 128,
471 .sector_size = 8192,
472 .page_size = 512,
473 },
474 /* .bank[1] = {*/
475 {
476 .present = 0,
477 .probed = 0,
478 .bank_number = 1,
479
480 },
481 },
482 },
483
484 /* Start at91sam4n* series */
485 /*atsam4n8a - LQFP48/QFN48*/
486 {
487 .chipid_cidr = 0x293B0AE0,
488 .name = "at91sam4n8a",
489 .total_flash_size = 512 * 1024,
490 .total_sram_size = 64 * 1024,
491 .n_gpnvms = 2,
492 .n_banks = 1,
493 {
494 /* .bank[0] = {*/
495 {
496 .probed = 0,
497 .pChip = NULL,
498 .pBank = NULL,
499 .bank_number = 0,
500 .base_address = FLASH_BANK_BASE_S,
501 .controller_address = 0x400e0a00,
502 .flash_wait_states = 6, /* workaround silicon bug */
503 .present = 1,
504 .size_bytes = 512 * 1024,
505 .nsectors = 64,
506 .sector_size = 8192,
507 .page_size = 512,
508 },
509 /* .bank[1] = {*/
510 {
511 .present = 0,
512 .probed = 0,
513 .bank_number = 1,
514
515 },
516 },
517 },
518 /*atsam4n8b - LQFP64/QFN64*/
519 {
520 .chipid_cidr = 0x294B0AE0,
521 .name = "at91sam4n8b",
522 .total_flash_size = 512 * 1024,
523 .total_sram_size = 64 * 1024,
524 .n_gpnvms = 2,
525 .n_banks = 1,
526 {
527 /* .bank[0] = {*/
528 {
529 .probed = 0,
530 .pChip = NULL,
531 .pBank = NULL,
532 .bank_number = 0,
533 .base_address = FLASH_BANK_BASE_S,
534 .controller_address = 0x400e0a00,
535 .flash_wait_states = 6, /* workaround silicon bug */
536 .present = 1,
537 .size_bytes = 512 * 1024,
538 .nsectors = 64,
539 .sector_size = 8192,
540 .page_size = 512,
541 },
542 /* .bank[1] = {*/
543 {
544 .present = 0,
545 .probed = 0,
546 .bank_number = 1,
547
548 },
549 },
550 },
551 /*atsam4n8c - LQFP100/TFBGA100/VFBGA100*/
552 {
553 .chipid_cidr = 0x295B0AE0,
554 .name = "at91sam4n8c",
555 .total_flash_size = 512 * 1024,
556 .total_sram_size = 64 * 1024,
557 .n_gpnvms = 2,
558 .n_banks = 1,
559 {
560 /* .bank[0] = {*/
561 {
562 .probed = 0,
563 .pChip = NULL,
564 .pBank = NULL,
565 .bank_number = 0,
566 .base_address = FLASH_BANK_BASE_S,
567 .controller_address = 0x400e0a00,
568 .flash_wait_states = 6, /* workaround silicon bug */
569 .present = 1,
570 .size_bytes = 512 * 1024,
571 .nsectors = 64,
572 .sector_size = 8192,
573 .page_size = 512,
574 },
575 /* .bank[1] = {*/
576 {
577 .present = 0,
578 .probed = 0,
579 .bank_number = 1,
580
581 },
582 },
583 },
584 /*atsam4n16b - LQFP64/QFN64*/
585 {
586 .chipid_cidr = 0x29460CE0,
587 .name = "at91sam4n16b",
588 .total_flash_size = 1024 * 1024,
589 .total_sram_size = 80 * 1024,
590 .n_gpnvms = 2,
591 .n_banks = 1,
592 {
593 /* .bank[0] = {*/
594 {
595 .probed = 0,
596 .pChip = NULL,
597 .pBank = NULL,
598 .bank_number = 0,
599 .base_address = FLASH_BANK_BASE_S,
600 .controller_address = 0x400e0a00,
601 .flash_wait_states = 6, /* workaround silicon bug */
602 .present = 1,
603 .size_bytes = 1024 * 1024,
604 .nsectors = 128,
605 .sector_size = 8192,
606 .page_size = 512,
607 },
608 /* .bank[1] = {*/
609 {
610 .present = 0,
611 .probed = 0,
612 .bank_number = 1,
613
614 },
615 },
616 },
617 /*atsam4n16c - LQFP100/TFBGA100/VFBGA100*/
618 {
619 .chipid_cidr = 0x29560CE0,
620 .name = "at91sam4n16c",
621 .total_flash_size = 1024 * 1024,
622 .total_sram_size = 80 * 1024,
623 .n_gpnvms = 2,
624 .n_banks = 1,
625 {
626 /* .bank[0] = {*/
627 {
628 .probed = 0,
629 .pChip = NULL,
630 .pBank = NULL,
631 .bank_number = 0,
632 .base_address = FLASH_BANK_BASE_S,
633 .controller_address = 0x400e0a00,
634 .flash_wait_states = 6, /* workaround silicon bug */
635 .present = 1,
636 .size_bytes = 1024 * 1024,
637 .nsectors = 128,
638 .sector_size = 8192,
639 .page_size = 512,
640 },
641 /* .bank[1] = {*/
642 {
643 .present = 0,
644 .probed = 0,
645 .bank_number = 1,
646
647 },
648 },
649 },
650
651 /* Start at91sam4s* series */
652 /*atsam4s16c - LQFP100/BGA100*/
653 {
654 .chipid_cidr = 0x28AC0CE0,
655 .name = "at91sam4s16c",
656 .total_flash_size = 1024 * 1024,
657 .total_sram_size = 128 * 1024,
658 .n_gpnvms = 2,
659 .n_banks = 1,
660 {
661 /* .bank[0] = {*/
662 {
663 .probed = 0,
664 .pChip = NULL,
665 .pBank = NULL,
666 .bank_number = 0,
667 .base_address = FLASH_BANK_BASE_S,
668 .controller_address = 0x400e0a00,
669 .flash_wait_states = 6, /* workaround silicon bug */
670 .present = 1,
671 .size_bytes = 1024 * 1024,
672 .nsectors = 128,
673 .sector_size = 8192,
674 .page_size = 512,
675 },
676 /* .bank[1] = {*/
677 {
678 .present = 0,
679 .probed = 0,
680 .bank_number = 1,
681
682 },
683 },
684 },
685 /*atsam4s16b - LQFP64/QFN64*/
686 {
687 .chipid_cidr = 0x289C0CE0,
688 .name = "at91sam4s16b",
689 .total_flash_size = 1024 * 1024,
690 .total_sram_size = 128 * 1024,
691 .n_gpnvms = 2,
692 .n_banks = 1,
693 {
694 /* .bank[0] = {*/
695 {
696 .probed = 0,
697 .pChip = NULL,
698 .pBank = NULL,
699 .bank_number = 0,
700 .base_address = FLASH_BANK_BASE_S,
701 .controller_address = 0x400e0a00,
702 .flash_wait_states = 6, /* workaround silicon bug */
703 .present = 1,
704 .size_bytes = 1024 * 1024,
705 .nsectors = 128,
706 .sector_size = 8192,
707 .page_size = 512,
708 },
709 /* .bank[1] = {*/
710 {
711 .present = 0,
712 .probed = 0,
713 .bank_number = 1,
714
715 },
716 },
717 },
718 /*atsam4sa16b - LQFP64/QFN64*/
719 {
720 .chipid_cidr = 0x28970CE0,
721 .name = "at91sam4sa16b",
722 .total_flash_size = 1024 * 1024,
723 .total_sram_size = 160 * 1024,
724 .n_gpnvms = 2,
725 .n_banks = 1,
726 {
727 /* .bank[0] = {*/
728 {
729 .probed = 0,
730 .pChip = NULL,
731 .pBank = NULL,
732 .bank_number = 0,
733 .base_address = FLASH_BANK_BASE_S,
734 .controller_address = 0x400e0a00,
735 .flash_wait_states = 6, /* workaround silicon bug */
736 .present = 1,
737 .size_bytes = 1024 * 1024,
738 .nsectors = 128,
739 .sector_size = 8192,
740 .page_size = 512,
741 },
742 /* .bank[1] = {*/
743 {
744 .present = 0,
745 .probed = 0,
746 .bank_number = 1,
747
748 },
749 },
750 },
751 /*atsam4s16a - LQFP48/QFN48*/
752 {
753 .chipid_cidr = 0x288C0CE0,
754 .name = "at91sam4s16a",
755 .total_flash_size = 1024 * 1024,
756 .total_sram_size = 128 * 1024,
757 .n_gpnvms = 2,
758 .n_banks = 1,
759 {
760 /* .bank[0] = {*/
761 {
762 .probed = 0,
763 .pChip = NULL,
764 .pBank = NULL,
765 .bank_number = 0,
766 .base_address = FLASH_BANK_BASE_S,
767 .controller_address = 0x400e0a00,
768 .flash_wait_states = 6, /* workaround silicon bug */
769 .present = 1,
770 .size_bytes = 1024 * 1024,
771 .nsectors = 128,
772 .sector_size = 8192,
773 .page_size = 512,
774 },
775 /* .bank[1] = {*/
776 {
777 .present = 0,
778 .probed = 0,
779 .bank_number = 1,
780
781 },
782 },
783 },
784 /*atsam4s8c - LQFP100/BGA100*/
785 {
786 .chipid_cidr = 0x28AC0AE0,
787 .name = "at91sam4s8c",
788 .total_flash_size = 512 * 1024,
789 .total_sram_size = 128 * 1024,
790 .n_gpnvms = 2,
791 .n_banks = 1,
792 {
793 /* .bank[0] = {*/
794 {
795 .probed = 0,
796 .pChip = NULL,
797 .pBank = NULL,
798 .bank_number = 0,
799 .base_address = FLASH_BANK_BASE_S,
800 .controller_address = 0x400e0a00,
801 .flash_wait_states = 6, /* workaround silicon bug */
802 .present = 1,
803 .size_bytes = 512 * 1024,
804 .nsectors = 64,
805 .sector_size = 8192,
806 .page_size = 512,
807 },
808 /* .bank[1] = {*/
809 {
810 .present = 0,
811 .probed = 0,
812 .bank_number = 1,
813
814 },
815 },
816 },
817 /*atsam4s8b - LQFP64/BGA64*/
818 {
819 .chipid_cidr = 0x289C0AE0,
820 .name = "at91sam4s8b",
821 .total_flash_size = 512 * 1024,
822 .total_sram_size = 128 * 1024,
823 .n_gpnvms = 2,
824 .n_banks = 1,
825 {
826 /* .bank[0] = {*/
827 {
828 .probed = 0,
829 .pChip = NULL,
830 .pBank = NULL,
831 .bank_number = 0,
832 .base_address = FLASH_BANK_BASE_S,
833 .controller_address = 0x400e0a00,
834 .flash_wait_states = 6, /* workaround silicon bug */
835 .present = 1,
836 .size_bytes = 512 * 1024,
837 .nsectors = 64,
838 .sector_size = 8192,
839 .page_size = 512,
840 },
841 /* .bank[1] = {*/
842 {
843 .present = 0,
844 .probed = 0,
845 .bank_number = 1,
846
847 },
848 },
849 },
850 /*atsam4s8a - LQFP48/BGA48*/
851 {
852 .chipid_cidr = 0x288C0AE0,
853 .name = "at91sam4s8a",
854 .total_flash_size = 512 * 1024,
855 .total_sram_size = 128 * 1024,
856 .n_gpnvms = 2,
857 .n_banks = 1,
858 {
859 /* .bank[0] = {*/
860 {
861 .probed = 0,
862 .pChip = NULL,
863 .pBank = NULL,
864 .bank_number = 0,
865 .base_address = FLASH_BANK_BASE_S,
866 .controller_address = 0x400e0a00,
867 .flash_wait_states = 6, /* workaround silicon bug */
868 .present = 1,
869 .size_bytes = 512 * 1024,
870 .nsectors = 64,
871 .sector_size = 8192,
872 .page_size = 512,
873 },
874 /* .bank[1] = {*/
875 {
876 .present = 0,
877 .probed = 0,
878 .bank_number = 1,
879
880 },
881 },
882 },
883
884 /*atsam4s4a - LQFP48/BGA48*/
885 {
886 .chipid_cidr = 0x288b09e0,
887 .name = "at91sam4s4a",
888 .total_flash_size = 256 * 1024,
889 .total_sram_size = 64 * 1024,
890 .n_gpnvms = 2,
891 .n_banks = 1,
892 {
893 /* .bank[0] = {*/
894 {
895 .probed = 0,
896 .pChip = NULL,
897 .pBank = NULL,
898 .bank_number = 0,
899 .base_address = FLASH_BANK_BASE_S,
900 .controller_address = 0x400e0a00,
901 .flash_wait_states = 6, /* workaround silicon bug */
902 .present = 1,
903 .size_bytes = 256 * 1024,
904 .nsectors = 32,
905 .sector_size = 8192,
906 .page_size = 512,
907 },
908 /* .bank[1] = {*/
909 {
910 .present = 0,
911 .probed = 0,
912 .bank_number = 1,
913
914 },
915 },
916 },
917
918 /*at91sam4sd32c*/
919 {
920 .chipid_cidr = 0x29a70ee0,
921 .name = "at91sam4sd32c",
922 .total_flash_size = 2048 * 1024,
923 .total_sram_size = 160 * 1024,
924 .n_gpnvms = 3,
925 .n_banks = 2,
926
927 /* .bank[0] = { */
928 {
929 {
930 .probed = 0,
931 .pChip = NULL,
932 .pBank = NULL,
933 .bank_number = 0,
934 .base_address = FLASH_BANK0_BASE_SD,
935 .controller_address = 0x400e0a00,
936 .flash_wait_states = 6, /* workaround silicon bug */
937 .present = 1,
938 .size_bytes = 1024 * 1024,
939 .nsectors = 128,
940 .sector_size = 8192,
941 .page_size = 512,
942 },
943
944 /* .bank[1] = { */
945 {
946 .probed = 0,
947 .pChip = NULL,
948 .pBank = NULL,
949 .bank_number = 1,
950 .base_address = FLASH_BANK1_BASE_2048K_SD,
951 .controller_address = 0x400e0c00,
952 .flash_wait_states = 6, /* workaround silicon bug */
953 .present = 1,
954 .size_bytes = 1024 * 1024,
955 .nsectors = 128,
956 .sector_size = 8192,
957 .page_size = 512,
958 },
959 },
960 },
961
962 /*at91sam4sd16c*/
963 {
964 .chipid_cidr = 0x29a70ce0,
965 .name = "at91sam4sd16c",
966 .total_flash_size = 1024 * 1024,
967 .total_sram_size = 160 * 1024,
968 .n_gpnvms = 3,
969 .n_banks = 2,
970
971 /* .bank[0] = { */
972 {
973 {
974 .probed = 0,
975 .pChip = NULL,
976 .pBank = NULL,
977 .bank_number = 0,
978 .base_address = FLASH_BANK0_BASE_SD,
979 .controller_address = 0x400e0a00,
980 .flash_wait_states = 6, /* workaround silicon bug */
981 .present = 1,
982 .size_bytes = 512 * 1024,
983 .nsectors = 64,
984 .sector_size = 8192,
985 .page_size = 512,
986 },
987
988 /* .bank[1] = { */
989 {
990 .probed = 0,
991 .pChip = NULL,
992 .pBank = NULL,
993 .bank_number = 1,
994 .base_address = FLASH_BANK1_BASE_1024K_SD,
995 .controller_address = 0x400e0c00,
996 .flash_wait_states = 6, /* workaround silicon bug */
997 .present = 1,
998 .size_bytes = 512 * 1024,
999 .nsectors = 64,
1000 .sector_size = 8192,
1001 .page_size = 512,
1002 },
1003 },
1004 },
1005
1006 /*at91sam4sa16c*/
1007 {
1008 .chipid_cidr = 0x28a70ce0,
1009 .name = "at91sam4sa16c",
1010 .total_flash_size = 1024 * 1024,
1011 .total_sram_size = 160 * 1024,
1012 .n_gpnvms = 3,
1013 .n_banks = 2,
1014
1015 /* .bank[0] = { */
1016 {
1017 {
1018 .probed = 0,
1019 .pChip = NULL,
1020 .pBank = NULL,
1021 .bank_number = 0,
1022 .base_address = FLASH_BANK0_BASE_SD,
1023 .controller_address = 0x400e0a00,
1024 .flash_wait_states = 6, /* workaround silicon bug */
1025 .present = 1,
1026 .size_bytes = 512 * 1024,
1027 .nsectors = 64,
1028 .sector_size = 8192,
1029 .page_size = 512,
1030 },
1031
1032 /* .bank[1] = { */
1033 {
1034 .probed = 0,
1035 .pChip = NULL,
1036 .pBank = NULL,
1037 .bank_number = 1,
1038 .base_address = FLASH_BANK1_BASE_1024K_SD,
1039 .controller_address = 0x400e0c00,
1040 .flash_wait_states = 6, /* workaround silicon bug */
1041 .present = 1,
1042 .size_bytes = 512 * 1024,
1043 .nsectors = 64,
1044 .sector_size = 8192,
1045 .page_size = 512,
1046 },
1047 },
1048 },
1049
1050 /* at91samg53n19 */
1051 {
1052 .chipid_cidr = 0x247e0ae0,
1053 .name = "at91samg53n19",
1054 .total_flash_size = 512 * 1024,
1055 .total_sram_size = 96 * 1024,
1056 .n_gpnvms = 2,
1057 .n_banks = 1,
1058
1059 /* .bank[0] = {*/
1060 {
1061 {
1062 .probed = 0,
1063 .pChip = NULL,
1064 .pBank = NULL,
1065 .bank_number = 0,
1066 .base_address = FLASH_BANK_BASE_S,
1067 .controller_address = 0x400e0a00,
1068 .flash_wait_states = 6, /* workaround silicon bug */
1069 .present = 1,
1070 .size_bytes = 512 * 1024,
1071 .nsectors = 64,
1072 .sector_size = 8192,
1073 .page_size = 512,
1074 },
1075 /* .bank[1] = {*/
1076 {
1077 .present = 0,
1078 .probed = 0,
1079 .bank_number = 1,
1080
1081 },
1082 }
1083 },
1084
1085 /* terminate */
1086 {
1087 .chipid_cidr = 0,
1088 .name = NULL,
1089 }
1090 };
1091
1092 /* Globals above */
1093 /***********************************************************************
1094 **********************************************************************
1095 **********************************************************************
1096 **********************************************************************
1097 **********************************************************************
1098 **********************************************************************/
1099 /* *ATMEL* style code - from the SAM4 driver code */
1100
1101 /**
1102 * Get the current status of the EEFC and
1103 * the value of some status bits (LOCKE, PROGE).
1104 * @param pPrivate - info about the bank
1105 * @param v - result goes here
1106 */
1107 static int EFC_GetStatus(struct sam4_bank_private *pPrivate, uint32_t *v)
1108 {
1109 int r;
1110 r = target_read_u32(pPrivate->pChip->target,
1111 pPrivate->controller_address + offset_EFC_FSR,
1112 v);
1113 LOG_DEBUG("Status: 0x%08x (lockerror: %d, cmderror: %d, ready: %d)",
1114 (unsigned int)(*v),
1115 ((unsigned int)((*v >> 2) & 1)),
1116 ((unsigned int)((*v >> 1) & 1)),
1117 ((unsigned int)((*v >> 0) & 1)));
1118
1119 return r;
1120 }
1121
1122 /**
1123 * Get the result of the last executed command.
1124 * @param pPrivate - info about the bank
1125 * @param v - result goes here
1126 */
1127 static int EFC_GetResult(struct sam4_bank_private *pPrivate, uint32_t *v)
1128 {
1129 int r;
1130 uint32_t rv;
1131 r = target_read_u32(pPrivate->pChip->target,
1132 pPrivate->controller_address + offset_EFC_FRR,
1133 &rv);
1134 if (v)
1135 *v = rv;
1136 LOG_DEBUG("Result: 0x%08x", ((unsigned int)(rv)));
1137 return r;
1138 }
1139
1140 static int EFC_StartCommand(struct sam4_bank_private *pPrivate,
1141 unsigned command, unsigned argument)
1142 {
1143 uint32_t n, v;
1144 int r;
1145 int retry;
1146
1147 retry = 0;
1148 do_retry:
1149
1150 /* Check command & argument */
1151 switch (command) {
1152
1153 case AT91C_EFC_FCMD_WP:
1154 case AT91C_EFC_FCMD_WPL:
1155 case AT91C_EFC_FCMD_EWP:
1156 case AT91C_EFC_FCMD_EWPL:
1157 /* case AT91C_EFC_FCMD_EPL: */
1158 case AT91C_EFC_FCMD_EPA:
1159 case AT91C_EFC_FCMD_SLB:
1160 case AT91C_EFC_FCMD_CLB:
1161 n = (pPrivate->size_bytes / pPrivate->page_size);
1162 if (argument >= n)
1163 LOG_ERROR("*BUG*: Embedded flash has only %u pages", (unsigned)(n));
1164 break;
1165
1166 case AT91C_EFC_FCMD_SFB:
1167 case AT91C_EFC_FCMD_CFB:
1168 if (argument >= pPrivate->pChip->details.n_gpnvms) {
1169 LOG_ERROR("*BUG*: Embedded flash has only %d GPNVMs",
1170 pPrivate->pChip->details.n_gpnvms);
1171 }
1172 break;
1173
1174 case AT91C_EFC_FCMD_GETD:
1175 case AT91C_EFC_FCMD_EA:
1176 case AT91C_EFC_FCMD_GLB:
1177 case AT91C_EFC_FCMD_GFB:
1178 case AT91C_EFC_FCMD_STUI:
1179 case AT91C_EFC_FCMD_SPUI:
1180 if (argument != 0)
1181 LOG_ERROR("Argument is meaningless for cmd: %d", command);
1182 break;
1183 default:
1184 LOG_ERROR("Unknown command %d", command);
1185 break;
1186 }
1187
1188 if (command == AT91C_EFC_FCMD_SPUI) {
1189 /* this is a very special situation. */
1190 /* Situation (1) - error/retry - see below */
1191 /* And we are being called recursively */
1192 /* Situation (2) - normal, finished reading unique id */
1193 } else {
1194 /* it should be "ready" */
1195 EFC_GetStatus(pPrivate, &v);
1196 if (v & 1) {
1197 /* then it is ready */
1198 /* we go on */
1199 } else {
1200 if (retry) {
1201 /* we have done this before */
1202 /* the controller is not responding. */
1203 LOG_ERROR("flash controller(%d) is not ready! Error",
1204 pPrivate->bank_number);
1205 return ERROR_FAIL;
1206 } else {
1207 retry++;
1208 LOG_ERROR("Flash controller(%d) is not ready, attempting reset",
1209 pPrivate->bank_number);
1210 /* we do that by issuing the *STOP* command */
1211 EFC_StartCommand(pPrivate, AT91C_EFC_FCMD_SPUI, 0);
1212 /* above is recursive, and further recursion is blocked by */
1213 /* if (command == AT91C_EFC_FCMD_SPUI) above */
1214 goto do_retry;
1215 }
1216 }
1217 }
1218
1219 v = (0x5A << 24) | (argument << 8) | command;
1220 LOG_DEBUG("Command: 0x%08x", ((unsigned int)(v)));
1221 r = target_write_u32(pPrivate->pBank->target,
1222 pPrivate->controller_address + offset_EFC_FCR, v);
1223 if (r != ERROR_OK)
1224 LOG_DEBUG("Error Write failed");
1225 return r;
1226 }
1227
1228 /**
1229 * Performs the given command and wait until its completion (or an error).
1230 * @param pPrivate - info about the bank
1231 * @param command - Command to perform.
1232 * @param argument - Optional command argument.
1233 * @param status - put command status bits here
1234 */
1235 static int EFC_PerformCommand(struct sam4_bank_private *pPrivate,
1236 unsigned command,
1237 unsigned argument,
1238 uint32_t *status)
1239 {
1240
1241 int r;
1242 uint32_t v;
1243 int64_t ms_now, ms_end;
1244
1245 /* default */
1246 if (status)
1247 *status = 0;
1248
1249 r = EFC_StartCommand(pPrivate, command, argument);
1250 if (r != ERROR_OK)
1251 return r;
1252
1253 ms_end = 10000 + timeval_ms();
1254
1255 do {
1256 r = EFC_GetStatus(pPrivate, &v);
1257 if (r != ERROR_OK)
1258 return r;
1259 ms_now = timeval_ms();
1260 if (ms_now > ms_end) {
1261 /* error */
1262 LOG_ERROR("Command timeout");
1263 return ERROR_FAIL;
1264 }
1265 } while ((v & 1) == 0);
1266
1267 /* error bits.. */
1268 if (status)
1269 *status = (v & 0x6);
1270 return ERROR_OK;
1271
1272 }
1273
1274 /**
1275 * Read the unique ID.
1276 * @param pPrivate - info about the bank
1277 * The unique ID is stored in the 'pPrivate' structure.
1278 */
1279 static int FLASHD_ReadUniqueID(struct sam4_bank_private *pPrivate)
1280 {
1281 int r;
1282 uint32_t v;
1283 int x;
1284 /* assume 0 */
1285 pPrivate->pChip->cfg.unique_id[0] = 0;
1286 pPrivate->pChip->cfg.unique_id[1] = 0;
1287 pPrivate->pChip->cfg.unique_id[2] = 0;
1288 pPrivate->pChip->cfg.unique_id[3] = 0;
1289
1290 LOG_DEBUG("Begin");
1291 r = EFC_StartCommand(pPrivate, AT91C_EFC_FCMD_STUI, 0);
1292 if (r < 0)
1293 return r;
1294
1295 for (x = 0; x < 4; x++) {
1296 r = target_read_u32(pPrivate->pChip->target,
1297 pPrivate->pBank->base + (x * 4),
1298 &v);
1299 if (r < 0)
1300 return r;
1301 pPrivate->pChip->cfg.unique_id[x] = v;
1302 }
1303
1304 r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_SPUI, 0, NULL);
1305 LOG_DEBUG("End: R=%d, id = 0x%08x, 0x%08x, 0x%08x, 0x%08x",
1306 r,
1307 (unsigned int)(pPrivate->pChip->cfg.unique_id[0]),
1308 (unsigned int)(pPrivate->pChip->cfg.unique_id[1]),
1309 (unsigned int)(pPrivate->pChip->cfg.unique_id[2]),
1310 (unsigned int)(pPrivate->pChip->cfg.unique_id[3]));
1311 return r;
1312
1313 }
1314
1315 /**
1316 * Erases the entire flash.
1317 * @param pPrivate - the info about the bank.
1318 */
1319 static int FLASHD_EraseEntireBank(struct sam4_bank_private *pPrivate)
1320 {
1321 LOG_DEBUG("Here");
1322 return EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_EA, 0, NULL);
1323 }
1324
1325 /**
1326 * Erases the entire flash.
1327 * @param pPrivate - the info about the bank.
1328 */
1329 static int FLASHD_ErasePages(struct sam4_bank_private *pPrivate,
1330 int firstPage,
1331 int numPages,
1332 uint32_t *status)
1333 {
1334 LOG_DEBUG("Here");
1335 uint8_t erasePages;
1336 switch (numPages) {
1337 case 4:
1338 erasePages = 0x00;
1339 break;
1340 case 8:
1341 erasePages = 0x01;
1342 break;
1343 case 16:
1344 erasePages = 0x02;
1345 break;
1346 case 32:
1347 erasePages = 0x03;
1348 break;
1349 default:
1350 erasePages = 0x00;
1351 break;
1352 }
1353
1354 /* AT91C_EFC_FCMD_EPA
1355 * According to the datasheet FARG[15:2] defines the page from which
1356 * the erase will start.This page must be modulo 4, 8, 16 or 32
1357 * according to the number of pages to erase. FARG[1:0] defines the
1358 * number of pages to be erased. Previously (firstpage << 2) was used
1359 * to conform to this, seems it should not be shifted...
1360 */
1361 return EFC_PerformCommand(pPrivate,
1362 /* send Erase Page */
1363 AT91C_EFC_FCMD_EPA,
1364 (firstPage) | erasePages,
1365 status);
1366 }
1367
1368 /**
1369 * Gets current GPNVM state.
1370 * @param pPrivate - info about the bank.
1371 * @param gpnvm - GPNVM bit index.
1372 * @param puthere - result stored here.
1373 */
1374 /* ------------------------------------------------------------------------------ */
1375 static int FLASHD_GetGPNVM(struct sam4_bank_private *pPrivate, unsigned gpnvm, unsigned *puthere)
1376 {
1377 uint32_t v;
1378 int r;
1379
1380 LOG_DEBUG("Here");
1381 if (pPrivate->bank_number != 0) {
1382 LOG_ERROR("GPNVM only works with Bank0");
1383 return ERROR_FAIL;
1384 }
1385
1386 if (gpnvm >= pPrivate->pChip->details.n_gpnvms) {
1387 LOG_ERROR("Invalid GPNVM %d, max: %d, ignored",
1388 gpnvm, pPrivate->pChip->details.n_gpnvms);
1389 return ERROR_FAIL;
1390 }
1391
1392 /* Get GPNVMs status */
1393 r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_GFB, 0, NULL);
1394 if (r != ERROR_OK) {
1395 LOG_ERROR("Failed");
1396 return r;
1397 }
1398
1399 r = EFC_GetResult(pPrivate, &v);
1400
1401 if (puthere) {
1402 /* Check if GPNVM is set */
1403 /* get the bit and make it a 0/1 */
1404 *puthere = (v >> gpnvm) & 1;
1405 }
1406
1407 return r;
1408 }
1409
1410 /**
1411 * Clears the selected GPNVM bit.
1412 * @param pPrivate info about the bank
1413 * @param gpnvm GPNVM index.
1414 * @returns 0 if successful; otherwise returns an error code.
1415 */
1416 static int FLASHD_ClrGPNVM(struct sam4_bank_private *pPrivate, unsigned gpnvm)
1417 {
1418 int r;
1419 unsigned v;
1420
1421 LOG_DEBUG("Here");
1422 if (pPrivate->bank_number != 0) {
1423 LOG_ERROR("GPNVM only works with Bank0");
1424 return ERROR_FAIL;
1425 }
1426
1427 if (gpnvm >= pPrivate->pChip->details.n_gpnvms) {
1428 LOG_ERROR("Invalid GPNVM %d, max: %d, ignored",
1429 gpnvm, pPrivate->pChip->details.n_gpnvms);
1430 return ERROR_FAIL;
1431 }
1432
1433 r = FLASHD_GetGPNVM(pPrivate, gpnvm, &v);
1434 if (r != ERROR_OK) {
1435 LOG_DEBUG("Failed: %d", r);
1436 return r;
1437 }
1438 r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_CFB, gpnvm, NULL);
1439 LOG_DEBUG("End: %d", r);
1440 return r;
1441 }
1442
1443 /**
1444 * Sets the selected GPNVM bit.
1445 * @param pPrivate info about the bank
1446 * @param gpnvm GPNVM index.
1447 */
1448 static int FLASHD_SetGPNVM(struct sam4_bank_private *pPrivate, unsigned gpnvm)
1449 {
1450 int r;
1451 unsigned v;
1452
1453 if (pPrivate->bank_number != 0) {
1454 LOG_ERROR("GPNVM only works with Bank0");
1455 return ERROR_FAIL;
1456 }
1457
1458 if (gpnvm >= pPrivate->pChip->details.n_gpnvms) {
1459 LOG_ERROR("Invalid GPNVM %d, max: %d, ignored",
1460 gpnvm, pPrivate->pChip->details.n_gpnvms);
1461 return ERROR_FAIL;
1462 }
1463
1464 r = FLASHD_GetGPNVM(pPrivate, gpnvm, &v);
1465 if (r != ERROR_OK)
1466 return r;
1467 if (v) {
1468 /* already set */
1469 r = ERROR_OK;
1470 } else {
1471 /* set it */
1472 r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_SFB, gpnvm, NULL);
1473 }
1474 return r;
1475 }
1476
1477 /**
1478 * Returns a bit field (at most 64) of locked regions within a page.
1479 * @param pPrivate info about the bank
1480 * @param v where to store locked bits
1481 */
1482 static int FLASHD_GetLockBits(struct sam4_bank_private *pPrivate, uint32_t *v)
1483 {
1484 int r;
1485 LOG_DEBUG("Here");
1486 r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_GLB, 0, NULL);
1487 if (r == ERROR_OK) {
1488 EFC_GetResult(pPrivate, v);
1489 EFC_GetResult(pPrivate, v);
1490 EFC_GetResult(pPrivate, v);
1491 r = EFC_GetResult(pPrivate, v);
1492 }
1493 LOG_DEBUG("End: %d", r);
1494 return r;
1495 }
1496
1497 /**
1498 * Unlocks all the regions in the given address range.
1499 * @param pPrivate info about the bank
1500 * @param start_sector first sector to unlock
1501 * @param end_sector last (inclusive) to unlock
1502 */
1503
1504 static int FLASHD_Unlock(struct sam4_bank_private *pPrivate,
1505 unsigned start_sector,
1506 unsigned end_sector)
1507 {
1508 int r;
1509 uint32_t status;
1510 uint32_t pg;
1511 uint32_t pages_per_sector;
1512
1513 pages_per_sector = pPrivate->sector_size / pPrivate->page_size;
1514
1515 /* Unlock all pages */
1516 while (start_sector <= end_sector) {
1517 pg = start_sector * pages_per_sector;
1518
1519 r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_CLB, pg, &status);
1520 if (r != ERROR_OK)
1521 return r;
1522 start_sector++;
1523 }
1524
1525 return ERROR_OK;
1526 }
1527
1528 /**
1529 * Locks regions
1530 * @param pPrivate - info about the bank
1531 * @param start_sector - first sector to lock
1532 * @param end_sector - last sector (inclusive) to lock
1533 */
1534 static int FLASHD_Lock(struct sam4_bank_private *pPrivate,
1535 unsigned start_sector,
1536 unsigned end_sector)
1537 {
1538 uint32_t status;
1539 uint32_t pg;
1540 uint32_t pages_per_sector;
1541 int r;
1542
1543 pages_per_sector = pPrivate->sector_size / pPrivate->page_size;
1544
1545 /* Lock all pages */
1546 while (start_sector <= end_sector) {
1547 pg = start_sector * pages_per_sector;
1548
1549 r = EFC_PerformCommand(pPrivate, AT91C_EFC_FCMD_SLB, pg, &status);
1550 if (r != ERROR_OK)
1551 return r;
1552 start_sector++;
1553 }
1554 return ERROR_OK;
1555 }
1556
1557 /****** END SAM4 CODE ********/
1558
1559 /* begin helpful debug code */
1560 /* print the fieldname, the field value, in dec & hex, and return field value */
1561 static uint32_t sam4_reg_fieldname(struct sam4_chip *pChip,
1562 const char *regname,
1563 uint32_t value,
1564 unsigned shift,
1565 unsigned width)
1566 {
1567 uint32_t v;
1568 int hwidth, dwidth;
1569
1570
1571 /* extract the field */
1572 v = value >> shift;
1573 v = v & ((1 << width)-1);
1574 if (width <= 16) {
1575 hwidth = 4;
1576 dwidth = 5;
1577 } else {
1578 hwidth = 8;
1579 dwidth = 12;
1580 }
1581
1582 /* show the basics */
1583 LOG_USER_N("\t%*s: %*" PRId32 " [0x%0*" PRIx32 "] ",
1584 REG_NAME_WIDTH, regname,
1585 dwidth, v,
1586 hwidth, v);
1587 return v;
1588 }
1589
1590 static const char _unknown[] = "unknown";
1591 static const char *const eproc_names[] = {
1592 "Cortex-M7", /* 0 */
1593 "arm946es", /* 1 */
1594 "arm7tdmi", /* 2 */
1595 "Cortex-M3", /* 3 */
1596 "arm920t", /* 4 */
1597 "arm926ejs", /* 5 */
1598 "Cortex-A5", /* 6 */
1599 "Cortex-M4", /* 7 */
1600 _unknown, /* 8 */
1601 _unknown, /* 9 */
1602 _unknown, /* 10 */
1603 _unknown, /* 11 */
1604 _unknown, /* 12 */
1605 _unknown, /* 13 */
1606 _unknown, /* 14 */
1607 _unknown, /* 15 */
1608 };
1609
1610 #define nvpsize2 nvpsize /* these two tables are identical */
1611 static const char *const nvpsize[] = {
1612 "none", /* 0 */
1613 "8K bytes", /* 1 */
1614 "16K bytes", /* 2 */
1615 "32K bytes", /* 3 */
1616 _unknown, /* 4 */
1617 "64K bytes", /* 5 */
1618 _unknown, /* 6 */
1619 "128K bytes", /* 7 */
1620 "160K bytes", /* 8 */
1621 "256K bytes", /* 9 */
1622 "512K bytes", /* 10 */
1623 _unknown, /* 11 */
1624 "1024K bytes", /* 12 */
1625 _unknown, /* 13 */
1626 "2048K bytes", /* 14 */
1627 _unknown, /* 15 */
1628 };
1629
1630 static const char *const sramsize[] = {
1631 "48K Bytes", /* 0 */
1632 "1K Bytes", /* 1 */
1633 "2K Bytes", /* 2 */
1634 "6K Bytes", /* 3 */
1635 "112K Bytes", /* 4 */
1636 "4K Bytes", /* 5 */
1637 "80K Bytes", /* 6 */
1638 "160K Bytes", /* 7 */
1639 "8K Bytes", /* 8 */
1640 "16K Bytes", /* 9 */
1641 "32K Bytes", /* 10 */
1642 "64K Bytes", /* 11 */
1643 "128K Bytes", /* 12 */
1644 "256K Bytes", /* 13 */
1645 "96K Bytes", /* 14 */
1646 "512K Bytes", /* 15 */
1647
1648 };
1649
1650 static const struct archnames { unsigned value; const char *name; } archnames[] = {
1651 { 0x19, "AT91SAM9xx Series" },
1652 { 0x29, "AT91SAM9XExx Series" },
1653 { 0x34, "AT91x34 Series" },
1654 { 0x37, "CAP7 Series" },
1655 { 0x39, "CAP9 Series" },
1656 { 0x3B, "CAP11 Series" },
1657 { 0x3C, "ATSAM4E" },
1658 { 0x40, "AT91x40 Series" },
1659 { 0x42, "AT91x42 Series" },
1660 { 0x43, "SAMG51 Series"
1661 },
1662 { 0x47, "SAMG53 Series"
1663 },
1664 { 0x55, "AT91x55 Series" },
1665 { 0x60, "AT91SAM7Axx Series" },
1666 { 0x61, "AT91SAM7AQxx Series" },
1667 { 0x63, "AT91x63 Series" },
1668 { 0x64, "SAM4CxxC (100-pin version)" },
1669 { 0x66, "SAM4CxxE (144-pin version)" },
1670 { 0x70, "AT91SAM7Sxx Series" },
1671 { 0x71, "AT91SAM7XCxx Series" },
1672 { 0x72, "AT91SAM7SExx Series" },
1673 { 0x73, "AT91SAM7Lxx Series" },
1674 { 0x75, "AT91SAM7Xxx Series" },
1675 { 0x76, "AT91SAM7SLxx Series" },
1676 { 0x80, "ATSAM3UxC Series (100-pin version)" },
1677 { 0x81, "ATSAM3UxE Series (144-pin version)" },
1678 { 0x83, "ATSAM3A/SAM4A xC Series (100-pin version)"},
1679 { 0x84, "ATSAM3X/SAM4X xC Series (100-pin version)"},
1680 { 0x85, "ATSAM3X/SAM4X xE Series (144-pin version)"},
1681 { 0x86, "ATSAM3X/SAM4X xG Series (208/217-pin version)" },
1682 { 0x88, "ATSAM3S/SAM4S xA Series (48-pin version)" },
1683 { 0x89, "ATSAM3S/SAM4S xB Series (64-pin version)" },
1684 { 0x8A, "ATSAM3S/SAM4S xC Series (100-pin version)"},
1685 { 0x92, "AT91x92 Series" },
1686 { 0x93, "ATSAM3NxA Series (48-pin version)" },
1687 { 0x94, "ATSAM3NxB Series (64-pin version)" },
1688 { 0x95, "ATSAM3NxC Series (100-pin version)" },
1689 { 0x98, "ATSAM3SDxA Series (48-pin version)" },
1690 { 0x99, "ATSAM3SDxB Series (64-pin version)" },
1691 { 0x9A, "ATSAM3SDxC Series (100-pin version)" },
1692 { 0xA5, "ATSAM5A" },
1693 { 0xF0, "AT75Cxx Series" },
1694 { -1, NULL },
1695 };
1696
1697 static const char *const nvptype[] = {
1698 "rom", /* 0 */
1699 "romless or onchip flash", /* 1 */
1700 "embedded flash memory",/* 2 */
1701 "rom(nvpsiz) + embedded flash (nvpsiz2)", /* 3 */
1702 "sram emulating flash", /* 4 */
1703 _unknown, /* 5 */
1704 _unknown, /* 6 */
1705 _unknown, /* 7 */
1706 };
1707
1708 static const char *_yes_or_no(uint32_t v)
1709 {
1710 if (v)
1711 return "YES";
1712 else
1713 return "NO";
1714 }
1715
1716 static const char *const _rc_freq[] = {
1717 "4 MHz", "8 MHz", "12 MHz", "reserved"
1718 };
1719
1720 static void sam4_explain_ckgr_mor(struct sam4_chip *pChip)
1721 {
1722 uint32_t v;
1723 uint32_t rcen;
1724
1725 v = sam4_reg_fieldname(pChip, "MOSCXTEN", pChip->cfg.CKGR_MOR, 0, 1);
1726 LOG_USER("(main xtal enabled: %s)", _yes_or_no(v));
1727 v = sam4_reg_fieldname(pChip, "MOSCXTBY", pChip->cfg.CKGR_MOR, 1, 1);
1728 LOG_USER("(main osc bypass: %s)", _yes_or_no(v));
1729 rcen = sam4_reg_fieldname(pChip, "MOSCRCEN", pChip->cfg.CKGR_MOR, 3, 1);
1730 LOG_USER("(onchip RC-OSC enabled: %s)", _yes_or_no(rcen));
1731 v = sam4_reg_fieldname(pChip, "MOSCRCF", pChip->cfg.CKGR_MOR, 4, 3);
1732 LOG_USER("(onchip RC-OSC freq: %s)", _rc_freq[v]);
1733
1734 pChip->cfg.rc_freq = 0;
1735 if (rcen) {
1736 switch (v) {
1737 default:
1738 pChip->cfg.rc_freq = 0;
1739 break;
1740 case 0:
1741 pChip->cfg.rc_freq = 4 * 1000 * 1000;
1742 break;
1743 case 1:
1744 pChip->cfg.rc_freq = 8 * 1000 * 1000;
1745 break;
1746 case 2:
1747 pChip->cfg.rc_freq = 12 * 1000 * 1000;
1748 break;
1749 }
1750 }
1751
1752 v = sam4_reg_fieldname(pChip, "MOSCXTST", pChip->cfg.CKGR_MOR, 8, 8);
1753 LOG_USER("(startup clks, time= %f uSecs)",
1754 ((float)(v * 1000000)) / ((float)(pChip->cfg.slow_freq)));
1755 v = sam4_reg_fieldname(pChip, "MOSCSEL", pChip->cfg.CKGR_MOR, 24, 1);
1756 LOG_USER("(mainosc source: %s)",
1757 v ? "external xtal" : "internal RC");
1758
1759 v = sam4_reg_fieldname(pChip, "CFDEN", pChip->cfg.CKGR_MOR, 25, 1);
1760 LOG_USER("(clock failure enabled: %s)",
1761 _yes_or_no(v));
1762 }
1763
1764 static void sam4_explain_chipid_cidr(struct sam4_chip *pChip)
1765 {
1766 int x;
1767 uint32_t v;
1768 const char *cp;
1769
1770 sam4_reg_fieldname(pChip, "Version", pChip->cfg.CHIPID_CIDR, 0, 5);
1771 LOG_USER_N("\n");
1772
1773 v = sam4_reg_fieldname(pChip, "EPROC", pChip->cfg.CHIPID_CIDR, 5, 3);
1774 LOG_USER("%s", eproc_names[v]);
1775
1776 v = sam4_reg_fieldname(pChip, "NVPSIZE", pChip->cfg.CHIPID_CIDR, 8, 4);
1777 LOG_USER("%s", nvpsize[v]);
1778
1779 v = sam4_reg_fieldname(pChip, "NVPSIZE2", pChip->cfg.CHIPID_CIDR, 12, 4);
1780 LOG_USER("%s", nvpsize2[v]);
1781
1782 v = sam4_reg_fieldname(pChip, "SRAMSIZE", pChip->cfg.CHIPID_CIDR, 16, 4);
1783 LOG_USER("%s", sramsize[v]);
1784
1785 v = sam4_reg_fieldname(pChip, "ARCH", pChip->cfg.CHIPID_CIDR, 20, 8);
1786 cp = _unknown;
1787 for (x = 0; archnames[x].name; x++) {
1788 if (v == archnames[x].value) {
1789 cp = archnames[x].name;
1790 break;
1791 }
1792 }
1793
1794 LOG_USER("%s", cp);
1795
1796 v = sam4_reg_fieldname(pChip, "NVPTYP", pChip->cfg.CHIPID_CIDR, 28, 3);
1797 LOG_USER("%s", nvptype[v]);
1798
1799 v = sam4_reg_fieldname(pChip, "EXTID", pChip->cfg.CHIPID_CIDR, 31, 1);
1800 LOG_USER("(exists: %s)", _yes_or_no(v));
1801 }
1802
1803 static void sam4_explain_ckgr_mcfr(struct sam4_chip *pChip)
1804 {
1805 uint32_t v;
1806
1807 v = sam4_reg_fieldname(pChip, "MAINFRDY", pChip->cfg.CKGR_MCFR, 16, 1);
1808 LOG_USER("(main ready: %s)", _yes_or_no(v));
1809
1810 v = sam4_reg_fieldname(pChip, "MAINF", pChip->cfg.CKGR_MCFR, 0, 16);
1811
1812 v = (v * pChip->cfg.slow_freq) / 16;
1813 pChip->cfg.mainosc_freq = v;
1814
1815 LOG_USER("(%3.03f Mhz (%" PRIu32 ".%03" PRIu32 "khz slowclk)",
1816 _tomhz(v),
1817 (uint32_t)(pChip->cfg.slow_freq / 1000),
1818 (uint32_t)(pChip->cfg.slow_freq % 1000));
1819 }
1820
1821 static void sam4_explain_ckgr_plla(struct sam4_chip *pChip)
1822 {
1823 uint32_t mula, diva;
1824
1825 diva = sam4_reg_fieldname(pChip, "DIVA", pChip->cfg.CKGR_PLLAR, 0, 8);
1826 LOG_USER_N("\n");
1827 mula = sam4_reg_fieldname(pChip, "MULA", pChip->cfg.CKGR_PLLAR, 16, 11);
1828 LOG_USER_N("\n");
1829 pChip->cfg.plla_freq = 0;
1830 if (mula == 0)
1831 LOG_USER("\tPLLA Freq: (Disabled,mula = 0)");
1832 else if (diva == 0)
1833 LOG_USER("\tPLLA Freq: (Disabled,diva = 0)");
1834 else if (diva >= 1) {
1835 pChip->cfg.plla_freq = (pChip->cfg.mainosc_freq * (mula + 1) / diva);
1836 LOG_USER("\tPLLA Freq: %3.03f MHz",
1837 _tomhz(pChip->cfg.plla_freq));
1838 }
1839 }
1840
1841 static void sam4_explain_mckr(struct sam4_chip *pChip)
1842 {
1843 uint32_t css, pres, fin = 0;
1844 int pdiv = 0;
1845 const char *cp = NULL;
1846
1847 css = sam4_reg_fieldname(pChip, "CSS", pChip->cfg.PMC_MCKR, 0, 2);
1848 switch (css & 3) {
1849 case 0:
1850 fin = pChip->cfg.slow_freq;
1851 cp = "slowclk";
1852 break;
1853 case 1:
1854 fin = pChip->cfg.mainosc_freq;
1855 cp = "mainosc";
1856 break;
1857 case 2:
1858 fin = pChip->cfg.plla_freq;
1859 cp = "plla";
1860 break;
1861 case 3:
1862 if (pChip->cfg.CKGR_UCKR & (1 << 16)) {
1863 fin = 480 * 1000 * 1000;
1864 cp = "upll";
1865 } else {
1866 fin = 0;
1867 cp = "upll (*ERROR* UPLL is disabled)";
1868 }
1869 break;
1870 default:
1871 assert(0);
1872 break;
1873 }
1874
1875 LOG_USER("%s (%3.03f Mhz)",
1876 cp,
1877 _tomhz(fin));
1878 pres = sam4_reg_fieldname(pChip, "PRES", pChip->cfg.PMC_MCKR, 4, 3);
1879 switch (pres & 0x07) {
1880 case 0:
1881 pdiv = 1;
1882 cp = "selected clock";
1883 break;
1884 case 1:
1885 pdiv = 2;
1886 cp = "clock/2";
1887 break;
1888 case 2:
1889 pdiv = 4;
1890 cp = "clock/4";
1891 break;
1892 case 3:
1893 pdiv = 8;
1894 cp = "clock/8";
1895 break;
1896 case 4:
1897 pdiv = 16;
1898 cp = "clock/16";
1899 break;
1900 case 5:
1901 pdiv = 32;
1902 cp = "clock/32";
1903 break;
1904 case 6:
1905 pdiv = 64;
1906 cp = "clock/64";
1907 break;
1908 case 7:
1909 pdiv = 6;
1910 cp = "clock/6";
1911 break;
1912 default:
1913 assert(0);
1914 break;
1915 }
1916 LOG_USER("(%s)", cp);
1917 fin = fin / pdiv;
1918 /* sam4 has a *SINGLE* clock - */
1919 /* other at91 series parts have divisors for these. */
1920 pChip->cfg.cpu_freq = fin;
1921 pChip->cfg.mclk_freq = fin;
1922 pChip->cfg.fclk_freq = fin;
1923 LOG_USER("\t\tResult CPU Freq: %3.03f",
1924 _tomhz(fin));
1925 }
1926
1927 #if 0
1928 static struct sam4_chip *target2sam4(struct target *pTarget)
1929 {
1930 struct sam4_chip *pChip;
1931
1932 if (pTarget == NULL)
1933 return NULL;
1934
1935 pChip = all_sam4_chips;
1936 while (pChip) {
1937 if (pChip->target == pTarget)
1938 break; /* return below */
1939 else
1940 pChip = pChip->next;
1941 }
1942 return pChip;
1943 }
1944 #endif
1945
1946 static uint32_t *sam4_get_reg_ptr(struct sam4_cfg *pCfg, const struct sam4_reg_list *pList)
1947 {
1948 /* this function exists to help */
1949 /* keep funky offsetof() errors */
1950 /* and casting from causing bugs */
1951
1952 /* By using prototypes - we can detect what would */
1953 /* be casting errors. */
1954
1955 return (uint32_t *)(void *)(((char *)(pCfg)) + pList->struct_offset);
1956 }
1957
1958
1959 #define SAM4_ENTRY(NAME, FUNC) { .address = SAM4_ ## NAME, .struct_offset = offsetof( \
1960 struct sam4_cfg, \
1961 NAME), # NAME, FUNC }
1962 static const struct sam4_reg_list sam4_all_regs[] = {
1963 SAM4_ENTRY(CKGR_MOR, sam4_explain_ckgr_mor),
1964 SAM4_ENTRY(CKGR_MCFR, sam4_explain_ckgr_mcfr),
1965 SAM4_ENTRY(CKGR_PLLAR, sam4_explain_ckgr_plla),
1966 SAM4_ENTRY(CKGR_UCKR, NULL),
1967 SAM4_ENTRY(PMC_FSMR, NULL),
1968 SAM4_ENTRY(PMC_FSPR, NULL),
1969 SAM4_ENTRY(PMC_IMR, NULL),
1970 SAM4_ENTRY(PMC_MCKR, sam4_explain_mckr),
1971 SAM4_ENTRY(PMC_PCK0, NULL),
1972 SAM4_ENTRY(PMC_PCK1, NULL),
1973 SAM4_ENTRY(PMC_PCK2, NULL),
1974 SAM4_ENTRY(PMC_PCSR, NULL),
1975 SAM4_ENTRY(PMC_SCSR, NULL),
1976 SAM4_ENTRY(PMC_SR, NULL),
1977 SAM4_ENTRY(CHIPID_CIDR, sam4_explain_chipid_cidr),
1978 SAM4_ENTRY(CHIPID_EXID, NULL),
1979 /* TERMINATE THE LIST */
1980 { .name = NULL }
1981 };
1982 #undef SAM4_ENTRY
1983
1984 static struct sam4_bank_private *get_sam4_bank_private(struct flash_bank *bank)
1985 {
1986 return bank->driver_priv;
1987 }
1988
1989 /**
1990 * Given a pointer to where it goes in the structure,
1991 * determine the register name, address from the all registers table.
1992 */
1993 static const struct sam4_reg_list *sam4_GetReg(struct sam4_chip *pChip, uint32_t *goes_here)
1994 {
1995 const struct sam4_reg_list *pReg;
1996
1997 pReg = &(sam4_all_regs[0]);
1998 while (pReg->name) {
1999 uint32_t *pPossible;
2000
2001 /* calculate where this one go.. */
2002 /* it is "possibly" this register. */
2003
2004 pPossible = ((uint32_t *)(void *)(((char *)(&(pChip->cfg))) + pReg->struct_offset));
2005
2006 /* well? Is it this register */
2007 if (pPossible == goes_here) {
2008 /* Jump for joy! */
2009 return pReg;
2010 }
2011
2012 /* next... */
2013 pReg++;
2014 }
2015 /* This is *TOTAL*PANIC* - we are totally screwed. */
2016 LOG_ERROR("INVALID SAM4 REGISTER");
2017 return NULL;
2018 }
2019
2020 static int sam4_ReadThisReg(struct sam4_chip *pChip, uint32_t *goes_here)
2021 {
2022 const struct sam4_reg_list *pReg;
2023 int r;
2024
2025 pReg = sam4_GetReg(pChip, goes_here);
2026 if (!pReg)
2027 return ERROR_FAIL;
2028
2029 r = target_read_u32(pChip->target, pReg->address, goes_here);
2030 if (r != ERROR_OK) {
2031 LOG_ERROR("Cannot read SAM4 register: %s @ 0x%08x, Err: %d",
2032 pReg->name, (unsigned)(pReg->address), r);
2033 }
2034 return r;
2035 }
2036
2037 static int sam4_ReadAllRegs(struct sam4_chip *pChip)
2038 {
2039 int r;
2040 const struct sam4_reg_list *pReg;
2041
2042 pReg = &(sam4_all_regs[0]);
2043 while (pReg->name) {
2044 r = sam4_ReadThisReg(pChip,
2045 sam4_get_reg_ptr(&(pChip->cfg), pReg));
2046 if (r != ERROR_OK) {
2047 LOG_ERROR("Cannot read SAM4 register: %s @ 0x%08x, Error: %d",
2048 pReg->name, ((unsigned)(pReg->address)), r);
2049 return r;
2050 }
2051 pReg++;
2052 }
2053
2054 return ERROR_OK;
2055 }
2056
2057 static int sam4_GetInfo(struct sam4_chip *pChip)
2058 {
2059 const struct sam4_reg_list *pReg;
2060 uint32_t regval;
2061
2062 pReg = &(sam4_all_regs[0]);
2063 while (pReg->name) {
2064 /* display all regs */
2065 LOG_DEBUG("Start: %s", pReg->name);
2066 regval = *sam4_get_reg_ptr(&(pChip->cfg), pReg);
2067 LOG_USER("%*s: [0x%08" PRIx32 "] -> 0x%08" PRIx32,
2068 REG_NAME_WIDTH,
2069 pReg->name,
2070 pReg->address,
2071 regval);
2072 if (pReg->explain_func)
2073 (*(pReg->explain_func))(pChip);
2074 LOG_DEBUG("End: %s", pReg->name);
2075 pReg++;
2076 }
2077 LOG_USER(" rc-osc: %3.03f MHz", _tomhz(pChip->cfg.rc_freq));
2078 LOG_USER(" mainosc: %3.03f MHz", _tomhz(pChip->cfg.mainosc_freq));
2079 LOG_USER(" plla: %3.03f MHz", _tomhz(pChip->cfg.plla_freq));
2080 LOG_USER(" cpu-freq: %3.03f MHz", _tomhz(pChip->cfg.cpu_freq));
2081 LOG_USER("mclk-freq: %3.03f MHz", _tomhz(pChip->cfg.mclk_freq));
2082
2083 LOG_USER(" UniqueId: 0x%08" PRIx32 " 0x%08" PRIx32 " 0x%08" PRIx32 " 0x%08"PRIx32,
2084 pChip->cfg.unique_id[0],
2085 pChip->cfg.unique_id[1],
2086 pChip->cfg.unique_id[2],
2087 pChip->cfg.unique_id[3]);
2088
2089 return ERROR_OK;
2090 }
2091
2092 static int sam4_protect_check(struct flash_bank *bank)
2093 {
2094 int r;
2095 uint32_t v[4] = {0};
2096 unsigned x;
2097 struct sam4_bank_private *pPrivate;
2098
2099 LOG_DEBUG("Begin");
2100 if (bank->target->state != TARGET_HALTED) {
2101 LOG_ERROR("Target not halted");
2102 return ERROR_TARGET_NOT_HALTED;
2103 }
2104
2105 pPrivate = get_sam4_bank_private(bank);
2106 if (!pPrivate) {
2107 LOG_ERROR("no private for this bank?");
2108 return ERROR_FAIL;
2109 }
2110 if (!(pPrivate->probed))
2111 return ERROR_FLASH_BANK_NOT_PROBED;
2112
2113 r = FLASHD_GetLockBits(pPrivate, v);
2114 if (r != ERROR_OK) {
2115 LOG_DEBUG("Failed: %d", r);
2116 return r;
2117 }
2118
2119 for (x = 0; x < pPrivate->nsectors; x++)
2120 bank->sectors[x].is_protected = (!!(v[x >> 5] & (1 << (x % 32))));
2121 LOG_DEBUG("Done");
2122 return ERROR_OK;
2123 }
2124
2125 FLASH_BANK_COMMAND_HANDLER(sam4_flash_bank_command)
2126 {
2127 struct sam4_chip *pChip;
2128
2129 pChip = all_sam4_chips;
2130
2131 /* is this an existing chip? */
2132 while (pChip) {
2133 if (pChip->target == bank->target)
2134 break;
2135 pChip = pChip->next;
2136 }
2137
2138 if (!pChip) {
2139 /* this is a *NEW* chip */
2140 pChip = calloc(1, sizeof(struct sam4_chip));
2141 if (!pChip) {
2142 LOG_ERROR("NO RAM!");
2143 return ERROR_FAIL;
2144 }
2145 pChip->target = bank->target;
2146 /* insert at head */
2147 pChip->next = all_sam4_chips;
2148 all_sam4_chips = pChip;
2149 pChip->target = bank->target;
2150 /* assumption is this runs at 32khz */
2151 pChip->cfg.slow_freq = 32768;
2152 pChip->probed = 0;
2153 }
2154
2155 switch (bank->base) {
2156 default:
2157 LOG_ERROR("Address 0x%08x invalid bank address (try 0x%08x"
2158 "[at91sam4s series] )",
2159 ((unsigned int)(bank->base)),
2160 ((unsigned int)(FLASH_BANK_BASE_S)));
2161 return ERROR_FAIL;
2162 break;
2163
2164 /* at91sam4s series only has bank 0*/
2165 /* at91sam4sd series has the same address for bank 0 (FLASH_BANK0_BASE_SD)*/
2166 case FLASH_BANK_BASE_S:
2167 case FLASH_BANK_BASE_C:
2168 bank->driver_priv = &(pChip->details.bank[0]);
2169 bank->bank_number = 0;
2170 pChip->details.bank[0].pChip = pChip;
2171 pChip->details.bank[0].pBank = bank;
2172 break;
2173
2174 /* Bank 1 of at91sam4sd/at91sam4c32 series */
2175 case FLASH_BANK1_BASE_1024K_SD:
2176 case FLASH_BANK1_BASE_2048K_SD:
2177 case FLASH_BANK1_BASE_C32:
2178 bank->driver_priv = &(pChip->details.bank[1]);
2179 bank->bank_number = 1;
2180 pChip->details.bank[1].pChip = pChip;
2181 pChip->details.bank[1].pBank = bank;
2182 break;
2183 }
2184
2185 /* we initialize after probing. */
2186 return ERROR_OK;
2187 }
2188
2189 static int sam4_GetDetails(struct sam4_bank_private *pPrivate)
2190 {
2191 const struct sam4_chip_details *pDetails;
2192 struct sam4_chip *pChip;
2193 struct flash_bank *saved_banks[SAM4_MAX_FLASH_BANKS];
2194 unsigned x;
2195
2196 LOG_DEBUG("Begin");
2197 pDetails = all_sam4_details;
2198 while (pDetails->name) {
2199 /* Compare cidr without version bits */
2200 if (pDetails->chipid_cidr == (pPrivate->pChip->cfg.CHIPID_CIDR & 0xFFFFFFE0))
2201 break;
2202 else
2203 pDetails++;
2204 }
2205 if (pDetails->name == NULL) {
2206 LOG_ERROR("SAM4 ChipID 0x%08x not found in table (perhaps you can ID this chip?)",
2207 (unsigned int)(pPrivate->pChip->cfg.CHIPID_CIDR));
2208 /* Help the victim, print details about the chip */
2209 LOG_INFO("SAM4 CHIPID_CIDR: 0x%08" PRIx32 " decodes as follows",
2210 pPrivate->pChip->cfg.CHIPID_CIDR);
2211 sam4_explain_chipid_cidr(pPrivate->pChip);
2212 return ERROR_FAIL;
2213 }
2214
2215 /* DANGER: THERE ARE DRAGONS HERE */
2216
2217 /* get our pChip - it is going */
2218 /* to be over-written shortly */
2219 pChip = pPrivate->pChip;
2220
2221 /* Note that, in reality: */
2222 /* */
2223 /* pPrivate = &(pChip->details.bank[0]) */
2224 /* or pPrivate = &(pChip->details.bank[1]) */
2225 /* */
2226
2227 /* save the "bank" pointers */
2228 for (x = 0; x < SAM4_MAX_FLASH_BANKS; x++)
2229 saved_banks[x] = pChip->details.bank[x].pBank;
2230
2231 /* Overwrite the "details" structure. */
2232 memcpy(&(pPrivate->pChip->details),
2233 pDetails,
2234 sizeof(pPrivate->pChip->details));
2235
2236 /* now fix the ghosted pointers */
2237 for (x = 0; x < SAM4_MAX_FLASH_BANKS; x++) {
2238 pChip->details.bank[x].pChip = pChip;
2239 pChip->details.bank[x].pBank = saved_banks[x];
2240 }
2241
2242 /* update the *BANK*SIZE* */
2243
2244 LOG_DEBUG("End");
2245 return ERROR_OK;
2246 }
2247
2248 static int _sam4_probe(struct flash_bank *bank, int noise)
2249 {
2250 unsigned x;
2251 int r;
2252 struct sam4_bank_private *pPrivate;
2253
2254
2255 LOG_DEBUG("Begin: Bank: %d, Noise: %d", bank->bank_number, noise);
2256 if (bank->target->state != TARGET_HALTED) {
2257 LOG_ERROR("Target not halted");
2258 return ERROR_TARGET_NOT_HALTED;
2259 }
2260
2261 pPrivate = get_sam4_bank_private(bank);
2262 if (!pPrivate) {
2263 LOG_ERROR("Invalid/unknown bank number");
2264 return ERROR_FAIL;
2265 }
2266
2267 r = sam4_ReadAllRegs(pPrivate->pChip);
2268 if (r != ERROR_OK)
2269 return r;
2270
2271 LOG_DEBUG("Here");
2272 if (pPrivate->pChip->probed)
2273 r = sam4_GetInfo(pPrivate->pChip);
2274 else
2275 r = sam4_GetDetails(pPrivate);
2276 if (r != ERROR_OK)
2277 return r;
2278
2279 /* update the flash bank size */
2280 for (x = 0; x < SAM4_MAX_FLASH_BANKS; x++) {
2281 if (bank->base == pPrivate->pChip->details.bank[x].base_address) {
2282 bank->size = pPrivate->pChip->details.bank[x].size_bytes;
2283 break;
2284 }
2285 }
2286
2287 if (bank->sectors == NULL) {
2288 bank->sectors = calloc(pPrivate->nsectors, (sizeof((bank->sectors)[0])));
2289 if (bank->sectors == NULL) {
2290 LOG_ERROR("No memory!");
2291 return ERROR_FAIL;
2292 }
2293 bank->num_sectors = pPrivate->nsectors;
2294
2295 for (x = 0; ((int)(x)) < bank->num_sectors; x++) {
2296 bank->sectors[x].size = pPrivate->sector_size;
2297 bank->sectors[x].offset = x * (pPrivate->sector_size);
2298 /* mark as unknown */
2299 bank->sectors[x].is_erased = -1;
2300 bank->sectors[x].is_protected = -1;
2301 }
2302 }
2303
2304 pPrivate->probed = 1;
2305
2306 r = sam4_protect_check(bank);
2307 if (r != ERROR_OK)
2308 return r;
2309
2310 LOG_DEBUG("Bank = %d, nbanks = %d",
2311 pPrivate->bank_number, pPrivate->pChip->details.n_banks);
2312 if ((pPrivate->bank_number + 1) == pPrivate->pChip->details.n_banks) {
2313 /* read unique id, */
2314 /* it appears to be associated with the *last* flash bank. */
2315 FLASHD_ReadUniqueID(pPrivate);
2316 }
2317
2318 return r;
2319 }
2320
2321 static int sam4_probe(struct flash_bank *bank)
2322 {
2323 return _sam4_probe(bank, 1);
2324 }
2325
2326 static int sam4_auto_probe(struct flash_bank *bank)
2327 {
2328 return _sam4_probe(bank, 0);
2329 }
2330
2331 static int sam4_erase(struct flash_bank *bank, int first, int last)
2332 {
2333 struct sam4_bank_private *pPrivate;
2334 int r;
2335 int i;
2336 int pageCount;
2337 /*16 pages equals 8KB - Same size as a lock region*/
2338 pageCount = 16;
2339 uint32_t status;
2340
2341 LOG_DEBUG("Here");
2342 if (bank->target->state != TARGET_HALTED) {
2343 LOG_ERROR("Target not halted");
2344 return ERROR_TARGET_NOT_HALTED;
2345 }
2346
2347 r = sam4_auto_probe(bank);
2348 if (r != ERROR_OK) {
2349 LOG_DEBUG("Here,r=%d", r);
2350 return r;
2351 }
2352
2353 pPrivate = get_sam4_bank_private(bank);
2354 if (!(pPrivate->probed))
2355 return ERROR_FLASH_BANK_NOT_PROBED;
2356
2357 if ((first == 0) && ((last + 1) == ((int)(pPrivate->nsectors)))) {
2358 /* whole chip */
2359 LOG_DEBUG("Here");
2360 return FLASHD_EraseEntireBank(pPrivate);
2361 }
2362 LOG_INFO("sam4 does not auto-erase while programming (Erasing relevant sectors)");
2363 LOG_INFO("sam4 First: 0x%08x Last: 0x%08x", (unsigned int)(first), (unsigned int)(last));
2364 for (i = first; i <= last; i++) {
2365 /*16 pages equals 8KB - Same size as a lock region*/
2366 r = FLASHD_ErasePages(pPrivate, (i * pageCount), pageCount, &status);
2367 LOG_INFO("Erasing sector: 0x%08x", (unsigned int)(i));
2368 if (r != ERROR_OK)
2369 LOG_ERROR("SAM4: Error performing Erase page @ lock region number %d",
2370 (unsigned int)(i));
2371 if (status & (1 << 2)) {
2372 LOG_ERROR("SAM4: Lock Region %d is locked", (unsigned int)(i));
2373 return ERROR_FAIL;
2374 }
2375 if (status & (1 << 1)) {
2376 LOG_ERROR("SAM4: Flash Command error @lock region %d", (unsigned int)(i));
2377 return ERROR_FAIL;
2378 }
2379 }
2380
2381 return ERROR_OK;
2382 }
2383
2384 static int sam4_protect(struct flash_bank *bank, int set, int first, int last)
2385 {
2386 struct sam4_bank_private *pPrivate;
2387 int r;
2388
2389 LOG_DEBUG("Here");
2390 if (bank->target->state != TARGET_HALTED) {
2391 LOG_ERROR("Target not halted");
2392 return ERROR_TARGET_NOT_HALTED;
2393 }
2394
2395 pPrivate = get_sam4_bank_private(bank);
2396 if (!(pPrivate->probed))
2397 return ERROR_FLASH_BANK_NOT_PROBED;
2398
2399 if (set)
2400 r = FLASHD_Lock(pPrivate, (unsigned)(first), (unsigned)(last));
2401 else
2402 r = FLASHD_Unlock(pPrivate, (unsigned)(first), (unsigned)(last));
2403 LOG_DEBUG("End: r=%d", r);
2404
2405 return r;
2406
2407 }
2408
2409 static int sam4_page_read(struct sam4_bank_private *pPrivate, unsigned pagenum, uint8_t *buf)
2410 {
2411 uint32_t adr;
2412 int r;
2413
2414 adr = pagenum * pPrivate->page_size;
2415 adr = adr + pPrivate->base_address;
2416
2417 r = target_read_memory(pPrivate->pChip->target,
2418 adr,
2419 4, /* THIS*MUST*BE* in 32bit values */
2420 pPrivate->page_size / 4,
2421 buf);
2422 if (r != ERROR_OK)
2423 LOG_ERROR("SAM4: Flash program failed to read page phys address: 0x%08x",
2424 (unsigned int)(adr));
2425 return r;
2426 }
2427
2428 static int sam4_page_write(struct sam4_bank_private *pPrivate, unsigned pagenum, const uint8_t *buf)
2429 {
2430 uint32_t adr;
2431 uint32_t status;
2432 uint32_t fmr; /* EEFC Flash Mode Register */
2433 int r;
2434
2435 adr = pagenum * pPrivate->page_size;
2436 adr = (adr + pPrivate->base_address);
2437
2438 /* Get flash mode register value */
2439 r = target_read_u32(pPrivate->pChip->target, pPrivate->controller_address, &fmr);
2440 if (r != ERROR_OK)
2441 LOG_DEBUG("Error Read failed: read flash mode register");
2442
2443 /* Clear flash wait state field */
2444 fmr &= 0xfffff0ff;
2445
2446 /* set FWS (flash wait states) field in the FMR (flash mode register) */
2447 fmr |= (pPrivate->flash_wait_states << 8);
2448
2449 LOG_DEBUG("Flash Mode: 0x%08x", ((unsigned int)(fmr)));
2450 r = target_write_u32(pPrivate->pBank->target, pPrivate->controller_address, fmr);
2451 if (r != ERROR_OK)
2452 LOG_DEBUG("Error Write failed: set flash mode register");
2453
2454 /* 1st sector 8kBytes - page 0 - 15*/
2455 /* 2nd sector 8kBytes - page 16 - 30*/
2456 /* 3rd sector 48kBytes - page 31 - 127*/
2457 LOG_DEBUG("Wr Page %u @ phys address: 0x%08x", pagenum, (unsigned int)(adr));
2458 r = target_write_memory(pPrivate->pChip->target,
2459 adr,
2460 4, /* THIS*MUST*BE* in 32bit values */
2461 pPrivate->page_size / 4,
2462 buf);
2463 if (r != ERROR_OK) {
2464 LOG_ERROR("SAM4: Failed to write (buffer) page at phys address 0x%08x",
2465 (unsigned int)(adr));
2466 return r;
2467 }
2468
2469 r = EFC_PerformCommand(pPrivate,
2470 /* send Erase & Write Page */
2471 AT91C_EFC_FCMD_WP, /*AT91C_EFC_FCMD_EWP only works on first two 8kb sectors*/
2472 pagenum,
2473 &status);
2474
2475 if (r != ERROR_OK)
2476 LOG_ERROR("SAM4: Error performing Write page @ phys address 0x%08x",
2477 (unsigned int)(adr));
2478 if (status & (1 << 2)) {
2479 LOG_ERROR("SAM4: Page @ Phys address 0x%08x is locked", (unsigned int)(adr));
2480 return ERROR_FAIL;
2481 }
2482 if (status & (1 << 1)) {
2483 LOG_ERROR("SAM4: Flash Command error @phys address 0x%08x", (unsigned int)(adr));
2484 return ERROR_FAIL;
2485 }
2486 return ERROR_OK;
2487 }
2488
2489 static int sam4_write(struct flash_bank *bank,
2490 const uint8_t *buffer,
2491 uint32_t offset,
2492 uint32_t count)
2493 {
2494 int n;
2495 unsigned page_cur;
2496 unsigned page_end;
2497 int r;
2498 unsigned page_offset;
2499 struct sam4_bank_private *pPrivate;
2500 uint8_t *pagebuffer;
2501
2502 /* incase we bail further below, set this to null */
2503 pagebuffer = NULL;
2504
2505 /* ignore dumb requests */
2506 if (count == 0) {
2507 r = ERROR_OK;
2508 goto done;
2509 }
2510
2511 if (bank->target->state != TARGET_HALTED) {
2512 LOG_ERROR("Target not halted");
2513 r = ERROR_TARGET_NOT_HALTED;
2514 goto done;
2515 }
2516
2517 pPrivate = get_sam4_bank_private(bank);
2518 if (!(pPrivate->probed)) {
2519 r = ERROR_FLASH_BANK_NOT_PROBED;
2520 goto done;
2521 }
2522
2523 if ((offset + count) > pPrivate->size_bytes) {
2524 LOG_ERROR("Flash write error - past end of bank");
2525 LOG_ERROR(" offset: 0x%08x, count 0x%08x, BankEnd: 0x%08x",
2526 (unsigned int)(offset),
2527 (unsigned int)(count),
2528 (unsigned int)(pPrivate->size_bytes));
2529 r = ERROR_FAIL;
2530 goto done;
2531 }
2532
2533 pagebuffer = malloc(pPrivate->page_size);
2534 if (!pagebuffer) {
2535 LOG_ERROR("No memory for %d Byte page buffer", (int)(pPrivate->page_size));
2536 r = ERROR_FAIL;
2537 goto done;
2538 }
2539
2540 /* what page do we start & end in? */
2541 page_cur = offset / pPrivate->page_size;
2542 page_end = (offset + count - 1) / pPrivate->page_size;
2543
2544 LOG_DEBUG("Offset: 0x%08x, Count: 0x%08x", (unsigned int)(offset), (unsigned int)(count));
2545 LOG_DEBUG("Page start: %d, Page End: %d", (int)(page_cur), (int)(page_end));
2546
2547 /* Special case: all one page */
2548 /* */
2549 /* Otherwise: */
2550 /* (1) non-aligned start */
2551 /* (2) body pages */
2552 /* (3) non-aligned end. */
2553
2554 /* Handle special case - all one page. */
2555 if (page_cur == page_end) {
2556 LOG_DEBUG("Special case, all in one page");
2557 r = sam4_page_read(pPrivate, page_cur, pagebuffer);
2558 if (r != ERROR_OK)
2559 goto done;
2560
2561 page_offset = (offset & (pPrivate->page_size-1));
2562 memcpy(pagebuffer + page_offset,
2563 buffer,
2564 count);
2565
2566 r = sam4_page_write(pPrivate, page_cur, pagebuffer);
2567 if (r != ERROR_OK)
2568 goto done;
2569 r = ERROR_OK;
2570 goto done;
2571 }
2572
2573 /* non-aligned start */
2574 page_offset = offset & (pPrivate->page_size - 1);
2575 if (page_offset) {
2576 LOG_DEBUG("Not-Aligned start");
2577 /* read the partial */
2578 r = sam4_page_read(pPrivate, page_cur, pagebuffer);
2579 if (r != ERROR_OK)
2580 goto done;
2581
2582 /* over-write with new data */
2583 n = (pPrivate->page_size - page_offset);
2584 memcpy(pagebuffer + page_offset,
2585 buffer,
2586 n);
2587
2588 r = sam4_page_write(pPrivate, page_cur, pagebuffer);
2589 if (r != ERROR_OK)
2590 goto done;
2591
2592 count -= n;
2593 offset += n;
2594 buffer += n;
2595 page_cur++;
2596 }
2597
2598 /* By checking that offset is correct here, we also
2599 fix a clang warning */
2600 assert(offset % pPrivate->page_size == 0);
2601
2602 /* intermediate large pages */
2603 /* also - the final *terminal* */
2604 /* if that terminal page is a full page */
2605 LOG_DEBUG("Full Page Loop: cur=%d, end=%d, count = 0x%08x",
2606 (int)page_cur, (int)page_end, (unsigned int)(count));
2607
2608 while ((page_cur < page_end) &&
2609 (count >= pPrivate->page_size)) {
2610 r = sam4_page_write(pPrivate, page_cur, buffer);
2611 if (r != ERROR_OK)
2612 goto done;
2613 count -= pPrivate->page_size;
2614 buffer += pPrivate->page_size;
2615 page_cur += 1;
2616 }
2617
2618 /* terminal partial page? */
2619 if (count) {
2620 LOG_DEBUG("Terminal partial page, count = 0x%08x", (unsigned int)(count));
2621 /* we have a partial page */
2622 r = sam4_page_read(pPrivate, page_cur, pagebuffer);
2623 if (r != ERROR_OK)
2624 goto done;
2625 /* data goes at start */
2626 memcpy(pagebuffer, buffer, count);
2627 r = sam4_page_write(pPrivate, page_cur, pagebuffer);
2628 if (r != ERROR_OK)
2629 goto done;
2630 }
2631 LOG_DEBUG("Done!");
2632 r = ERROR_OK;
2633 done:
2634 if (pagebuffer)
2635 free(pagebuffer);
2636 return r;
2637 }
2638
2639 COMMAND_HANDLER(sam4_handle_info_command)
2640 {
2641 struct sam4_chip *pChip;
2642 pChip = get_current_sam4(CMD_CTX);
2643 if (!pChip)
2644 return ERROR_OK;
2645
2646 unsigned x;
2647 int r;
2648
2649 /* bank0 must exist before we can do anything */
2650 if (pChip->details.bank[0].pBank == NULL) {
2651 x = 0;
2652 need_define:
2653 command_print(CMD_CTX,
2654 "Please define bank %d via command: flash bank %s ... ",
2655 x,
2656 at91sam4_flash.name);
2657 return ERROR_FAIL;
2658 }
2659
2660 /* if bank 0 is not probed, then probe it */
2661 if (!(pChip->details.bank[0].probed)) {
2662 r = sam4_auto_probe(pChip->details.bank[0].pBank);
2663 if (r != ERROR_OK)
2664 return ERROR_FAIL;
2665 }
2666 /* above guarantees the "chip details" structure is valid */
2667 /* and thus, bank private areas are valid */
2668 /* and we have a SAM4 chip, what a concept! */
2669
2670 /* auto-probe other banks, 0 done above */
2671 for (x = 1; x < SAM4_MAX_FLASH_BANKS; x++) {
2672 /* skip banks not present */
2673 if (!(pChip->details.bank[x].present))
2674 continue;
2675
2676 if (pChip->details.bank[x].pBank == NULL)
2677 goto need_define;
2678
2679 if (pChip->details.bank[x].probed)
2680 continue;
2681
2682 r = sam4_auto_probe(pChip->details.bank[x].pBank);
2683 if (r != ERROR_OK)
2684 return r;
2685 }
2686
2687 r = sam4_GetInfo(pChip);
2688 if (r != ERROR_OK) {
2689 LOG_DEBUG("Sam4Info, Failed %d", r);
2690 return r;
2691 }
2692
2693 return ERROR_OK;
2694 }
2695
2696 COMMAND_HANDLER(sam4_handle_gpnvm_command)
2697 {
2698 unsigned x, v;
2699 int r, who;
2700 struct sam4_chip *pChip;
2701
2702 pChip = get_current_sam4(CMD_CTX);
2703 if (!pChip)
2704 return ERROR_OK;
2705
2706 if (pChip->target->state != TARGET_HALTED) {
2707 LOG_ERROR("sam4 - target not halted");
2708 return ERROR_TARGET_NOT_HALTED;
2709 }
2710
2711 if (pChip->details.bank[0].pBank == NULL) {
2712 command_print(CMD_CTX, "Bank0 must be defined first via: flash bank %s ...",
2713 at91sam4_flash.name);
2714 return ERROR_FAIL;
2715 }
2716 if (!pChip->details.bank[0].probed) {
2717 r = sam4_auto_probe(pChip->details.bank[0].pBank);
2718 if (r != ERROR_OK)
2719 return r;
2720 }
2721
2722 switch (CMD_ARGC) {
2723 default:
2724 return ERROR_COMMAND_SYNTAX_ERROR;
2725 break;
2726 case 0:
2727 goto showall;
2728 break;
2729 case 1:
2730 who = -1;
2731 break;
2732 case 2:
2733 if ((0 == strcmp(CMD_ARGV[0], "show")) && (0 == strcmp(CMD_ARGV[1], "all")))
2734 who = -1;
2735 else {
2736 uint32_t v32;
2737 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], v32);
2738 who = v32;
2739 }
2740 break;
2741 }
2742
2743 if (0 == strcmp("show", CMD_ARGV[0])) {
2744 if (who == -1) {
2745 showall:
2746 r = ERROR_OK;
2747 for (x = 0; x < pChip->details.n_gpnvms; x++) {
2748 r = FLASHD_GetGPNVM(&(pChip->details.bank[0]), x, &v);
2749 if (r != ERROR_OK)
2750 break;
2751 command_print(CMD_CTX, "sam4-gpnvm%u: %u", x, v);
2752 }
2753 return r;
2754 }
2755 if ((who >= 0) && (((unsigned)(who)) < pChip->details.n_gpnvms)) {
2756 r = FLASHD_GetGPNVM(&(pChip->details.bank[0]), who, &v);
2757 command_print(CMD_CTX, "sam4-gpnvm%u: %u", who, v);
2758 return r;
2759 } else {
2760 command_print(CMD_CTX, "sam4-gpnvm invalid GPNVM: %u", who);
2761 return ERROR_COMMAND_SYNTAX_ERROR;
2762 }
2763 }
2764
2765 if (who == -1) {
2766 command_print(CMD_CTX, "Missing GPNVM number");
2767 return ERROR_COMMAND_SYNTAX_ERROR;
2768 }
2769
2770 if (0 == strcmp("set", CMD_ARGV[0]))
2771 r = FLASHD_SetGPNVM(&(pChip->details.bank[0]), who);
2772 else if ((0 == strcmp("clr", CMD_ARGV[0])) ||
2773 (0 == strcmp("clear", CMD_ARGV[0]))) /* quietly accept both */
2774 r = FLASHD_ClrGPNVM(&(pChip->details.bank[0]), who);
2775 else {
2776 command_print(CMD_CTX, "Unknown command: %s", CMD_ARGV[0]);
2777 r = ERROR_COMMAND_SYNTAX_ERROR;
2778 }
2779 return r;
2780 }
2781
2782 COMMAND_HANDLER(sam4_handle_slowclk_command)
2783 {
2784 struct sam4_chip *pChip;
2785
2786 pChip = get_current_sam4(CMD_CTX);
2787 if (!pChip)
2788 return ERROR_OK;
2789
2790 switch (CMD_ARGC) {
2791 case 0:
2792 /* show */
2793 break;
2794 case 1:
2795 {
2796 /* set */
2797 uint32_t v;
2798 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], v);
2799 if (v > 200000) {
2800 /* absurd slow clock of 200Khz? */
2801 command_print(CMD_CTX, "Absurd/illegal slow clock freq: %d\n", (int)(v));
2802 return ERROR_COMMAND_SYNTAX_ERROR;
2803 }
2804 pChip->cfg.slow_freq = v;
2805 break;
2806 }
2807 default:
2808 /* error */
2809 command_print(CMD_CTX, "Too many parameters");
2810 return ERROR_COMMAND_SYNTAX_ERROR;
2811 break;
2812 }
2813 command_print(CMD_CTX, "Slowclk freq: %d.%03dkhz",
2814 (int)(pChip->cfg.slow_freq / 1000),
2815 (int)(pChip->cfg.slow_freq % 1000));
2816 return ERROR_OK;
2817 }
2818
2819 static const struct command_registration at91sam4_exec_command_handlers[] = {
2820 {
2821 .name = "gpnvm",
2822 .handler = sam4_handle_gpnvm_command,
2823 .mode = COMMAND_EXEC,
2824 .usage = "[('clr'|'set'|'show') bitnum]",
2825 .help = "Without arguments, shows all bits in the gpnvm "
2826 "register. Otherwise, clears, sets, or shows one "
2827 "General Purpose Non-Volatile Memory (gpnvm) bit.",
2828 },
2829 {
2830 .name = "info",
2831 .handler = sam4_handle_info_command,
2832 .mode = COMMAND_EXEC,
2833 .help = "Print information about the current at91sam4 chip"
2834 "and its flash configuration.",
2835 },
2836 {
2837 .name = "slowclk",
2838 .handler = sam4_handle_slowclk_command,
2839 .mode = COMMAND_EXEC,
2840 .usage = "[clock_hz]",
2841 .help = "Display or set the slowclock frequency "
2842 "(default 32768 Hz).",
2843 },
2844 COMMAND_REGISTRATION_DONE
2845 };
2846 static const struct command_registration at91sam4_command_handlers[] = {
2847 {
2848 .name = "at91sam4",
2849 .mode = COMMAND_ANY,
2850 .help = "at91sam4 flash command group",
2851 .usage = "",
2852 .chain = at91sam4_exec_command_handlers,
2853 },
2854 COMMAND_REGISTRATION_DONE
2855 };
2856
2857 struct flash_driver at91sam4_flash = {
2858 .name = "at91sam4",
2859 .commands = at91sam4_command_handlers,
2860 .flash_bank_command = sam4_flash_bank_command,
2861 .erase = sam4_erase,
2862 .protect = sam4_protect,
2863 .write = sam4_write,
2864 .read = default_flash_read,
2865 .probe = sam4_probe,
2866 .auto_probe = sam4_auto_probe,
2867 .erase_check = default_flash_blank_check,
2868 .protect_check = sam4_protect_check,
2869 };

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)