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

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)