433d91e9e0c909475194a9a62906055007a45bbb
[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 if (count - i < 4) {
439 uint32_t padding = 0xffffffff;
440 memcpy(&padding, buffer + i, count - i);
441 w1 = buf_get_u32(&padding, 0, 32);
442 } else {
443 w1 = buf_get_u32(buffer + i, 0, 32);
444 }
445
446 result = kinetis_ftfx_command(bank, w0, w1, w2, &ftfx_fstat);
447
448 if (result != ERROR_OK)
449 return ERROR_FLASH_OPERATION_FAILED;
450 }
451 } else {
452 LOG_ERROR("Flash write strategy not implemented");
453 return ERROR_FLASH_OPERATION_FAILED;
454 }
455
456 return ERROR_OK;
457 }
458
459 static int kinetis_read_part_info(struct flash_bank *bank)
460 {
461 int result, i;
462 uint8_t buf[4];
463 uint32_t offset = 0;
464 uint8_t fcfg1_nvmsize, fcfg1_pfsize, fcfg1_eesize, fcfg2_pflsh;
465 uint32_t nvm_size = 0, pf_size = 0, ee_size = 0;
466 unsigned granularity, num_blocks = 0, num_pflash_blocks = 0, num_nvm_blocks = 0,
467 first_nvm_bank = 0, reassign = 0;
468 struct kinetis_flash_bank *kinfo = bank->driver_priv;
469
470 result = target_read_memory(bank->target, 0x40048024, 1, 4, buf);
471 if (result != ERROR_OK)
472 return result;
473 kinfo->sim_sdid = target_buffer_get_u32(bank->target, buf);
474 granularity = (kinfo->sim_sdid >> 7) & 0x03;
475 result = target_read_memory(bank->target, 0x4004804c, 1, 4, buf);
476 if (result != ERROR_OK)
477 return result;
478 kinfo->sim_fcfg1 = target_buffer_get_u32(bank->target, buf);
479 result = target_read_memory(bank->target, 0x40048050, 1, 4, buf);
480 if (result != ERROR_OK)
481 return result;
482 kinfo->sim_fcfg2 = target_buffer_get_u32(bank->target, buf);
483 fcfg2_pflsh = (kinfo->sim_fcfg2 >> 23) & 0x01;
484
485 LOG_DEBUG("SDID: %08X FCFG1: %08X FCFG2: %08X", kinfo->sim_sdid,
486 kinfo->sim_fcfg1, kinfo->sim_fcfg2);
487
488 fcfg1_nvmsize = (uint8_t)((kinfo->sim_fcfg1 >> 28) & 0x0f);
489 fcfg1_pfsize = (uint8_t)((kinfo->sim_fcfg1 >> 24) & 0x0f);
490 fcfg1_eesize = (uint8_t)((kinfo->sim_fcfg1 >> 16) & 0x0f);
491
492 /* when the PFLSH bit is set, there is no FlexNVM/FlexRAM */
493 if (!fcfg2_pflsh) {
494 switch (fcfg1_nvmsize) {
495 case 0x03:
496 case 0x07:
497 case 0x09:
498 case 0x0b:
499 nvm_size = 1 << (14 + (fcfg1_nvmsize >> 1));
500 break;
501 case 0x0f:
502 if (granularity == 3)
503 nvm_size = 512<<10;
504 else
505 nvm_size = 256<<10;
506 break;
507 default:
508 nvm_size = 0;
509 break;
510 }
511
512 switch (fcfg1_eesize) {
513 case 0x00:
514 case 0x01:
515 case 0x02:
516 case 0x03:
517 case 0x04:
518 case 0x05:
519 case 0x06:
520 case 0x07:
521 case 0x08:
522 case 0x09:
523 ee_size = (16 << (10 - fcfg1_eesize));
524 break;
525 default:
526 ee_size = 0;
527 break;
528 }
529 }
530
531 switch (fcfg1_pfsize) {
532 case 0x03:
533 case 0x05:
534 case 0x07:
535 case 0x09:
536 case 0x0b:
537 case 0x0d:
538 pf_size = 1 << (14 + (fcfg1_pfsize >> 1));
539 break;
540 case 0x0f:
541 if (granularity == 3)
542 pf_size = 1024<<10;
543 else if (fcfg2_pflsh)
544 pf_size = 512<<10;
545 else
546 pf_size = 256<<10;
547 break;
548 default:
549 pf_size = 0;
550 break;
551 }
552
553 LOG_DEBUG("FlexNVM: %d PFlash: %d FlexRAM: %d PFLSH: %d",
554 nvm_size, pf_size, ee_size, fcfg2_pflsh);
555
556 num_blocks = kinetis_flash_params[granularity].num_blocks;
557 num_pflash_blocks = num_blocks / (2 - fcfg2_pflsh);
558 first_nvm_bank = num_pflash_blocks;
559 num_nvm_blocks = num_blocks - num_pflash_blocks;
560
561 LOG_DEBUG("%d blocks total: %d PFlash, %d FlexNVM",
562 num_blocks, num_pflash_blocks, num_nvm_blocks);
563
564 /*
565 * If the flash class is already assigned, verify the
566 * parameters.
567 */
568 if (kinfo->flash_class != FC_AUTO) {
569 if (kinfo->bank_ordinal != (unsigned) bank->bank_number) {
570 LOG_WARNING("Flash ordinal/bank number mismatch");
571 reassign = 1;
572 } else if (kinfo->granularity != granularity) {
573 LOG_WARNING("Flash granularity mismatch");
574 reassign = 1;
575 } else {
576 switch (kinfo->flash_class) {
577 case FC_PFLASH:
578 if (kinfo->bank_ordinal >= first_nvm_bank) {
579 LOG_WARNING("Class mismatch, bank %d is not PFlash",
580 bank->bank_number);
581 reassign = 1;
582 } else if (bank->size != (pf_size / num_pflash_blocks)) {
583 LOG_WARNING("PFlash size mismatch");
584 reassign = 1;
585 } else if (bank->base !=
586 (0x00000000 + bank->size * kinfo->bank_ordinal)) {
587 LOG_WARNING("PFlash address range mismatch");
588 reassign = 1;
589 } else if (kinfo->sector_size !=
590 kinetis_flash_params[granularity].pflash_sector_size_bytes) {
591 LOG_WARNING("PFlash sector size mismatch");
592 reassign = 1;
593 } else {
594 LOG_DEBUG("PFlash bank %d already configured okay",
595 kinfo->bank_ordinal);
596 }
597 break;
598 case FC_FLEX_NVM:
599 if ((kinfo->bank_ordinal >= num_blocks) ||
600 (kinfo->bank_ordinal < first_nvm_bank)) {
601 LOG_WARNING("Class mismatch, bank %d is not FlexNVM",
602 bank->bank_number);
603 reassign = 1;
604 } else if (bank->size != (nvm_size / num_nvm_blocks)) {
605 LOG_WARNING("FlexNVM size mismatch");
606 reassign = 1;
607 } else if (bank->base !=
608 (0x10000000 + bank->size * kinfo->bank_ordinal)) {
609 LOG_WARNING("FlexNVM address range mismatch");
610 reassign = 1;
611 } else if (kinfo->sector_size !=
612 kinetis_flash_params[granularity].nvm_sector_size_bytes) {
613 LOG_WARNING("FlexNVM sector size mismatch");
614 reassign = 1;
615 } else {
616 LOG_DEBUG("FlexNVM bank %d already configured okay",
617 kinfo->bank_ordinal);
618 }
619 break;
620 case FC_FLEX_RAM:
621 if (kinfo->bank_ordinal != num_blocks) {
622 LOG_WARNING("Class mismatch, bank %d is not FlexRAM",
623 bank->bank_number);
624 reassign = 1;
625 } else if (bank->size != ee_size) {
626 LOG_WARNING("FlexRAM size mismatch");
627 reassign = 1;
628 } else if (bank->base != 0x14000000) {
629 LOG_WARNING("FlexRAM address mismatch");
630 reassign = 1;
631 } else if (kinfo->sector_size !=
632 kinetis_flash_params[granularity].nvm_sector_size_bytes) {
633 LOG_WARNING("FlexRAM sector size mismatch");
634 reassign = 1;
635 } else {
636 LOG_DEBUG("FlexRAM bank %d already configured okay",
637 kinfo->bank_ordinal);
638 }
639 break;
640
641 default:
642 LOG_WARNING("Unknown or inconsistent flash class");
643 reassign = 1;
644 break;
645 }
646 }
647 } else {
648 LOG_INFO("Probing flash info for bank %d", bank->bank_number);
649 reassign = 1;
650 }
651
652 if (!reassign)
653 return ERROR_OK;
654
655 kinfo->granularity = granularity;
656
657 if ((unsigned)bank->bank_number < num_pflash_blocks) {
658 /* pflash, banks start at address zero */
659 kinfo->flash_class = FC_PFLASH;
660 bank->size = (pf_size / num_pflash_blocks);
661 bank->base = 0x00000000 + bank->size * bank->bank_number;
662 kinfo->sector_size = kinetis_flash_params[granularity].pflash_sector_size_bytes;
663 kinfo->protection_size = pf_size / 32;
664 } else if ((unsigned)bank->bank_number < num_blocks) {
665 /* nvm, banks start at address 0x10000000 */
666 kinfo->flash_class = FC_FLEX_NVM;
667 bank->size = (nvm_size / num_nvm_blocks);
668 bank->base = 0x10000000 + bank->size * (bank->bank_number - first_nvm_bank);
669 kinfo->sector_size = kinetis_flash_params[granularity].nvm_sector_size_bytes;
670 kinfo->protection_size = 0; /* FIXME: TODO: depends on DEPART bits, chip */
671 } else if ((unsigned)bank->bank_number == num_blocks) {
672 LOG_ERROR("FlexRAM support not yet implemented");
673 return ERROR_FLASH_OPER_UNSUPPORTED;
674 } else {
675 LOG_ERROR("Cannot determine parameters for bank %d, only %d banks on device",
676 bank->bank_number, num_blocks);
677 return ERROR_FLASH_BANK_INVALID;
678 }
679
680 if (bank->sectors) {
681 free(bank->sectors);
682 bank->sectors = NULL;
683 }
684
685 bank->num_sectors = bank->size / kinfo->sector_size;
686 assert(bank->num_sectors > 0);
687 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
688
689 for (i = 0; i < bank->num_sectors; i++) {
690 bank->sectors[i].offset = offset;
691 bank->sectors[i].size = kinfo->sector_size;
692 offset += kinfo->sector_size;
693 bank->sectors[i].is_erased = -1;
694 bank->sectors[i].is_protected = 1;
695 }
696
697 return ERROR_OK;
698 }
699
700 static int kinetis_probe(struct flash_bank *bank)
701 {
702 if (bank->target->state != TARGET_HALTED) {
703 LOG_WARNING("Cannot communicate... target not halted.");
704 return ERROR_TARGET_NOT_HALTED;
705 }
706
707 return kinetis_read_part_info(bank);
708 }
709
710 static int kinetis_auto_probe(struct flash_bank *bank)
711 {
712 struct kinetis_flash_bank *kinfo = bank->driver_priv;
713
714 if (kinfo->sim_sdid)
715 return ERROR_OK;
716
717 return kinetis_probe(bank);
718 }
719
720 static int kinetis_info(struct flash_bank *bank, char *buf, int buf_size)
721 {
722 const char *bank_class_names[] = {
723 "(ANY)", "PFlash", "FlexNVM", "FlexRAM"
724 };
725
726 struct kinetis_flash_bank *kinfo = bank->driver_priv;
727
728 (void) snprintf(buf, buf_size,
729 "%s driver for %s flash bank %s at 0x%8.8" PRIx32 "",
730 bank->driver->name, bank_class_names[kinfo->flash_class],
731 bank->name, bank->base);
732
733 return ERROR_OK;
734 }
735
736 static int kinetis_blank_check(struct flash_bank *bank)
737 {
738 struct kinetis_flash_bank *kinfo = bank->driver_priv;
739
740 if (bank->target->state != TARGET_HALTED) {
741 LOG_ERROR("Target not halted");
742 return ERROR_TARGET_NOT_HALTED;
743 }
744
745 if (kinfo->flash_class == FC_PFLASH) {
746 int result;
747 uint32_t w0 = 0, w1 = 0, w2 = 0;
748 uint8_t ftfx_fstat;
749
750 /* check if whole bank is blank */
751 w0 = (0x00 << 24) | bank->base;
752 w1 = 0; /* "normal margin" */
753
754 result = kinetis_ftfx_command(bank, w0, w1, w2, &ftfx_fstat);
755
756 if (result != ERROR_OK)
757 return result;
758
759 if (ftfx_fstat & 0x01) {
760 /* the whole bank is not erased, check sector-by-sector */
761 int i;
762 for (i = 0; i < bank->num_sectors; i++) {
763 w0 = (0x01 << 24) | (bank->base + bank->sectors[i].offset);
764 w1 = (0x100 << 16) | 0; /* normal margin */
765
766 result = kinetis_ftfx_command(bank, w0, w1, w2, &ftfx_fstat);
767
768 if (result == ERROR_OK) {
769 bank->sectors[i].is_erased = !(ftfx_fstat & 0x01);
770 } else {
771 LOG_DEBUG("Ignoring errored PFlash sector blank-check");
772 bank->sectors[i].is_erased = -1;
773 }
774 }
775 } else {
776 /* the whole bank is erased, update all sectors */
777 int i;
778 for (i = 0; i < bank->num_sectors; i++)
779 bank->sectors[i].is_erased = 1;
780 }
781 } else {
782 LOG_WARNING("kinetis_blank_check not supported yet for FlexNVM");
783 return ERROR_FLASH_OPERATION_FAILED;
784 }
785
786 return ERROR_OK;
787 }
788
789 static int kinetis_flash_read(struct flash_bank *bank,
790 uint8_t *buffer, uint32_t offset, uint32_t count)
791 {
792 LOG_WARNING("kinetis_flash_read not supported yet");
793
794 if (bank->target->state != TARGET_HALTED) {
795 LOG_ERROR("Target not halted");
796 return ERROR_TARGET_NOT_HALTED;
797 }
798
799 return ERROR_FLASH_OPERATION_FAILED;
800 }
801
802 struct flash_driver kinetis_flash = {
803 .name = "kinetis",
804 .flash_bank_command = kinetis_flash_bank_command,
805 .erase = kinetis_erase,
806 .protect = kinetis_protect,
807 .write = kinetis_write,
808 .read = kinetis_flash_read,
809 .probe = kinetis_probe,
810 .auto_probe = kinetis_auto_probe,
811 .erase_check = kinetis_blank_check,
812 .protect_check = kinetis_protect_check,
813 .info = kinetis_info,
814 };

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)