1 /***************************************************************************
2 * Copyright (C) 2011 by Mathias Kuester *
5 * Copyright (C) 2011 sleep(5) ltd *
6 * tomas@sleepfive.com *
8 * Copyright (C) 2012 by Christopher D. Kilgour *
9 * techie at whiterocker.com *
11 * Copyright (C) 2013 Nemui Trinomius *
12 * nemuisan_kawausogasuki@live.jp *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program; if not, write to the *
26 * Free Software Foundation, Inc., *
27 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
28 ***************************************************************************/
35 #include <helper/binarybuffer.h>
36 #include <target/algorithm.h>
37 #include <target/armv7m.h>
40 * Implementation Notes
42 * The persistent memories in the Kinetis chip families K10 through
43 * K70 are all manipulated with the Flash Memory Module. Some
44 * variants call this module the FTFE, others call it the FTFL. To
45 * indicate that both are considered here, we use FTFX.
47 * Within the module, according to the chip variant, the persistent
48 * memory is divided into what Freescale terms Program Flash, FlexNVM,
49 * and FlexRAM. All chip variants have Program Flash. Some chip
50 * variants also have FlexNVM and FlexRAM, which always appear
53 * A given Kinetis chip may have 2 or 4 blocks of flash. Here we map
54 * each block to a separate bank. Each block size varies by chip and
55 * may be determined by the read-only SIM_FCFG1 register. The sector
56 * size within each bank/block varies by the chip granularity as
59 * Kinetis offers four different of flash granularities applicable
60 * across the chip families. The granularity is apparently reflected
61 * by at least the reference manual suffix. For example, for chip
62 * MK60FN1M0VLQ12, reference manual K60P144M150SF3RM ends in "SF3RM",
63 * where the "3" indicates there are four flash blocks with 4kiB
64 * sectors. All possible granularities are indicated below.
66 * The first half of the flash (1 or 2 blocks, depending on the
67 * granularity) is always Program Flash and always starts at address
68 * 0x00000000. The "PFLSH" flag, bit 23 of the read-only SIM_FCFG2
69 * register, determines whether the second half of the flash is also
70 * Program Flash or FlexNVM+FlexRAM. When PFLSH is set, the second
71 * half of flash is Program Flash and is contiguous in the memory map
72 * from the first half. When PFLSH is clear, the second half of flash
73 * is FlexNVM and always starts at address 0x10000000. FlexRAM, which
74 * is also present when PFLSH is clear, always starts at address
77 * The Flash Memory Module provides a register set where flash
78 * commands are loaded to perform flash operations like erase and
79 * program. Different commands are available depending on whether
80 * Program Flash or FlexNVM/FlexRAM is being manipulated. Although
81 * the commands used are quite consistent between flash blocks, the
82 * parameters they accept differ according to the flash granularity.
83 * Some Kinetis chips have different granularity between Program Flash
84 * and FlexNVM/FlexRAM, so flash command arguments may differ between
85 * blocks in the same chip.
87 * Although not documented as such by Freescale, it appears that bits
88 * 8:7 of the read-only SIM_SDID register reflect the granularity
89 * settings 0..3, so sector sizes and block counts are applicable
90 * according to the following table.
94 unsigned pflash_sector_size_bytes
;
95 unsigned nvm_sector_size_bytes
;
97 } kinetis_flash_params
[4] = {
105 #define FLEXRAM 0x14000000
106 #define FTFx_FSTAT 0x40020000
107 #define FTFx_FCNFG 0x40020001
108 #define FTFx_FCCOB3 0x40020004
109 #define FTFx_FPROT3 0x40020010
110 #define SIM_SDID 0x40048024
111 #define SIM_FCFG1 0x4004804c
112 #define SIM_FCFG2 0x40048050
115 #define FTFx_CMD_BLOCKSTAT 0x00
116 #define FTFx_CMD_SECTSTAT 0x01
117 #define FTFx_CMD_LWORDPROG 0x06
118 #define FTFx_CMD_SECTERASE 0x09
119 #define FTFx_CMD_SECTWRITE 0x0b
120 #define FTFx_CMD_SETFLEXRAM 0x81
121 #define FTFx_CMD_MASSERASE 0x44
123 struct kinetis_flash_bank
{
124 unsigned granularity
;
125 unsigned bank_ordinal
;
126 uint32_t sector_size
;
127 uint32_t protection_size
;
142 FLASH_BANK_COMMAND_HANDLER(kinetis_flash_bank_command
)
144 struct kinetis_flash_bank
*bank_info
;
147 return ERROR_COMMAND_SYNTAX_ERROR
;
149 LOG_INFO("add flash_bank kinetis %s", bank
->name
);
151 bank_info
= malloc(sizeof(struct kinetis_flash_bank
));
153 memset(bank_info
, 0, sizeof(struct kinetis_flash_bank
));
155 bank
->driver_priv
= bank_info
;
160 /* Kinetis Program-LongWord Microcodes */
161 static const uint8_t kinetis_flash_write_code
[] = {
163 * r0 - workarea buffer
164 * r1 - target address
174 /* for(register uint32_t i=0;i<wcount;i++){ */
175 0x04, 0x1C, /* mov r4, r0 */
176 0x00, 0x23, /* mov r3, #0 */
178 0x0E, 0x1A, /* sub r6, r1, r0 */
179 0xA6, 0x19, /* add r6, r4, r6 */
180 0x93, 0x42, /* cmp r3, r2 */
181 0x16, 0xD0, /* beq .L9 */
183 /* while((FTFx_FSTAT&FTFA_FSTAT_CCIF_MASK) != FTFA_FSTAT_CCIF_MASK){}; */
184 0x0B, 0x4D, /* ldr r5, .L10 */
185 0x2F, 0x78, /* ldrb r7, [r5] */
186 0x7F, 0xB2, /* sxtb r7, r7 */
187 0x00, 0x2F, /* cmp r7, #0 */
188 0xFA, 0xDA, /* bge .L5 */
189 /* FTFx_FSTAT = FTFA_FSTAT_ACCERR_MASK|FTFA_FSTAT_FPVIOL_MASK|FTFA_FSTAT_RDCO */
190 0x70, 0x27, /* mov r7, #112 */
191 0x2F, 0x70, /* strb r7, [r5] */
192 /* FTFx_FCCOB3 = faddr; */
193 0x09, 0x4F, /* ldr r7, .L10+4 */
194 0x3E, 0x60, /* str r6, [r7] */
195 0x06, 0x27, /* mov r7, #6 */
196 /* FTFx_FCCOB0 = 0x06; */
197 0x08, 0x4E, /* ldr r6, .L10+8 */
198 0x37, 0x70, /* strb r7, [r6] */
199 /* FTFx_FCCOB7 = *pLW; */
200 0x80, 0xCC, /* ldmia r4!, {r7} */
201 0x08, 0x4E, /* ldr r6, .L10+12 */
202 0x37, 0x60, /* str r7, [r6] */
203 /* FTFx_FSTAT = FTFA_FSTAT_CCIF_MASK; */
204 0x80, 0x27, /* mov r7, #128 */
205 0x2F, 0x70, /* strb r7, [r5] */
207 /* while((FTFx_FSTAT&FTFA_FSTAT_CCIF_MASK) != FTFA_FSTAT_CCIF_MASK){}; */
208 0x2E, 0x78, /* ldrb r6, [r5] */
209 0x77, 0xB2, /* sxtb r7, r6 */
210 0x00, 0x2F, /* cmp r7, #0 */
211 0xFB, 0xDA, /* bge .L4 */
212 0x01, 0x33, /* add r3, r3, #1 */
213 0xE4, 0xE7, /* b .L2 */
215 0x00, 0xBE, /* bkpt #0 */
217 0x00, 0x00, 0x02, 0x40, /* .word 1073872896 */
218 0x04, 0x00, 0x02, 0x40, /* .word 1073872900 */
219 0x07, 0x00, 0x02, 0x40, /* .word 1073872903 */
220 0x08, 0x00, 0x02, 0x40, /* .word 1073872904 */
223 /* Program LongWord Block Write */
224 static int kinetis_write_block(struct flash_bank
*bank
, uint8_t *buffer
,
225 uint32_t offset
, uint32_t wcount
)
227 struct target
*target
= bank
->target
;
228 uint32_t buffer_size
= 2048; /* Default minimum value */
229 struct working_area
*write_algorithm
;
230 struct working_area
*source
;
231 uint32_t address
= bank
->base
+ offset
;
232 struct reg_param reg_params
[3];
233 struct armv7m_algorithm armv7m_info
;
234 int retval
= ERROR_OK
;
237 * r0 - workarea buffer
238 * r1 - target address
247 /* Increase buffer_size if needed */
248 if (buffer_size
< (target
->working_area_size
/2))
249 buffer_size
= (target
->working_area_size
/2);
251 LOG_INFO("Kinetis: FLASH Write ...");
253 /* check code alignment */
255 LOG_WARNING("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
256 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
259 /* allocate working area with flash programming code */
260 if (target_alloc_working_area(target
, sizeof(kinetis_flash_write_code
),
261 &write_algorithm
) != ERROR_OK
) {
262 LOG_WARNING("no working area available, can't do block memory writes");
263 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
266 retval
= target_write_buffer(target
, write_algorithm
->address
,
267 sizeof(kinetis_flash_write_code
), kinetis_flash_write_code
);
268 if (retval
!= ERROR_OK
)
272 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
) {
274 if (buffer_size
<= 256) {
275 /* free working area, write algorithm already allocated */
276 target_free_working_area(target
, write_algorithm
);
278 LOG_WARNING("No large enough working area available, can't do block memory writes");
279 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
283 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
284 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
286 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
); /* *pLW (*buffer) */
287 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* faddr */
288 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* number of words to program */
290 /* write code buffer and use Flash programming code within kinetis */
291 /* Set breakpoint to 0 with time-out of 1000 ms */
293 uint32_t thisrun_count
= (wcount
> (buffer_size
/ 4)) ? (buffer_size
/ 4) : wcount
;
295 retval
= target_write_buffer(target
, write_algorithm
->address
, 8,
296 kinetis_flash_write_code
);
297 if (retval
!= ERROR_OK
)
300 retval
= target_write_buffer(target
, source
->address
, thisrun_count
* 4, buffer
);
301 if (retval
!= ERROR_OK
)
304 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
305 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
306 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
);
308 retval
= target_run_algorithm(target
, 0, NULL
, 3, reg_params
,
309 write_algorithm
->address
, 0, 100000, &armv7m_info
);
310 if (retval
!= ERROR_OK
) {
311 LOG_ERROR("Error executing kinetis Flash programming algorithm");
312 retval
= ERROR_FLASH_OPERATION_FAILED
;
316 buffer
+= thisrun_count
* 4;
317 address
+= thisrun_count
* 4;
318 wcount
-= thisrun_count
;
321 target_free_working_area(target
, source
);
322 target_free_working_area(target
, write_algorithm
);
324 destroy_reg_param(®_params
[0]);
325 destroy_reg_param(®_params
[1]);
326 destroy_reg_param(®_params
[2]);
331 static int kinetis_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
333 LOG_WARNING("kinetis_protect not supported yet");
336 if (bank
->target
->state
!= TARGET_HALTED
) {
337 LOG_ERROR("Target not halted");
338 return ERROR_TARGET_NOT_HALTED
;
341 return ERROR_FLASH_BANK_INVALID
;
344 static int kinetis_protect_check(struct flash_bank
*bank
)
346 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
348 if (bank
->target
->state
!= TARGET_HALTED
) {
349 LOG_ERROR("Target not halted");
350 return ERROR_TARGET_NOT_HALTED
;
353 if (kinfo
->flash_class
== FC_PFLASH
) {
356 uint32_t fprot
, psec
;
359 /* read protection register */
360 result
= target_read_memory(bank
->target
, FTFx_FPROT3
, 1, 4, buffer
);
362 if (result
!= ERROR_OK
)
365 fprot
= target_buffer_get_u32(bank
->target
, buffer
);
368 * Every bit protects 1/32 of the full flash (not necessarily
369 * just this bank), but we enforce the bank ordinals for
370 * PFlash to start at zero.
372 b
= kinfo
->bank_ordinal
* (bank
->size
/ kinfo
->protection_size
);
373 for (psec
= 0, i
= 0; i
< bank
->num_sectors
; i
++) {
374 if ((fprot
>> b
) & 1)
375 bank
->sectors
[i
].is_protected
= 0;
377 bank
->sectors
[i
].is_protected
= 1;
379 psec
+= bank
->sectors
[i
].size
;
381 if (psec
>= kinfo
->protection_size
) {
387 LOG_ERROR("Protection checks for FlexNVM not yet supported");
388 return ERROR_FLASH_BANK_INVALID
;
394 static int kinetis_ftfx_command(struct flash_bank
*bank
, uint8_t fcmd
, uint32_t faddr
,
395 uint8_t fccob4
, uint8_t fccob5
, uint8_t fccob6
, uint8_t fccob7
,
396 uint8_t fccob8
, uint8_t fccob9
, uint8_t fccoba
, uint8_t fccobb
,
399 uint8_t command
[12] = {faddr
& 0xff, (faddr
>> 8) & 0xff, (faddr
>> 16) & 0xff, fcmd
,
400 fccob7
, fccob6
, fccob5
, fccob4
,
401 fccobb
, fccoba
, fccob9
, fccob8
};
406 for (i
= 0; i
< 50; i
++) {
408 target_read_memory(bank
->target
, FTFx_FSTAT
, 1, 1, &buffer
);
410 if (result
!= ERROR_OK
)
419 if (buffer
!= 0x80) {
420 /* reset error flags */
423 target_write_memory(bank
->target
, FTFx_FSTAT
, 1, 1, &buffer
);
424 if (result
!= ERROR_OK
)
428 result
= target_write_memory(bank
->target
, FTFx_FCCOB3
, 4, 3, command
);
430 if (result
!= ERROR_OK
)
435 result
= target_write_memory(bank
->target
, FTFx_FSTAT
, 1, 1, &buffer
);
436 if (result
!= ERROR_OK
)
440 for (i
= 0; i
< 240; i
++) { /* Need Entire Erase Nemui Changed */
442 target_read_memory(bank
->target
, FTFx_FSTAT
, 1, 1, ftfx_fstat
);
444 if (result
!= ERROR_OK
)
447 if (*ftfx_fstat
& 0x80)
451 if ((*ftfx_fstat
& 0xf0) != 0x80) {
453 ("ftfx command failed FSTAT: %02X FCCOB: %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X",
454 *ftfx_fstat
, command
[3], command
[2], command
[1], command
[0],
455 command
[7], command
[6], command
[5], command
[4],
456 command
[11], command
[10], command
[9], command
[8]);
457 return ERROR_FLASH_OPERATION_FAILED
;
463 static int kinetis_mass_erase(struct flash_bank
*bank
)
468 if (bank
->target
->state
!= TARGET_HALTED
) {
469 LOG_ERROR("Target not halted");
470 return ERROR_TARGET_NOT_HALTED
;
473 /* check if whole bank is blank */
474 LOG_INFO("Kinetis L Series Erase All Blocks");
475 /* set command and sector address */
476 result
= kinetis_ftfx_command(bank
, FTFx_CMD_MASSERASE
, 0,
477 0, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat
);
478 /* Anyway Result, write unsecure byte */
479 /* if (result != ERROR_OK)
482 /* Write to MCU security status unsecure in Flash security byte(Work around) */
483 LOG_INFO("Write to MCU security status unsecure Anyway!");
484 uint8_t padding
[4] = {0xFE, 0xFF, 0xFF, 0xFF}; /* Write 0xFFFFFFFE */
486 result
= kinetis_ftfx_command(bank
, FTFx_CMD_LWORDPROG
, (bank
->base
+ 0x0000040C),
487 padding
[3], padding
[2], padding
[1], padding
[0],
488 0, 0, 0, 0, &ftfx_fstat
);
489 if (result
!= ERROR_OK
)
490 return ERROR_FLASH_OPERATION_FAILED
;
495 static int kinetis_erase(struct flash_bank
*bank
, int first
, int last
)
498 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
500 if (bank
->target
->state
!= TARGET_HALTED
) {
501 LOG_ERROR("Target not halted");
502 return ERROR_TARGET_NOT_HALTED
;
505 if ((first
> bank
->num_sectors
) || (last
> bank
->num_sectors
))
506 return ERROR_FLASH_OPERATION_FAILED
;
508 if ((first
== 0) && (last
== (bank
->num_sectors
- 1)) && (kinfo
->klxx
))
509 return kinetis_mass_erase(bank
);
512 * FIXME: TODO: use the 'Erase Flash Block' command if the
513 * requested erase is PFlash or NVM and encompasses the entire
514 * block. Should be quicker.
516 for (i
= first
; i
<= last
; i
++) {
518 /* set command and sector address */
519 result
= kinetis_ftfx_command(bank
, FTFx_CMD_SECTERASE
, bank
->base
+ bank
->sectors
[i
].offset
,
520 0, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat
);
522 if (result
!= ERROR_OK
) {
523 LOG_WARNING("erase sector %d failed", i
);
524 return ERROR_FLASH_OPERATION_FAILED
;
527 bank
->sectors
[i
].is_erased
= 1;
532 ("flash configuration field erased, please reset the device");
538 static int kinetis_write(struct flash_bank
*bank
, uint8_t *buffer
,
539 uint32_t offset
, uint32_t count
)
541 unsigned int i
, result
, fallback
= 0;
544 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
545 uint8_t *new_buffer
= NULL
;
547 if (bank
->target
->state
!= TARGET_HALTED
) {
548 LOG_ERROR("Target not halted");
549 return ERROR_TARGET_NOT_HALTED
;
553 /* fallback to longword write */
555 LOG_WARNING("Kinetis L Series supports Program Longword execution only.");
556 LOG_DEBUG("flash write into PFLASH @08%" PRIX32
, offset
);
558 } else if (kinfo
->flash_class
== FC_FLEX_NVM
) {
561 LOG_DEBUG("flash write into FlexNVM @%08" PRIX32
, offset
);
563 /* make flex ram available */
564 result
= kinetis_ftfx_command(bank
, FTFx_CMD_SETFLEXRAM
, 0x00ff0000, 0, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat
);
566 if (result
!= ERROR_OK
)
567 return ERROR_FLASH_OPERATION_FAILED
;
569 /* check if ram ready */
570 result
= target_read_memory(bank
->target
, FTFx_FCNFG
, 1, 1, buf
);
572 if (result
!= ERROR_OK
)
575 if (!(buf
[0] & (1 << 1))) {
576 /* fallback to longword write */
579 LOG_WARNING("ram not ready, fallback to slow longword write (FCNFG: %02X)", buf
[0]);
582 LOG_DEBUG("flash write into PFLASH @08%" PRIX32
, offset
);
586 /* program section command */
589 * Kinetis uses different terms for the granularity of
590 * sector writes, e.g. "phrase" or "128 bits". We use
591 * the generic term "chunk". The largest possible
592 * Kinetis "chunk" is 16 bytes (128 bits).
594 unsigned prog_section_chunk_bytes
= kinfo
->sector_size
>> 8;
595 /* assume the NVM sector size is half the FlexRAM size */
596 unsigned prog_size_bytes
= MIN(kinfo
->sector_size
,
597 kinetis_flash_params
[kinfo
->granularity
].nvm_sector_size_bytes
);
598 for (i
= 0; i
< count
; i
+= prog_size_bytes
) {
599 uint8_t residual_buffer
[16];
601 uint32_t section_count
= prog_size_bytes
/ prog_section_chunk_bytes
;
602 uint32_t residual_wc
= 0;
605 * Assume the word count covers an entire
608 wc
= prog_size_bytes
/ 4;
611 * If bytes to be programmed are less than the
612 * full sector, then determine the number of
613 * full-words to program, and put together the
614 * residual buffer so that a full "section"
615 * may always be programmed.
617 if ((count
- i
) < prog_size_bytes
) {
618 /* number of bytes to program beyond full section */
619 unsigned residual_bc
= (count
-i
) % prog_section_chunk_bytes
;
621 /* number of complete words to copy directly from buffer */
622 wc
= (count
- i
) / 4;
624 /* number of total sections to write, including residual */
625 section_count
= DIV_ROUND_UP((count
-i
), prog_section_chunk_bytes
);
627 /* any residual bytes delivers a whole residual section */
628 residual_wc
= (residual_bc
? prog_section_chunk_bytes
: 0)/4;
630 /* clear residual buffer then populate residual bytes */
631 (void) memset(residual_buffer
, 0xff, prog_section_chunk_bytes
);
632 (void) memcpy(residual_buffer
, &buffer
[i
+4*wc
], residual_bc
);
635 LOG_DEBUG("write section @ %08" PRIX32
" with length %" PRIu32
" bytes",
636 offset
+ i
, (uint32_t)wc
*4);
638 /* write data to flexram as whole-words */
639 result
= target_write_memory(bank
->target
, FLEXRAM
, 4, wc
,
642 if (result
!= ERROR_OK
) {
643 LOG_ERROR("target_write_memory failed");
647 /* write the residual words to the flexram */
649 result
= target_write_memory(bank
->target
,
654 if (result
!= ERROR_OK
) {
655 LOG_ERROR("target_write_memory failed");
660 /* execute section-write command */
661 result
= kinetis_ftfx_command(bank
, FTFx_CMD_SECTWRITE
, bank
->base
+ offset
+ i
,
662 section_count
>>8, section_count
, 0, 0,
663 0, 0, 0, 0, &ftfx_fstat
);
665 if (result
!= ERROR_OK
)
666 return ERROR_FLASH_OPERATION_FAILED
;
669 /* program longword command, not supported in "SF3" devices */
670 else if ((kinfo
->granularity
!= 3) || (kinfo
->klxx
)) {
673 uint32_t old_count
= count
;
674 count
= (old_count
| 3) + 1;
675 new_buffer
= malloc(count
);
676 if (new_buffer
== NULL
) {
677 LOG_ERROR("odd number of bytes to write and no memory "
678 "for padding buffer");
681 LOG_INFO("odd number of bytes to write (%" PRIu32
"), extending to %" PRIu32
" "
682 "and padding with 0xff", old_count
, count
);
683 memset(buffer
, 0xff, count
);
684 buffer
= memcpy(new_buffer
, buffer
, old_count
);
687 uint32_t words_remaining
= count
/ 4;
689 /* try using a block write */
690 int retval
= kinetis_write_block(bank
, buffer
, offset
, words_remaining
);
692 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
) {
693 /* if block write failed (no sufficient working area),
694 * we use normal (slow) single word accesses */
695 LOG_WARNING("couldn't use block writes, falling back to single "
698 for (i
= 0; i
< count
; i
+= 4) {
701 LOG_DEBUG("write longword @ %08" PRIX32
, (uint32_t)(offset
+ i
));
703 uint8_t padding
[4] = {0xff, 0xff, 0xff, 0xff};
704 memcpy(padding
, buffer
+ i
, MIN(4, count
-i
));
706 result
= kinetis_ftfx_command(bank
, FTFx_CMD_LWORDPROG
, bank
->base
+ offset
+ i
,
707 padding
[3], padding
[2], padding
[1], padding
[0],
708 0, 0, 0, 0, &ftfx_fstat
);
710 if (result
!= ERROR_OK
)
711 return ERROR_FLASH_OPERATION_FAILED
;
716 LOG_ERROR("Flash write strategy not implemented");
717 return ERROR_FLASH_OPERATION_FAILED
;
723 static int kinetis_read_part_info(struct flash_bank
*bank
)
727 uint8_t fcfg1_nvmsize
, fcfg1_pfsize
, fcfg1_eesize
, fcfg2_pflsh
;
728 uint32_t nvm_size
= 0, pf_size
= 0, ee_size
= 0;
729 unsigned granularity
, num_blocks
= 0, num_pflash_blocks
= 0, num_nvm_blocks
= 0,
730 first_nvm_bank
= 0, reassign
= 0;
731 struct target
*target
= bank
->target
;
732 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
734 result
= target_read_u32(target
, SIM_SDID
, &kinfo
->sim_sdid
);
735 if (result
!= ERROR_OK
)
738 /* Kinetis L Series SubFamily Check */
740 i
= (kinfo
->sim_sdid
>> 20) & 0x0F;
745 granularity
= (kinfo
->sim_sdid
>> 7) & 0x03;
747 result
= target_read_u32(target
, SIM_FCFG1
, &kinfo
->sim_fcfg1
);
748 if (result
!= ERROR_OK
)
751 result
= target_read_u32(target
, SIM_FCFG2
, &kinfo
->sim_fcfg2
);
752 if (result
!= ERROR_OK
)
754 fcfg2_pflsh
= (kinfo
->sim_fcfg2
>> 23) & 0x01;
756 LOG_DEBUG("SDID: 0x%08" PRIX32
" FCFG1: 0x%08" PRIX32
" FCFG2: 0x%08" PRIX32
, kinfo
->sim_sdid
,
757 kinfo
->sim_fcfg1
, kinfo
->sim_fcfg2
);
759 fcfg1_nvmsize
= (uint8_t)((kinfo
->sim_fcfg1
>> 28) & 0x0f);
760 fcfg1_pfsize
= (uint8_t)((kinfo
->sim_fcfg1
>> 24) & 0x0f);
761 fcfg1_eesize
= (uint8_t)((kinfo
->sim_fcfg1
>> 16) & 0x0f);
763 /* when the PFLSH bit is set, there is no FlexNVM/FlexRAM */
765 switch (fcfg1_nvmsize
) {
770 nvm_size
= 1 << (14 + (fcfg1_nvmsize
>> 1));
773 if (granularity
== 3)
783 switch (fcfg1_eesize
) {
794 ee_size
= (16 << (10 - fcfg1_eesize
));
802 switch (fcfg1_pfsize
) {
809 pf_size
= 1 << (14 + (fcfg1_pfsize
>> 1));
812 if (granularity
== 3)
814 else if (fcfg2_pflsh
)
824 LOG_DEBUG("FlexNVM: %" PRIu32
" PFlash: %" PRIu32
" FlexRAM: %" PRIu32
" PFLSH: %d",
825 nvm_size
, pf_size
, ee_size
, fcfg2_pflsh
);
829 num_blocks
= kinetis_flash_params
[granularity
].num_blocks
;
831 num_pflash_blocks
= num_blocks
/ (2 - fcfg2_pflsh
);
832 first_nvm_bank
= num_pflash_blocks
;
833 num_nvm_blocks
= num_blocks
- num_pflash_blocks
;
835 LOG_DEBUG("%d blocks total: %d PFlash, %d FlexNVM",
836 num_blocks
, num_pflash_blocks
, num_nvm_blocks
);
839 * If the flash class is already assigned, verify the
842 if (kinfo
->flash_class
!= FC_AUTO
) {
843 if (kinfo
->bank_ordinal
!= (unsigned) bank
->bank_number
) {
844 LOG_WARNING("Flash ordinal/bank number mismatch");
846 } else if (kinfo
->granularity
!= granularity
) {
847 LOG_WARNING("Flash granularity mismatch");
850 switch (kinfo
->flash_class
) {
852 if (kinfo
->bank_ordinal
>= first_nvm_bank
) {
853 LOG_WARNING("Class mismatch, bank %d is not PFlash", bank
->bank_number
);
855 } else if (bank
->size
!= (pf_size
/ num_pflash_blocks
)) {
856 LOG_WARNING("PFlash size mismatch");
858 } else if (bank
->base
!=
859 (0x00000000 + bank
->size
* kinfo
->bank_ordinal
)) {
860 LOG_WARNING("PFlash address range mismatch");
862 } else if (kinfo
->sector_size
!=
863 kinetis_flash_params
[granularity
].pflash_sector_size_bytes
) {
864 LOG_WARNING("PFlash sector size mismatch");
867 LOG_DEBUG("PFlash bank %d already configured okay",
868 kinfo
->bank_ordinal
);
872 if ((kinfo
->bank_ordinal
>= num_blocks
) ||
873 (kinfo
->bank_ordinal
< first_nvm_bank
)) {
874 LOG_WARNING("Class mismatch, bank %d is not FlexNVM", bank
->bank_number
);
876 } else if (bank
->size
!= (nvm_size
/ num_nvm_blocks
)) {
877 LOG_WARNING("FlexNVM size mismatch");
879 } else if (bank
->base
!=
880 (0x10000000 + bank
->size
* kinfo
->bank_ordinal
)) {
881 LOG_WARNING("FlexNVM address range mismatch");
883 } else if (kinfo
->sector_size
!=
884 kinetis_flash_params
[granularity
].nvm_sector_size_bytes
) {
885 LOG_WARNING("FlexNVM sector size mismatch");
888 LOG_DEBUG("FlexNVM bank %d already configured okay",
889 kinfo
->bank_ordinal
);
893 if (kinfo
->bank_ordinal
!= num_blocks
) {
894 LOG_WARNING("Class mismatch, bank %d is not FlexRAM", bank
->bank_number
);
896 } else if (bank
->size
!= ee_size
) {
897 LOG_WARNING("FlexRAM size mismatch");
899 } else if (bank
->base
!= FLEXRAM
) {
900 LOG_WARNING("FlexRAM address mismatch");
902 } else if (kinfo
->sector_size
!=
903 kinetis_flash_params
[granularity
].nvm_sector_size_bytes
) {
904 LOG_WARNING("FlexRAM sector size mismatch");
907 LOG_DEBUG("FlexRAM bank %d already configured okay", kinfo
->bank_ordinal
);
912 LOG_WARNING("Unknown or inconsistent flash class");
918 LOG_INFO("Probing flash info for bank %d", bank
->bank_number
);
925 kinfo
->granularity
= granularity
;
927 if ((unsigned)bank
->bank_number
< num_pflash_blocks
) {
928 /* pflash, banks start at address zero */
929 kinfo
->flash_class
= FC_PFLASH
;
930 bank
->size
= (pf_size
/ num_pflash_blocks
);
931 bank
->base
= 0x00000000 + bank
->size
* bank
->bank_number
;
932 kinfo
->sector_size
= kinetis_flash_params
[granularity
].pflash_sector_size_bytes
;
933 kinfo
->protection_size
= pf_size
/ 32;
934 } else if ((unsigned)bank
->bank_number
< num_blocks
) {
935 /* nvm, banks start at address 0x10000000 */
936 kinfo
->flash_class
= FC_FLEX_NVM
;
937 bank
->size
= (nvm_size
/ num_nvm_blocks
);
938 bank
->base
= 0x10000000 + bank
->size
* (bank
->bank_number
- first_nvm_bank
);
939 kinfo
->sector_size
= kinetis_flash_params
[granularity
].nvm_sector_size_bytes
;
940 kinfo
->protection_size
= 0; /* FIXME: TODO: depends on DEPART bits, chip */
941 } else if ((unsigned)bank
->bank_number
== num_blocks
) {
942 LOG_ERROR("FlexRAM support not yet implemented");
943 return ERROR_FLASH_OPER_UNSUPPORTED
;
945 LOG_ERROR("Cannot determine parameters for bank %d, only %d banks on device",
946 bank
->bank_number
, num_blocks
);
947 return ERROR_FLASH_BANK_INVALID
;
952 bank
->sectors
= NULL
;
955 bank
->num_sectors
= bank
->size
/ kinfo
->sector_size
;
956 assert(bank
->num_sectors
> 0);
957 bank
->sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
959 for (i
= 0; i
< bank
->num_sectors
; i
++) {
960 bank
->sectors
[i
].offset
= offset
;
961 bank
->sectors
[i
].size
= kinfo
->sector_size
;
962 offset
+= kinfo
->sector_size
;
963 bank
->sectors
[i
].is_erased
= -1;
964 bank
->sectors
[i
].is_protected
= 1;
970 static int kinetis_probe(struct flash_bank
*bank
)
972 if (bank
->target
->state
!= TARGET_HALTED
) {
973 LOG_WARNING("Cannot communicate... target not halted.");
974 return ERROR_TARGET_NOT_HALTED
;
977 return kinetis_read_part_info(bank
);
980 static int kinetis_auto_probe(struct flash_bank
*bank
)
982 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
987 return kinetis_probe(bank
);
990 static int kinetis_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
992 const char *bank_class_names
[] = {
993 "(ANY)", "PFlash", "FlexNVM", "FlexRAM"
996 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
998 (void) snprintf(buf
, buf_size
,
999 "%s driver for %s flash bank %s at 0x%8.8" PRIx32
"",
1000 bank
->driver
->name
, bank_class_names
[kinfo
->flash_class
],
1001 bank
->name
, bank
->base
);
1006 static int kinetis_blank_check(struct flash_bank
*bank
)
1008 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
1010 if (bank
->target
->state
!= TARGET_HALTED
) {
1011 LOG_ERROR("Target not halted");
1012 return ERROR_TARGET_NOT_HALTED
;
1015 if (kinfo
->flash_class
== FC_PFLASH
) {
1019 /* check if whole bank is blank */
1020 result
= kinetis_ftfx_command(bank
, FTFx_CMD_BLOCKSTAT
, bank
->base
, 0, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat
);
1022 if (result
!= ERROR_OK
)
1025 if (ftfx_fstat
& 0x01) {
1026 /* the whole bank is not erased, check sector-by-sector */
1028 for (i
= 0; i
< bank
->num_sectors
; i
++) {
1030 result
= kinetis_ftfx_command(bank
, FTFx_CMD_SECTSTAT
, bank
->base
+ bank
->sectors
[i
].offset
,
1031 1, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat
);
1033 if (result
== ERROR_OK
) {
1034 bank
->sectors
[i
].is_erased
= !(ftfx_fstat
& 0x01);
1036 LOG_DEBUG("Ignoring errored PFlash sector blank-check");
1037 bank
->sectors
[i
].is_erased
= -1;
1041 /* the whole bank is erased, update all sectors */
1043 for (i
= 0; i
< bank
->num_sectors
; i
++)
1044 bank
->sectors
[i
].is_erased
= 1;
1047 LOG_WARNING("kinetis_blank_check not supported yet for FlexNVM");
1048 return ERROR_FLASH_OPERATION_FAILED
;
1054 struct flash_driver kinetis_flash
= {
1056 .flash_bank_command
= kinetis_flash_bank_command
,
1057 .erase
= kinetis_erase
,
1058 .protect
= kinetis_protect
,
1059 .write
= kinetis_write
,
1060 .read
= default_flash_read
,
1061 .probe
= kinetis_probe
,
1062 .auto_probe
= kinetis_auto_probe
,
1063 .erase_check
= kinetis_blank_check
,
1064 .protect_check
= kinetis_protect_check
,
1065 .info
= kinetis_info
,
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)