Kinetis: Symbolic names for Addresses and Commands
[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 /* Addressess */
99 #define FLEXRAM 0x14000000
100 #define FTFx_FSTAT 0x40020000
101 #define FTFx_FCNFG 0x40020001
102 #define FTFx_FCCOB3 0x40020004
103 #define FTFx_FPROT3 0x40020010
104 #define SIM_SDID 0x40048024
105 #define SIM_FCFG1 0x4004804c
106 #define SIM_FCFG2 0x40048050
107
108 /* Commands */
109 #define FTFx_CMD_BLOCKSTAT 0x00
110 #define FTFx_CMD_SECTSTAT 0x01
111 #define FTFx_CMD_LWORDPROG 0x06
112 #define FTFx_CMD_SECTERASE 0x09
113 #define FTFx_CMD_SECTWRITE 0x0b
114 #define FTFx_CMD_SETFLEXRAM 0x81
115
116 struct kinetis_flash_bank {
117 unsigned granularity;
118 unsigned bank_ordinal;
119 uint32_t sector_size;
120 uint32_t protection_size;
121
122 uint32_t sim_sdid;
123 uint32_t sim_fcfg1;
124 uint32_t sim_fcfg2;
125
126 enum {
127 FC_AUTO = 0,
128 FC_PFLASH,
129 FC_FLEX_NVM,
130 FC_FLEX_RAM,
131 } flash_class;
132 };
133
134 FLASH_BANK_COMMAND_HANDLER(kinetis_flash_bank_command)
135 {
136 struct kinetis_flash_bank *bank_info;
137
138 if (CMD_ARGC < 6)
139 return ERROR_COMMAND_SYNTAX_ERROR;
140
141 LOG_INFO("add flash_bank kinetis %s", bank->name);
142
143 bank_info = malloc(sizeof(struct kinetis_flash_bank));
144
145 memset(bank_info, 0, sizeof(struct kinetis_flash_bank));
146
147 bank->driver_priv = bank_info;
148
149 return ERROR_OK;
150 }
151
152 static int kinetis_protect(struct flash_bank *bank, int set, int first,
153 int last)
154 {
155 LOG_WARNING("kinetis_protect not supported yet");
156 /* FIXME: TODO */
157
158 if (bank->target->state != TARGET_HALTED) {
159 LOG_ERROR("Target not halted");
160 return ERROR_TARGET_NOT_HALTED;
161 }
162
163 return ERROR_FLASH_BANK_INVALID;
164 }
165
166 static int kinetis_protect_check(struct flash_bank *bank)
167 {
168 struct kinetis_flash_bank *kinfo = bank->driver_priv;
169
170 if (bank->target->state != TARGET_HALTED) {
171 LOG_ERROR("Target not halted");
172 return ERROR_TARGET_NOT_HALTED;
173 }
174
175 if (kinfo->flash_class == FC_PFLASH) {
176 int result;
177 uint8_t buffer[4];
178 uint32_t fprot, psec;
179 int i, b;
180
181 /* read protection register */
182 result = target_read_memory(bank->target, FTFx_FPROT3, 1, 4, buffer);
183
184 if (result != ERROR_OK)
185 return result;
186
187 fprot = target_buffer_get_u32(bank->target, buffer);
188
189 /*
190 * Every bit protects 1/32 of the full flash (not necessarily
191 * just this bank), but we enforce the bank ordinals for
192 * PFlash to start at zero.
193 */
194 b = kinfo->bank_ordinal * (bank->size / kinfo->protection_size);
195 for (psec = 0, i = 0; i < bank->num_sectors; i++) {
196 if ((fprot >> b) & 1)
197 bank->sectors[i].is_protected = 0;
198 else
199 bank->sectors[i].is_protected = 1;
200
201 psec += bank->sectors[i].size;
202
203 if (psec >= kinfo->protection_size) {
204 psec = 0;
205 b++;
206 }
207 }
208 } else {
209 LOG_ERROR("Protection checks for FlexNVM not yet supported");
210 return ERROR_FLASH_BANK_INVALID;
211 }
212
213 return ERROR_OK;
214 }
215
216 static int kinetis_ftfx_command(struct flash_bank *bank, uint32_t w0,
217 uint32_t w1, uint32_t w2, uint8_t *ftfx_fstat)
218 {
219 uint8_t buffer[12];
220 int result, i;
221
222 /* wait for done */
223 for (i = 0; i < 50; i++) {
224 result =
225 target_read_memory(bank->target, FTFx_FSTAT, 1, 1, buffer);
226
227 if (result != ERROR_OK)
228 return result;
229
230 if (buffer[0] & 0x80)
231 break;
232
233 buffer[0] = 0x00;
234 }
235
236 if (buffer[0] != 0x80) {
237 /* reset error flags */
238 buffer[0] = 0x30;
239 result =
240 target_write_memory(bank->target, FTFx_FSTAT, 1, 1, buffer);
241 if (result != ERROR_OK)
242 return result;
243 }
244
245 target_buffer_set_u32(bank->target, buffer, w0);
246 target_buffer_set_u32(bank->target, buffer + 4, w1);
247 target_buffer_set_u32(bank->target, buffer + 8, w2);
248
249 result = target_write_memory(bank->target, FTFx_FCCOB3, 4, 3, buffer);
250
251 if (result != ERROR_OK)
252 return result;
253
254 /* start command */
255 buffer[0] = 0x80;
256 result = target_write_memory(bank->target, FTFx_FSTAT, 1, 1, buffer);
257 if (result != ERROR_OK)
258 return result;
259
260 /* wait for done */
261 for (i = 0; i < 50; i++) {
262 result =
263 target_read_memory(bank->target, FTFx_FSTAT, 1, 1, ftfx_fstat);
264
265 if (result != ERROR_OK)
266 return result;
267
268 if (*ftfx_fstat & 0x80)
269 break;
270 }
271
272 if ((*ftfx_fstat & 0xf0) != 0x80) {
273 LOG_ERROR
274 ("ftfx command failed FSTAT: %02X W0: %08X W1: %08X W2: %08X",
275 *ftfx_fstat, w0, w1, w2);
276
277 return ERROR_FLASH_OPERATION_FAILED;
278 }
279
280 return ERROR_OK;
281 }
282
283 static int kinetis_erase(struct flash_bank *bank, int first, int last)
284 {
285 int result, i;
286 uint32_t w0 = 0, w1 = 0, w2 = 0;
287
288 if (bank->target->state != TARGET_HALTED) {
289 LOG_ERROR("Target not halted");
290 return ERROR_TARGET_NOT_HALTED;
291 }
292
293 if ((first > bank->num_sectors) || (last > bank->num_sectors))
294 return ERROR_FLASH_OPERATION_FAILED;
295
296 /*
297 * FIXME: TODO: use the 'Erase Flash Block' command if the
298 * requested erase is PFlash or NVM and encompasses the entire
299 * block. Should be quicker.
300 */
301 for (i = first; i <= last; i++) {
302 uint8_t ftfx_fstat;
303 /* set command and sector address */
304 w0 = (FTFx_CMD_SECTERASE << 24) | (bank->base + bank->sectors[i].offset);
305
306 result = kinetis_ftfx_command(bank, w0, w1, w2, &ftfx_fstat);
307
308 if (result != ERROR_OK) {
309 LOG_WARNING("erase sector %d failed", i);
310 return ERROR_FLASH_OPERATION_FAILED;
311 }
312
313 bank->sectors[i].is_erased = 1;
314 }
315
316 if (first == 0) {
317 LOG_WARNING
318 ("flash configuration field erased, please reset the device");
319 }
320
321 return ERROR_OK;
322 }
323
324 static int kinetis_write(struct flash_bank *bank, uint8_t *buffer,
325 uint32_t offset, uint32_t count)
326 {
327 unsigned int i, result, fallback = 0;
328 uint8_t buf[8];
329 uint32_t wc, w0 = 0, w1 = 0, w2 = 0;
330 struct kinetis_flash_bank *kinfo = bank->driver_priv;
331
332 if (bank->target->state != TARGET_HALTED) {
333 LOG_ERROR("Target not halted");
334 return ERROR_TARGET_NOT_HALTED;
335 }
336
337 if (kinfo->flash_class == FC_FLEX_NVM) {
338 uint8_t ftfx_fstat;
339
340 LOG_DEBUG("flash write into FlexNVM @%08X", offset);
341
342 /* make flex ram available */
343 w0 = (FTFx_CMD_SETFLEXRAM << 24) | 0x00ff0000;
344
345 result = kinetis_ftfx_command(bank, w0, w1, w2, &ftfx_fstat);
346
347 if (result != ERROR_OK)
348 return ERROR_FLASH_OPERATION_FAILED;
349
350 /* check if ram ready */
351 result = target_read_memory(bank->target, FTFx_FCNFG, 1, 1, buf);
352
353 if (result != ERROR_OK)
354 return result;
355
356 if (!(buf[0] & (1 << 1))) {
357 /* fallback to longword write */
358 fallback = 1;
359
360 LOG_WARNING("ram not ready, fallback to slow longword write (FCNFG: %02X)",
361 buf[0]);
362 }
363 } else {
364 LOG_DEBUG("flash write into PFLASH @08%X", offset);
365 }
366
367
368 /* program section command */
369 if (fallback == 0) {
370 unsigned prog_section_bytes = kinfo->sector_size >> 8;
371 for (i = 0; i < count; i += kinfo->sector_size) {
372 /*
373 * The largest possible Kinetis "section" is
374 * 16 bytes. A full Kinetis sector is always
375 * 256 "section"s.
376 */
377 uint8_t residual_buffer[16];
378 uint8_t ftfx_fstat;
379 uint32_t section_count = 256;
380 uint32_t residual_wc = 0;
381
382 /*
383 * Assume the word count covers an entire
384 * sector.
385 */
386 wc = kinfo->sector_size / 4;
387
388 /*
389 * If bytes to be programmed are less than the
390 * full sector, then determine the number of
391 * full-words to program, and put together the
392 * residual buffer so that a full "section"
393 * may always be programmed.
394 */
395 if ((count - i) < kinfo->sector_size) {
396 /* number of bytes to program beyond full section */
397 unsigned residual_bc = (count-i) % prog_section_bytes;
398
399 /* number of complete words to copy directly from buffer */
400 wc = (count - i) / 4;
401
402 /* number of total sections to write, including residual */
403 section_count = DIV_ROUND_UP((count-i), prog_section_bytes);
404
405 /* any residual bytes delivers a whole residual section */
406 residual_wc = (residual_bc ? prog_section_bytes : 0)/4;
407
408 /* clear residual buffer then populate residual bytes */
409 (void) memset(residual_buffer, 0xff, prog_section_bytes);
410 (void) memcpy(residual_buffer, &buffer[i+4*wc], residual_bc);
411 }
412
413 LOG_DEBUG("write section @ %08X with length %d bytes",
414 offset + i, (count - i));
415
416 /* write data to flexram as whole-words */
417 result = target_write_memory(bank->target, FLEXRAM, 4, wc,
418 buffer + i);
419
420 if (result != ERROR_OK) {
421 LOG_ERROR("target_write_memory failed");
422 return result;
423 }
424
425 /* write the residual words to the flexram */
426 if (residual_wc) {
427 result = target_write_memory(bank->target,
428 FLEXRAM+4*wc,
429 4, residual_wc,
430 residual_buffer);
431
432 if (result != ERROR_OK) {
433 LOG_ERROR("target_write_memory failed");
434 return result;
435 }
436 }
437
438 /* execute section-write command */
439 w0 = (FTFx_CMD_SECTWRITE << 24) | (bank->base + offset + i);
440 w1 = section_count << 16;
441
442 result = kinetis_ftfx_command(bank, w0, w1, w2, &ftfx_fstat);
443
444 if (result != ERROR_OK)
445 return ERROR_FLASH_OPERATION_FAILED;
446 }
447 }
448 /* program longword command, not supported in "SF3" devices */
449 else if (kinfo->granularity != 3) {
450 for (i = 0; i < count; i += 4) {
451 uint8_t ftfx_fstat;
452
453 LOG_DEBUG("write longword @ %08X", offset + i);
454
455 w0 = (FTFx_CMD_LWORDPROG << 24) | (bank->base + offset + i);
456 if (count - i < 4) {
457 uint32_t padding = 0xffffffff;
458 memcpy(&padding, buffer + i, count - i);
459 w1 = buf_get_u32(&padding, 0, 32);
460 } else {
461 w1 = buf_get_u32(buffer + i, 0, 32);
462 }
463
464 result = kinetis_ftfx_command(bank, w0, w1, w2, &ftfx_fstat);
465
466 if (result != ERROR_OK)
467 return ERROR_FLASH_OPERATION_FAILED;
468 }
469 } else {
470 LOG_ERROR("Flash write strategy not implemented");
471 return ERROR_FLASH_OPERATION_FAILED;
472 }
473
474 return ERROR_OK;
475 }
476
477 static int kinetis_read_part_info(struct flash_bank *bank)
478 {
479 int result, i;
480 uint8_t buf[4];
481 uint32_t offset = 0;
482 uint8_t fcfg1_nvmsize, fcfg1_pfsize, fcfg1_eesize, fcfg2_pflsh;
483 uint32_t nvm_size = 0, pf_size = 0, ee_size = 0;
484 unsigned granularity, num_blocks = 0, num_pflash_blocks = 0, num_nvm_blocks = 0,
485 first_nvm_bank = 0, reassign = 0;
486 struct kinetis_flash_bank *kinfo = bank->driver_priv;
487
488 result = target_read_memory(bank->target, SIM_SDID, 1, 4, buf);
489 if (result != ERROR_OK)
490 return result;
491 kinfo->sim_sdid = target_buffer_get_u32(bank->target, buf);
492 granularity = (kinfo->sim_sdid >> 7) & 0x03;
493
494 result = target_read_memory(bank->target, SIM_FCFG1, 1, 4, buf);
495 if (result != ERROR_OK)
496 return result;
497 kinfo->sim_fcfg1 = target_buffer_get_u32(bank->target, buf);
498
499 result = target_read_memory(bank->target, SIM_FCFG2, 1, 4, buf);
500 if (result != ERROR_OK)
501 return result;
502 kinfo->sim_fcfg2 = target_buffer_get_u32(bank->target, buf);
503 fcfg2_pflsh = (kinfo->sim_fcfg2 >> 23) & 0x01;
504
505 LOG_DEBUG("SDID: %08X FCFG1: %08X FCFG2: %08X", kinfo->sim_sdid,
506 kinfo->sim_fcfg1, kinfo->sim_fcfg2);
507
508 fcfg1_nvmsize = (uint8_t)((kinfo->sim_fcfg1 >> 28) & 0x0f);
509 fcfg1_pfsize = (uint8_t)((kinfo->sim_fcfg1 >> 24) & 0x0f);
510 fcfg1_eesize = (uint8_t)((kinfo->sim_fcfg1 >> 16) & 0x0f);
511
512 /* when the PFLSH bit is set, there is no FlexNVM/FlexRAM */
513 if (!fcfg2_pflsh) {
514 switch (fcfg1_nvmsize) {
515 case 0x03:
516 case 0x07:
517 case 0x09:
518 case 0x0b:
519 nvm_size = 1 << (14 + (fcfg1_nvmsize >> 1));
520 break;
521 case 0x0f:
522 if (granularity == 3)
523 nvm_size = 512<<10;
524 else
525 nvm_size = 256<<10;
526 break;
527 default:
528 nvm_size = 0;
529 break;
530 }
531
532 switch (fcfg1_eesize) {
533 case 0x00:
534 case 0x01:
535 case 0x02:
536 case 0x03:
537 case 0x04:
538 case 0x05:
539 case 0x06:
540 case 0x07:
541 case 0x08:
542 case 0x09:
543 ee_size = (16 << (10 - fcfg1_eesize));
544 break;
545 default:
546 ee_size = 0;
547 break;
548 }
549 }
550
551 switch (fcfg1_pfsize) {
552 case 0x03:
553 case 0x05:
554 case 0x07:
555 case 0x09:
556 case 0x0b:
557 case 0x0d:
558 pf_size = 1 << (14 + (fcfg1_pfsize >> 1));
559 break;
560 case 0x0f:
561 if (granularity == 3)
562 pf_size = 1024<<10;
563 else if (fcfg2_pflsh)
564 pf_size = 512<<10;
565 else
566 pf_size = 256<<10;
567 break;
568 default:
569 pf_size = 0;
570 break;
571 }
572
573 LOG_DEBUG("FlexNVM: %d PFlash: %d FlexRAM: %d PFLSH: %d",
574 nvm_size, pf_size, ee_size, fcfg2_pflsh);
575
576 num_blocks = kinetis_flash_params[granularity].num_blocks;
577 num_pflash_blocks = num_blocks / (2 - fcfg2_pflsh);
578 first_nvm_bank = num_pflash_blocks;
579 num_nvm_blocks = num_blocks - num_pflash_blocks;
580
581 LOG_DEBUG("%d blocks total: %d PFlash, %d FlexNVM",
582 num_blocks, num_pflash_blocks, num_nvm_blocks);
583
584 /*
585 * If the flash class is already assigned, verify the
586 * parameters.
587 */
588 if (kinfo->flash_class != FC_AUTO) {
589 if (kinfo->bank_ordinal != (unsigned) bank->bank_number) {
590 LOG_WARNING("Flash ordinal/bank number mismatch");
591 reassign = 1;
592 } else if (kinfo->granularity != granularity) {
593 LOG_WARNING("Flash granularity mismatch");
594 reassign = 1;
595 } else {
596 switch (kinfo->flash_class) {
597 case FC_PFLASH:
598 if (kinfo->bank_ordinal >= first_nvm_bank) {
599 LOG_WARNING("Class mismatch, bank %d is not PFlash",
600 bank->bank_number);
601 reassign = 1;
602 } else if (bank->size != (pf_size / num_pflash_blocks)) {
603 LOG_WARNING("PFlash size mismatch");
604 reassign = 1;
605 } else if (bank->base !=
606 (0x00000000 + bank->size * kinfo->bank_ordinal)) {
607 LOG_WARNING("PFlash address range mismatch");
608 reassign = 1;
609 } else if (kinfo->sector_size !=
610 kinetis_flash_params[granularity].pflash_sector_size_bytes) {
611 LOG_WARNING("PFlash sector size mismatch");
612 reassign = 1;
613 } else {
614 LOG_DEBUG("PFlash bank %d already configured okay",
615 kinfo->bank_ordinal);
616 }
617 break;
618 case FC_FLEX_NVM:
619 if ((kinfo->bank_ordinal >= num_blocks) ||
620 (kinfo->bank_ordinal < first_nvm_bank)) {
621 LOG_WARNING("Class mismatch, bank %d is not FlexNVM",
622 bank->bank_number);
623 reassign = 1;
624 } else if (bank->size != (nvm_size / num_nvm_blocks)) {
625 LOG_WARNING("FlexNVM size mismatch");
626 reassign = 1;
627 } else if (bank->base !=
628 (0x10000000 + bank->size * kinfo->bank_ordinal)) {
629 LOG_WARNING("FlexNVM address range mismatch");
630 reassign = 1;
631 } else if (kinfo->sector_size !=
632 kinetis_flash_params[granularity].nvm_sector_size_bytes) {
633 LOG_WARNING("FlexNVM sector size mismatch");
634 reassign = 1;
635 } else {
636 LOG_DEBUG("FlexNVM bank %d already configured okay",
637 kinfo->bank_ordinal);
638 }
639 break;
640 case FC_FLEX_RAM:
641 if (kinfo->bank_ordinal != num_blocks) {
642 LOG_WARNING("Class mismatch, bank %d is not FlexRAM",
643 bank->bank_number);
644 reassign = 1;
645 } else if (bank->size != ee_size) {
646 LOG_WARNING("FlexRAM size mismatch");
647 reassign = 1;
648 } else if (bank->base != FLEXRAM) {
649 LOG_WARNING("FlexRAM address mismatch");
650 reassign = 1;
651 } else if (kinfo->sector_size !=
652 kinetis_flash_params[granularity].nvm_sector_size_bytes) {
653 LOG_WARNING("FlexRAM sector size mismatch");
654 reassign = 1;
655 } else {
656 LOG_DEBUG("FlexRAM bank %d already configured okay",
657 kinfo->bank_ordinal);
658 }
659 break;
660
661 default:
662 LOG_WARNING("Unknown or inconsistent flash class");
663 reassign = 1;
664 break;
665 }
666 }
667 } else {
668 LOG_INFO("Probing flash info for bank %d", bank->bank_number);
669 reassign = 1;
670 }
671
672 if (!reassign)
673 return ERROR_OK;
674
675 kinfo->granularity = granularity;
676
677 if ((unsigned)bank->bank_number < num_pflash_blocks) {
678 /* pflash, banks start at address zero */
679 kinfo->flash_class = FC_PFLASH;
680 bank->size = (pf_size / num_pflash_blocks);
681 bank->base = 0x00000000 + bank->size * bank->bank_number;
682 kinfo->sector_size = kinetis_flash_params[granularity].pflash_sector_size_bytes;
683 kinfo->protection_size = pf_size / 32;
684 } else if ((unsigned)bank->bank_number < num_blocks) {
685 /* nvm, banks start at address 0x10000000 */
686 kinfo->flash_class = FC_FLEX_NVM;
687 bank->size = (nvm_size / num_nvm_blocks);
688 bank->base = 0x10000000 + bank->size * (bank->bank_number - first_nvm_bank);
689 kinfo->sector_size = kinetis_flash_params[granularity].nvm_sector_size_bytes;
690 kinfo->protection_size = 0; /* FIXME: TODO: depends on DEPART bits, chip */
691 } else if ((unsigned)bank->bank_number == num_blocks) {
692 LOG_ERROR("FlexRAM support not yet implemented");
693 return ERROR_FLASH_OPER_UNSUPPORTED;
694 } else {
695 LOG_ERROR("Cannot determine parameters for bank %d, only %d banks on device",
696 bank->bank_number, num_blocks);
697 return ERROR_FLASH_BANK_INVALID;
698 }
699
700 if (bank->sectors) {
701 free(bank->sectors);
702 bank->sectors = NULL;
703 }
704
705 bank->num_sectors = bank->size / kinfo->sector_size;
706 assert(bank->num_sectors > 0);
707 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
708
709 for (i = 0; i < bank->num_sectors; i++) {
710 bank->sectors[i].offset = offset;
711 bank->sectors[i].size = kinfo->sector_size;
712 offset += kinfo->sector_size;
713 bank->sectors[i].is_erased = -1;
714 bank->sectors[i].is_protected = 1;
715 }
716
717 return ERROR_OK;
718 }
719
720 static int kinetis_probe(struct flash_bank *bank)
721 {
722 if (bank->target->state != TARGET_HALTED) {
723 LOG_WARNING("Cannot communicate... target not halted.");
724 return ERROR_TARGET_NOT_HALTED;
725 }
726
727 return kinetis_read_part_info(bank);
728 }
729
730 static int kinetis_auto_probe(struct flash_bank *bank)
731 {
732 struct kinetis_flash_bank *kinfo = bank->driver_priv;
733
734 if (kinfo->sim_sdid)
735 return ERROR_OK;
736
737 return kinetis_probe(bank);
738 }
739
740 static int kinetis_info(struct flash_bank *bank, char *buf, int buf_size)
741 {
742 const char *bank_class_names[] = {
743 "(ANY)", "PFlash", "FlexNVM", "FlexRAM"
744 };
745
746 struct kinetis_flash_bank *kinfo = bank->driver_priv;
747
748 (void) snprintf(buf, buf_size,
749 "%s driver for %s flash bank %s at 0x%8.8" PRIx32 "",
750 bank->driver->name, bank_class_names[kinfo->flash_class],
751 bank->name, bank->base);
752
753 return ERROR_OK;
754 }
755
756 static int kinetis_blank_check(struct flash_bank *bank)
757 {
758 struct kinetis_flash_bank *kinfo = bank->driver_priv;
759
760 if (bank->target->state != TARGET_HALTED) {
761 LOG_ERROR("Target not halted");
762 return ERROR_TARGET_NOT_HALTED;
763 }
764
765 if (kinfo->flash_class == FC_PFLASH) {
766 int result;
767 uint32_t w0 = 0, w1 = 0, w2 = 0;
768 uint8_t ftfx_fstat;
769
770 /* check if whole bank is blank */
771 w0 = (FTFx_CMD_BLOCKSTAT << 24) | bank->base;
772 w1 = 0; /* "normal margin" */
773
774 result = kinetis_ftfx_command(bank, w0, w1, w2, &ftfx_fstat);
775
776 if (result != ERROR_OK)
777 return result;
778
779 if (ftfx_fstat & 0x01) {
780 /* the whole bank is not erased, check sector-by-sector */
781 int i;
782 for (i = 0; i < bank->num_sectors; i++) {
783 w0 = (FTFx_CMD_SECTSTAT << 24) | (bank->base + bank->sectors[i].offset);
784 w1 = (0x100 << 16) | 0; /* normal margin */
785
786 result = kinetis_ftfx_command(bank, w0, w1, w2, &ftfx_fstat);
787
788 if (result == ERROR_OK) {
789 bank->sectors[i].is_erased = !(ftfx_fstat & 0x01);
790 } else {
791 LOG_DEBUG("Ignoring errored PFlash sector blank-check");
792 bank->sectors[i].is_erased = -1;
793 }
794 }
795 } else {
796 /* the whole bank is erased, update all sectors */
797 int i;
798 for (i = 0; i < bank->num_sectors; i++)
799 bank->sectors[i].is_erased = 1;
800 }
801 } else {
802 LOG_WARNING("kinetis_blank_check not supported yet for FlexNVM");
803 return ERROR_FLASH_OPERATION_FAILED;
804 }
805
806 return ERROR_OK;
807 }
808
809 static int kinetis_flash_read(struct flash_bank *bank,
810 uint8_t *buffer, uint32_t offset, uint32_t count)
811 {
812 LOG_WARNING("kinetis_flash_read not supported yet");
813
814 if (bank->target->state != TARGET_HALTED) {
815 LOG_ERROR("Target not halted");
816 return ERROR_TARGET_NOT_HALTED;
817 }
818
819 return ERROR_FLASH_OPERATION_FAILED;
820 }
821
822 struct flash_driver kinetis_flash = {
823 .name = "kinetis",
824 .flash_bank_command = kinetis_flash_bank_command,
825 .erase = kinetis_erase,
826 .protect = kinetis_protect,
827 .write = kinetis_write,
828 .read = kinetis_flash_read,
829 .probe = kinetis_probe,
830 .auto_probe = kinetis_auto_probe,
831 .erase_check = kinetis_blank_check,
832 .protect_check = kinetis_protect_check,
833 .info = kinetis_info,
834 };

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)