Remove FSF address from GPL notices
[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 struct flash_bank *fb = bank;
375 struct flash_bank *t_bank = bank;
376
377 while (t_bank) {
378 /* re-calculate master clock frequency */
379 at91sam7_read_clock_info(t_bank);
380
381 /* no timming */
382 at91sam7_set_flash_mode(t_bank, FMR_TIMING_NONE);
383
384 /* check protect state */
385 at91sam7_protect_check(t_bank);
386
387 t_bank = fb->next;
388 fb = t_bank;
389 }
390
391 return ERROR_OK;
392 }
393
394 /* Read and parse chip identification register */
395 target_read_u32(target, DBGU_CIDR, &cidr);
396 if (cidr == 0) {
397 LOG_WARNING("Cannot identify target as an AT91SAM");
398 return ERROR_FLASH_OPERATION_FAILED;
399 }
400
401 if (at91sam7_info->flash_autodetection == 0) {
402 /* banks and sectors are already created, based on data from input file */
403 struct flash_bank *fb = bank;
404 struct flash_bank *t_bank = bank;
405 while (t_bank) {
406 at91sam7_info = t_bank->driver_priv;
407
408 at91sam7_info->cidr = cidr;
409 at91sam7_info->cidr_ext = (cidr >> 31)&0x0001;
410 at91sam7_info->cidr_nvptyp = (cidr >> 28)&0x0007;
411 at91sam7_info->cidr_arch = (cidr >> 20)&0x00FF;
412 at91sam7_info->cidr_sramsiz = (cidr >> 16)&0x000F;
413 at91sam7_info->cidr_nvpsiz2 = (cidr >> 12)&0x000F;
414 at91sam7_info->cidr_nvpsiz = (cidr >> 8)&0x000F;
415 at91sam7_info->cidr_eproc = (cidr >> 5)&0x0007;
416 at91sam7_info->cidr_version = cidr&0x001F;
417
418 /* calculate master clock frequency */
419 at91sam7_read_clock_info(t_bank);
420
421 /* no timming */
422 at91sam7_set_flash_mode(t_bank, FMR_TIMING_NONE);
423
424 /* check protect state */
425 at91sam7_protect_check(t_bank);
426
427 t_bank = fb->next;
428 fb = t_bank;
429 }
430
431 return ERROR_OK;
432 }
433
434 arch = (cidr >> 20)&0x00FF;
435
436 /* check flash size */
437 switch ((cidr >> 8)&0x000F) {
438 case FLASH_SIZE_8KB:
439 break;
440
441 case FLASH_SIZE_16KB:
442 banks_num = 1;
443 sectors_num = 8;
444 pages_per_sector = 32;
445 page_size = 64;
446 base_address = 0x00100000;
447 if (arch == 0x70) {
448 num_nvmbits = 2;
449 target_name_t = "AT91SAM7S161/16";
450 }
451 break;
452
453 case FLASH_SIZE_32KB:
454 banks_num = 1;
455 sectors_num = 8;
456 pages_per_sector = 32;
457 page_size = 128;
458 base_address = 0x00100000;
459 if (arch == 0x70) {
460 num_nvmbits = 2;
461 target_name_t = "AT91SAM7S321/32";
462 }
463 if (arch == 0x72) {
464 num_nvmbits = 3;
465 target_name_t = "AT91SAM7SE32";
466 }
467 break;
468
469 case FLASH_SIZE_64KB:
470 banks_num = 1;
471 sectors_num = 16;
472 pages_per_sector = 32;
473 page_size = 128;
474 base_address = 0x00100000;
475 if (arch == 0x70) {
476 num_nvmbits = 2;
477 target_name_t = "AT91SAM7S64";
478 }
479 break;
480
481 case FLASH_SIZE_128KB:
482 banks_num = 1;
483 sectors_num = 8;
484 pages_per_sector = 64;
485 page_size = 256;
486 base_address = 0x00100000;
487 if (arch == 0x70) {
488 num_nvmbits = 2;
489 target_name_t = "AT91SAM7S128";
490 }
491 if (arch == 0x71) {
492 num_nvmbits = 3;
493 target_name_t = "AT91SAM7XC128";
494 }
495 if (arch == 0x72) {
496 num_nvmbits = 3;
497 target_name_t = "AT91SAM7SE128";
498 }
499 if (arch == 0x75) {
500 num_nvmbits = 3;
501 target_name_t = "AT91SAM7X128";
502 }
503 break;
504
505 case FLASH_SIZE_256KB:
506 banks_num = 1;
507 sectors_num = 16;
508 pages_per_sector = 64;
509 page_size = 256;
510 base_address = 0x00100000;
511 if (arch == 0x60) {
512 num_nvmbits = 3;
513 target_name_t = "AT91SAM7A3";
514 }
515 if (arch == 0x70) {
516 num_nvmbits = 2;
517 target_name_t = "AT91SAM7S256";
518 }
519 if (arch == 0x71) {
520 num_nvmbits = 3;
521 target_name_t = "AT91SAM7XC256";
522 }
523 if (arch == 0x72) {
524 num_nvmbits = 3;
525 target_name_t = "AT91SAM7SE256";
526 }
527 if (arch == 0x75) {
528 num_nvmbits = 3;
529 target_name_t = "AT91SAM7X256";
530 }
531 break;
532
533 case FLASH_SIZE_512KB:
534 banks_num = 2;
535 sectors_num = 16;
536 pages_per_sector = 64;
537 page_size = 256;
538 base_address = 0x00100000;
539 if (arch == 0x70) {
540 num_nvmbits = 2;
541 target_name_t = "AT91SAM7S512";
542 }
543 if (arch == 0x71) {
544 num_nvmbits = 3;
545 target_name_t = "AT91SAM7XC512";
546 }
547 if (arch == 0x72) {
548 num_nvmbits = 3;
549 target_name_t = "AT91SAM7SE512";
550 }
551 if (arch == 0x75) {
552 num_nvmbits = 3;
553 target_name_t = "AT91SAM7X512";
554 }
555 break;
556
557 case FLASH_SIZE_1024KB:
558 break;
559
560 case FLASH_SIZE_2048KB:
561 break;
562 }
563
564 if (strcmp(target_name_t, "Unknown") == 0) {
565 LOG_ERROR(
566 "Target autodetection failed! Please specify target parameters in configuration file");
567 return ERROR_FLASH_OPERATION_FAILED;
568 }
569
570 ext_freq = at91sam7_info->ext_freq;
571
572 /* calculate bank size */
573 bank_size = sectors_num * pages_per_sector * page_size;
574
575 for (bnk = 0; bnk < banks_num; bnk++) {
576 struct flash_bank *t_bank = bank;
577 if (bnk > 0) {
578 if (!t_bank->next) {
579 /* create a new flash bank element */
580 struct flash_bank *fb = malloc(sizeof(struct flash_bank));
581 fb->target = target;
582 fb->driver = bank->driver;
583 fb->driver_priv = malloc(sizeof(struct at91sam7_flash_bank));
584 fb->name = "sam7_probed";
585 fb->next = NULL;
586
587 /* link created bank in 'flash_banks' list */
588 t_bank->next = fb;
589 }
590 t_bank = t_bank->next;
591 }
592
593 t_bank->bank_number = bnk;
594 t_bank->base = base_address + bnk * bank_size;
595 t_bank->size = bank_size;
596 t_bank->chip_width = 0;
597 t_bank->bus_width = 4;
598 t_bank->num_sectors = sectors_num;
599
600 /* allocate sectors */
601 t_bank->sectors = malloc(sectors_num * sizeof(struct flash_sector));
602 for (sec = 0; sec < sectors_num; sec++) {
603 t_bank->sectors[sec].offset = sec * pages_per_sector * page_size;
604 t_bank->sectors[sec].size = pages_per_sector * page_size;
605 t_bank->sectors[sec].is_erased = -1;
606 t_bank->sectors[sec].is_protected = -1;
607 }
608
609 at91sam7_info = t_bank->driver_priv;
610
611 at91sam7_info->cidr = cidr;
612 at91sam7_info->cidr_ext = (cidr >> 31)&0x0001;
613 at91sam7_info->cidr_nvptyp = (cidr >> 28)&0x0007;
614 at91sam7_info->cidr_arch = (cidr >> 20)&0x00FF;
615 at91sam7_info->cidr_sramsiz = (cidr >> 16)&0x000F;
616 at91sam7_info->cidr_nvpsiz2 = (cidr >> 12)&0x000F;
617 at91sam7_info->cidr_nvpsiz = (cidr >> 8)&0x000F;
618 at91sam7_info->cidr_eproc = (cidr >> 5)&0x0007;
619 at91sam7_info->cidr_version = cidr&0x001F;
620
621 at91sam7_info->target_name = target_name_t;
622 at91sam7_info->flashmode = 0;
623 at91sam7_info->ext_freq = ext_freq;
624 at91sam7_info->num_nvmbits = num_nvmbits;
625 at91sam7_info->num_nvmbits_on = 0;
626 at91sam7_info->pagesize = page_size;
627 at91sam7_info->pages_per_sector = pages_per_sector;
628
629 /* calculate master clock frequency */
630 at91sam7_read_clock_info(t_bank);
631
632 /* no timming */
633 at91sam7_set_flash_mode(t_bank, FMR_TIMING_NONE);
634
635 /* check protect state */
636 at91sam7_protect_check(t_bank);
637 }
638
639 LOG_DEBUG("nvptyp: 0x%3.3x, arch: 0x%4.4x",
640 at91sam7_info->cidr_nvptyp,
641 at91sam7_info->cidr_arch);
642
643 return ERROR_OK;
644 }
645
646 static int at91sam7_erase_check(struct flash_bank *bank)
647 {
648 struct target *target = bank->target;
649 uint16_t retval;
650 uint32_t blank;
651 uint16_t fast_check;
652 uint8_t *buffer;
653 uint16_t nSector;
654 uint16_t nByte;
655
656 if (bank->target->state != TARGET_HALTED) {
657 LOG_ERROR("Target not halted");
658 return ERROR_TARGET_NOT_HALTED;
659 }
660
661 /* Configure the flash controller timing */
662 at91sam7_read_clock_info(bank);
663 at91sam7_set_flash_mode(bank, FMR_TIMING_FLASH);
664
665 fast_check = 1;
666 for (nSector = 0; nSector < bank->num_sectors; nSector++) {
667 retval = target_blank_check_memory(target,
668 bank->base + bank->sectors[nSector].offset,
669 bank->sectors[nSector].size,
670 &blank);
671 if (retval != ERROR_OK) {
672 fast_check = 0;
673 break;
674 }
675 if (blank == 0xFF)
676 bank->sectors[nSector].is_erased = 1;
677 else
678 bank->sectors[nSector].is_erased = 0;
679 }
680
681 if (fast_check)
682 return ERROR_OK;
683
684 LOG_USER("Running slow fallback erase check - add working memory");
685
686 buffer = malloc(bank->sectors[0].size);
687 for (nSector = 0; nSector < bank->num_sectors; nSector++) {
688 bank->sectors[nSector].is_erased = 1;
689 retval = target_read_memory(target, bank->base + bank->sectors[nSector].offset, 4,
690 bank->sectors[nSector].size/4, buffer);
691 if (retval != ERROR_OK)
692 return retval;
693
694 for (nByte = 0; nByte < bank->sectors[nSector].size; nByte++) {
695 if (buffer[nByte] != 0xFF) {
696 bank->sectors[nSector].is_erased = 0;
697 break;
698 }
699 }
700 }
701 free(buffer);
702
703 return ERROR_OK;
704 }
705
706 static int at91sam7_protect_check(struct flash_bank *bank)
707 {
708 uint8_t lock_pos, gpnvm_pos;
709 uint32_t status;
710
711 struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
712
713 if (at91sam7_info->cidr == 0)
714 return ERROR_FLASH_BANK_NOT_PROBED;
715 if (bank->target->state != TARGET_HALTED) {
716 LOG_ERROR("Target not halted");
717 return ERROR_TARGET_NOT_HALTED;
718 }
719
720 status = at91sam7_get_flash_status(bank->target, bank->bank_number);
721 at91sam7_info->lockbits = (status >> 16);
722
723 at91sam7_info->num_lockbits_on = 0;
724 for (lock_pos = 0; lock_pos < bank->num_sectors; lock_pos++) {
725 if (((status >> (16 + lock_pos))&(0x0001)) == 1) {
726 at91sam7_info->num_lockbits_on++;
727 bank->sectors[lock_pos].is_protected = 1;
728 } else
729 bank->sectors[lock_pos].is_protected = 0;
730 }
731
732 /* GPNVM and SECURITY bits apply only for MC_FSR of EFC0 */
733 status = at91sam7_get_flash_status(bank->target, 0);
734
735 at91sam7_info->securitybit = (status >> 4)&0x01;
736 at91sam7_info->nvmbits = (status >> 8)&0xFF;
737
738 at91sam7_info->num_nvmbits_on = 0;
739 for (gpnvm_pos = 0; gpnvm_pos < at91sam7_info->num_nvmbits; gpnvm_pos++) {
740 if (((status >> (8 + gpnvm_pos))&(0x01)) == 1)
741 at91sam7_info->num_nvmbits_on++;
742 }
743
744 return ERROR_OK;
745 }
746
747 FLASH_BANK_COMMAND_HANDLER(at91sam7_flash_bank_command)
748 {
749 struct flash_bank *t_bank = bank;
750 struct at91sam7_flash_bank *at91sam7_info;
751 struct target *target = t_bank->target;
752
753 uint32_t base_address;
754 uint32_t bank_size;
755 uint32_t ext_freq = 0;
756
757 int chip_width;
758 int bus_width;
759 int banks_num;
760 int num_sectors;
761
762 uint16_t pages_per_sector;
763 uint16_t page_size;
764 uint16_t num_nvmbits;
765
766 char *target_name_t;
767
768 int bnk, sec;
769
770 at91sam7_info = malloc(sizeof(struct at91sam7_flash_bank));
771 t_bank->driver_priv = at91sam7_info;
772
773 /* part wasn't probed for info yet */
774 at91sam7_info->cidr = 0;
775 at91sam7_info->flashmode = 0;
776 at91sam7_info->ext_freq = 0;
777 at91sam7_info->flash_autodetection = 0;
778
779 if (CMD_ARGC < 13) {
780 at91sam7_info->flash_autodetection = 1;
781 return ERROR_OK;
782 }
783
784 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], base_address);
785
786 COMMAND_PARSE_NUMBER(int, CMD_ARGV[3], chip_width);
787 COMMAND_PARSE_NUMBER(int, CMD_ARGV[4], bus_width);
788
789 COMMAND_PARSE_NUMBER(int, CMD_ARGV[8], banks_num);
790 COMMAND_PARSE_NUMBER(int, CMD_ARGV[9], num_sectors);
791 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[10], pages_per_sector);
792 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[11], page_size);
793 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[12], num_nvmbits);
794
795 if (CMD_ARGC == 14) {
796 unsigned long freq;
797 COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[13], freq);
798 ext_freq = freq * 1000;
799 at91sam7_info->ext_freq = ext_freq;
800 }
801
802 if ((bus_width == 0) || (banks_num == 0) || (num_sectors == 0) ||
803 (pages_per_sector == 0) || (page_size == 0) || (num_nvmbits == 0)) {
804 at91sam7_info->flash_autodetection = 1;
805 return ERROR_OK;
806 }
807
808 target_name_t = calloc(strlen(CMD_ARGV[7]) + 1, sizeof(char));
809 strcpy(target_name_t, CMD_ARGV[7]);
810
811 /* calculate bank size */
812 bank_size = num_sectors * pages_per_sector * page_size;
813
814 for (bnk = 0; bnk < banks_num; bnk++) {
815 if (bnk > 0) {
816 if (!t_bank->next) {
817 /* create a new bank element */
818 struct flash_bank *fb = malloc(sizeof(struct flash_bank));
819 fb->target = target;
820 fb->driver = bank->driver;
821 fb->driver_priv = malloc(sizeof(struct at91sam7_flash_bank));
822 fb->name = "sam7_probed";
823 fb->next = NULL;
824
825 /* link created bank in 'flash_banks' list */
826 t_bank->next = fb;
827 }
828 t_bank = t_bank->next;
829 }
830
831 t_bank->bank_number = bnk;
832 t_bank->base = base_address + bnk * bank_size;
833 t_bank->size = bank_size;
834 t_bank->chip_width = chip_width;
835 t_bank->bus_width = bus_width;
836 t_bank->num_sectors = num_sectors;
837
838 /* allocate sectors */
839 t_bank->sectors = malloc(num_sectors * sizeof(struct flash_sector));
840 for (sec = 0; sec < num_sectors; sec++) {
841 t_bank->sectors[sec].offset = sec * pages_per_sector * page_size;
842 t_bank->sectors[sec].size = pages_per_sector * page_size;
843 t_bank->sectors[sec].is_erased = -1;
844 t_bank->sectors[sec].is_protected = -1;
845 }
846
847 at91sam7_info = t_bank->driver_priv;
848
849 at91sam7_info->target_name = target_name_t;
850 at91sam7_info->flashmode = 0;
851 at91sam7_info->ext_freq = ext_freq;
852 at91sam7_info->num_nvmbits = num_nvmbits;
853 at91sam7_info->num_nvmbits_on = 0;
854 at91sam7_info->pagesize = page_size;
855 at91sam7_info->pages_per_sector = pages_per_sector;
856 }
857
858 return ERROR_OK;
859 }
860
861 static int at91sam7_erase(struct flash_bank *bank, int first, int last)
862 {
863 struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
864 int sec;
865 uint32_t nbytes, pos;
866 uint8_t *buffer;
867 uint8_t erase_all;
868
869 if (at91sam7_info->cidr == 0)
870 return ERROR_FLASH_BANK_NOT_PROBED;
871
872 if (bank->target->state != TARGET_HALTED) {
873 LOG_ERROR("Target not halted");
874 return ERROR_TARGET_NOT_HALTED;
875 }
876
877 if ((first < 0) || (last < first) || (last >= bank->num_sectors))
878 return ERROR_FLASH_SECTOR_INVALID;
879
880 erase_all = 0;
881 if ((first == 0) && (last == (bank->num_sectors-1)))
882 erase_all = 1;
883
884 /* Configure the flash controller timing */
885 at91sam7_read_clock_info(bank);
886 at91sam7_set_flash_mode(bank, FMR_TIMING_FLASH);
887
888 if (erase_all) {
889 if (at91sam7_flash_command(bank, EA, 0) != ERROR_OK)
890 return ERROR_FLASH_OPERATION_FAILED;
891 } else {
892 /* allocate and clean buffer */
893 nbytes = (last - first + 1) * bank->sectors[first].size;
894 buffer = malloc(nbytes * sizeof(uint8_t));
895 for (pos = 0; pos < nbytes; pos++)
896 buffer[pos] = 0xFF;
897
898 if (at91sam7_write(bank, buffer, bank->sectors[first].offset, nbytes) != ERROR_OK) {
899 free(buffer);
900 return ERROR_FLASH_OPERATION_FAILED;
901 }
902
903 free(buffer);
904 }
905
906 /* mark erased sectors */
907 for (sec = first; sec <= last; sec++)
908 bank->sectors[sec].is_erased = 1;
909
910 return ERROR_OK;
911 }
912
913 static int at91sam7_protect(struct flash_bank *bank, int set, int first, int last)
914 {
915 uint32_t cmd;
916 int sector;
917 uint32_t pagen;
918
919 struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
920
921 if (at91sam7_info->cidr == 0)
922 return ERROR_FLASH_BANK_NOT_PROBED;
923
924 if (bank->target->state != TARGET_HALTED) {
925 LOG_ERROR("Target not halted");
926 return ERROR_TARGET_NOT_HALTED;
927 }
928
929 if ((first < 0) || (last < first) || (last >= bank->num_sectors))
930 return ERROR_FLASH_SECTOR_INVALID;
931
932 /* Configure the flash controller timing */
933 at91sam7_read_clock_info(bank);
934 at91sam7_set_flash_mode(bank, FMR_TIMING_NVBITS);
935
936 for (sector = first; sector <= last; sector++) {
937 if (set)
938 cmd = SLB;
939 else
940 cmd = CLB;
941
942 /* if we lock a page from one sector then entire sector will be locked, also,
943 * if we unlock a page from a locked sector, entire sector will be unlocked */
944 pagen = sector * at91sam7_info->pages_per_sector;
945
946 if (at91sam7_flash_command(bank, cmd, pagen) != ERROR_OK)
947 return ERROR_FLASH_OPERATION_FAILED;
948 }
949
950 at91sam7_protect_check(bank);
951
952 return ERROR_OK;
953 }
954
955 static int at91sam7_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
956 {
957 int retval;
958 struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
959 struct target *target = bank->target;
960 uint32_t dst_min_alignment, wcount, bytes_remaining = count;
961 uint32_t first_page, last_page, pagen, buffer_pos;
962
963 if (at91sam7_info->cidr == 0)
964 return ERROR_FLASH_BANK_NOT_PROBED;
965
966 if (bank->target->state != TARGET_HALTED) {
967 LOG_ERROR("Target not halted");
968 return ERROR_TARGET_NOT_HALTED;
969 }
970
971 if (offset + count > bank->size)
972 return ERROR_FLASH_DST_OUT_OF_BANK;
973
974 dst_min_alignment = at91sam7_info->pagesize;
975
976 if (offset % dst_min_alignment) {
977 LOG_WARNING("offset 0x%" PRIx32 " breaks required alignment 0x%" PRIx32 "",
978 offset,
979 dst_min_alignment);
980 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
981 }
982
983 if (at91sam7_info->cidr_arch == 0)
984 return ERROR_FLASH_BANK_NOT_PROBED;
985
986 first_page = offset/dst_min_alignment;
987 last_page = DIV_ROUND_UP(offset + count, dst_min_alignment);
988
989 LOG_DEBUG("first_page: %i, last_page: %i, count %i",
990 (int)first_page,
991 (int)last_page,
992 (int)count);
993
994 /* Configure the flash controller timing */
995 at91sam7_read_clock_info(bank);
996 at91sam7_set_flash_mode(bank, FMR_TIMING_FLASH);
997
998 for (pagen = first_page; pagen < last_page; pagen++) {
999 if (bytes_remaining < dst_min_alignment)
1000 count = bytes_remaining;
1001 else
1002 count = dst_min_alignment;
1003 bytes_remaining -= count;
1004
1005 /* Write one block to the PageWriteBuffer */
1006 buffer_pos = (pagen-first_page)*dst_min_alignment;
1007 wcount = DIV_ROUND_UP(count, 4);
1008 retval = target_write_memory(target, bank->base + pagen*dst_min_alignment, 4,
1009 wcount, buffer + buffer_pos);
1010 if (retval != ERROR_OK)
1011 return retval;
1012
1013 /* Send Write Page command to Flash Controller */
1014 if (at91sam7_flash_command(bank, WP, pagen) != ERROR_OK)
1015 return ERROR_FLASH_OPERATION_FAILED;
1016 LOG_DEBUG("Write flash bank:%i page number:%" PRIi32 "", bank->bank_number, pagen);
1017 }
1018
1019 return ERROR_OK;
1020 }
1021
1022 static int at91sam7_probe(struct flash_bank *bank)
1023 {
1024 /* we can't probe on an at91sam7
1025 * if this is an at91sam7, it has the configured flash */
1026 int retval;
1027
1028 if (bank->target->state != TARGET_HALTED) {
1029 LOG_ERROR("Target not halted");
1030 return ERROR_TARGET_NOT_HALTED;
1031 }
1032
1033 retval = at91sam7_read_part_info(bank);
1034 if (retval != ERROR_OK)
1035 return retval;
1036
1037 return ERROR_OK;
1038 }
1039
1040 static int get_at91sam7_info(struct flash_bank *bank, char *buf, int buf_size)
1041 {
1042 int printed;
1043 struct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;
1044
1045 if (at91sam7_info->cidr == 0)
1046 return ERROR_FLASH_BANK_NOT_PROBED;
1047
1048 printed = snprintf(buf, buf_size,
1049 "\n at91sam7 driver information: Chip is %s\n",
1050 at91sam7_info->target_name);
1051
1052 buf += printed;
1053 buf_size -= printed;
1054
1055 printed = snprintf(buf,
1056 buf_size,
1057 " Cidr: 0x%8.8" PRIx32 " | Arch: 0x%4.4x | Eproc: %s | Version: 0x%3.3x | "
1058 "Flashsize: 0x%8.8" PRIx32 "\n",
1059 at91sam7_info->cidr,
1060 at91sam7_info->cidr_arch,
1061 EPROC[at91sam7_info->cidr_eproc],
1062 at91sam7_info->cidr_version,
1063 bank->size);
1064
1065 buf += printed;
1066 buf_size -= printed;
1067
1068 printed = snprintf(buf, buf_size,
1069 " Master clock (estimated): %u KHz | External clock: %u KHz\n",
1070 (unsigned)(at91sam7_info->mck_freq / 1000),
1071 (unsigned)(at91sam7_info->ext_freq / 1000));
1072
1073 buf += printed;
1074 buf_size -= printed;
1075
1076 printed = snprintf(buf,
1077 buf_size,
1078 " Pagesize: %i bytes | Lockbits(%i): %i 0x%4.4x | Pages in lock region: %i\n",
1079 at91sam7_info->pagesize,
1080 bank->num_sectors,
1081 at91sam7_info->num_lockbits_on,
1082 at91sam7_info->lockbits,
1083 at91sam7_info->pages_per_sector*at91sam7_info->num_lockbits_on);
1084
1085 buf += printed;
1086 buf_size -= printed;
1087
1088 snprintf(buf, buf_size,
1089 " Securitybit: %i | Nvmbits(%i): %i 0x%1.1x\n",
1090 at91sam7_info->securitybit, at91sam7_info->num_nvmbits,
1091 at91sam7_info->num_nvmbits_on, at91sam7_info->nvmbits);
1092
1093 return ERROR_OK;
1094 }
1095
1096 /*
1097 * On AT91SAM7S: When the gpnvm bits are set with
1098 * > at91sam7 gpnvm bitnr set
1099 * the changes are not visible in the flash controller status register MC_FSR
1100 * until the processor has been reset.
1101 * On the Olimex board this requires a power cycle.
1102 * Note that the AT91SAM7S has the following errata (doc6175.pdf sec 14.1.3):
1103 * The maximum number of write/erase cycles for Non volatile Memory bits is 100. this includes
1104 * Lock Bits (LOCKx), General Purpose NVM bits (GPNVMx) and the Security Bit.
1105 */
1106 COMMAND_HANDLER(at91sam7_handle_gpnvm_command)
1107 {
1108 struct flash_bank *bank;
1109 int bit;
1110 uint8_t flashcmd;
1111 uint32_t status;
1112 struct at91sam7_flash_bank *at91sam7_info;
1113 int retval;
1114
1115 if (CMD_ARGC != 2)
1116 return ERROR_COMMAND_SYNTAX_ERROR;
1117
1118 bank = get_flash_bank_by_num_noprobe(0);
1119 if (bank == NULL)
1120 return ERROR_FLASH_BANK_INVALID;
1121 if (strcmp(bank->driver->name, "at91sam7")) {
1122 command_print(CMD_CTX, "not an at91sam7 flash bank '%s'", CMD_ARGV[0]);
1123 return ERROR_FLASH_BANK_INVALID;
1124 }
1125 if (bank->target->state != TARGET_HALTED) {
1126 LOG_ERROR("target has to be halted to perform flash operation");
1127 return ERROR_TARGET_NOT_HALTED;
1128 }
1129
1130 if (strcmp(CMD_ARGV[1], "set") == 0)
1131 flashcmd = SGPB;
1132 else if (strcmp(CMD_ARGV[1], "clear") == 0)
1133 flashcmd = CGPB;
1134 else
1135 return ERROR_COMMAND_SYNTAX_ERROR;
1136
1137 at91sam7_info = bank->driver_priv;
1138 if (at91sam7_info->cidr == 0) {
1139 retval = at91sam7_read_part_info(bank);
1140 if (retval != ERROR_OK)
1141 return retval;
1142 }
1143
1144 COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], bit);
1145 if ((bit < 0) || (bit >= at91sam7_info->num_nvmbits)) {
1146 command_print(CMD_CTX,
1147 "gpnvm bit '#%s' is out of bounds for target %s",
1148 CMD_ARGV[0],
1149 at91sam7_info->target_name);
1150 return ERROR_OK;
1151 }
1152
1153 /* Configure the flash controller timing */
1154 at91sam7_read_clock_info(bank);
1155 at91sam7_set_flash_mode(bank, FMR_TIMING_NVBITS);
1156
1157 if (at91sam7_flash_command(bank, flashcmd, bit) != ERROR_OK)
1158 return ERROR_FLASH_OPERATION_FAILED;
1159
1160 /* GPNVM and SECURITY bits apply only for MC_FSR of EFC0 */
1161 status = at91sam7_get_flash_status(bank->target, 0);
1162 LOG_DEBUG("at91sam7_handle_gpnvm_command: cmd 0x%x, value %d, status 0x%" PRIx32,
1163 flashcmd,
1164 bit,
1165 status);
1166
1167 /* check protect state */
1168 at91sam7_protect_check(bank);
1169
1170 return ERROR_OK;
1171 }
1172
1173 static const struct command_registration at91sam7_exec_command_handlers[] = {
1174 {
1175 .name = "gpnvm",
1176 .handler = at91sam7_handle_gpnvm_command,
1177 .mode = COMMAND_EXEC,
1178 .help = "set or clear one General Purpose Non-Volatile Memory "
1179 "(gpnvm) bit",
1180 .usage = "bitnum ('set'|'clear')",
1181 },
1182 COMMAND_REGISTRATION_DONE
1183 };
1184 static const struct command_registration at91sam7_command_handlers[] = {
1185 {
1186 .name = "at91sam7",
1187 .mode = COMMAND_ANY,
1188 .help = "at91sam7 flash command group",
1189 .usage = "",
1190 .chain = at91sam7_exec_command_handlers,
1191 },
1192 COMMAND_REGISTRATION_DONE
1193 };
1194
1195 struct flash_driver at91sam7_flash = {
1196 .name = "at91sam7",
1197 .usage = "gpnvm <bit> <set | clear>",
1198 .commands = at91sam7_command_handlers,
1199 .flash_bank_command = at91sam7_flash_bank_command,
1200 .erase = at91sam7_erase,
1201 .protect = at91sam7_protect,
1202 .write = at91sam7_write,
1203 .read = default_flash_read,
1204 .probe = at91sam7_probe,
1205 .auto_probe = at91sam7_probe,
1206 .erase_check = at91sam7_erase_check,
1207 .protect_check = at91sam7_protect_check,
1208 .info = get_at91sam7_info,
1209 };

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)