kinetis: add kl flash support
[openocd.git] / src / flash / nor / kinetis.c
blob51e7676fa26e66115db3b4efedf817a01752666b
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 * Copyright (C) 2013 Nemui Trinomius *
12 * nemuisan_kawausogasuki@live.jp *
13 * *
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. *
18 * *
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. *
23 * *
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 ***************************************************************************/
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
34 #include "imp.h"
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
51 * together.
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
57 * described below.
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
75 * 0x14000000.
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.
93 const struct {
94 unsigned pflash_sector_size_bytes;
95 unsigned nvm_sector_size_bytes;
96 unsigned num_blocks;
97 } kinetis_flash_params[4] = {
98 { 1<<10, 1<<10, 2 },
99 { 2<<10, 1<<10, 2 },
100 { 2<<10, 2<<10, 2 },
101 { 4<<10, 4<<10, 4 }
104 /* Addressess */
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
114 /* Commands */
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;
128 uint32_t klxx;
130 uint32_t sim_sdid;
131 uint32_t sim_fcfg1;
132 uint32_t sim_fcfg2;
134 enum {
135 FC_AUTO = 0,
136 FC_PFLASH,
137 FC_FLEX_NVM,
138 FC_FLEX_RAM,
139 } flash_class;
142 FLASH_BANK_COMMAND_HANDLER(kinetis_flash_bank_command)
144 struct kinetis_flash_bank *bank_info;
146 if (CMD_ARGC < 6)
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;
157 return ERROR_OK;
160 /* Kinetis Program-LongWord Microcodes */
161 static const uint8_t kinetis_flash_write_code[] = {
162 /* Params:
163 * r0 - workarea buffer
164 * r1 - target address
165 * r2 - wordcount
166 * Clobbered:
167 * r4 - tmp
168 * r5 - tmp
169 * r6 - tmp
170 * r7 - tmp
173 /* .L1: */
174 /* for(register uint32_t i=0;i<wcount;i++){ */
175 0x04, 0x1C, /* mov r4, r0 */
176 0x00, 0x23, /* mov r3, #0 */
177 /* .L2: */
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 */
182 /* .L5: */
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] */
206 /* .L4: */
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 */
214 /* .L9: */
215 0x00, 0xBE, /* bkpt #0 */
216 /* .L10: */
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;
236 /* Params:
237 * r0 - workarea buffer
238 * r1 - target address
239 * r2 - wordcount
240 * Clobbered:
241 * r4 - tmp
242 * r5 - tmp
243 * r6 - tmp
244 * r7 - tmp
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 */
254 if (offset & 0x1) {
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)
269 return retval;
271 /* memory buffer */
272 while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) {
273 buffer_size /= 4;
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(&reg_params[0], "r0", 32, PARAM_OUT); /* *pLW (*buffer) */
287 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* faddr */
288 init_reg_param(&reg_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 */
292 while (wcount > 0) {
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)
298 break;
300 retval = target_write_buffer(target, source->address, thisrun_count * 4, buffer);
301 if (retval != ERROR_OK)
302 break;
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;
313 break;
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(&reg_params[0]);
325 destroy_reg_param(&reg_params[1]);
326 destroy_reg_param(&reg_params[2]);
328 return retval;
331 static int kinetis_protect(struct flash_bank *bank, int set, int first, int last)
333 LOG_WARNING("kinetis_protect not supported yet");
334 /* FIXME: TODO */
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) {
354 int result;
355 uint8_t buffer[4];
356 uint32_t fprot, psec;
357 int i, b;
359 /* read protection register */
360 result = target_read_memory(bank->target, FTFx_FPROT3, 1, 4, buffer);
362 if (result != ERROR_OK)
363 return result;
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;
376 else
377 bank->sectors[i].is_protected = 1;
379 psec += bank->sectors[i].size;
381 if (psec >= kinfo->protection_size) {
382 psec = 0;
383 b++;
386 } else {
387 LOG_ERROR("Protection checks for FlexNVM not yet supported");
388 return ERROR_FLASH_BANK_INVALID;
391 return ERROR_OK;
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,
397 uint8_t *ftfx_fstat)
399 uint8_t command[12] = {faddr & 0xff, (faddr >> 8) & 0xff, (faddr >> 16) & 0xff, fcmd,
400 fccob7, fccob6, fccob5, fccob4,
401 fccobb, fccoba, fccob9, fccob8};
402 int result, i;
403 uint8_t buffer;
405 /* wait for done */
406 for (i = 0; i < 50; i++) {
407 result =
408 target_read_memory(bank->target, FTFx_FSTAT, 1, 1, &buffer);
410 if (result != ERROR_OK)
411 return result;
413 if (buffer & 0x80)
414 break;
416 buffer = 0x00;
419 if (buffer != 0x80) {
420 /* reset error flags */
421 buffer = 0x30;
422 result =
423 target_write_memory(bank->target, FTFx_FSTAT, 1, 1, &buffer);
424 if (result != ERROR_OK)
425 return result;
428 result = target_write_memory(bank->target, FTFx_FCCOB3, 4, 3, command);
430 if (result != ERROR_OK)
431 return result;
433 /* start command */
434 buffer = 0x80;
435 result = target_write_memory(bank->target, FTFx_FSTAT, 1, 1, &buffer);
436 if (result != ERROR_OK)
437 return result;
439 /* wait for done */
440 for (i = 0; i < 240; i++) { /* Need Entire Erase Nemui Changed */
441 result =
442 target_read_memory(bank->target, FTFx_FSTAT, 1, 1, ftfx_fstat);
444 if (result != ERROR_OK)
445 return result;
447 if (*ftfx_fstat & 0x80)
448 break;
451 if ((*ftfx_fstat & 0xf0) != 0x80) {
452 LOG_ERROR
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;
460 return ERROR_OK;
463 static int kinetis_mass_erase(struct flash_bank *bank)
465 int result;
466 uint8_t ftfx_fstat;
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)
480 return result;*/
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;
492 return ERROR_OK;
495 static int kinetis_erase(struct flash_bank *bank, int first, int last)
497 int result, i;
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++) {
517 uint8_t ftfx_fstat;
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;
530 if (first == 0) {
531 LOG_WARNING
532 ("flash configuration field erased, please reset the device");
535 return ERROR_OK;
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;
542 uint8_t buf[8];
543 uint32_t wc;
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;
552 if (kinfo->klxx) {
553 /* fallback to longword write */
554 fallback = 1;
555 LOG_WARNING("Kinetis L Series supports Program Longword execution only.");
556 LOG_DEBUG("flash write into PFLASH @08%X", offset);
558 } else if (kinfo->flash_class == FC_FLEX_NVM) {
559 uint8_t ftfx_fstat;
561 LOG_DEBUG("flash write into FlexNVM @%08X", 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)
573 return result;
575 if (!(buf[0] & (1 << 1))) {
576 /* fallback to longword write */
577 fallback = 1;
579 LOG_WARNING("ram not ready, fallback to slow longword write (FCNFG: %02X)", buf[0]);
581 } else {
582 LOG_DEBUG("flash write into PFLASH @08%X", offset);
586 /* program section command */
587 if (fallback == 0) {
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];
600 uint8_t ftfx_fstat;
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
606 * sector.
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 @ %08X with length %d bytes",
636 offset + i, wc*4);
638 /* write data to flexram as whole-words */
639 result = target_write_memory(bank->target, FLEXRAM, 4, wc,
640 buffer + i);
642 if (result != ERROR_OK) {
643 LOG_ERROR("target_write_memory failed");
644 return result;
647 /* write the residual words to the flexram */
648 if (residual_wc) {
649 result = target_write_memory(bank->target,
650 FLEXRAM+4*wc,
651 4, residual_wc,
652 residual_buffer);
654 if (result != ERROR_OK) {
655 LOG_ERROR("target_write_memory failed");
656 return result;
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)) {
672 if (count & 0x3) {
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");
679 return ERROR_FAIL;
681 LOG_INFO("odd number of bytes to write (%d), extending to %d "
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 "
696 "memory accesses");
698 for (i = 0; i < count; i += 4) {
699 uint8_t ftfx_fstat;
701 LOG_DEBUG("write longword @ %08X", 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;
715 } else {
716 LOG_ERROR("Flash write strategy not implemented");
717 return ERROR_FLASH_OPERATION_FAILED;
720 return ERROR_OK;
723 static int kinetis_read_part_info(struct flash_bank *bank)
725 int result, i;
726 uint32_t offset = 0;
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)
736 return result;
738 /* Kinetis L Series SubFamily Check */
739 kinfo->klxx = 0;
740 i = (kinfo->sim_sdid >> 20) & 0x0F;
741 if (i == 1) {
742 kinfo->klxx = 1;
743 granularity = 0;
744 } else
745 granularity = (kinfo->sim_sdid >> 7) & 0x03;
747 result = target_read_u32(target, SIM_FCFG1, &kinfo->sim_fcfg1);
748 if (result != ERROR_OK)
749 return result;
751 result = target_read_u32(target, SIM_FCFG2, &kinfo->sim_fcfg2);
752 if (result != ERROR_OK)
753 return result;
754 fcfg2_pflsh = (kinfo->sim_fcfg2 >> 23) & 0x01;
756 LOG_DEBUG("SDID: 0x%08X FCFG1: 0x%08X FCFG2: 0x%08X", 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 */
764 if (!fcfg2_pflsh) {
765 switch (fcfg1_nvmsize) {
766 case 0x03:
767 case 0x07:
768 case 0x09:
769 case 0x0b:
770 nvm_size = 1 << (14 + (fcfg1_nvmsize >> 1));
771 break;
772 case 0x0f:
773 if (granularity == 3)
774 nvm_size = 512<<10;
775 else
776 nvm_size = 256<<10;
777 break;
778 default:
779 nvm_size = 0;
780 break;
783 switch (fcfg1_eesize) {
784 case 0x00:
785 case 0x01:
786 case 0x02:
787 case 0x03:
788 case 0x04:
789 case 0x05:
790 case 0x06:
791 case 0x07:
792 case 0x08:
793 case 0x09:
794 ee_size = (16 << (10 - fcfg1_eesize));
795 break;
796 default:
797 ee_size = 0;
798 break;
802 switch (fcfg1_pfsize) {
803 case 0x03:
804 case 0x05:
805 case 0x07:
806 case 0x09:
807 case 0x0b:
808 case 0x0d:
809 pf_size = 1 << (14 + (fcfg1_pfsize >> 1));
810 break;
811 case 0x0f:
812 if (granularity == 3)
813 pf_size = 1024<<10;
814 else if (fcfg2_pflsh)
815 pf_size = 512<<10;
816 else
817 pf_size = 256<<10;
818 break;
819 default:
820 pf_size = 0;
821 break;
824 LOG_DEBUG("FlexNVM: %d PFlash: %d FlexRAM: %d PFLSH: %d",
825 nvm_size, pf_size, ee_size, fcfg2_pflsh);
826 if (kinfo->klxx)
827 num_blocks = 1;
828 else
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
840 * parameters.
842 if (kinfo->flash_class != FC_AUTO) {
843 if (kinfo->bank_ordinal != (unsigned) bank->bank_number) {
844 LOG_WARNING("Flash ordinal/bank number mismatch");
845 reassign = 1;
846 } else if (kinfo->granularity != granularity) {
847 LOG_WARNING("Flash granularity mismatch");
848 reassign = 1;
849 } else {
850 switch (kinfo->flash_class) {
851 case FC_PFLASH:
852 if (kinfo->bank_ordinal >= first_nvm_bank) {
853 LOG_WARNING("Class mismatch, bank %d is not PFlash", bank->bank_number);
854 reassign = 1;
855 } else if (bank->size != (pf_size / num_pflash_blocks)) {
856 LOG_WARNING("PFlash size mismatch");
857 reassign = 1;
858 } else if (bank->base !=
859 (0x00000000 + bank->size * kinfo->bank_ordinal)) {
860 LOG_WARNING("PFlash address range mismatch");
861 reassign = 1;
862 } else if (kinfo->sector_size !=
863 kinetis_flash_params[granularity].pflash_sector_size_bytes) {
864 LOG_WARNING("PFlash sector size mismatch");
865 reassign = 1;
866 } else {
867 LOG_DEBUG("PFlash bank %d already configured okay",
868 kinfo->bank_ordinal);
870 break;
871 case FC_FLEX_NVM:
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);
875 reassign = 1;
876 } else if (bank->size != (nvm_size / num_nvm_blocks)) {
877 LOG_WARNING("FlexNVM size mismatch");
878 reassign = 1;
879 } else if (bank->base !=
880 (0x10000000 + bank->size * kinfo->bank_ordinal)) {
881 LOG_WARNING("FlexNVM address range mismatch");
882 reassign = 1;
883 } else if (kinfo->sector_size !=
884 kinetis_flash_params[granularity].nvm_sector_size_bytes) {
885 LOG_WARNING("FlexNVM sector size mismatch");
886 reassign = 1;
887 } else {
888 LOG_DEBUG("FlexNVM bank %d already configured okay",
889 kinfo->bank_ordinal);
891 break;
892 case FC_FLEX_RAM:
893 if (kinfo->bank_ordinal != num_blocks) {
894 LOG_WARNING("Class mismatch, bank %d is not FlexRAM", bank->bank_number);
895 reassign = 1;
896 } else if (bank->size != ee_size) {
897 LOG_WARNING("FlexRAM size mismatch");
898 reassign = 1;
899 } else if (bank->base != FLEXRAM) {
900 LOG_WARNING("FlexRAM address mismatch");
901 reassign = 1;
902 } else if (kinfo->sector_size !=
903 kinetis_flash_params[granularity].nvm_sector_size_bytes) {
904 LOG_WARNING("FlexRAM sector size mismatch");
905 reassign = 1;
906 } else {
907 LOG_DEBUG("FlexRAM bank %d already configured okay", kinfo->bank_ordinal);
909 break;
911 default:
912 LOG_WARNING("Unknown or inconsistent flash class");
913 reassign = 1;
914 break;
917 } else {
918 LOG_INFO("Probing flash info for bank %d", bank->bank_number);
919 reassign = 1;
922 if (!reassign)
923 return ERROR_OK;
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;
944 } else {
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;
950 if (bank->sectors) {
951 free(bank->sectors);
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;
967 return ERROR_OK;
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;
984 if (kinfo->sim_sdid)
985 return ERROR_OK;
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);
1003 return ERROR_OK;
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) {
1016 int result;
1017 uint8_t ftfx_fstat;
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)
1023 return result;
1025 if (ftfx_fstat & 0x01) {
1026 /* the whole bank is not erased, check sector-by-sector */
1027 int i;
1028 for (i = 0; i < bank->num_sectors; i++) {
1029 /* normal margin */
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);
1035 } else {
1036 LOG_DEBUG("Ignoring errored PFlash sector blank-check");
1037 bank->sectors[i].is_erased = -1;
1040 } else {
1041 /* the whole bank is erased, update all sectors */
1042 int i;
1043 for (i = 0; i < bank->num_sectors; i++)
1044 bank->sectors[i].is_erased = 1;
1046 } else {
1047 LOG_WARNING("kinetis_blank_check not supported yet for FlexNVM");
1048 return ERROR_FLASH_OPERATION_FAILED;
1051 return ERROR_OK;
1054 static int kinetis_flash_read(struct flash_bank *bank,
1055 uint8_t *buffer, uint32_t offset, uint32_t count)
1057 LOG_WARNING("kinetis_flash_read not supported yet");
1059 if (bank->target->state != TARGET_HALTED) {
1060 LOG_ERROR("Target not halted");
1061 return ERROR_TARGET_NOT_HALTED;
1064 return ERROR_FLASH_OPERATION_FAILED;
1067 struct flash_driver kinetis_flash = {
1068 .name = "kinetis",
1069 .flash_bank_command = kinetis_flash_bank_command,
1070 .erase = kinetis_erase,
1071 .protect = kinetis_protect,
1072 .write = kinetis_write,
1073 .read = kinetis_flash_read,
1074 .probe = kinetis_probe,
1075 .auto_probe = kinetis_auto_probe,
1076 .erase_check = kinetis_blank_check,
1077 .protect_check = kinetis_protect_check,
1078 .info = kinetis_info,