kinetis: ensure flash writes are not truncated
[openocd.git] / src / flash / nor / kinetis.c
1 /***************************************************************************
2 * Copyright (C) 2011 by Mathias Kuester *
3 * kesmtp@freenet.de *
4 * *
5 * Copyright (C) 2011 sleep(5) ltd *
6 * tomas@sleepfive.com *
7 * *
8 * Copyright (C) 2012 by Christopher D. Kilgour *
9 * techie at whiterocker.com *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
20 * *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 ***************************************************************************/
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include "imp.h"
32 #include "helper/binarybuffer.h"
33
34 /*
35 * Implementation Notes
36 *
37 * The persistent memories in the Kinetis chip families K10 through
38 * K70 are all manipulated with the Flash Memory Module. Some
39 * variants call this module the FTFE, others call it the FTFL. To
40 * indicate that both are considered here, we use FTFX.
41 *
42 * Within the module, according to the chip variant, the persistent
43 * memory is divided into what Freescale terms Program Flash, FlexNVM,
44 * and FlexRAM. All chip variants have Program Flash. Some chip
45 * variants also have FlexNVM and FlexRAM, which always appear
46 * together.
47 *
48 * A given Kinetis chip may have 2 or 4 blocks of flash. Here we map
49 * each block to a separate bank. Each block size varies by chip and
50 * may be determined by the read-only SIM_FCFG1 register. The sector
51 * size within each bank/block varies by the chip granularity as
52 * described below.
53 *
54 * Kinetis offers four different of flash granularities applicable
55 * across the chip families. The granularity is apparently reflected
56 * by at least the reference manual suffix. For example, for chip
57 * MK60FN1M0VLQ12, reference manual K60P144M150SF3RM ends in "SF3RM",
58 * where the "3" indicates there are four flash blocks with 4kiB
59 * sectors. All possible granularities are indicated below.
60 *
61 * The first half of the flash (1 or 2 blocks, depending on the
62 * granularity) is always Program Flash and always starts at address
63 * 0x00000000. The "PFLSH" flag, bit 23 of the read-only SIM_FCFG2
64 * register, determines whether the second half of the flash is also
65 * Program Flash or FlexNVM+FlexRAM. When PFLSH is set, the second
66 * half of flash is Program Flash and is contiguous in the memory map
67 * from the first half. When PFLSH is clear, the second half of flash
68 * is FlexNVM and always starts at address 0x10000000. FlexRAM, which
69 * is also present when PFLSH is clear, always starts at address
70 * 0x14000000.
71 *
72 * The Flash Memory Module provides a register set where flash
73 * commands are loaded to perform flash operations like erase and
74 * program. Different commands are available depending on whether
75 * Program Flash or FlexNVM/FlexRAM is being manipulated. Although
76 * the commands used are quite consistent between flash blocks, the
77 * parameters they accept differ according to the flash granularity.
78 * Some Kinetis chips have different granularity between Program Flash
79 * and FlexNVM/FlexRAM, so flash command arguments may differ between
80 * blocks in the same chip.
81 *
82 * Although not documented as such by Freescale, it appears that bits
83 * 8:7 of the read-only SIM_SDID register reflect the granularity
84 * settings 0..3, so sector sizes and block counts are applicable
85 * according to the following table.
86 */
87 const struct {
88 unsigned pflash_sector_size_bytes;
89 unsigned nvm_sector_size_bytes;
90 unsigned num_blocks;
91 } kinetis_flash_params[4] = {
92 { 1<<10, 1<<10, 2 },
93 { 2<<10, 1<<10, 2 },
94 { 2<<10, 2<<10, 2 },
95 { 4<<10, 4<<10, 4 }
96 };
97
98 struct kinetis_flash_bank {
99 unsigned granularity;
100 unsigned bank_ordinal;
101 uint32_t sector_size;
102 uint32_t protection_size;
103
104 uint32_t sim_sdid;
105 uint32_t sim_fcfg1;
106 uint32_t sim_fcfg2;
107
108 enum {
109 FC_AUTO = 0,
110 FC_PFLASH,
111 FC_FLEX_NVM,
112 FC_FLEX_RAM,
113 } flash_class;
114 };
115
116 FLASH_BANK_COMMAND_HANDLER(kinetis_flash_bank_command)
117 {
118 struct kinetis_flash_bank *bank_info;
119
120 if (CMD_ARGC < 6)
121 return ERROR_COMMAND_SYNTAX_ERROR;
122
123 LOG_INFO("add flash_bank kinetis %s", bank->name);
124
125 bank_info = malloc(sizeof(struct kinetis_flash_bank));
126
127 memset(bank_info, 0, sizeof(struct kinetis_flash_bank));
128
129 bank->driver_priv = bank_info;
130
131 return ERROR_OK;
132 }
133
134 static int kinetis_protect(struct flash_bank *bank, int set, int first,
135 int last)
136 {
137 LOG_WARNING("kinetis_protect not supported yet");
138 /* FIXME: TODO */
139
140 if (bank->target->state != TARGET_HALTED) {
141 LOG_ERROR("Target not halted");
142 return ERROR_TARGET_NOT_HALTED;
143 }
144
145 return ERROR_FLASH_BANK_INVALID;
146 }
147
148 static int kinetis_protect_check(struct flash_bank *bank)
149 {
150 struct kinetis_flash_bank *kinfo = bank->driver_priv;
151
152 if (bank->target->state != TARGET_HALTED) {
153 LOG_ERROR("Target not halted");
154 return ERROR_TARGET_NOT_HALTED;
155 }
156
157 if (kinfo->flash_class == FC_PFLASH) {
158 int result;
159 uint8_t buffer[4];
160 uint32_t fprot, psec;
161 int i, b;
162
163 /* read protection register FTFx_FPROT */
164 result = target_read_memory(bank->target, 0x40020010, 1, 4, buffer);
165
166 if (result != ERROR_OK)
167 return result;
168
169 fprot = target_buffer_get_u32(bank->target, buffer);
170
171 /*
172 * Every bit protects 1/32 of the full flash (not necessarily
173 * just this bank), but we enforce the bank ordinals for
174 * PFlash to start at zero.
175 */
176 b = kinfo->bank_ordinal * (bank->size / kinfo->protection_size);
177 for (psec = 0, i = 0; i < bank->num_sectors; i++) {
178 if ((fprot >> b) & 1)
179 bank->sectors[i].is_protected = 0;
180 else
181 bank->sectors[i].is_protected = 1;
182
183 psec += bank->sectors[i].size;
184
185 if (psec >= kinfo->protection_size) {
186 psec = 0;
187 b++;
188 }
189 }
190 } else {
191 LOG_ERROR("Protection checks for FlexNVM not yet supported");
192 return ERROR_FLASH_BANK_INVALID;
193 }
194
195 return ERROR_OK;
196 }
197
198 static int kinetis_ftfx_command(struct flash_bank *bank, uint32_t w0,
199 uint32_t w1, uint32_t w2, uint8_t *ftfx_fstat)
200 {
201 uint8_t buffer[12];
202 int result, i;
203
204 /* wait for done */
205 for (i = 0; i < 50; i++) {
206 result =
207 target_read_memory(bank->target, 0x40020000, 1, 1, buffer);
208
209 if (result != ERROR_OK)
210 return result;
211
212 if (buffer[0] & 0x80)
213 break;
214
215 buffer[0] = 0x00;
216 }
217
218 if (buffer[0] != 0x80) {
219 /* reset error flags */
220 buffer[0] = 0x30;
221 result =
222 target_write_memory(bank->target, 0x40020000, 1, 1, buffer);
223 if (result != ERROR_OK)
224 return result;
225 }
226
227 target_buffer_set_u32(bank->target, buffer, w0);
228 target_buffer_set_u32(bank->target, buffer + 4, w1);
229 target_buffer_set_u32(bank->target, buffer + 8, w2);
230
231 result = target_write_memory(bank->target, 0x40020004, 4, 3, buffer);
232
233 if (result != ERROR_OK)
234 return result;
235
236 /* start command */
237 buffer[0] = 0x80;
238 result = target_write_memory(bank->target, 0x40020000, 1, 1, buffer);
239 if (result != ERROR_OK)
240 return result;
241
242 /* wait for done */
243 for (i = 0; i < 50; i++) {
244 result =
245 target_read_memory(bank->target, 0x40020000, 1, 1, ftfx_fstat);
246
247 if (result != ERROR_OK)
248 return result;
249
250 if (*ftfx_fstat & 0x80)
251 break;
252 }
253
254 if ((*ftfx_fstat & 0xf0) != 0x80) {
255 LOG_ERROR
256 ("ftfx command failed FSTAT: %02X W0: %08X W1: %08X W2: %08X",
257 *ftfx_fstat, w0, w1, w2);
258
259 return ERROR_FLASH_OPERATION_FAILED;
260 }
261
262 return ERROR_OK;
263 }
264
265 static int kinetis_erase(struct flash_bank *bank, int first, int last)
266 {
267 int result, i;
268 uint32_t w0 = 0, w1 = 0, w2 = 0;
269
270 if (bank->target->state != TARGET_HALTED) {
271 LOG_ERROR("Target not halted");
272 return ERROR_TARGET_NOT_HALTED;
273 }
274
275 if ((first > bank->num_sectors) || (last > bank->num_sectors))
276 return ERROR_FLASH_OPERATION_FAILED;
277
278 /*
279 * FIXME: TODO: use the 'Erase Flash Block' command if the
280 * requested erase is PFlash or NVM and encompasses the entire
281 * block. Should be quicker.
282 */
283 for (i = first; i <= last; i++) {
284 uint8_t ftfx_fstat;
285 /* set command and sector address */
286 w0 = (0x09 << 24) | (bank->base + bank->sectors[i].offset);
287
288 result = kinetis_ftfx_command(bank, w0, w1, w2, &ftfx_fstat);
289
290 if (result != ERROR_OK) {
291 LOG_WARNING("erase sector %d failed", i);
292 return ERROR_FLASH_OPERATION_FAILED;
293 }
294
295 bank->sectors[i].is_erased = 1;
296 }
297
298 if (first == 0) {
299 LOG_WARNING
300 ("flash configuration field erased, please reset the device");
301 }
302
303 return ERROR_OK;
304 }
305
306 static int kinetis_write(struct flash_bank *bank, uint8_t *buffer,
307 uint32_t offset, uint32_t count)
308 {
309 unsigned int i, result, fallback = 0;
310 uint8_t buf[8];
311 uint32_t wc, w0 = 0, w1 = 0, w2 = 0;
312 struct kinetis_flash_bank *kinfo = bank->driver_priv;
313
314 if (bank->target->state != TARGET_HALTED) {
315 LOG_ERROR("Target not halted");
316 return ERROR_TARGET_NOT_HALTED;
317 }
318
319 if (kinfo->flash_class == FC_FLEX_NVM) {
320 uint8_t ftfx_fstat;
321
322 LOG_DEBUG("flash write into FlexNVM @%08X", offset);
323
324 /* make flex ram available */
325 w0 = (0x81 << 24) | 0x00ff0000;
326
327 result = kinetis_ftfx_command(bank, w0, w1, w2, &ftfx_fstat);
328
329 if (result != ERROR_OK)
330 return ERROR_FLASH_OPERATION_FAILED;
331
332 /* check if ram ready */
333 result = target_read_memory(bank->target, 0x40020001, 1, 1, buf);
334
335 if (result != ERROR_OK)
336 return result;
337
338 if (!(buf[0] & (1 << 1))) {
339 /* fallback to longword write */
340 fallback = 1;
341
342 LOG_WARNING("ram not ready, fallback to slow longword write (FCNFG: %02X)",
343 buf[0]);
344 }
345 } else {
346 LOG_DEBUG("flash write into PFLASH @08%X", offset);
347 }
348
349
350 /* program section command */
351 if (fallback == 0) {
352 unsigned prog_section_bytes = kinfo->sector_size >> 8;
353 for (i = 0; i < count; i += kinfo->sector_size) {
354 /*
355 * The largest possible Kinetis "section" is
356 * 16 bytes. A full Kinetis sector is always
357 * 256 "section"s.
358 */
359 uint8_t residual_buffer[16];
360 uint8_t ftfx_fstat;
361 uint32_t section_count = 256;
362 uint32_t residual_wc = 0;
363
364 /*
365 * Assume the word count covers an entire
366 * sector.
367 */
368 wc = kinfo->sector_size / 4;
369
370 /*
371 * If bytes to be programmed are less than the
372 * full sector, then determine the number of
373 * full-words to program, and put together the
374 * residual buffer so that a full "section"
375 * may always be programmed.
376 */
377 if ((count - i) < kinfo->sector_size) {
378 /* number of bytes to program beyond full section */
379 unsigned residual_bc = (count-i) % prog_section_bytes;
380
381 /* number of complete words to copy directly from buffer */
382 wc = (count - i) / 4;
383
384 /* number of total sections to write, including residual */
385 section_count = DIV_ROUND_UP((count-i), prog_section_bytes);
386
387 /* any residual bytes delivers a whole residual section */
388 residual_wc = (residual_bc ? prog_section_bytes : 0)/4;
389
390 /* clear residual buffer then populate residual bytes */
391 (void) memset(residual_buffer, 0xff, prog_section_bytes);
392 (void) memcpy(residual_buffer, &buffer[i+4*wc], residual_bc);
393 }
394
395 LOG_DEBUG("write section @ %08X with length %d bytes",
396 offset + i, (count - i));
397
398 /* write data to flexram as whole-words */
399 result = target_write_memory(bank->target, 0x14000000, 4, wc,
400 buffer + i);
401
402 if (result != ERROR_OK) {
403 LOG_ERROR("target_write_memory failed");
404 return result;
405 }
406
407 /* write the residual words to the flexram */
408 if (residual_wc) {
409 result = target_write_memory(bank->target,
410 0x14000000+4*wc,
411 4, residual_wc,
412 residual_buffer);
413
414 if (result != ERROR_OK) {
415 LOG_ERROR("target_write_memory failed");
416 return result;
417 }
418 }
419
420 /* execute section-write command */
421 w0 = (0x0b << 24) | (bank->base + offset + i);
422 w1 = section_count << 16;
423
424 result = kinetis_ftfx_command(bank, w0, w1, w2, &ftfx_fstat);
425
426 if (result != ERROR_OK)
427 return ERROR_FLASH_OPERATION_FAILED;
428 }
429 }
430 /* program longword command, not supported in "SF3" devices */
431 else if (kinfo->granularity != 3) {
432 for (i = 0; i < count; i += 4) {
433 uint8_t ftfx_fstat;
434
435 LOG_DEBUG("write longword @ %08X", offset + i);
436
437 w0 = (0x06 << 24) | (bank->base + offset + i);
438 w1 = buf_get_u32(buffer + offset + i, 0, 32);
439
440 result = kinetis_ftfx_command(bank, w0, w1, w2, &ftfx_fstat);
441
442 if (result != ERROR_OK)
443 return ERROR_FLASH_OPERATION_FAILED;
444 }
445 } else {
446 LOG_ERROR("Flash write strategy not implemented");
447 return ERROR_FLASH_OPERATION_FAILED;
448 }
449
450 return ERROR_OK;
451 }
452
453 static int kinetis_read_part_info(struct flash_bank *bank)
454 {
455 int result, i;
456 uint8_t buf[4];
457 uint32_t offset = 0;
458 uint8_t fcfg1_nvmsize, fcfg1_pfsize, fcfg1_eesize, fcfg2_pflsh;
459 uint32_t nvm_size = 0, pf_size = 0, ee_size = 0;
460 unsigned granularity, num_blocks = 0, num_pflash_blocks = 0, num_nvm_blocks = 0,
461 first_nvm_bank = 0, reassign = 0;
462 struct kinetis_flash_bank *kinfo = bank->driver_priv;
463
464 result = target_read_memory(bank->target, 0x40048024, 1, 4, buf);
465 if (result != ERROR_OK)
466 return result;
467 kinfo->sim_sdid = target_buffer_get_u32(bank->target, buf);
468 granularity = (kinfo->sim_sdid >> 7) & 0x03;
469 result = target_read_memory(bank->target, 0x4004804c, 1, 4, buf);
470 if (result != ERROR_OK)
471 return result;
472 kinfo->sim_fcfg1 = target_buffer_get_u32(bank->target, buf);
473 result = target_read_memory(bank->target, 0x40048050, 1, 4, buf);
474 if (result != ERROR_OK)
475 return result;
476 kinfo->sim_fcfg2 = target_buffer_get_u32(bank->target, buf);
477 fcfg2_pflsh = (kinfo->sim_fcfg2 >> 23) & 0x01;
478
479 LOG_DEBUG("SDID: %08X FCFG1: %08X FCFG2: %08X", kinfo->sim_sdid,
480 kinfo->sim_fcfg1, kinfo->sim_fcfg2);
481
482 fcfg1_nvmsize = (uint8_t)((kinfo->sim_fcfg1 >> 28) & 0x0f);
483 fcfg1_pfsize = (uint8_t)((kinfo->sim_fcfg1 >> 24) & 0x0f);
484 fcfg1_eesize = (uint8_t)((kinfo->sim_fcfg1 >> 16) & 0x0f);
485
486 /* when the PFLSH bit is set, there is no FlexNVM/FlexRAM */
487 if (!fcfg2_pflsh) {
488 switch (fcfg1_nvmsize) {
489 case 0x03:
490 case 0x07:
491 case 0x09:
492 case 0x0b:
493 nvm_size = 1 << (14 + (fcfg1_nvmsize >> 1));
494 break;
495 case 0x0f:
496 if (granularity == 3)
497 nvm_size = 512<<10;
498 else
499 nvm_size = 256<<10;
500 break;
501 default:
502 nvm_size = 0;
503 break;
504 }
505
506 switch (fcfg1_eesize) {
507 case 0x00:
508 case 0x01:
509 case 0x02:
510 case 0x03:
511 case 0x04:
512 case 0x05:
513 case 0x06:
514 case 0x07:
515 case 0x08:
516 case 0x09:
517 ee_size = (16 << (10 - fcfg1_eesize));
518 break;
519 default:
520 ee_size = 0;
521 break;
522 }
523 }
524
525 switch (fcfg1_pfsize) {
526 case 0x03:
527 case 0x05:
528 case 0x07:
529 case 0x09:
530 case 0x0b:
531 case 0x0d:
532 pf_size = 1 << (14 + (fcfg1_pfsize >> 1));
533 break;
534 case 0x0f:
535 if (granularity == 3)
536 pf_size = 1024<<10;
537 else if (fcfg2_pflsh)
538 pf_size = 512<<10;
539 else
540 pf_size = 256<<10;
541 break;
542 default:
543 pf_size = 0;
544 break;
545 }
546
547 LOG_DEBUG("FlexNVM: %d PFlash: %d FlexRAM: %d PFLSH: %d",
548 nvm_size, pf_size, ee_size, fcfg2_pflsh);
549
550 num_blocks = kinetis_flash_params[granularity].num_blocks;
551 num_pflash_blocks = num_blocks / (2 - fcfg2_pflsh);
552 first_nvm_bank = num_pflash_blocks;
553 num_nvm_blocks = num_blocks - num_pflash_blocks;
554
555 LOG_DEBUG("%d blocks total: %d PFlash, %d FlexNVM",
556 num_blocks, num_pflash_blocks, num_nvm_blocks);
557
558 /*
559 * If the flash class is already assigned, verify the
560 * parameters.
561 */
562 if (kinfo->flash_class != FC_AUTO) {
563 if (kinfo->bank_ordinal != (unsigned) bank->bank_number) {
564 LOG_WARNING("Flash ordinal/bank number mismatch");
565 reassign = 1;
566 } else if (kinfo->granularity != granularity) {
567 LOG_WARNING("Flash granularity mismatch");
568 reassign = 1;
569 } else {
570 switch (kinfo->flash_class) {
571 case FC_PFLASH:
572 if (kinfo->bank_ordinal >= first_nvm_bank) {
573 LOG_WARNING("Class mismatch, bank %d is not PFlash",
574 bank->bank_number);
575 reassign = 1;
576 } else if (bank->size != (pf_size / num_pflash_blocks)) {
577 LOG_WARNING("PFlash size mismatch");
578 reassign = 1;
579 } else if (bank->base !=
580 (0x00000000 + bank->size * kinfo->bank_ordinal)) {
581 LOG_WARNING("PFlash address range mismatch");
582 reassign = 1;
583 } else if (kinfo->sector_size !=
584 kinetis_flash_params[granularity].pflash_sector_size_bytes) {
585 LOG_WARNING("PFlash sector size mismatch");
586 reassign = 1;
587 } else {
588 LOG_DEBUG("PFlash bank %d already configured okay",
589 kinfo->bank_ordinal);
590 }
591 break;
592 case FC_FLEX_NVM:
593 if ((kinfo->bank_ordinal >= num_blocks) ||
594 (kinfo->bank_ordinal < first_nvm_bank)) {
595 LOG_WARNING("Class mismatch, bank %d is not FlexNVM",
596 bank->bank_number);
597 reassign = 1;
598 } else if (bank->size != (nvm_size / num_nvm_blocks)) {
599 LOG_WARNING("FlexNVM size mismatch");
600 reassign = 1;
601 } else if (bank->base !=
602 (0x10000000 + bank->size * kinfo->bank_ordinal)) {
603 LOG_WARNING("FlexNVM address range mismatch");
604 reassign = 1;
605 } else if (kinfo->sector_size !=
606 kinetis_flash_params[granularity].nvm_sector_size_bytes) {
607 LOG_WARNING("FlexNVM sector size mismatch");
608 reassign = 1;
609 } else {
610 LOG_DEBUG("FlexNVM bank %d already configured okay",
611 kinfo->bank_ordinal);
612 }
613 break;
614 case FC_FLEX_RAM:
615 if (kinfo->bank_ordinal != num_blocks) {
616 LOG_WARNING("Class mismatch, bank %d is not FlexRAM",
617 bank->bank_number);
618 reassign = 1;
619 } else if (bank->size != ee_size) {
620 LOG_WARNING("FlexRAM size mismatch");
621 reassign = 1;
622 } else if (bank->base != 0x14000000) {
623 LOG_WARNING("FlexRAM address mismatch");
624 reassign = 1;
625 } else if (kinfo->sector_size !=
626 kinetis_flash_params[granularity].nvm_sector_size_bytes) {
627 LOG_WARNING("FlexRAM sector size mismatch");
628 reassign = 1;
629 } else {
630 LOG_DEBUG("FlexRAM bank %d already configured okay",
631 kinfo->bank_ordinal);
632 }
633 break;
634
635 default:
636 LOG_WARNING("Unknown or inconsistent flash class");
637 reassign = 1;
638 break;
639 }
640 }
641 } else {
642 LOG_INFO("Probing flash info for bank %d", bank->bank_number);
643 reassign = 1;
644 }
645
646 if (!reassign)
647 return ERROR_OK;
648
649 kinfo->granularity = granularity;
650
651 if ((unsigned)bank->bank_number < num_pflash_blocks) {
652 /* pflash, banks start at address zero */
653 kinfo->flash_class = FC_PFLASH;
654 bank->size = (pf_size / num_pflash_blocks);
655 bank->base = 0x00000000 + bank->size * bank->bank_number;
656 kinfo->sector_size = kinetis_flash_params[granularity].pflash_sector_size_bytes;
657 kinfo->protection_size = pf_size / 32;
658 } else if ((unsigned)bank->bank_number < num_blocks) {
659 /* nvm, banks start at address 0x10000000 */
660 kinfo->flash_class = FC_FLEX_NVM;
661 bank->size = (nvm_size / num_nvm_blocks);
662 bank->base = 0x10000000 + bank->size * (bank->bank_number - first_nvm_bank);
663 kinfo->sector_size = kinetis_flash_params[granularity].nvm_sector_size_bytes;
664 kinfo->protection_size = 0; /* FIXME: TODO: depends on DEPART bits, chip */
665 } else if ((unsigned)bank->bank_number == num_blocks) {
666 LOG_ERROR("FlexRAM support not yet implemented");
667 return ERROR_FLASH_OPER_UNSUPPORTED;
668 } else {
669 LOG_ERROR("Cannot determine parameters for bank %d, only %d banks on device",
670 bank->bank_number, num_blocks);
671 return ERROR_FLASH_BANK_INVALID;
672 }
673
674 if (bank->sectors) {
675 free(bank->sectors);
676 bank->sectors = NULL;
677 }
678
679 bank->num_sectors = bank->size / kinfo->sector_size;
680 assert(bank->num_sectors > 0);
681 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
682
683 for (i = 0; i < bank->num_sectors; i++) {
684 bank->sectors[i].offset = offset;
685 bank->sectors[i].size = kinfo->sector_size;
686 offset += kinfo->sector_size;
687 bank->sectors[i].is_erased = -1;
688 bank->sectors[i].is_protected = 1;
689 }
690
691 return ERROR_OK;
692 }
693
694 static int kinetis_probe(struct flash_bank *bank)
695 {
696 if (bank->target->state != TARGET_HALTED) {
697 LOG_WARNING("Cannot communicate... target not halted.");
698 return ERROR_TARGET_NOT_HALTED;
699 }
700
701 return kinetis_read_part_info(bank);
702 }
703
704 static int kinetis_auto_probe(struct flash_bank *bank)
705 {
706 struct kinetis_flash_bank *kinfo = bank->driver_priv;
707
708 if (kinfo->sim_sdid)
709 return ERROR_OK;
710
711 return kinetis_probe(bank);
712 }
713
714 static int kinetis_info(struct flash_bank *bank, char *buf, int buf_size)
715 {
716 const char *bank_class_names[] = {
717 "(ANY)", "PFlash", "FlexNVM", "FlexRAM"
718 };
719
720 struct kinetis_flash_bank *kinfo = bank->driver_priv;
721
722 (void) snprintf(buf, buf_size,
723 "%s driver for %s flash bank %s at 0x%8.8" PRIx32 "",
724 bank->driver->name, bank_class_names[kinfo->flash_class],
725 bank->name, bank->base);
726
727 return ERROR_OK;
728 }
729
730 static int kinetis_blank_check(struct flash_bank *bank)
731 {
732 struct kinetis_flash_bank *kinfo = bank->driver_priv;
733
734 if (bank->target->state != TARGET_HALTED) {
735 LOG_ERROR("Target not halted");
736 return ERROR_TARGET_NOT_HALTED;
737 }
738
739 if (kinfo->flash_class == FC_PFLASH) {
740 int result;
741 uint32_t w0 = 0, w1 = 0, w2 = 0;
742 uint8_t ftfx_fstat;
743
744 /* check if whole bank is blank */
745 w0 = (0x00 << 24) | bank->base;
746 w1 = 0; /* "normal margin" */
747
748 result = kinetis_ftfx_command(bank, w0, w1, w2, &ftfx_fstat);
749
750 if (result != ERROR_OK)
751 return result;
752
753 if (ftfx_fstat & 0x01) {
754 /* the whole bank is not erased, check sector-by-sector */
755 int i;
756 for (i = 0; i < bank->num_sectors; i++) {
757 w0 = (0x01 << 24) | (bank->base + bank->sectors[i].offset);
758 w1 = (0x100 << 16) | 0; /* normal margin */
759
760 result = kinetis_ftfx_command(bank, w0, w1, w2, &ftfx_fstat);
761
762 if (result == ERROR_OK) {
763 bank->sectors[i].is_erased = !(ftfx_fstat & 0x01);
764 } else {
765 LOG_DEBUG("Ignoring errored PFlash sector blank-check");
766 bank->sectors[i].is_erased = -1;
767 }
768 }
769 } else {
770 /* the whole bank is erased, update all sectors */
771 int i;
772 for (i = 0; i < bank->num_sectors; i++)
773 bank->sectors[i].is_erased = 1;
774 }
775 } else {
776 LOG_WARNING("kinetis_blank_check not supported yet for FlexNVM");
777 return ERROR_FLASH_OPERATION_FAILED;
778 }
779
780 return ERROR_OK;
781 }
782
783 static int kinetis_flash_read(struct flash_bank *bank,
784 uint8_t *buffer, uint32_t offset, uint32_t count)
785 {
786 LOG_WARNING("kinetis_flash_read not supported yet");
787
788 if (bank->target->state != TARGET_HALTED) {
789 LOG_ERROR("Target not halted");
790 return ERROR_TARGET_NOT_HALTED;
791 }
792
793 return ERROR_FLASH_OPERATION_FAILED;
794 }
795
796 struct flash_driver kinetis_flash = {
797 .name = "kinetis",
798 .flash_bank_command = kinetis_flash_bank_command,
799 .erase = kinetis_erase,
800 .protect = kinetis_protect,
801 .write = kinetis_write,
802 .read = kinetis_flash_read,
803 .probe = kinetis_probe,
804 .auto_probe = kinetis_auto_probe,
805 .erase_check = kinetis_blank_check,
806 .protect_check = kinetis_protect_check,
807 .info = kinetis_info,
808 };

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)