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.
91 * NB. These undocumented bits does not work for all MCUs.
92 * A more reliable way is to detect the particular MCU model from the
93 * SDID field and pick the correct granularity based on that. See
94 * the handling of K21 in kinetis_read_part_info() for an example.
98 unsigned pflash_sector_size_bytes
;
99 unsigned nvm_sector_size_bytes
;
101 } kinetis_flash_params
[4] = {
109 #define FLEXRAM 0x14000000
110 #define FTFx_FSTAT 0x40020000
111 #define FTFx_FCNFG 0x40020001
112 #define FTFx_FCCOB3 0x40020004
113 #define FTFx_FPROT3 0x40020010
114 #define SIM_SDID 0x40048024
115 #define SIM_FCFG1 0x4004804c
116 #define SIM_FCFG2 0x40048050
119 #define FTFx_CMD_BLOCKSTAT 0x00
120 #define FTFx_CMD_SECTSTAT 0x01
121 #define FTFx_CMD_LWORDPROG 0x06
122 #define FTFx_CMD_SECTERASE 0x09
123 #define FTFx_CMD_SECTWRITE 0x0b
124 #define FTFx_CMD_SETFLEXRAM 0x81
125 #define FTFx_CMD_MASSERASE 0x44
127 #define KINETIS_SDID_FAMID_MASK 0x00000070
128 #define KINETIS_SDID_FAMID_K10 0x00000000
129 #define KINETIS_SDID_FAMID_K12 0x00000000
130 #define KINETIS_SDID_FAMID_K20 0x00000010
131 #define KINETIS_SDID_FAMID_K22 0x00000010
132 #define KINETIS_SDID_FAMID_K30 0x00000020
133 #define KINETIS_SDID_FAMID_K11 0x00000020
134 #define KINETIS_SDID_FAMID_K61 0x00000020
135 #define KINETIS_SDID_FAMID_K40 0x00000030
136 #define KINETIS_SDID_FAMID_K21 0x00000030
137 #define KINETIS_SDID_FAMID_K60 0x00000040
138 #define KINETIS_SDID_FAMID_K62 0x00000040
139 #define KINETIS_SDID_FAMID_K70 0x00000050
140 #define KINETIS_SDID_FAMID_KW24 0x00000060
142 struct kinetis_flash_bank
{
143 unsigned granularity
;
144 unsigned bank_ordinal
;
145 uint32_t sector_size
;
146 uint32_t protection_size
;
161 FLASH_BANK_COMMAND_HANDLER(kinetis_flash_bank_command
)
163 struct kinetis_flash_bank
*bank_info
;
166 return ERROR_COMMAND_SYNTAX_ERROR
;
168 LOG_INFO("add flash_bank kinetis %s", bank
->name
);
170 bank_info
= malloc(sizeof(struct kinetis_flash_bank
));
172 memset(bank_info
, 0, sizeof(struct kinetis_flash_bank
));
174 bank
->driver_priv
= bank_info
;
179 /* Kinetis Program-LongWord Microcodes */
180 static const uint8_t kinetis_flash_write_code
[] = {
182 * r0 - workarea buffer
183 * r1 - target address
193 /* for(register uint32_t i=0;i<wcount;i++){ */
194 0x04, 0x1C, /* mov r4, r0 */
195 0x00, 0x23, /* mov r3, #0 */
197 0x0E, 0x1A, /* sub r6, r1, r0 */
198 0xA6, 0x19, /* add r6, r4, r6 */
199 0x93, 0x42, /* cmp r3, r2 */
200 0x16, 0xD0, /* beq .L9 */
202 /* while((FTFx_FSTAT&FTFA_FSTAT_CCIF_MASK) != FTFA_FSTAT_CCIF_MASK){}; */
203 0x0B, 0x4D, /* ldr r5, .L10 */
204 0x2F, 0x78, /* ldrb r7, [r5] */
205 0x7F, 0xB2, /* sxtb r7, r7 */
206 0x00, 0x2F, /* cmp r7, #0 */
207 0xFA, 0xDA, /* bge .L5 */
208 /* FTFx_FSTAT = FTFA_FSTAT_ACCERR_MASK|FTFA_FSTAT_FPVIOL_MASK|FTFA_FSTAT_RDCO */
209 0x70, 0x27, /* mov r7, #112 */
210 0x2F, 0x70, /* strb r7, [r5] */
211 /* FTFx_FCCOB3 = faddr; */
212 0x09, 0x4F, /* ldr r7, .L10+4 */
213 0x3E, 0x60, /* str r6, [r7] */
214 0x06, 0x27, /* mov r7, #6 */
215 /* FTFx_FCCOB0 = 0x06; */
216 0x08, 0x4E, /* ldr r6, .L10+8 */
217 0x37, 0x70, /* strb r7, [r6] */
218 /* FTFx_FCCOB7 = *pLW; */
219 0x80, 0xCC, /* ldmia r4!, {r7} */
220 0x08, 0x4E, /* ldr r6, .L10+12 */
221 0x37, 0x60, /* str r7, [r6] */
222 /* FTFx_FSTAT = FTFA_FSTAT_CCIF_MASK; */
223 0x80, 0x27, /* mov r7, #128 */
224 0x2F, 0x70, /* strb r7, [r5] */
226 /* while((FTFx_FSTAT&FTFA_FSTAT_CCIF_MASK) != FTFA_FSTAT_CCIF_MASK){}; */
227 0x2E, 0x78, /* ldrb r6, [r5] */
228 0x77, 0xB2, /* sxtb r7, r6 */
229 0x00, 0x2F, /* cmp r7, #0 */
230 0xFB, 0xDA, /* bge .L4 */
231 0x01, 0x33, /* add r3, r3, #1 */
232 0xE4, 0xE7, /* b .L2 */
234 0x00, 0xBE, /* bkpt #0 */
236 0x00, 0x00, 0x02, 0x40, /* .word 1073872896 */
237 0x04, 0x00, 0x02, 0x40, /* .word 1073872900 */
238 0x07, 0x00, 0x02, 0x40, /* .word 1073872903 */
239 0x08, 0x00, 0x02, 0x40, /* .word 1073872904 */
242 /* Program LongWord Block Write */
243 static int kinetis_write_block(struct flash_bank
*bank
, uint8_t *buffer
,
244 uint32_t offset
, uint32_t wcount
)
246 struct target
*target
= bank
->target
;
247 uint32_t buffer_size
= 2048; /* Default minimum value */
248 struct working_area
*write_algorithm
;
249 struct working_area
*source
;
250 uint32_t address
= bank
->base
+ offset
;
251 struct reg_param reg_params
[3];
252 struct armv7m_algorithm armv7m_info
;
253 int retval
= ERROR_OK
;
256 * r0 - workarea buffer
257 * r1 - target address
266 /* Increase buffer_size if needed */
267 if (buffer_size
< (target
->working_area_size
/2))
268 buffer_size
= (target
->working_area_size
/2);
270 LOG_INFO("Kinetis: FLASH Write ...");
272 /* check code alignment */
274 LOG_WARNING("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
275 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
278 /* allocate working area with flash programming code */
279 if (target_alloc_working_area(target
, sizeof(kinetis_flash_write_code
),
280 &write_algorithm
) != ERROR_OK
) {
281 LOG_WARNING("no working area available, can't do block memory writes");
282 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
285 retval
= target_write_buffer(target
, write_algorithm
->address
,
286 sizeof(kinetis_flash_write_code
), kinetis_flash_write_code
);
287 if (retval
!= ERROR_OK
)
291 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
) {
293 if (buffer_size
<= 256) {
294 /* free working area, write algorithm already allocated */
295 target_free_working_area(target
, write_algorithm
);
297 LOG_WARNING("No large enough working area available, can't do block memory writes");
298 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
302 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
303 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
305 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
); /* *pLW (*buffer) */
306 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* faddr */
307 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* number of words to program */
309 /* write code buffer and use Flash programming code within kinetis */
310 /* Set breakpoint to 0 with time-out of 1000 ms */
312 uint32_t thisrun_count
= (wcount
> (buffer_size
/ 4)) ? (buffer_size
/ 4) : wcount
;
314 retval
= target_write_buffer(target
, write_algorithm
->address
, 8,
315 kinetis_flash_write_code
);
316 if (retval
!= ERROR_OK
)
319 retval
= target_write_buffer(target
, source
->address
, thisrun_count
* 4, buffer
);
320 if (retval
!= ERROR_OK
)
323 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
324 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
325 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
);
327 retval
= target_run_algorithm(target
, 0, NULL
, 3, reg_params
,
328 write_algorithm
->address
, 0, 100000, &armv7m_info
);
329 if (retval
!= ERROR_OK
) {
330 LOG_ERROR("Error executing kinetis Flash programming algorithm");
331 retval
= ERROR_FLASH_OPERATION_FAILED
;
335 buffer
+= thisrun_count
* 4;
336 address
+= thisrun_count
* 4;
337 wcount
-= thisrun_count
;
340 target_free_working_area(target
, source
);
341 target_free_working_area(target
, write_algorithm
);
343 destroy_reg_param(®_params
[0]);
344 destroy_reg_param(®_params
[1]);
345 destroy_reg_param(®_params
[2]);
350 static int kinetis_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
352 LOG_WARNING("kinetis_protect not supported yet");
355 if (bank
->target
->state
!= TARGET_HALTED
) {
356 LOG_ERROR("Target not halted");
357 return ERROR_TARGET_NOT_HALTED
;
360 return ERROR_FLASH_BANK_INVALID
;
363 static int kinetis_protect_check(struct flash_bank
*bank
)
365 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
367 if (bank
->target
->state
!= TARGET_HALTED
) {
368 LOG_ERROR("Target not halted");
369 return ERROR_TARGET_NOT_HALTED
;
372 if (kinfo
->flash_class
== FC_PFLASH
) {
375 uint32_t fprot
, psec
;
378 /* read protection register */
379 result
= target_read_memory(bank
->target
, FTFx_FPROT3
, 1, 4, buffer
);
381 if (result
!= ERROR_OK
)
384 fprot
= target_buffer_get_u32(bank
->target
, buffer
);
387 * Every bit protects 1/32 of the full flash (not necessarily
388 * just this bank), but we enforce the bank ordinals for
389 * PFlash to start at zero.
391 b
= kinfo
->bank_ordinal
* (bank
->size
/ kinfo
->protection_size
);
392 for (psec
= 0, i
= 0; i
< bank
->num_sectors
; i
++) {
393 if ((fprot
>> b
) & 1)
394 bank
->sectors
[i
].is_protected
= 0;
396 bank
->sectors
[i
].is_protected
= 1;
398 psec
+= bank
->sectors
[i
].size
;
400 if (psec
>= kinfo
->protection_size
) {
406 LOG_ERROR("Protection checks for FlexNVM not yet supported");
407 return ERROR_FLASH_BANK_INVALID
;
413 static int kinetis_ftfx_command(struct flash_bank
*bank
, uint8_t fcmd
, uint32_t faddr
,
414 uint8_t fccob4
, uint8_t fccob5
, uint8_t fccob6
, uint8_t fccob7
,
415 uint8_t fccob8
, uint8_t fccob9
, uint8_t fccoba
, uint8_t fccobb
,
418 uint8_t command
[12] = {faddr
& 0xff, (faddr
>> 8) & 0xff, (faddr
>> 16) & 0xff, fcmd
,
419 fccob7
, fccob6
, fccob5
, fccob4
,
420 fccobb
, fccoba
, fccob9
, fccob8
};
425 for (i
= 0; i
< 50; i
++) {
427 target_read_memory(bank
->target
, FTFx_FSTAT
, 1, 1, &buffer
);
429 if (result
!= ERROR_OK
)
438 if (buffer
!= 0x80) {
439 /* reset error flags */
442 target_write_memory(bank
->target
, FTFx_FSTAT
, 1, 1, &buffer
);
443 if (result
!= ERROR_OK
)
447 result
= target_write_memory(bank
->target
, FTFx_FCCOB3
, 4, 3, command
);
449 if (result
!= ERROR_OK
)
454 result
= target_write_memory(bank
->target
, FTFx_FSTAT
, 1, 1, &buffer
);
455 if (result
!= ERROR_OK
)
459 for (i
= 0; i
< 240; i
++) { /* Need Entire Erase Nemui Changed */
461 target_read_memory(bank
->target
, FTFx_FSTAT
, 1, 1, ftfx_fstat
);
463 if (result
!= ERROR_OK
)
466 if (*ftfx_fstat
& 0x80)
470 if ((*ftfx_fstat
& 0xf0) != 0x80) {
472 ("ftfx command failed FSTAT: %02X FCCOB: %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X",
473 *ftfx_fstat
, command
[3], command
[2], command
[1], command
[0],
474 command
[7], command
[6], command
[5], command
[4],
475 command
[11], command
[10], command
[9], command
[8]);
476 return ERROR_FLASH_OPERATION_FAILED
;
482 static int kinetis_mass_erase(struct flash_bank
*bank
)
487 if (bank
->target
->state
!= TARGET_HALTED
) {
488 LOG_ERROR("Target not halted");
489 return ERROR_TARGET_NOT_HALTED
;
492 /* check if whole bank is blank */
493 LOG_INFO("Kinetis L Series Erase All Blocks");
494 /* set command and sector address */
495 result
= kinetis_ftfx_command(bank
, FTFx_CMD_MASSERASE
, 0,
496 0, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat
);
497 /* Anyway Result, write unsecure byte */
498 /* if (result != ERROR_OK)
501 /* Write to MCU security status unsecure in Flash security byte(Work around) */
502 LOG_INFO("Write to MCU security status unsecure Anyway!");
503 uint8_t padding
[4] = {0xFE, 0xFF, 0xFF, 0xFF}; /* Write 0xFFFFFFFE */
505 result
= kinetis_ftfx_command(bank
, FTFx_CMD_LWORDPROG
, (bank
->base
+ 0x0000040C),
506 padding
[3], padding
[2], padding
[1], padding
[0],
507 0, 0, 0, 0, &ftfx_fstat
);
508 if (result
!= ERROR_OK
)
509 return ERROR_FLASH_OPERATION_FAILED
;
514 static int kinetis_erase(struct flash_bank
*bank
, int first
, int last
)
517 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
519 if (bank
->target
->state
!= TARGET_HALTED
) {
520 LOG_ERROR("Target not halted");
521 return ERROR_TARGET_NOT_HALTED
;
524 if ((first
> bank
->num_sectors
) || (last
> bank
->num_sectors
))
525 return ERROR_FLASH_OPERATION_FAILED
;
527 if ((first
== 0) && (last
== (bank
->num_sectors
- 1)) && (kinfo
->klxx
))
528 return kinetis_mass_erase(bank
);
531 * FIXME: TODO: use the 'Erase Flash Block' command if the
532 * requested erase is PFlash or NVM and encompasses the entire
533 * block. Should be quicker.
535 for (i
= first
; i
<= last
; i
++) {
537 /* set command and sector address */
538 result
= kinetis_ftfx_command(bank
, FTFx_CMD_SECTERASE
, bank
->base
+ bank
->sectors
[i
].offset
,
539 0, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat
);
541 if (result
!= ERROR_OK
) {
542 LOG_WARNING("erase sector %d failed", i
);
543 return ERROR_FLASH_OPERATION_FAILED
;
546 bank
->sectors
[i
].is_erased
= 1;
551 ("flash configuration field erased, please reset the device");
557 static int kinetis_write(struct flash_bank
*bank
, uint8_t *buffer
,
558 uint32_t offset
, uint32_t count
)
560 unsigned int i
, result
, fallback
= 0;
563 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
564 uint8_t *new_buffer
= NULL
;
566 if (bank
->target
->state
!= TARGET_HALTED
) {
567 LOG_ERROR("Target not halted");
568 return ERROR_TARGET_NOT_HALTED
;
572 /* fallback to longword write */
574 LOG_WARNING("Kinetis L Series supports Program Longword execution only.");
575 LOG_DEBUG("flash write into PFLASH @08%" PRIX32
, offset
);
577 } else if (kinfo
->flash_class
== FC_FLEX_NVM
) {
580 LOG_DEBUG("flash write into FlexNVM @%08" PRIX32
, offset
);
582 /* make flex ram available */
583 result
= kinetis_ftfx_command(bank
, FTFx_CMD_SETFLEXRAM
, 0x00ff0000, 0, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat
);
585 if (result
!= ERROR_OK
)
586 return ERROR_FLASH_OPERATION_FAILED
;
588 /* check if ram ready */
589 result
= target_read_memory(bank
->target
, FTFx_FCNFG
, 1, 1, buf
);
591 if (result
!= ERROR_OK
)
594 if (!(buf
[0] & (1 << 1))) {
595 /* fallback to longword write */
598 LOG_WARNING("ram not ready, fallback to slow longword write (FCNFG: %02X)", buf
[0]);
601 LOG_DEBUG("flash write into PFLASH @08%" PRIX32
, offset
);
605 /* program section command */
608 * Kinetis uses different terms for the granularity of
609 * sector writes, e.g. "phrase" or "128 bits". We use
610 * the generic term "chunk". The largest possible
611 * Kinetis "chunk" is 16 bytes (128 bits).
613 unsigned prog_section_chunk_bytes
= kinfo
->sector_size
>> 8;
614 /* assume the NVM sector size is half the FlexRAM size */
615 unsigned prog_size_bytes
= MIN(kinfo
->sector_size
,
616 kinetis_flash_params
[kinfo
->granularity
].nvm_sector_size_bytes
);
617 for (i
= 0; i
< count
; i
+= prog_size_bytes
) {
618 uint8_t residual_buffer
[16];
620 uint32_t section_count
= prog_size_bytes
/ prog_section_chunk_bytes
;
621 uint32_t residual_wc
= 0;
624 * Assume the word count covers an entire
627 wc
= prog_size_bytes
/ 4;
630 * If bytes to be programmed are less than the
631 * full sector, then determine the number of
632 * full-words to program, and put together the
633 * residual buffer so that a full "section"
634 * may always be programmed.
636 if ((count
- i
) < prog_size_bytes
) {
637 /* number of bytes to program beyond full section */
638 unsigned residual_bc
= (count
-i
) % prog_section_chunk_bytes
;
640 /* number of complete words to copy directly from buffer */
641 wc
= (count
- i
) / 4;
643 /* number of total sections to write, including residual */
644 section_count
= DIV_ROUND_UP((count
-i
), prog_section_chunk_bytes
);
646 /* any residual bytes delivers a whole residual section */
647 residual_wc
= (residual_bc
? prog_section_chunk_bytes
: 0)/4;
649 /* clear residual buffer then populate residual bytes */
650 (void) memset(residual_buffer
, 0xff, prog_section_chunk_bytes
);
651 (void) memcpy(residual_buffer
, &buffer
[i
+4*wc
], residual_bc
);
654 LOG_DEBUG("write section @ %08" PRIX32
" with length %" PRIu32
" bytes",
655 offset
+ i
, (uint32_t)wc
*4);
657 /* write data to flexram as whole-words */
658 result
= target_write_memory(bank
->target
, FLEXRAM
, 4, wc
,
661 if (result
!= ERROR_OK
) {
662 LOG_ERROR("target_write_memory failed");
666 /* write the residual words to the flexram */
668 result
= target_write_memory(bank
->target
,
673 if (result
!= ERROR_OK
) {
674 LOG_ERROR("target_write_memory failed");
679 /* execute section-write command */
680 result
= kinetis_ftfx_command(bank
, FTFx_CMD_SECTWRITE
, bank
->base
+ offset
+ i
,
681 section_count
>>8, section_count
, 0, 0,
682 0, 0, 0, 0, &ftfx_fstat
);
684 if (result
!= ERROR_OK
)
685 return ERROR_FLASH_OPERATION_FAILED
;
688 /* program longword command, not supported in "SF3" devices */
689 else if ((kinfo
->granularity
!= 3) || (kinfo
->klxx
)) {
692 uint32_t old_count
= count
;
693 count
= (old_count
| 3) + 1;
694 new_buffer
= malloc(count
);
695 if (new_buffer
== NULL
) {
696 LOG_ERROR("odd number of bytes to write and no memory "
697 "for padding buffer");
700 LOG_INFO("odd number of bytes to write (%" PRIu32
"), extending to %" PRIu32
" "
701 "and padding with 0xff", old_count
, count
);
702 memset(buffer
, 0xff, count
);
703 buffer
= memcpy(new_buffer
, buffer
, old_count
);
706 uint32_t words_remaining
= count
/ 4;
708 /* try using a block write */
709 int retval
= kinetis_write_block(bank
, buffer
, offset
, words_remaining
);
711 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
) {
712 /* if block write failed (no sufficient working area),
713 * we use normal (slow) single word accesses */
714 LOG_WARNING("couldn't use block writes, falling back to single "
717 for (i
= 0; i
< count
; i
+= 4) {
720 LOG_DEBUG("write longword @ %08" PRIX32
, (uint32_t)(offset
+ i
));
722 uint8_t padding
[4] = {0xff, 0xff, 0xff, 0xff};
723 memcpy(padding
, buffer
+ i
, MIN(4, count
-i
));
725 result
= kinetis_ftfx_command(bank
, FTFx_CMD_LWORDPROG
, bank
->base
+ offset
+ i
,
726 padding
[3], padding
[2], padding
[1], padding
[0],
727 0, 0, 0, 0, &ftfx_fstat
);
729 if (result
!= ERROR_OK
)
730 return ERROR_FLASH_OPERATION_FAILED
;
735 LOG_ERROR("Flash write strategy not implemented");
736 return ERROR_FLASH_OPERATION_FAILED
;
742 static int kinetis_read_part_info(struct flash_bank
*bank
)
746 uint8_t fcfg1_nvmsize
, fcfg1_pfsize
, fcfg1_eesize
, fcfg2_pflsh
;
747 uint32_t nvm_size
= 0, pf_size
= 0, ee_size
= 0;
748 unsigned granularity
, num_blocks
= 0, num_pflash_blocks
= 0, num_nvm_blocks
= 0,
749 first_nvm_bank
= 0, reassign
= 0;
750 struct target
*target
= bank
->target
;
751 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
753 result
= target_read_u32(target
, SIM_SDID
, &kinfo
->sim_sdid
);
754 if (result
!= ERROR_OK
)
757 /* Kinetis L Series SubFamily Check */
759 i
= (kinfo
->sim_sdid
>> 20) & 0x0F;
763 } else if ((kinfo
->sim_sdid
& KINETIS_SDID_FAMID_MASK
)
764 == KINETIS_SDID_FAMID_K21
) {
767 granularity
= (kinfo
->sim_sdid
>> 7) & 0x03;
769 result
= target_read_u32(target
, SIM_FCFG1
, &kinfo
->sim_fcfg1
);
770 if (result
!= ERROR_OK
)
773 result
= target_read_u32(target
, SIM_FCFG2
, &kinfo
->sim_fcfg2
);
774 if (result
!= ERROR_OK
)
776 fcfg2_pflsh
= (kinfo
->sim_fcfg2
>> 23) & 0x01;
778 LOG_DEBUG("SDID: 0x%08" PRIX32
" FCFG1: 0x%08" PRIX32
" FCFG2: 0x%08" PRIX32
, kinfo
->sim_sdid
,
779 kinfo
->sim_fcfg1
, kinfo
->sim_fcfg2
);
781 fcfg1_nvmsize
= (uint8_t)((kinfo
->sim_fcfg1
>> 28) & 0x0f);
782 fcfg1_pfsize
= (uint8_t)((kinfo
->sim_fcfg1
>> 24) & 0x0f);
783 fcfg1_eesize
= (uint8_t)((kinfo
->sim_fcfg1
>> 16) & 0x0f);
785 /* when the PFLSH bit is set, there is no FlexNVM/FlexRAM */
787 switch (fcfg1_nvmsize
) {
792 nvm_size
= 1 << (14 + (fcfg1_nvmsize
>> 1));
795 if (granularity
== 3)
805 switch (fcfg1_eesize
) {
816 ee_size
= (16 << (10 - fcfg1_eesize
));
824 switch (fcfg1_pfsize
) {
831 pf_size
= 1 << (14 + (fcfg1_pfsize
>> 1));
834 if (granularity
== 3)
836 else if (fcfg2_pflsh
)
846 LOG_DEBUG("FlexNVM: %" PRIu32
" PFlash: %" PRIu32
" FlexRAM: %" PRIu32
" PFLSH: %d",
847 nvm_size
, pf_size
, ee_size
, fcfg2_pflsh
);
851 num_blocks
= kinetis_flash_params
[granularity
].num_blocks
;
853 num_pflash_blocks
= num_blocks
/ (2 - fcfg2_pflsh
);
854 first_nvm_bank
= num_pflash_blocks
;
855 num_nvm_blocks
= num_blocks
- num_pflash_blocks
;
857 LOG_DEBUG("%d blocks total: %d PFlash, %d FlexNVM",
858 num_blocks
, num_pflash_blocks
, num_nvm_blocks
);
861 * If the flash class is already assigned, verify the
864 if (kinfo
->flash_class
!= FC_AUTO
) {
865 if (kinfo
->bank_ordinal
!= (unsigned) bank
->bank_number
) {
866 LOG_WARNING("Flash ordinal/bank number mismatch");
868 } else if (kinfo
->granularity
!= granularity
) {
869 LOG_WARNING("Flash granularity mismatch");
872 switch (kinfo
->flash_class
) {
874 if (kinfo
->bank_ordinal
>= first_nvm_bank
) {
875 LOG_WARNING("Class mismatch, bank %d is not PFlash", bank
->bank_number
);
877 } else if (bank
->size
!= (pf_size
/ num_pflash_blocks
)) {
878 LOG_WARNING("PFlash size mismatch");
880 } else if (bank
->base
!=
881 (0x00000000 + bank
->size
* kinfo
->bank_ordinal
)) {
882 LOG_WARNING("PFlash address range mismatch");
884 } else if (kinfo
->sector_size
!=
885 kinetis_flash_params
[granularity
].pflash_sector_size_bytes
) {
886 LOG_WARNING("PFlash sector size mismatch");
889 LOG_DEBUG("PFlash bank %d already configured okay",
890 kinfo
->bank_ordinal
);
894 if ((kinfo
->bank_ordinal
>= num_blocks
) ||
895 (kinfo
->bank_ordinal
< first_nvm_bank
)) {
896 LOG_WARNING("Class mismatch, bank %d is not FlexNVM", bank
->bank_number
);
898 } else if (bank
->size
!= (nvm_size
/ num_nvm_blocks
)) {
899 LOG_WARNING("FlexNVM size mismatch");
901 } else if (bank
->base
!=
902 (0x10000000 + bank
->size
* kinfo
->bank_ordinal
)) {
903 LOG_WARNING("FlexNVM address range mismatch");
905 } else if (kinfo
->sector_size
!=
906 kinetis_flash_params
[granularity
].nvm_sector_size_bytes
) {
907 LOG_WARNING("FlexNVM sector size mismatch");
910 LOG_DEBUG("FlexNVM bank %d already configured okay",
911 kinfo
->bank_ordinal
);
915 if (kinfo
->bank_ordinal
!= num_blocks
) {
916 LOG_WARNING("Class mismatch, bank %d is not FlexRAM", bank
->bank_number
);
918 } else if (bank
->size
!= ee_size
) {
919 LOG_WARNING("FlexRAM size mismatch");
921 } else if (bank
->base
!= FLEXRAM
) {
922 LOG_WARNING("FlexRAM address mismatch");
924 } else if (kinfo
->sector_size
!=
925 kinetis_flash_params
[granularity
].nvm_sector_size_bytes
) {
926 LOG_WARNING("FlexRAM sector size mismatch");
929 LOG_DEBUG("FlexRAM bank %d already configured okay", kinfo
->bank_ordinal
);
934 LOG_WARNING("Unknown or inconsistent flash class");
940 LOG_INFO("Probing flash info for bank %d", bank
->bank_number
);
947 kinfo
->granularity
= granularity
;
949 if ((unsigned)bank
->bank_number
< num_pflash_blocks
) {
950 /* pflash, banks start at address zero */
951 kinfo
->flash_class
= FC_PFLASH
;
952 bank
->size
= (pf_size
/ num_pflash_blocks
);
953 bank
->base
= 0x00000000 + bank
->size
* bank
->bank_number
;
954 kinfo
->sector_size
= kinetis_flash_params
[granularity
].pflash_sector_size_bytes
;
955 kinfo
->protection_size
= pf_size
/ 32;
956 } else if ((unsigned)bank
->bank_number
< num_blocks
) {
957 /* nvm, banks start at address 0x10000000 */
958 kinfo
->flash_class
= FC_FLEX_NVM
;
959 bank
->size
= (nvm_size
/ num_nvm_blocks
);
960 bank
->base
= 0x10000000 + bank
->size
* (bank
->bank_number
- first_nvm_bank
);
961 kinfo
->sector_size
= kinetis_flash_params
[granularity
].nvm_sector_size_bytes
;
962 kinfo
->protection_size
= 0; /* FIXME: TODO: depends on DEPART bits, chip */
963 } else if ((unsigned)bank
->bank_number
== num_blocks
) {
964 LOG_ERROR("FlexRAM support not yet implemented");
965 return ERROR_FLASH_OPER_UNSUPPORTED
;
967 LOG_ERROR("Cannot determine parameters for bank %d, only %d banks on device",
968 bank
->bank_number
, num_blocks
);
969 return ERROR_FLASH_BANK_INVALID
;
974 bank
->sectors
= NULL
;
977 bank
->num_sectors
= bank
->size
/ kinfo
->sector_size
;
978 assert(bank
->num_sectors
> 0);
979 bank
->sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
981 for (i
= 0; i
< bank
->num_sectors
; i
++) {
982 bank
->sectors
[i
].offset
= offset
;
983 bank
->sectors
[i
].size
= kinfo
->sector_size
;
984 offset
+= kinfo
->sector_size
;
985 bank
->sectors
[i
].is_erased
= -1;
986 bank
->sectors
[i
].is_protected
= 1;
992 static int kinetis_probe(struct flash_bank
*bank
)
994 if (bank
->target
->state
!= TARGET_HALTED
) {
995 LOG_WARNING("Cannot communicate... target not halted.");
996 return ERROR_TARGET_NOT_HALTED
;
999 return kinetis_read_part_info(bank
);
1002 static int kinetis_auto_probe(struct flash_bank
*bank
)
1004 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
1006 if (kinfo
->sim_sdid
)
1009 return kinetis_probe(bank
);
1012 static int kinetis_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
1014 const char *bank_class_names
[] = {
1015 "(ANY)", "PFlash", "FlexNVM", "FlexRAM"
1018 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
1020 (void) snprintf(buf
, buf_size
,
1021 "%s driver for %s flash bank %s at 0x%8.8" PRIx32
"",
1022 bank
->driver
->name
, bank_class_names
[kinfo
->flash_class
],
1023 bank
->name
, bank
->base
);
1028 static int kinetis_blank_check(struct flash_bank
*bank
)
1030 struct kinetis_flash_bank
*kinfo
= bank
->driver_priv
;
1032 if (bank
->target
->state
!= TARGET_HALTED
) {
1033 LOG_ERROR("Target not halted");
1034 return ERROR_TARGET_NOT_HALTED
;
1037 if (kinfo
->flash_class
== FC_PFLASH
) {
1041 /* check if whole bank is blank */
1042 result
= kinetis_ftfx_command(bank
, FTFx_CMD_BLOCKSTAT
, bank
->base
, 0, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat
);
1044 if (result
!= ERROR_OK
)
1047 if (ftfx_fstat
& 0x01) {
1048 /* the whole bank is not erased, check sector-by-sector */
1050 for (i
= 0; i
< bank
->num_sectors
; i
++) {
1052 result
= kinetis_ftfx_command(bank
, FTFx_CMD_SECTSTAT
, bank
->base
+ bank
->sectors
[i
].offset
,
1053 1, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat
);
1055 if (result
== ERROR_OK
) {
1056 bank
->sectors
[i
].is_erased
= !(ftfx_fstat
& 0x01);
1058 LOG_DEBUG("Ignoring errored PFlash sector blank-check");
1059 bank
->sectors
[i
].is_erased
= -1;
1063 /* the whole bank is erased, update all sectors */
1065 for (i
= 0; i
< bank
->num_sectors
; i
++)
1066 bank
->sectors
[i
].is_erased
= 1;
1069 LOG_WARNING("kinetis_blank_check not supported yet for FlexNVM");
1070 return ERROR_FLASH_OPERATION_FAILED
;
1076 struct flash_driver kinetis_flash
= {
1078 .flash_bank_command
= kinetis_flash_bank_command
,
1079 .erase
= kinetis_erase
,
1080 .protect
= kinetis_protect
,
1081 .write
= kinetis_write
,
1082 .read
= default_flash_read
,
1083 .probe
= kinetis_probe
,
1084 .auto_probe
= kinetis_auto_probe
,
1085 .erase_check
= kinetis_blank_check
,
1086 .protect_check
= kinetis_protect_check
,
1087 .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)