atsamv: Support for ATSAMS70N19 Memory Configuration
[openocd.git] / src / flash / nor / at91sam7.c
1 /***************************************************************************
2 * Copyright (C) 2006 by Magnus Lundin *
3 * lundin@mlu.mine.nu *
4 * *
5 * Copyright (C) 2008 by Gheorghe Guran (atlas) *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19 ****************************************************************************/
20
21 /***************************************************************************
22 *
23 * New flash setup command:
24 *
25 * flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_id>
26 * [<chip_type> <banks>
27 * <sectors_per_bank> <pages_per_sector>
28 * <page_size> <num_nvmbits>
29 * <ext_freq_khz>]
30 *
31 * <ext_freq_khz> - MUST be used if clock is from external source,
32 * CAN be used if main oscillator frequency is known (recommended)
33 * Examples:
34 * ==== RECOMMENDED (covers clock speed) ============
35 * flash bank at91sam7 0x00100000 0 0 4 $_TARGETNAME AT91SAM7XC256 1 16 64 256 3 25000
36 * (if auto-detect fails; provides clock spec)
37 * flash bank at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 25000
38 * (auto-detect everything except the clock)
39 * ==== NOT RECOMMENDED !!! (clock speed is not configured) ====
40 * flash bank at91sam7 0x00100000 0 0 4 $_TARGETNAME AT91SAM7XC256 1 16 64 256 3 0
41 * (if auto-detect fails)
42 * flash bank at91sam7 0 0 0 0 $_TARGETNAME
43 * (old style, auto-detect everything)
44 ****************************************************************************/
45
46 #ifdef HAVE_CONFIG_H
47 #include "config.h"
48 #endif
49
50 #include "imp.h"
51 #include <helper/binarybuffer.h>
52
53 /* AT91SAM7 control registers */
54 #define DBGU_CIDR 0xFFFFF240
55 #define CKGR_MCFR 0xFFFFFC24
56 #define CKGR_MOR 0xFFFFFC20
57 #define CKGR_MCFR_MAINRDY 0x10000
58 #define CKGR_PLLR 0xFFFFFC2c
59 #define CKGR_PLLR_DIV 0xff
60 #define CKGR_PLLR_MUL 0x07ff0000
61 #define PMC_MCKR 0xFFFFFC30
62 #define PMC_MCKR_CSS 0x03
63 #define PMC_MCKR_PRES 0x1c
64
65 /* Flash Controller Commands */
66 #define WP 0x01
67 #define SLB 0x02
68 #define WPL 0x03
69 #define CLB 0x04
70 #define EA 0x08
71 #define SGPB 0x0B
72 #define CGPB 0x0D
73 #define SSB 0x0F
74
75 /* MC_FSR bit definitions */
76 #define MC_FSR_FRDY 1
77 #define MC_FSR_EOL 2
78
79 /* AT91SAM7 constants */
80 #define RC_FREQ 32000
81
82 /* Flash timing modes */
83 #define FMR_TIMING_NONE 0
84 #define FMR_TIMING_NVBITS 1
85 #define FMR_TIMING_FLASH 2
86
87 /* Flash size constants */
88 #define FLASH_SIZE_8KB 1
89 #define FLASH_SIZE_16KB 2
90 #define FLASH_SIZE_32KB 3
91 #define FLASH_SIZE_64KB 5
92 #define FLASH_SIZE_128KB 7
93 #define FLASH_SIZE_256KB 9
94 #define FLASH_SIZE_512KB 10
95 #define FLASH_SIZE_1024KB 12
96 #define FLASH_SIZE_2048KB 14
97
98 static int at91sam7_protect_check(struct flash_bank *bank);
99 static int at91sam7_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset,
100 uint32_t count);
101
102 static uint32_t at91sam7_get_flash_status(struct target *target, int bank_number);
103 static void at91sam7_set_flash_mode(struct flash_bank *bank, int mode);
104 static uint32_t at91sam7_wait_status_busy(struct flash_bank *bank, uint32_t waitbits, int timeout);
105 static int at91sam7_flash_command(struct flash_bank *bank, uint8_t cmd, uint16_t pagen);
106
107 static const uint32_t MC_FMR[4] = { 0xFFFFFF60, 0xFFFFFF70, 0xFFFFFF80, 0xFFFFFF90 };
108 static const uint32_t MC_FCR[4] = { 0xFFFFFF64, 0xFFFFFF74, 0xFFFFFF84, 0xFFFFFF94 };
109 static const uint32_t MC_FSR[4] = { 0xFFFFFF68, 0xFFFFFF78, 0xFFFFFF88, 0xFFFFFF98 };
110
111 static const char *EPROC[8] = {
112 "Unknown", "ARM946-E", "ARM7TDMI", "Unknown", "ARM920T", "ARM926EJ-S", "Unknown", "Unknown"
113 };
114
115 struct at91sam7_flash_bank {
116 /* chip id register */
117 uint32_t cidr;
118 uint16_t cidr_ext;
119 uint16_t cidr_nvptyp;
120 uint16_t cidr_arch;
121 uint16_t cidr_sramsiz;
122 uint16_t cidr_nvpsiz;
123 uint16_t cidr_nvpsiz2;
124 uint16_t cidr_eproc;
125 uint16_t cidr_version;
126 const char *target_name;
127
128 /* flash auto-detection */
129 uint8_t flash_autodetection;
130
131 /* flash geometry */
132 uint16_t pages_per_sector;
133 uint16_t pagesize;
134 uint16_t pages_in_lockregion;
135
136 /* nv memory bits */
137 uint16_t num_lockbits_on;
138 uint16_t lockbits;
139 uint16_t num_nvmbits;
140 uint16_t num_nvmbits_on;
141 uint16_t nvmbits;
142 uint8_t securitybit;
143
144 /* 0: not init
145 * 1: fmcn for nvbits (1uS)
146 * 2: fmcn for flash (1.5uS) */
147 uint8_t flashmode;
148
149 /* main clock status */
150 uint8_t mck_valid;
151 uint32_t mck_freq;
152
153 /* external clock frequency */
154 uint32_t ext_freq;
155
156 };
157
158 #if 0
159 static long SRAMSIZ[16] = {
160 -1,
161 0x0400, /* 1K */
162 0x0800, /* 2K */
163 -1,
164 0x1c000, /* 112K */
165 0x1000, /* 4K */
166 0x14000, /* 80K */
167 0x28000, /* 160K */
168 0x2000, /* 8K */
169 0x4000, /* 16K */
170 0x8000, /* 32K */
171 0x10000, /* 64K */
172 0x20000, /* 128K */
173 0x40000, /* 256K */
174 0x18000, /* 96K */
175 0x80000, /* 512K */
176 };
177 #endif
178
179 static uint32_t at91sam7_get_flash_status(struct target *target, int bank_number)
180 {
181 uint32_t fsr;
182 target_read_u32(target, MC_FSR[bank_number], &fsr);
183
184 return fsr;
185 }
186
187 /* Read clock configuration and set at91sam7_info->mck_freq */
188 static void at91sam7_read_clock_info(struct flash_bank *bank)
189 {
190 struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
191 struct target *target = bank->target;
192 uint32_t mckr, mcfr, pllr, mor;
193 unsigned long tmp = 0, mainfreq;
194
195 /* Read Clock Generator Main Oscillator Register */
196 target_read_u32(target, CKGR_MOR, &mor);
197 /* Read Clock Generator Main Clock Frequency Register */
198 target_read_u32(target, CKGR_MCFR, &mcfr);
199 /* Read Master Clock Register*/
200 target_read_u32(target, PMC_MCKR, &mckr);
201 /* Read Clock Generator PLL Register */
202 target_read_u32(target, CKGR_PLLR, &pllr);
203
204 at91sam7_info->mck_valid = 0;
205 at91sam7_info->mck_freq = 0;
206 switch (mckr & PMC_MCKR_CSS) {
207 case 0: /* Slow Clock */
208 at91sam7_info->mck_valid = 1;
209 tmp = RC_FREQ;
210 break;
211
212 case 1: /* Main Clock */
213 if ((mcfr & CKGR_MCFR_MAINRDY) &&
214 (at91sam7_info->ext_freq == 0)) {
215 at91sam7_info->mck_valid = 1;
216 tmp = RC_FREQ / 16ul * (mcfr & 0xffff);
217 } else if (at91sam7_info->ext_freq != 0) {
218 at91sam7_info->mck_valid = 1;
219 tmp = at91sam7_info->ext_freq;
220 }
221 break;
222
223 case 2: /* Reserved */
224 break;
225
226 case 3: /* PLL Clock */
227 if ((mcfr & CKGR_MCFR_MAINRDY) &&
228 (at91sam7_info->ext_freq == 0)) {
229 target_read_u32(target, CKGR_PLLR, &pllr);
230 if (!(pllr & CKGR_PLLR_DIV))
231 break; /* 0 Hz */
232 at91sam7_info->mck_valid = 1;
233 mainfreq = RC_FREQ / 16ul * (mcfr & 0xffff);
234 /* Integer arithmetic should have sufficient precision
235 * as long as PLL is properly configured. */
236 tmp = mainfreq / (pllr & CKGR_PLLR_DIV)*
237 (((pllr & CKGR_PLLR_MUL) >> 16) + 1);
238 } else if ((at91sam7_info->ext_freq != 0) &&
239 ((pllr&CKGR_PLLR_DIV) != 0)) {
240 at91sam7_info->mck_valid = 1;
241 tmp = at91sam7_info->ext_freq / (pllr&CKGR_PLLR_DIV)*
242 (((pllr & CKGR_PLLR_MUL) >> 16) + 1);
243 }
244 break;
245 }
246
247 /* Prescaler adjust */
248 if ((((mckr & PMC_MCKR_PRES) >> 2) == 7) || (tmp == 0)) {
249 at91sam7_info->mck_valid = 0;
250 at91sam7_info->mck_freq = 0;
251 } else if (((mckr & PMC_MCKR_PRES) >> 2) != 0)
252 at91sam7_info->mck_freq = tmp >> ((mckr & PMC_MCKR_PRES) >> 2);
253 else
254 at91sam7_info->mck_freq = tmp;
255 }
256
257 /* Setup the timimg registers for nvbits or normal flash */
258 static void at91sam7_set_flash_mode(struct flash_bank *bank, int mode)
259 {
260 uint32_t fmr, fmcn = 0, fws = 0;
261 struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
262 struct target *target = bank->target;
263
264 if (mode && (mode != at91sam7_info->flashmode)) {
265 /* Always round up (ceil) */
266 if (mode == FMR_TIMING_NVBITS) {
267 if (at91sam7_info->cidr_arch == 0x60) {
268 /* AT91SAM7A3 uses master clocks in 100 ns */
269 fmcn = (at91sam7_info->mck_freq/10000000ul) + 1;
270 } else {
271 /* master clocks in 1uS for ARCH 0x7 types */
272 fmcn = (at91sam7_info->mck_freq/1000000ul) + 1;
273 }
274 } else if (mode == FMR_TIMING_FLASH) {
275 /* main clocks in 1.5uS */
276 fmcn = (at91sam7_info->mck_freq/1000000ul)+
277 (at91sam7_info->mck_freq/2000000ul) + 1;
278 }
279
280 /* hard overclocking */
281 if (fmcn > 0xFF)
282 fmcn = 0xFF;
283
284 /* Only allow fmcn = 0 if clock period is > 30 us = 33kHz. */
285 if (at91sam7_info->mck_freq <= 33333ul)
286 fmcn = 0;
287 /* Only allow fws = 0 if clock frequency is < 30 MHz. */
288 if (at91sam7_info->mck_freq > 30000000ul)
289 fws = 1;
290
291 LOG_DEBUG("fmcn[%i]: %i", bank->bank_number, (int)(fmcn));
292 fmr = fmcn << 16 | fws << 8;
293 target_write_u32(target, MC_FMR[bank->bank_number], fmr);
294 }
295
296 at91sam7_info->flashmode = mode;
297 }
298
299 static uint32_t at91sam7_wait_status_busy(struct flash_bank *bank, uint32_t waitbits, int timeout)
300 {
301 uint32_t status;
302
303 while ((!((status = at91sam7_get_flash_status(bank->target,
304 bank->bank_number)) & waitbits)) && (timeout-- > 0)) {
305 LOG_DEBUG("status[%i]: 0x%" PRIx32 "", (int)bank->bank_number, status);
306 alive_sleep(1);
307 }
308
309 LOG_DEBUG("status[%i]: 0x%" PRIx32 "", bank->bank_number, status);
310
311 if (status & 0x0C) {
312 LOG_ERROR("status register: 0x%" PRIx32 "", status);
313 if (status & 0x4)
314 LOG_ERROR("Lock Error Bit Detected, Operation Abort");
315 if (status & 0x8)
316 LOG_ERROR("Invalid command and/or bad keyword, Operation Abort");
317 if (status & 0x10)
318 LOG_ERROR("Security Bit Set, Operation Abort");
319 }
320
321 return status;
322 }
323
324 /* Send one command to the AT91SAM flash controller */
325 static int at91sam7_flash_command(struct flash_bank *bank, uint8_t cmd, uint16_t pagen)
326 {
327 uint32_t fcr;
328 struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
329 struct target *target = bank->target;
330
331 fcr = (0x5A << 24) | ((pagen&0x3FF) << 8) | cmd;
332 target_write_u32(target, MC_FCR[bank->bank_number], fcr);
333 LOG_DEBUG("Flash command: 0x%" PRIx32 ", flash bank: %i, page number: %u",
334 fcr,
335 bank->bank_number + 1,
336 pagen);
337
338 if ((at91sam7_info->cidr_arch == 0x60) && ((cmd == SLB) | (cmd == CLB))) {
339 /* Lock bit manipulation on AT91SAM7A3 waits for FC_FSR bit 1, EOL */
340 if (at91sam7_wait_status_busy(bank, MC_FSR_EOL, 10)&0x0C)
341 return ERROR_FLASH_OPERATION_FAILED;
342 return ERROR_OK;
343 }
344
345 if (at91sam7_wait_status_busy(bank, MC_FSR_FRDY, 10)&0x0C)
346 return ERROR_FLASH_OPERATION_FAILED;
347
348 return ERROR_OK;
349 }
350
351 /* Read device id register, main clock frequency register and fill in driver info structure */
352 static int at91sam7_read_part_info(struct flash_bank *bank)
353 {
354 struct at91sam7_flash_bank *at91sam7_info;
355 struct target *target = bank->target;
356
357 uint16_t bnk, sec;
358 uint16_t arch;
359 uint32_t cidr;
360 uint8_t banks_num = 0;
361 uint16_t num_nvmbits = 0;
362 uint16_t sectors_num = 0;
363 uint16_t pages_per_sector = 0;
364 uint16_t page_size = 0;
365 uint32_t ext_freq;
366 uint32_t bank_size;
367 uint32_t base_address = 0;
368 char *target_name_t = "Unknown";
369
370 at91sam7_info = bank->driver_priv;
371
372 if (at91sam7_info->cidr != 0) {
373 /* flash already configured, update clock and check for protected sectors */
374 for (struct flash_bank *t_bank = bank; t_bank; t_bank = t_bank->next) {
375 if (t_bank->target != target)
376 continue;
377 /* re-calculate master clock frequency */
378 at91sam7_read_clock_info(t_bank);
379
380 /* no timming */
381 at91sam7_set_flash_mode(t_bank, FMR_TIMING_NONE);
382
383 /* check protect state */
384 at91sam7_protect_check(t_bank);
385 }
386
387 return ERROR_OK;
388 }
389
390 /* Read and parse chip identification register */
391 target_read_u32(target, DBGU_CIDR, &cidr);
392 if (cidr == 0) {
393 LOG_WARNING("Cannot identify target as an AT91SAM");
394 return ERROR_FLASH_OPERATION_FAILED;
395 }
396
397 if (at91sam7_info->flash_autodetection == 0) {
398 /* banks and sectors are already created, based on data from input file */
399 for (struct flash_bank *t_bank = bank; t_bank; t_bank = t_bank->next) {
400 if (t_bank->target != target)
401 continue;
402
403 at91sam7_info = t_bank->driver_priv;
404
405 at91sam7_info->cidr = cidr;
406 at91sam7_info->cidr_ext = (cidr >> 31)&0x0001;
407 at91sam7_info->cidr_nvptyp = (cidr >> 28)&0x0007;
408 at91sam7_info->cidr_arch = (cidr >> 20)&0x00FF;
409 at91sam7_info->cidr_sramsiz = (cidr >> 16)&0x000F;
410 at91sam7_info->cidr_nvpsiz2 = (cidr >> 12)&0x000F;
411 at91sam7_info->cidr_nvpsiz = (cidr >> 8)&0x000F;
412 at91sam7_info->cidr_eproc = (cidr >> 5)&0x0007;
413 at91sam7_info->cidr_version = cidr&0x001F;
414
415 /* calculate master clock frequency */
416 at91sam7_read_clock_info(t_bank);
417
418 /* no timming */
419 at91sam7_set_flash_mode(t_bank, FMR_TIMING_NONE);
420
421 /* check protect state */
422 at91sam7_protect_check(t_bank);
423 }
424
425 return ERROR_OK;
426 }
427
428 arch = (cidr >> 20)&0x00FF;
429
430 /* check flash size */
431 switch ((cidr >> 8)&0x000F) {
432 case FLASH_SIZE_8KB:
433 break;
434
435 case FLASH_SIZE_16KB:
436 banks_num = 1;
437 sectors_num = 8;
438 pages_per_sector = 32;
439 page_size = 64;
440 base_address = 0x00100000;
441 if (arch == 0x70) {
442 num_nvmbits = 2;
443 target_name_t = "AT91SAM7S161/16";
444 }
445 break;
446
447 case FLASH_SIZE_32KB:
448 banks_num = 1;
449 sectors_num = 8;
450 pages_per_sector = 32;
451 page_size = 128;
452 base_address = 0x00100000;
453 if (arch == 0x70) {
454 num_nvmbits = 2;
455 target_name_t = "AT91SAM7S321/32";
456 }
457 if (arch == 0x72) {
458 num_nvmbits = 3;
459 target_name_t = "AT91SAM7SE32";
460 }
461 break;
462
463 case FLASH_SIZE_64KB:
464 banks_num = 1;
465 sectors_num = 16;
466 pages_per_sector = 32;
467 page_size = 128;
468 base_address = 0x00100000;
469 if (arch == 0x70) {
470 num_nvmbits = 2;
471 target_name_t = "AT91SAM7S64";
472 }
473 break;
474
475 case FLASH_SIZE_128KB:
476 banks_num = 1;
477 sectors_num = 8;
478 pages_per_sector = 64;
479 page_size = 256;
480 base_address = 0x00100000;
481 if (arch == 0x70) {
482 num_nvmbits = 2;
483 target_name_t = "AT91SAM7S128";
484 }
485 if (arch == 0x71) {
486 num_nvmbits = 3;
487 target_name_t = "AT91SAM7XC128";
488 }
489 if (arch == 0x72) {
490 num_nvmbits = 3;
491 target_name_t = "AT91SAM7SE128";
492 }
493 if (arch == 0x75) {
494 num_nvmbits = 3;
495 target_name_t = "AT91SAM7X128";
496 }
497 break;
498
499 case FLASH_SIZE_256KB:
500 banks_num = 1;
501 sectors_num = 16;
502 pages_per_sector = 64;
503 page_size = 256;
504 base_address = 0x00100000;
505 if (arch == 0x60) {
506 num_nvmbits = 3;
507 target_name_t = "AT91SAM7A3";
508 }
509 if (arch == 0x70) {
510 num_nvmbits = 2;
511 target_name_t = "AT91SAM7S256";
512 }
513 if (arch == 0x71) {
514 num_nvmbits = 3;
515 target_name_t = "AT91SAM7XC256";
516 }
517 if (arch == 0x72) {
518 num_nvmbits = 3;
519 target_name_t = "AT91SAM7SE256";
520 }
521 if (arch == 0x75) {
522 num_nvmbits = 3;
523 target_name_t = "AT91SAM7X256";
524 }
525 break;
526
527 case FLASH_SIZE_512KB:
528 banks_num = 2;
529 sectors_num = 16;
530 pages_per_sector = 64;
531 page_size = 256;
532 base_address = 0x00100000;
533 if (arch == 0x70) {
534 num_nvmbits = 2;
535 target_name_t = "AT91SAM7S512";
536 }
537 if (arch == 0x71) {
538 num_nvmbits = 3;
539 target_name_t = "AT91SAM7XC512";
540 }
541 if (arch == 0x72) {
542 num_nvmbits = 3;
543 target_name_t = "AT91SAM7SE512";
544 }
545 if (arch == 0x75) {
546 num_nvmbits = 3;
547 target_name_t = "AT91SAM7X512";
548 }
549 break;
550
551 case FLASH_SIZE_1024KB:
552 break;
553
554 case FLASH_SIZE_2048KB:
555 break;
556 }
557
558 if (strcmp(target_name_t, "Unknown") == 0) {
559 LOG_ERROR(
560 "Target autodetection failed! Please specify target parameters in configuration file");
561 return ERROR_FLASH_OPERATION_FAILED;
562 }
563
564 ext_freq = at91sam7_info->ext_freq;
565
566 /* calculate bank size */
567 bank_size = sectors_num * pages_per_sector * page_size;
568
569 for (bnk = 0; bnk < banks_num; bnk++) {
570 struct flash_bank *t_bank = bank;
571 if (bnk > 0) {
572 if (!t_bank->next) {
573 /* create a new flash bank element */
574 struct flash_bank *fb = malloc(sizeof(struct flash_bank));
575 fb->target = target;
576 fb->driver = bank->driver;
577 fb->driver_priv = malloc(sizeof(struct at91sam7_flash_bank));
578 fb->name = "sam7_probed";
579 fb->next = NULL;
580
581 /* link created bank in 'flash_banks' list */
582 t_bank->next = fb;
583 }
584 t_bank = t_bank->next;
585 }
586
587 t_bank->bank_number = bnk;
588 t_bank->base = base_address + bnk * bank_size;
589 t_bank->size = bank_size;
590 t_bank->chip_width = 0;
591 t_bank->bus_width = 4;
592 t_bank->num_sectors = sectors_num;
593
594 /* allocate sectors */
595 t_bank->sectors = malloc(sectors_num * sizeof(struct flash_sector));
596 for (sec = 0; sec < sectors_num; sec++) {
597 t_bank->sectors[sec].offset = sec * pages_per_sector * page_size;
598 t_bank->sectors[sec].size = pages_per_sector * page_size;
599 t_bank->sectors[sec].is_erased = -1;
600 t_bank->sectors[sec].is_protected = -1;
601 }
602
603 at91sam7_info = t_bank->driver_priv;
604
605 at91sam7_info->cidr = cidr;
606 at91sam7_info->cidr_ext = (cidr >> 31)&0x0001;
607 at91sam7_info->cidr_nvptyp = (cidr >> 28)&0x0007;
608 at91sam7_info->cidr_arch = (cidr >> 20)&0x00FF;
609 at91sam7_info->cidr_sramsiz = (cidr >> 16)&0x000F;
610 at91sam7_info->cidr_nvpsiz2 = (cidr >> 12)&0x000F;
611 at91sam7_info->cidr_nvpsiz = (cidr >> 8)&0x000F;
612 at91sam7_info->cidr_eproc = (cidr >> 5)&0x0007;
613 at91sam7_info->cidr_version = cidr&0x001F;
614
615 at91sam7_info->target_name = target_name_t;
616 at91sam7_info->flashmode = 0;
617 at91sam7_info->ext_freq = ext_freq;
618 at91sam7_info->num_nvmbits = num_nvmbits;
619 at91sam7_info->num_nvmbits_on = 0;
620 at91sam7_info->pagesize = page_size;
621 at91sam7_info->pages_per_sector = pages_per_sector;
622
623 /* calculate master clock frequency */
624 at91sam7_read_clock_info(t_bank);
625
626 /* no timming */
627 at91sam7_set_flash_mode(t_bank, FMR_TIMING_NONE);
628
629 /* check protect state */
630 at91sam7_protect_check(t_bank);
631 }
632
633 LOG_DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x",
634 at91sam7_info->cidr_nvptyp,
635 at91sam7_info->cidr_arch);
636
637 return ERROR_OK;
638 }
639
640 static int at91sam7_erase_check(struct flash_bank *bank)
641 {
642 struct target *target = bank->target;
643 uint16_t retval;
644 uint32_t blank;
645 uint16_t fast_check;
646 uint8_t *buffer;
647 uint16_t nSector;
648 uint16_t nByte;
649
650 if (bank->target->state != TARGET_HALTED) {
651 LOG_ERROR("Target not halted");
652 return ERROR_TARGET_NOT_HALTED;
653 }
654
655 /* Configure the flash controller timing */
656 at91sam7_read_clock_info(bank);
657 at91sam7_set_flash_mode(bank, FMR_TIMING_FLASH);
658
659 fast_check = 1;
660 for (nSector = 0; nSector < bank->num_sectors; nSector++) {
661 retval = target_blank_check_memory(target,
662 bank->base + bank->sectors[nSector].offset,
663 bank->sectors[nSector].size,
664 &blank);
665 if (retval != ERROR_OK) {
666 fast_check = 0;
667 break;
668 }
669 if (blank == 0xFF)
670 bank->sectors[nSector].is_erased = 1;
671 else
672 bank->sectors[nSector].is_erased = 0;
673 }
674
675 if (fast_check)
676 return ERROR_OK;
677
678 LOG_USER("Running slow fallback erase check - add working memory");
679
680 buffer = malloc(bank->sectors[0].size);
681 for (nSector = 0; nSector < bank->num_sectors; nSector++) {
682 bank->sectors[nSector].is_erased = 1;
683 retval = target_read_memory(target, bank->base + bank->sectors[nSector].offset, 4,
684 bank->sectors[nSector].size/4, buffer);
685 if (retval != ERROR_OK)
686 return retval;
687
688 for (nByte = 0; nByte < bank->sectors[nSector].size; nByte++) {
689 if (buffer[nByte] != 0xFF) {
690 bank->sectors[nSector].is_erased = 0;
691 break;
692 }
693 }
694 }
695 free(buffer);
696
697 return ERROR_OK;
698 }
699
700 static int at91sam7_protect_check(struct flash_bank *bank)
701 {
702 uint8_t lock_pos, gpnvm_pos;
703 uint32_t status;
704
705 struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
706
707 if (at91sam7_info->cidr == 0)
708 return ERROR_FLASH_BANK_NOT_PROBED;
709 if (bank->target->state != TARGET_HALTED) {
710 LOG_ERROR("Target not halted");
711 return ERROR_TARGET_NOT_HALTED;
712 }
713
714 status = at91sam7_get_flash_status(bank->target, bank->bank_number);
715 at91sam7_info->lockbits = (status >> 16);
716
717 at91sam7_info->num_lockbits_on = 0;
718 for (lock_pos = 0; lock_pos < bank->num_sectors; lock_pos++) {
719 if (((status >> (16 + lock_pos))&(0x0001)) == 1) {
720 at91sam7_info->num_lockbits_on++;
721 bank->sectors[lock_pos].is_protected = 1;
722 } else
723 bank->sectors[lock_pos].is_protected = 0;
724 }
725
726 /* GPNVM and SECURITY bits apply only for MC_FSR of EFC0 */
727 status = at91sam7_get_flash_status(bank->target, 0);
728
729 at91sam7_info->securitybit = (status >> 4)&0x01;
730 at91sam7_info->nvmbits = (status >> 8)&0xFF;
731
732 at91sam7_info->num_nvmbits_on = 0;
733 for (gpnvm_pos = 0; gpnvm_pos < at91sam7_info->num_nvmbits; gpnvm_pos++) {
734 if (((status >> (8 + gpnvm_pos))&(0x01)) == 1)
735 at91sam7_info->num_nvmbits_on++;
736 }
737
738 return ERROR_OK;
739 }
740
741 FLASH_BANK_COMMAND_HANDLER(at91sam7_flash_bank_command)
742 {
743 struct flash_bank *t_bank = bank;
744 struct at91sam7_flash_bank *at91sam7_info;
745 struct target *target = t_bank->target;
746
747 uint32_t base_address;
748 uint32_t bank_size;
749 uint32_t ext_freq = 0;
750
751 int chip_width;
752 int bus_width;
753 int banks_num;
754 int num_sectors;
755
756 uint16_t pages_per_sector;
757 uint16_t page_size;
758 uint16_t num_nvmbits;
759
760 char *target_name_t;
761
762 int bnk, sec;
763
764 at91sam7_info = malloc(sizeof(struct at91sam7_flash_bank));
765 t_bank->driver_priv = at91sam7_info;
766
767 /* part wasn't probed for info yet */
768 at91sam7_info->cidr = 0;
769 at91sam7_info->flashmode = 0;
770 at91sam7_info->ext_freq = 0;
771 at91sam7_info->flash_autodetection = 0;
772
773 if (CMD_ARGC < 13) {
774 at91sam7_info->flash_autodetection = 1;
775 return ERROR_OK;
776 }
777
778 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], base_address);
779
780 COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], chip_width);
781 COMMAND_PARSE_NUMBER(int, CMD_ARGV[4], bus_width);
782
783 COMMAND_PARSE_NUMBER(int, CMD_ARGV[8], banks_num);
784 COMMAND_PARSE_NUMBER(int, CMD_ARGV[9], num_sectors);
785 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[10], pages_per_sector);
786 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[11], page_size);
787 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[12], num_nvmbits);
788
789 if (CMD_ARGC == 14) {
790 unsigned long freq;
791 COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[13], freq);
792 ext_freq = freq * 1000;
793 at91sam7_info->ext_freq = ext_freq;
794 }
795
796 if ((bus_width == 0) || (banks_num == 0) || (num_sectors == 0) ||
797 (pages_per_sector == 0) || (page_size == 0) || (num_nvmbits == 0)) {
798 at91sam7_info->flash_autodetection = 1;
799 return ERROR_OK;
800 }
801
802 target_name_t = calloc(strlen(CMD_ARGV[7]) + 1, sizeof(char));
803 strcpy(target_name_t, CMD_ARGV[7]);
804
805 /* calculate bank size */
806 bank_size = num_sectors * pages_per_sector * page_size;
807
808 for (bnk = 0; bnk < banks_num; bnk++) {
809 if (bnk > 0) {
810 if (!t_bank->next) {
811 /* create a new bank element */
812 struct flash_bank *fb = malloc(sizeof(struct flash_bank));
813 fb->target = target;
814 fb->driver = bank->driver;
815 fb->driver_priv = malloc(sizeof(struct at91sam7_flash_bank));
816 fb->name = "sam7_probed";
817 fb->next = NULL;
818
819 /* link created bank in 'flash_banks' list */
820 t_bank->next = fb;
821 }
822 t_bank = t_bank->next;
823 }
824
825 t_bank->bank_number = bnk;
826 t_bank->base = base_address + bnk * bank_size;
827 t_bank->size = bank_size;
828 t_bank->chip_width = chip_width;
829 t_bank->bus_width = bus_width;
830 t_bank->num_sectors = num_sectors;
831
832 /* allocate sectors */
833 t_bank->sectors = malloc(num_sectors * sizeof(struct flash_sector));
834 for (sec = 0; sec < num_sectors; sec++) {
835 t_bank->sectors[sec].offset = sec * pages_per_sector * page_size;
836 t_bank->sectors[sec].size = pages_per_sector * page_size;
837 t_bank->sectors[sec].is_erased = -1;
838 t_bank->sectors[sec].is_protected = -1;
839 }
840
841 at91sam7_info = t_bank->driver_priv;
842
843 at91sam7_info->target_name = target_name_t;
844 at91sam7_info->flashmode = 0;
845 at91sam7_info->ext_freq = ext_freq;
846 at91sam7_info->num_nvmbits = num_nvmbits;
847 at91sam7_info->num_nvmbits_on = 0;
848 at91sam7_info->pagesize = page_size;
849 at91sam7_info->pages_per_sector = pages_per_sector;
850 }
851
852 return ERROR_OK;
853 }
854
855 static int at91sam7_erase(struct flash_bank *bank, int first, int last)
856 {
857 struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
858 int sec;
859 uint32_t nbytes, pos;
860 uint8_t *buffer;
861 uint8_t erase_all;
862
863 if (at91sam7_info->cidr == 0)
864 return ERROR_FLASH_BANK_NOT_PROBED;
865
866 if (bank->target->state != TARGET_HALTED) {
867 LOG_ERROR("Target not halted");
868 return ERROR_TARGET_NOT_HALTED;
869 }
870
871 if ((first < 0) || (last < first) || (last >= bank->num_sectors))
872 return ERROR_FLASH_SECTOR_INVALID;
873
874 erase_all = 0;
875 if ((first == 0) && (last == (bank->num_sectors-1)))
876 erase_all = 1;
877
878 /* Configure the flash controller timing */
879 at91sam7_read_clock_info(bank);
880 at91sam7_set_flash_mode(bank, FMR_TIMING_FLASH);
881
882 if (erase_all) {
883 if (at91sam7_flash_command(bank, EA, 0) != ERROR_OK)
884 return ERROR_FLASH_OPERATION_FAILED;
885 } else {
886 /* allocate and clean buffer */
887 nbytes = (last - first + 1) * bank->sectors[first].size;
888 buffer = malloc(nbytes * sizeof(uint8_t));
889 for (pos = 0; pos < nbytes; pos++)
890 buffer[pos] = 0xFF;
891
892 if (at91sam7_write(bank, buffer, bank->sectors[first].offset, nbytes) != ERROR_OK) {
893 free(buffer);
894 return ERROR_FLASH_OPERATION_FAILED;
895 }
896
897 free(buffer);
898 }
899
900 /* mark erased sectors */
901 for (sec = first; sec <= last; sec++)
902 bank->sectors[sec].is_erased = 1;
903
904 return ERROR_OK;
905 }
906
907 static int at91sam7_protect(struct flash_bank *bank, int set, int first, int last)
908 {
909 uint32_t cmd;
910 int sector;
911 uint32_t pagen;
912
913 struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
914
915 if (at91sam7_info->cidr == 0)
916 return ERROR_FLASH_BANK_NOT_PROBED;
917
918 if (bank->target->state != TARGET_HALTED) {
919 LOG_ERROR("Target not halted");
920 return ERROR_TARGET_NOT_HALTED;
921 }
922
923 if ((first < 0) || (last < first) || (last >= bank->num_sectors))
924 return ERROR_FLASH_SECTOR_INVALID;
925
926 /* Configure the flash controller timing */
927 at91sam7_read_clock_info(bank);
928 at91sam7_set_flash_mode(bank, FMR_TIMING_NVBITS);
929
930 for (sector = first; sector <= last; sector++) {
931 if (set)
932 cmd = SLB;
933 else
934 cmd = CLB;
935
936 /* if we lock a page from one sector then entire sector will be locked, also,
937 * if we unlock a page from a locked sector, entire sector will be unlocked */
938 pagen = sector * at91sam7_info->pages_per_sector;
939
940 if (at91sam7_flash_command(bank, cmd, pagen) != ERROR_OK)
941 return ERROR_FLASH_OPERATION_FAILED;
942 }
943
944 at91sam7_protect_check(bank);
945
946 return ERROR_OK;
947 }
948
949 static int at91sam7_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
950 {
951 int retval;
952 struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
953 struct target *target = bank->target;
954 uint32_t dst_min_alignment, wcount, bytes_remaining = count;
955 uint32_t first_page, last_page, pagen, buffer_pos;
956
957 if (at91sam7_info->cidr == 0)
958 return ERROR_FLASH_BANK_NOT_PROBED;
959
960 if (bank->target->state != TARGET_HALTED) {
961 LOG_ERROR("Target not halted");
962 return ERROR_TARGET_NOT_HALTED;
963 }
964
965 if (offset + count > bank->size)
966 return ERROR_FLASH_DST_OUT_OF_BANK;
967
968 dst_min_alignment = at91sam7_info->pagesize;
969
970 if (offset % dst_min_alignment) {
971 LOG_WARNING("offset 0x%" PRIx32 " breaks required alignment 0x%" PRIx32 "",
972 offset,
973 dst_min_alignment);
974 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
975 }
976
977 if (at91sam7_info->cidr_arch == 0)
978 return ERROR_FLASH_BANK_NOT_PROBED;
979
980 first_page = offset/dst_min_alignment;
981 last_page = DIV_ROUND_UP(offset + count, dst_min_alignment);
982
983 LOG_DEBUG("first_page: %i, last_page: %i, count %i",
984 (int)first_page,
985 (int)last_page,
986 (int)count);
987
988 /* Configure the flash controller timing */
989 at91sam7_read_clock_info(bank);
990 at91sam7_set_flash_mode(bank, FMR_TIMING_FLASH);
991
992 for (pagen = first_page; pagen < last_page; pagen++) {
993 if (bytes_remaining < dst_min_alignment)
994 count = bytes_remaining;
995 else
996 count = dst_min_alignment;
997 bytes_remaining -= count;
998
999 /* Write one block to the PageWriteBuffer */
1000 buffer_pos = (pagen-first_page)*dst_min_alignment;
1001 wcount = DIV_ROUND_UP(count, 4);
1002 retval = target_write_memory(target, bank->base + pagen*dst_min_alignment, 4,
1003 wcount, buffer + buffer_pos);
1004 if (retval != ERROR_OK)
1005 return retval;
1006
1007 /* Send Write Page command to Flash Controller */
1008 if (at91sam7_flash_command(bank, WP, pagen) != ERROR_OK)
1009 return ERROR_FLASH_OPERATION_FAILED;
1010 LOG_DEBUG("Write flash bank:%i page number:%" PRIi32 "", bank->bank_number, pagen);
1011 }
1012
1013 return ERROR_OK;
1014 }
1015
1016 static int at91sam7_probe(struct flash_bank *bank)
1017 {
1018 /* we can't probe on an at91sam7
1019 * if this is an at91sam7, it has the configured flash */
1020 int retval;
1021
1022 if (bank->target->state != TARGET_HALTED) {
1023 LOG_ERROR("Target not halted");
1024 return ERROR_TARGET_NOT_HALTED;
1025 }
1026
1027 retval = at91sam7_read_part_info(bank);
1028 if (retval != ERROR_OK)
1029 return retval;
1030
1031 return ERROR_OK;
1032 }
1033
1034 static int get_at91sam7_info(struct flash_bank *bank, char *buf, int buf_size)
1035 {
1036 int printed;
1037 struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
1038
1039 if (at91sam7_info->cidr == 0)
1040 return ERROR_FLASH_BANK_NOT_PROBED;
1041
1042 printed = snprintf(buf, buf_size,
1043 "\n at91sam7 driver information: Chip is %s\n",
1044 at91sam7_info->target_name);
1045
1046 buf += printed;
1047 buf_size -= printed;
1048
1049 printed = snprintf(buf,
1050 buf_size,
1051 " Cidr: 0x%8.8" PRIx32 " | Arch: 0x%4.4x | Eproc: %s | Version: 0x%3.3x | "
1052 "Flashsize: 0x%8.8" PRIx32 "\n",
1053 at91sam7_info->cidr,
1054 at91sam7_info->cidr_arch,
1055 EPROC[at91sam7_info->cidr_eproc],
1056 at91sam7_info->cidr_version,
1057 bank->size);
1058
1059 buf += printed;
1060 buf_size -= printed;
1061
1062 printed = snprintf(buf, buf_size,
1063 " Master clock (estimated): %u KHz | External clock: %u KHz\n",
1064 (unsigned)(at91sam7_info->mck_freq / 1000),
1065 (unsigned)(at91sam7_info->ext_freq / 1000));
1066
1067 buf += printed;
1068 buf_size -= printed;
1069
1070 printed = snprintf(buf,
1071 buf_size,
1072 " Pagesize: %i bytes | Lockbits(%i): %i 0x%4.4x | Pages in lock region: %i\n",
1073 at91sam7_info->pagesize,
1074 bank->num_sectors,
1075 at91sam7_info->num_lockbits_on,
1076 at91sam7_info->lockbits,
1077 at91sam7_info->pages_per_sector*at91sam7_info->num_lockbits_on);
1078
1079 buf += printed;
1080 buf_size -= printed;
1081
1082 snprintf(buf, buf_size,
1083 " Securitybit: %i | Nvmbits(%i): %i 0x%1.1x\n",
1084 at91sam7_info->securitybit, at91sam7_info->num_nvmbits,
1085 at91sam7_info->num_nvmbits_on, at91sam7_info->nvmbits);
1086
1087 return ERROR_OK;
1088 }
1089
1090 /*
1091 * On AT91SAM7S: When the gpnvm bits are set with
1092 * > at91sam7 gpnvm bitnr set
1093 * the changes are not visible in the flash controller status register MC_FSR
1094 * until the processor has been reset.
1095 * On the Olimex board this requires a power cycle.
1096 * Note that the AT91SAM7S has the following errata (doc6175.pdf sec 14.1.3):
1097 * The maximum number of write/erase cycles for Non volatile Memory bits is 100. this includes
1098 * Lock Bits (LOCKx), General Purpose NVM bits (GPNVMx) and the Security Bit.
1099 */
1100 COMMAND_HANDLER(at91sam7_handle_gpnvm_command)
1101 {
1102 struct flash_bank *bank;
1103 int bit;
1104 uint8_t flashcmd;
1105 uint32_t status;
1106 struct at91sam7_flash_bank *at91sam7_info;
1107 int retval;
1108
1109 if (CMD_ARGC != 2)
1110 return ERROR_COMMAND_SYNTAX_ERROR;
1111
1112 bank = get_flash_bank_by_num_noprobe(0);
1113 if (bank == NULL)
1114 return ERROR_FLASH_BANK_INVALID;
1115 if (strcmp(bank->driver->name, "at91sam7")) {
1116 command_print(CMD_CTX, "not an at91sam7 flash bank '%s'", CMD_ARGV[0]);
1117 return ERROR_FLASH_BANK_INVALID;
1118 }
1119 if (bank->target->state != TARGET_HALTED) {
1120 LOG_ERROR("target has to be halted to perform flash operation");
1121 return ERROR_TARGET_NOT_HALTED;
1122 }
1123
1124 if (strcmp(CMD_ARGV[1], "set") == 0)
1125 flashcmd = SGPB;
1126 else if (strcmp(CMD_ARGV[1], "clear") == 0)
1127 flashcmd = CGPB;
1128 else
1129 return ERROR_COMMAND_SYNTAX_ERROR;
1130
1131 at91sam7_info = bank->driver_priv;
1132 if (at91sam7_info->cidr == 0) {
1133 retval = at91sam7_read_part_info(bank);
1134 if (retval != ERROR_OK)
1135 return retval;
1136 }
1137
1138 COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], bit);
1139 if ((bit < 0) || (bit >= at91sam7_info->num_nvmbits)) {
1140 command_print(CMD_CTX,
1141 "gpnvm bit '#%s' is out of bounds for target %s",
1142 CMD_ARGV[0],
1143 at91sam7_info->target_name);
1144 return ERROR_OK;
1145 }
1146
1147 /* Configure the flash controller timing */
1148 at91sam7_read_clock_info(bank);
1149 at91sam7_set_flash_mode(bank, FMR_TIMING_NVBITS);
1150
1151 if (at91sam7_flash_command(bank, flashcmd, bit) != ERROR_OK)
1152 return ERROR_FLASH_OPERATION_FAILED;
1153
1154 /* GPNVM and SECURITY bits apply only for MC_FSR of EFC0 */
1155 status = at91sam7_get_flash_status(bank->target, 0);
1156 LOG_DEBUG("at91sam7_handle_gpnvm_command: cmd 0x%x, value %d, status 0x%" PRIx32,
1157 flashcmd,
1158 bit,
1159 status);
1160
1161 /* check protect state */
1162 at91sam7_protect_check(bank);
1163
1164 return ERROR_OK;
1165 }
1166
1167 static const struct command_registration at91sam7_exec_command_handlers[] = {
1168 {
1169 .name = "gpnvm",
1170 .handler = at91sam7_handle_gpnvm_command,
1171 .mode = COMMAND_EXEC,
1172 .help = "set or clear one General Purpose Non-Volatile Memory "
1173 "(gpnvm) bit",
1174 .usage = "bitnum ('set'|'clear')",
1175 },
1176 COMMAND_REGISTRATION_DONE
1177 };
1178 static const struct command_registration at91sam7_command_handlers[] = {
1179 {
1180 .name = "at91sam7",
1181 .mode = COMMAND_ANY,
1182 .help = "at91sam7 flash command group",
1183 .usage = "",
1184 .chain = at91sam7_exec_command_handlers,
1185 },
1186 COMMAND_REGISTRATION_DONE
1187 };
1188
1189 struct flash_driver at91sam7_flash = {
1190 .name = "at91sam7",
1191 .usage = "gpnvm <bit> <set | clear>",
1192 .commands = at91sam7_command_handlers,
1193 .flash_bank_command = at91sam7_flash_bank_command,
1194 .erase = at91sam7_erase,
1195 .protect = at91sam7_protect,
1196 .write = at91sam7_write,
1197 .read = default_flash_read,
1198 .probe = at91sam7_probe,
1199 .auto_probe = at91sam7_probe,
1200 .erase_check = at91sam7_erase_check,
1201 .protect_check = at91sam7_protect_check,
1202 .info = get_at91sam7_info,
1203 };

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)