936f07ca62caa0990dafccfdb4f7829d87d23641
[openocd.git] / src / flash / nor / core.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de> *
3 * Copyright (C) 2007-2010 Øyvind Harboe <oyvind.harboe@zylin.com> *
4 * Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk> *
5 * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net> *
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 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 #include <flash/common.h>
27 #include <flash/nor/core.h>
28 #include <flash/nor/imp.h>
29 #include <target/image.h>
30
31
32 /**
33 * @file
34 * Upper level of NOR flash framework.
35 * The lower level interfaces are to drivers. These upper level ones
36 * primarily support access from Tcl scripts or from GDB.
37 */
38
39 static struct flash_bank *flash_banks;
40
41 int flash_driver_erase(struct flash_bank *bank, int first, int last)
42 {
43 int retval;
44
45 retval = bank->driver->erase(bank, first, last);
46 if (retval != ERROR_OK)
47 {
48 LOG_ERROR("failed erasing sectors %d to %d (%d)", first, last, retval);
49 }
50
51 return retval;
52 }
53
54 int flash_driver_protect(struct flash_bank *bank, int set, int first, int last)
55 {
56 int retval;
57
58 /* callers may not supply illegal parameters ... */
59 if (first < 0 || first > last || last >= bank->num_sectors)
60 {
61 LOG_ERROR("illegal sector range");
62 return ERROR_FAIL;
63 }
64
65 /* force "set" to 0/1 */
66 set = !!set;
67
68 /* DANGER!
69 *
70 * We must not use any cached information about protection state!!!!
71 *
72 * There are a million things that could change the protect state:
73 *
74 * the target could have reset, power cycled, been hot plugged,
75 * the application could have run, etc.
76 *
77 * Drivers only receive valid sector range.
78 */
79 retval = bank->driver->protect(bank, set, first, last);
80 if (retval != ERROR_OK)
81 {
82 LOG_ERROR("failed setting protection for areas %d to %d (%d)", first, last, retval);
83 }
84
85 return retval;
86 }
87
88 int flash_driver_write(struct flash_bank *bank,
89 uint8_t *buffer, uint32_t offset, uint32_t count)
90 {
91 int retval;
92
93 retval = bank->driver->write(bank, buffer, offset, count);
94 if (retval != ERROR_OK)
95 {
96 LOG_ERROR("error writing to flash at address 0x%08" PRIx32 " at offset 0x%8.8" PRIx32 " (%d)",
97 bank->base, offset, retval);
98 }
99
100 return retval;
101 }
102
103 void flash_bank_add(struct flash_bank *bank)
104 {
105 /* put flash bank in linked list */
106 unsigned bank_num = 0;
107 if (flash_banks)
108 {
109 /* find last flash bank */
110 struct flash_bank *p = flash_banks;
111 while (NULL != p->next)
112 {
113 bank_num += 1;
114 p = p->next;
115 }
116 p->next = bank;
117 bank_num += 1;
118 }
119 else
120 flash_banks = bank;
121
122 bank->bank_number = bank_num;
123 }
124
125 struct flash_bank *flash_bank_list(void)
126 {
127 return flash_banks;
128 }
129
130 struct flash_bank *get_flash_bank_by_num_noprobe(int num)
131 {
132 struct flash_bank *p;
133 int i = 0;
134
135 for (p = flash_banks; p; p = p->next)
136 {
137 if (i++ == num)
138 {
139 return p;
140 }
141 }
142 LOG_ERROR("flash bank %d does not exist", num);
143 return NULL;
144 }
145
146 int flash_get_bank_count(void)
147 {
148 struct flash_bank *p;
149 int i = 0;
150 for (p = flash_banks; p; p = p->next)
151 {
152 i++;
153 }
154 return i;
155 }
156
157 struct flash_bank *get_flash_bank_by_name(const char *name)
158 {
159 unsigned requested = get_flash_name_index(name);
160 unsigned found = 0;
161
162 struct flash_bank *bank;
163 for (bank = flash_banks; NULL != bank; bank = bank->next)
164 {
165 if (strcmp(bank->name, name) == 0)
166 return bank;
167 if (!flash_driver_name_matches(bank->driver->name, name))
168 continue;
169 if (++found < requested)
170 continue;
171 return bank;
172 }
173 return NULL;
174 }
175
176 int get_flash_bank_by_num(int num, struct flash_bank **bank)
177 {
178 struct flash_bank *p = get_flash_bank_by_num_noprobe(num);
179 int retval;
180
181 if (p == NULL)
182 {
183 return ERROR_FAIL;
184 }
185
186 retval = p->driver->auto_probe(p);
187
188 if (retval != ERROR_OK)
189 {
190 LOG_ERROR("auto_probe failed %d\n", retval);
191 return retval;
192 }
193 *bank = p;
194 return ERROR_OK;
195 }
196
197 /* lookup flash bank by address */
198 struct flash_bank *get_flash_bank_by_addr(struct target *target, uint32_t addr)
199 {
200 struct flash_bank *c;
201
202 /* cycle through bank list */
203 for (c = flash_banks; c; c = c->next)
204 {
205 int retval;
206 retval = c->driver->auto_probe(c);
207
208 if (retval != ERROR_OK)
209 {
210 LOG_ERROR("auto_probe failed %d\n", retval);
211 return NULL;
212 }
213 /* check whether address belongs to this flash bank */
214 if ((addr >= c->base) && (addr <= c->base + (c->size - 1)) && target == c->target)
215 return c;
216 }
217 LOG_ERROR("No flash at address 0x%08" PRIx32 "\n", addr);
218 return NULL;
219 }
220
221 int default_flash_mem_blank_check(struct flash_bank *bank)
222 {
223 struct target *target = bank->target;
224 const int buffer_size = 1024;
225 int i;
226 uint32_t nBytes;
227 int retval = ERROR_OK;
228
229 if (bank->target->state != TARGET_HALTED)
230 {
231 LOG_ERROR("Target not halted");
232 return ERROR_TARGET_NOT_HALTED;
233 }
234
235 uint8_t *buffer = malloc(buffer_size);
236
237 for (i = 0; i < bank->num_sectors; i++)
238 {
239 uint32_t j;
240 bank->sectors[i].is_erased = 1;
241
242 for (j = 0; j < bank->sectors[i].size; j += buffer_size)
243 {
244 uint32_t chunk;
245 chunk = buffer_size;
246 if (chunk > (j - bank->sectors[i].size))
247 {
248 chunk = (j - bank->sectors[i].size);
249 }
250
251 retval = target_read_memory(target, bank->base + bank->sectors[i].offset + j, 4, chunk/4, buffer);
252 if (retval != ERROR_OK)
253 {
254 goto done;
255 }
256
257 for (nBytes = 0; nBytes < chunk; nBytes++)
258 {
259 if (buffer[nBytes] != 0xFF)
260 {
261 bank->sectors[i].is_erased = 0;
262 break;
263 }
264 }
265 }
266 }
267
268 done:
269 free(buffer);
270
271 return retval;
272 }
273
274 int default_flash_blank_check(struct flash_bank *bank)
275 {
276 struct target *target = bank->target;
277 int i;
278 int retval;
279 int fast_check = 0;
280 uint32_t blank;
281
282 if (bank->target->state != TARGET_HALTED)
283 {
284 LOG_ERROR("Target not halted");
285 return ERROR_TARGET_NOT_HALTED;
286 }
287
288 for (i = 0; i < bank->num_sectors; i++)
289 {
290 uint32_t address = bank->base + bank->sectors[i].offset;
291 uint32_t size = bank->sectors[i].size;
292
293 if ((retval = target_blank_check_memory(target, address, size, &blank)) != ERROR_OK)
294 {
295 fast_check = 0;
296 break;
297 }
298 if (blank == 0xFF)
299 bank->sectors[i].is_erased = 1;
300 else
301 bank->sectors[i].is_erased = 0;
302 fast_check = 1;
303 }
304
305 if (!fast_check)
306 {
307 LOG_USER("Running slow fallback erase check - add working memory");
308 return default_flash_mem_blank_check(bank);
309 }
310
311 return ERROR_OK;
312 }
313
314 /* Manipulate given flash region, selecting the bank according to target
315 * and address. Maps an address range to a set of sectors, and issues
316 * the callback() on that set ... e.g. to erase or unprotect its members.
317 *
318 * (Note a current bad assumption: that protection operates on the same
319 * size sectors as erase operations use.)
320 *
321 * The "pad_reason" parameter is a kind of boolean: when it's NULL, the
322 * range must fit those sectors exactly. This is clearly safe; it can't
323 * erase data which the caller said to leave alone, for example. If it's
324 * non-NULL, rather than failing, extra data in the first and/or last
325 * sectors will be added to the range, and that reason string is used when
326 * warning about those additions.
327 */
328 static int flash_iterate_address_range(struct target *target,
329 char *pad_reason, uint32_t addr, uint32_t length,
330 int (*callback)(struct flash_bank *bank, int first, int last))
331 {
332 struct flash_bank *c;
333 uint32_t last_addr = addr + length; /* first address AFTER end */
334 int first = -1;
335 int last = -1;
336 int i;
337
338 if ((c = get_flash_bank_by_addr(target, addr)) == NULL)
339 return ERROR_FLASH_DST_OUT_OF_BANK; /* no corresponding bank found */
340
341 if (c->size == 0 || c->num_sectors == 0)
342 {
343 LOG_ERROR("Bank is invalid");
344 return ERROR_FLASH_BANK_INVALID;
345 }
346
347 if (length == 0)
348 {
349 /* special case, erase whole bank when length is zero */
350 if (addr != c->base)
351 {
352 LOG_ERROR("Whole bank access must start at beginning of bank.");
353 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
354 }
355
356 return callback(c, 0, c->num_sectors - 1);
357 }
358
359 /* check whether it all fits in this bank */
360 if (addr + length - 1 > c->base + c->size - 1)
361 {
362 LOG_ERROR("Flash access does not fit into bank.");
363 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
364 }
365
366 /** @todo: handle erasures that cross into adjacent banks */
367
368 addr -= c->base;
369 last_addr -= c->base;
370
371 for (i = 0; i < c->num_sectors; i++)
372 {
373 struct flash_sector *f = c->sectors + i;
374 uint32_t end = f->offset + f->size;
375
376 /* start only on a sector boundary */
377 if (first < 0) {
378 /* scanned past the first sector? */
379 if (addr < f->offset)
380 break;
381
382 /* is this the first sector? */
383 if (addr == f->offset)
384 first = i;
385
386 /* Does this need head-padding? If so, pad and warn;
387 * or else force an error.
388 *
389 * Such padding can make trouble, since *WE* can't
390 * ever know if that data was in use. The warning
391 * should help users sort out messes later.
392 */
393 else if (addr < end && pad_reason) {
394 /* FIXME say how many bytes (e.g. 80 KB) */
395 LOG_WARNING("Adding extra %s range, "
396 "%#8.8x to %#8.8x",
397 pad_reason,
398 (unsigned) f->offset,
399 (unsigned) addr - 1);
400 first = i;
401 } else
402 continue;
403 }
404
405 /* is this (also?) the last sector? */
406 if (last_addr == end) {
407 last = i;
408 break;
409 }
410
411 /* Does this need tail-padding? If so, pad and warn;
412 * or else force an error.
413 */
414 if (last_addr < end && pad_reason) {
415 /* FIXME say how many bytes (e.g. 80 KB) */
416 LOG_WARNING("Adding extra %s range, "
417 "%#8.8x to %#8.8x",
418 pad_reason,
419 (unsigned) last_addr,
420 (unsigned) end - 1);
421 last = i;
422 break;
423 }
424
425 /* MUST finish on a sector boundary */
426 if (last_addr <= f->offset)
427 break;
428 }
429
430 /* invalid start or end address? */
431 if (first == -1 || last == -1) {
432 LOG_ERROR("address range 0x%8.8x .. 0x%8.8x "
433 "is not sector-aligned",
434 (unsigned) (c->base + addr),
435 (unsigned) (c->base + last_addr - 1));
436 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
437 }
438
439 /* The NOR driver may trim this range down, based on what
440 * sectors are already erased/unprotected. GDB currently
441 * blocks such optimizations.
442 */
443 return callback(c, first, last);
444 }
445
446 int flash_erase_address_range(struct target *target,
447 bool pad, uint32_t addr, uint32_t length)
448 {
449 return flash_iterate_address_range(target, pad ? "erase" : NULL,
450 addr, length, &flash_driver_erase);
451 }
452
453 static int flash_driver_unprotect(struct flash_bank *bank, int first, int last)
454 {
455 return flash_driver_protect(bank, 0, first, last);
456 }
457
458 int flash_unlock_address_range(struct target *target, uint32_t addr, uint32_t length)
459 {
460 /* By default, pad to sector boundaries ... the real issue here
461 * is that our (only) caller *permanently* removes protection,
462 * and doesn't restore it.
463 */
464 return flash_iterate_address_range(target, "unprotect",
465 addr, length, &flash_driver_unprotect);
466 }
467
468 static int compare_section (const void * a, const void * b)
469 {
470 struct imageection *b1, *b2;
471 b1=*((struct imageection **)a);
472 b2=*((struct imageection **)b);
473
474 if (b1->base_address == b2->base_address)
475 {
476 return 0;
477 } else if (b1->base_address > b2->base_address)
478 {
479 return 1;
480 } else
481 {
482 return -1;
483 }
484 }
485
486
487 int flash_write_unlock(struct target *target, struct image *image,
488 uint32_t *written, int erase, bool unlock)
489 {
490 int retval = ERROR_OK;
491
492 int section;
493 uint32_t section_offset;
494 struct flash_bank *c;
495 int *padding;
496
497 section = 0;
498 section_offset = 0;
499
500 if (written)
501 *written = 0;
502
503 if (erase)
504 {
505 /* assume all sectors need erasing - stops any problems
506 * when flash_write is called multiple times */
507
508 flash_set_dirty();
509 }
510
511 /* allocate padding array */
512 padding = calloc(image->num_sections, sizeof(*padding));
513
514 /* This fn requires all sections to be in ascending order of addresses,
515 * whereas an image can have sections out of order. */
516 struct imageection **sections = malloc(sizeof(struct imageection *) *
517 image->num_sections);
518 int i;
519 for (i = 0; i < image->num_sections; i++)
520 {
521 sections[i] = &image->sections[i];
522 }
523
524 qsort(sections, image->num_sections, sizeof(struct imageection *),
525 compare_section);
526
527 /* loop until we reach end of the image */
528 while (section < image->num_sections)
529 {
530 uint32_t buffer_size;
531 uint8_t *buffer;
532 int section_first;
533 int section_last;
534 uint32_t run_address = sections[section]->base_address + section_offset;
535 uint32_t run_size = sections[section]->size - section_offset;
536 int pad_bytes = 0;
537
538 if (sections[section]->size == 0)
539 {
540 LOG_WARNING("empty section %d", section);
541 section++;
542 section_offset = 0;
543 continue;
544 }
545
546 /* find the corresponding flash bank */
547 if ((c = get_flash_bank_by_addr(target, run_address)) == NULL)
548 {
549 section++; /* and skip it */
550 section_offset = 0;
551 continue;
552 }
553
554 /* collect consecutive sections which fall into the same bank */
555 section_first = section;
556 section_last = section;
557 padding[section] = 0;
558 while ((run_address + run_size - 1 < c->base + c->size - 1)
559 && (section_last + 1 < image->num_sections))
560 {
561 /* sections are sorted */
562 assert(sections[section_last + 1]->base_address >= c->base);
563 if (sections[section_last + 1]->base_address >= (c->base + c->size))
564 {
565 /* Done with this bank */
566 break;
567 }
568
569 /* FIXME This needlessly touches sectors BETWEEN the
570 * sections it's writing. Without auto erase, it just
571 * writes ones. That WILL INVALIDATE data in cases
572 * like Stellaris Tempest chips, corrupting internal
573 * ECC codes; and at least FreeScale suggests issues
574 * with that approach (in HC11 documentation).
575 *
576 * With auto erase enabled, data in those sectors will
577 * be needlessly destroyed; and some of the limited
578 * number of flash erase cycles will be wasted...
579 *
580 * In both cases, the extra writes slow things down.
581 */
582
583 /* if we have multiple sections within our image,
584 * flash programming could fail due to alignment issues
585 * attempt to rebuild a consecutive buffer for the flash loader */
586 pad_bytes = (sections[section_last + 1]->base_address) - (run_address + run_size);
587 padding[section_last] = pad_bytes;
588 run_size += sections[++section_last]->size;
589 run_size += pad_bytes;
590
591 if (pad_bytes > 0)
592 LOG_INFO("Padding image section %d with %d bytes", section_last-1, pad_bytes);
593 }
594
595 assert (run_address + run_size - 1 <= c->base + c->size - 1);
596
597 /* If we're applying any sector automagic, then pad this
598 * (maybe-combined) segment to the end of its last sector.
599 */
600 if (unlock || erase) {
601 int sector;
602 uint32_t offset_start = run_address - c->base;
603 uint32_t offset_end = offset_start + run_size;
604 uint32_t end = offset_end, delta;
605
606 for (sector = 0; sector < c->num_sectors; sector++) {
607 end = c->sectors[sector].offset
608 + c->sectors[sector].size;
609 if (offset_end <= end)
610 break;
611 }
612
613 delta = end - offset_end;
614 padding[section_last] += delta;
615 run_size += delta;
616 }
617
618 /* allocate buffer */
619 buffer = malloc(run_size);
620 buffer_size = 0;
621
622 /* read sections to the buffer */
623 while (buffer_size < run_size)
624 {
625 size_t size_read;
626
627 size_read = run_size - buffer_size;
628 if (size_read > sections[section]->size - section_offset)
629 size_read = sections[section]->size - section_offset;
630
631 /* KLUDGE!
632 *
633 * #¤%#"%¤% we have to figure out the section # from the sorted
634 * list of pointers to sections to invoke image_read_section()...
635 */
636 intptr_t diff = (intptr_t)sections[section] - (intptr_t)image->sections;
637 int t_section_num = diff / sizeof(struct imageection);
638
639 LOG_DEBUG("image_read_section: section = %d, t_section_num = %d, section_offset = %d, buffer_size = %d, size_read = %d",
640 (int)section,
641 (int)t_section_num, (int)section_offset, (int)buffer_size, (int)size_read);
642 if ((retval = image_read_section(image, t_section_num, section_offset,
643 size_read, buffer + buffer_size, &size_read)) != ERROR_OK || size_read == 0)
644 {
645 free(buffer);
646 goto done;
647 }
648
649 /* see if we need to pad the section */
650 while (padding[section]--)
651 (buffer + buffer_size)[size_read++] = 0xff;
652
653 buffer_size += size_read;
654 section_offset += size_read;
655
656 if (section_offset >= sections[section]->size)
657 {
658 section++;
659 section_offset = 0;
660 }
661 }
662
663 retval = ERROR_OK;
664
665 if (unlock)
666 {
667 retval = flash_unlock_address_range(target, run_address, run_size);
668 }
669 if (retval == ERROR_OK)
670 {
671 if (erase)
672 {
673 /* calculate and erase sectors */
674 retval = flash_erase_address_range(target,
675 true, run_address, run_size);
676 }
677 }
678
679 if (retval == ERROR_OK)
680 {
681 /* write flash sectors */
682 retval = flash_driver_write(c, buffer, run_address - c->base, run_size);
683 }
684
685 free(buffer);
686
687 if (retval != ERROR_OK)
688 {
689 /* abort operation */
690 goto done;
691 }
692
693 if (written != NULL)
694 *written += run_size; /* add run size to total written counter */
695 }
696
697
698 done:
699 free(sections);
700 free(padding);
701
702 return retval;
703 }
704
705 int flash_write(struct target *target, struct image *image,
706 uint32_t *written, int erase)
707 {
708 return flash_write_unlock(target, image, written, erase, false);
709 }

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)