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

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)