kinetis : Detect MCU flash parameters based on the SDID register.
[openocd.git] / src / flash / nor / kinetis.c
1 /***************************************************************************
2 * Copyright (C) 2011 by Mathias Kuester *
3 * kesmtp@freenet.de *
4 * *
5 * Copyright (C) 2011 sleep(5) ltd *
6 * tomas@sleepfive.com *
7 * *
8 * Copyright (C) 2012 by Christopher D. Kilgour *
9 * techie at whiterocker.com *
10 * *
11 * 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 ***************************************************************************/
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include "imp.h"
35 #include <helper/binarybuffer.h>
36 #include <target/algorithm.h>
37 #include <target/armv7m.h>
38
39 /*
40 * Implementation Notes
41 *
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.
46 *
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.
52 *
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.
58 *
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.
65 *
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.
76 *
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.
86 *
87 */
88
89 const struct {
90 unsigned pflash_sector_size_bytes;
91 unsigned nvm_sector_size_bytes;
92 unsigned num_blocks;
93 } kinetis_flash_params[4] = {
94 { 1<<10, 1<<10, 2 },
95 { 2<<10, 1<<10, 2 },
96 { 2<<10, 2<<10, 2 },
97 { 4<<10, 4<<10, 4 }
98 };
99
100 /* Addressess */
101 #define FLEXRAM 0x14000000
102 #define FTFx_FSTAT 0x40020000
103 #define FTFx_FCNFG 0x40020001
104 #define FTFx_FCCOB3 0x40020004
105 #define FTFx_FPROT3 0x40020010
106 #define SIM_SDID 0x40048024
107 #define SIM_FCFG1 0x4004804c
108 #define SIM_FCFG2 0x40048050
109
110 /* Commands */
111 #define FTFx_CMD_BLOCKSTAT 0x00
112 #define FTFx_CMD_SECTSTAT 0x01
113 #define FTFx_CMD_LWORDPROG 0x06
114 #define FTFx_CMD_SECTERASE 0x09
115 #define FTFx_CMD_SECTWRITE 0x0b
116 #define FTFx_CMD_SETFLEXRAM 0x81
117 #define FTFx_CMD_MASSERASE 0x44
118
119 /* The Kinetis K series uses the following SDID layout :
120 * Bit 31-16 : 0
121 * Bit 15-12 : REVID
122 * Bit 11-7 : DIEID
123 * Bit 6-4 : FAMID
124 * Bit 3-0 : PINID
125 *
126 * The Kinetis KL series uses the following SDID layout :
127 * Bit 31-28 : FAMID
128 * Bit 27-24 : SUBFAMID
129 * Bit 23-20 : SERIESID
130 * Bit 19-16 : SRAMSIZE
131 * Bit 15-12 : REVID
132 * Bit 6-4 : Reserved (0)
133 * Bit 3-0 : PINID
134 *
135 * SERIESID should be 1 for the KL-series so we assume that if
136 * bits 31-16 are 0 then it's a K-series MCU.
137 */
138
139 #define KINETIS_SDID_K_SERIES_MASK 0x0000FFFF
140
141 #define KINETIS_SDID_DIEID_MASK 0x00000F80
142 #define KINETIS_SDID_DIEID_K_A 0x00000100
143 #define KINETIS_SDID_DIEID_K_B 0x00000200
144 #define KINETIS_SDID_DIEID_KL 0x00000000
145
146 /* We can't rely solely on the FAMID field to determine the MCU
147 * type since some FAMID values identify multiple MCUs with
148 * different flash sector sizes (K20 and K22 for instance).
149 * Therefore we combine it with the DIEID bits which may possibly
150 * break if Freescale bumps the DIEID for a particular MCU. */
151 #define KINETIS_K_SDID_TYPE_MASK 0x00000FF0
152 #define KINETIS_K_SDID_K10 0x00000000
153 #define KINETIS_K_SDID_K11 0x00000220
154 #define KINETIS_K_SDID_K12 0x00000200
155 #define KINETIS_K_SDID_K20 0x00000290
156 #define KINETIS_K_SDID_K21 0x00000230
157 #define KINETIS_K_SDID_K22 0x00000210
158 #define KINETIS_K_SDID_K30 0x00000120
159 #define KINETIS_K_SDID_K40 0x00000130
160 #define KINETIS_K_SDID_K50 0x000000E0
161 #define KINETIS_K_SDID_K51 0x000000F0
162 #define KINETIS_K_SDID_K53 0x00000170
163 #define KINETIS_K_SDID_K60 0x000001C0
164 #define KINETIS_K_SDID_K70 0x000001D0
165
166 #define KINETIS_KL_SDID_SERIESID_MASK 0x00F00000
167 #define KINETIS_KL_SDID_SERIESID_KL 0x00100000
168
169 struct kinetis_flash_bank {
170 unsigned granularity;
171 unsigned bank_ordinal;
172 uint32_t sector_size;
173 uint32_t protection_size;
174 uint32_t klxx;
175
176 uint32_t sim_sdid;
177 uint32_t sim_fcfg1;
178 uint32_t sim_fcfg2;
179
180 enum {
181 FC_AUTO = 0,
182 FC_PFLASH,
183 FC_FLEX_NVM,
184 FC_FLEX_RAM,
185 } flash_class;
186 };
187
188 FLASH_BANK_COMMAND_HANDLER(kinetis_flash_bank_command)
189 {
190 struct kinetis_flash_bank *bank_info;
191
192 if (CMD_ARGC < 6)
193 return ERROR_COMMAND_SYNTAX_ERROR;
194
195 LOG_INFO("add flash_bank kinetis %s", bank->name);
196
197 bank_info = malloc(sizeof(struct kinetis_flash_bank));
198
199 memset(bank_info, 0, sizeof(struct kinetis_flash_bank));
200
201 bank->driver_priv = bank_info;
202
203 return ERROR_OK;
204 }
205
206 /* Kinetis Program-LongWord Microcodes */
207 static const uint8_t kinetis_flash_write_code[] = {
208 /* Params:
209 * r0 - workarea buffer
210 * r1 - target address
211 * r2 - wordcount
212 * Clobbered:
213 * r4 - tmp
214 * r5 - tmp
215 * r6 - tmp
216 * r7 - tmp
217 */
218
219 /* .L1: */
220 /* for(register uint32_t i=0;i<wcount;i++){ */
221 0x04, 0x1C, /* mov r4, r0 */
222 0x00, 0x23, /* mov r3, #0 */
223 /* .L2: */
224 0x0E, 0x1A, /* sub r6, r1, r0 */
225 0xA6, 0x19, /* add r6, r4, r6 */
226 0x93, 0x42, /* cmp r3, r2 */
227 0x16, 0xD0, /* beq .L9 */
228 /* .L5: */
229 /* while((FTFx_FSTAT&FTFA_FSTAT_CCIF_MASK) != FTFA_FSTAT_CCIF_MASK){}; */
230 0x0B, 0x4D, /* ldr r5, .L10 */
231 0x2F, 0x78, /* ldrb r7, [r5] */
232 0x7F, 0xB2, /* sxtb r7, r7 */
233 0x00, 0x2F, /* cmp r7, #0 */
234 0xFA, 0xDA, /* bge .L5 */
235 /* FTFx_FSTAT = FTFA_FSTAT_ACCERR_MASK|FTFA_FSTAT_FPVIOL_MASK|FTFA_FSTAT_RDCO */
236 0x70, 0x27, /* mov r7, #112 */
237 0x2F, 0x70, /* strb r7, [r5] */
238 /* FTFx_FCCOB3 = faddr; */
239 0x09, 0x4F, /* ldr r7, .L10+4 */
240 0x3E, 0x60, /* str r6, [r7] */
241 0x06, 0x27, /* mov r7, #6 */
242 /* FTFx_FCCOB0 = 0x06; */
243 0x08, 0x4E, /* ldr r6, .L10+8 */
244 0x37, 0x70, /* strb r7, [r6] */
245 /* FTFx_FCCOB7 = *pLW; */
246 0x80, 0xCC, /* ldmia r4!, {r7} */
247 0x08, 0x4E, /* ldr r6, .L10+12 */
248 0x37, 0x60, /* str r7, [r6] */
249 /* FTFx_FSTAT = FTFA_FSTAT_CCIF_MASK; */
250 0x80, 0x27, /* mov r7, #128 */
251 0x2F, 0x70, /* strb r7, [r5] */
252 /* .L4: */
253 /* while((FTFx_FSTAT&FTFA_FSTAT_CCIF_MASK) != FTFA_FSTAT_CCIF_MASK){}; */
254 0x2E, 0x78, /* ldrb r6, [r5] */
255 0x77, 0xB2, /* sxtb r7, r6 */
256 0x00, 0x2F, /* cmp r7, #0 */
257 0xFB, 0xDA, /* bge .L4 */
258 0x01, 0x33, /* add r3, r3, #1 */
259 0xE4, 0xE7, /* b .L2 */
260 /* .L9: */
261 0x00, 0xBE, /* bkpt #0 */
262 /* .L10: */
263 0x00, 0x00, 0x02, 0x40, /* .word 1073872896 */
264 0x04, 0x00, 0x02, 0x40, /* .word 1073872900 */
265 0x07, 0x00, 0x02, 0x40, /* .word 1073872903 */
266 0x08, 0x00, 0x02, 0x40, /* .word 1073872904 */
267 };
268
269 /* Program LongWord Block Write */
270 static int kinetis_write_block(struct flash_bank *bank, uint8_t *buffer,
271 uint32_t offset, uint32_t wcount)
272 {
273 struct target *target = bank->target;
274 uint32_t buffer_size = 2048; /* Default minimum value */
275 struct working_area *write_algorithm;
276 struct working_area *source;
277 uint32_t address = bank->base + offset;
278 struct reg_param reg_params[3];
279 struct armv7m_algorithm armv7m_info;
280 int retval = ERROR_OK;
281
282 /* Params:
283 * r0 - workarea buffer
284 * r1 - target address
285 * r2 - wordcount
286 * Clobbered:
287 * r4 - tmp
288 * r5 - tmp
289 * r6 - tmp
290 * r7 - tmp
291 */
292
293 /* Increase buffer_size if needed */
294 if (buffer_size < (target->working_area_size/2))
295 buffer_size = (target->working_area_size/2);
296
297 LOG_INFO("Kinetis: FLASH Write ...");
298
299 /* check code alignment */
300 if (offset & 0x1) {
301 LOG_WARNING("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset);
302 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
303 }
304
305 /* allocate working area with flash programming code */
306 if (target_alloc_working_area(target, sizeof(kinetis_flash_write_code),
307 &write_algorithm) != ERROR_OK) {
308 LOG_WARNING("no working area available, can't do block memory writes");
309 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
310 }
311
312 retval = target_write_buffer(target, write_algorithm->address,
313 sizeof(kinetis_flash_write_code), kinetis_flash_write_code);
314 if (retval != ERROR_OK)
315 return retval;
316
317 /* memory buffer */
318 while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) {
319 buffer_size /= 4;
320 if (buffer_size <= 256) {
321 /* free working area, write algorithm already allocated */
322 target_free_working_area(target, write_algorithm);
323
324 LOG_WARNING("No large enough working area available, can't do block memory writes");
325 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
326 }
327 }
328
329 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
330 armv7m_info.core_mode = ARM_MODE_THREAD;
331
332 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT); /* *pLW (*buffer) */
333 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* faddr */
334 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* number of words to program */
335
336 /* write code buffer and use Flash programming code within kinetis */
337 /* Set breakpoint to 0 with time-out of 1000 ms */
338 while (wcount > 0) {
339 uint32_t thisrun_count = (wcount > (buffer_size / 4)) ? (buffer_size / 4) : wcount;
340
341 retval = target_write_buffer(target, write_algorithm->address, 8,
342 kinetis_flash_write_code);
343 if (retval != ERROR_OK)
344 break;
345
346 retval = target_write_buffer(target, source->address, thisrun_count * 4, buffer);
347 if (retval != ERROR_OK)
348 break;
349
350 buf_set_u32(reg_params[0].value, 0, 32, source->address);
351 buf_set_u32(reg_params[1].value, 0, 32, address);
352 buf_set_u32(reg_params[2].value, 0, 32, thisrun_count);
353
354 retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
355 write_algorithm->address, 0, 100000, &armv7m_info);
356 if (retval != ERROR_OK) {
357 LOG_ERROR("Error executing kinetis Flash programming algorithm");
358 retval = ERROR_FLASH_OPERATION_FAILED;
359 break;
360 }
361
362 buffer += thisrun_count * 4;
363 address += thisrun_count * 4;
364 wcount -= thisrun_count;
365 }
366
367 target_free_working_area(target, source);
368 target_free_working_area(target, write_algorithm);
369
370 destroy_reg_param(&reg_params[0]);
371 destroy_reg_param(&reg_params[1]);
372 destroy_reg_param(&reg_params[2]);
373
374 return retval;
375 }
376
377 static int kinetis_protect(struct flash_bank *bank, int set, int first, int last)
378 {
379 LOG_WARNING("kinetis_protect not supported yet");
380 /* FIXME: TODO */
381
382 if (bank->target->state != TARGET_HALTED) {
383 LOG_ERROR("Target not halted");
384 return ERROR_TARGET_NOT_HALTED;
385 }
386
387 return ERROR_FLASH_BANK_INVALID;
388 }
389
390 static int kinetis_protect_check(struct flash_bank *bank)
391 {
392 struct kinetis_flash_bank *kinfo = bank->driver_priv;
393
394 if (bank->target->state != TARGET_HALTED) {
395 LOG_ERROR("Target not halted");
396 return ERROR_TARGET_NOT_HALTED;
397 }
398
399 if (kinfo->flash_class == FC_PFLASH) {
400 int result;
401 uint8_t buffer[4];
402 uint32_t fprot, psec;
403 int i, b;
404
405 /* read protection register */
406 result = target_read_memory(bank->target, FTFx_FPROT3, 1, 4, buffer);
407
408 if (result != ERROR_OK)
409 return result;
410
411 fprot = target_buffer_get_u32(bank->target, buffer);
412
413 /*
414 * Every bit protects 1/32 of the full flash (not necessarily
415 * just this bank), but we enforce the bank ordinals for
416 * PFlash to start at zero.
417 */
418 b = kinfo->bank_ordinal * (bank->size / kinfo->protection_size);
419 for (psec = 0, i = 0; i < bank->num_sectors; i++) {
420 if ((fprot >> b) & 1)
421 bank->sectors[i].is_protected = 0;
422 else
423 bank->sectors[i].is_protected = 1;
424
425 psec += bank->sectors[i].size;
426
427 if (psec >= kinfo->protection_size) {
428 psec = 0;
429 b++;
430 }
431 }
432 } else {
433 LOG_ERROR("Protection checks for FlexNVM not yet supported");
434 return ERROR_FLASH_BANK_INVALID;
435 }
436
437 return ERROR_OK;
438 }
439
440 static int kinetis_ftfx_command(struct flash_bank *bank, uint8_t fcmd, uint32_t faddr,
441 uint8_t fccob4, uint8_t fccob5, uint8_t fccob6, uint8_t fccob7,
442 uint8_t fccob8, uint8_t fccob9, uint8_t fccoba, uint8_t fccobb,
443 uint8_t *ftfx_fstat)
444 {
445 uint8_t command[12] = {faddr & 0xff, (faddr >> 8) & 0xff, (faddr >> 16) & 0xff, fcmd,
446 fccob7, fccob6, fccob5, fccob4,
447 fccobb, fccoba, fccob9, fccob8};
448 int result, i;
449 uint8_t buffer;
450
451 /* wait for done */
452 for (i = 0; i < 50; i++) {
453 result =
454 target_read_memory(bank->target, FTFx_FSTAT, 1, 1, &buffer);
455
456 if (result != ERROR_OK)
457 return result;
458
459 if (buffer & 0x80)
460 break;
461
462 buffer = 0x00;
463 }
464
465 if (buffer != 0x80) {
466 /* reset error flags */
467 buffer = 0x30;
468 result =
469 target_write_memory(bank->target, FTFx_FSTAT, 1, 1, &buffer);
470 if (result != ERROR_OK)
471 return result;
472 }
473
474 result = target_write_memory(bank->target, FTFx_FCCOB3, 4, 3, command);
475
476 if (result != ERROR_OK)
477 return result;
478
479 /* start command */
480 buffer = 0x80;
481 result = target_write_memory(bank->target, FTFx_FSTAT, 1, 1, &buffer);
482 if (result != ERROR_OK)
483 return result;
484
485 /* wait for done */
486 for (i = 0; i < 240; i++) { /* Need Entire Erase Nemui Changed */
487 result =
488 target_read_memory(bank->target, FTFx_FSTAT, 1, 1, ftfx_fstat);
489
490 if (result != ERROR_OK)
491 return result;
492
493 if (*ftfx_fstat & 0x80)
494 break;
495 }
496
497 if ((*ftfx_fstat & 0xf0) != 0x80) {
498 LOG_ERROR
499 ("ftfx command failed FSTAT: %02X FCCOB: %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X",
500 *ftfx_fstat, command[3], command[2], command[1], command[0],
501 command[7], command[6], command[5], command[4],
502 command[11], command[10], command[9], command[8]);
503 return ERROR_FLASH_OPERATION_FAILED;
504 }
505
506 return ERROR_OK;
507 }
508
509 static int kinetis_mass_erase(struct flash_bank *bank)
510 {
511 int result;
512 uint8_t ftfx_fstat;
513
514 if (bank->target->state != TARGET_HALTED) {
515 LOG_ERROR("Target not halted");
516 return ERROR_TARGET_NOT_HALTED;
517 }
518
519 /* check if whole bank is blank */
520 LOG_INFO("Kinetis L Series Erase All Blocks");
521 /* set command and sector address */
522 result = kinetis_ftfx_command(bank, FTFx_CMD_MASSERASE, 0,
523 0, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat);
524 /* Anyway Result, write unsecure byte */
525 /* if (result != ERROR_OK)
526 return result;*/
527
528 /* Write to MCU security status unsecure in Flash security byte(Work around) */
529 LOG_INFO("Write to MCU security status unsecure Anyway!");
530 uint8_t padding[4] = {0xFE, 0xFF, 0xFF, 0xFF}; /* Write 0xFFFFFFFE */
531
532 result = kinetis_ftfx_command(bank, FTFx_CMD_LWORDPROG, (bank->base + 0x0000040C),
533 padding[3], padding[2], padding[1], padding[0],
534 0, 0, 0, 0, &ftfx_fstat);
535 if (result != ERROR_OK)
536 return ERROR_FLASH_OPERATION_FAILED;
537
538 return ERROR_OK;
539 }
540
541 static int kinetis_erase(struct flash_bank *bank, int first, int last)
542 {
543 int result, i;
544 struct kinetis_flash_bank *kinfo = bank->driver_priv;
545
546 if (bank->target->state != TARGET_HALTED) {
547 LOG_ERROR("Target not halted");
548 return ERROR_TARGET_NOT_HALTED;
549 }
550
551 if ((first > bank->num_sectors) || (last > bank->num_sectors))
552 return ERROR_FLASH_OPERATION_FAILED;
553
554 if ((first == 0) && (last == (bank->num_sectors - 1)) && (kinfo->klxx))
555 return kinetis_mass_erase(bank);
556
557 /*
558 * FIXME: TODO: use the 'Erase Flash Block' command if the
559 * requested erase is PFlash or NVM and encompasses the entire
560 * block. Should be quicker.
561 */
562 for (i = first; i <= last; i++) {
563 uint8_t ftfx_fstat;
564 /* set command and sector address */
565 result = kinetis_ftfx_command(bank, FTFx_CMD_SECTERASE, bank->base + bank->sectors[i].offset,
566 0, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat);
567
568 if (result != ERROR_OK) {
569 LOG_WARNING("erase sector %d failed", i);
570 return ERROR_FLASH_OPERATION_FAILED;
571 }
572
573 bank->sectors[i].is_erased = 1;
574 }
575
576 if (first == 0) {
577 LOG_WARNING
578 ("flash configuration field erased, please reset the device");
579 }
580
581 return ERROR_OK;
582 }
583
584 static int kinetis_write(struct flash_bank *bank, uint8_t *buffer,
585 uint32_t offset, uint32_t count)
586 {
587 unsigned int i, result, fallback = 0;
588 uint8_t buf[8];
589 uint32_t wc;
590 struct kinetis_flash_bank *kinfo = bank->driver_priv;
591 uint8_t *new_buffer = NULL;
592
593 if (bank->target->state != TARGET_HALTED) {
594 LOG_ERROR("Target not halted");
595 return ERROR_TARGET_NOT_HALTED;
596 }
597
598 if (kinfo->klxx) {
599 /* fallback to longword write */
600 fallback = 1;
601 LOG_WARNING("Kinetis L Series supports Program Longword execution only.");
602 LOG_DEBUG("flash write into PFLASH @08%" PRIX32, offset);
603
604 } else if (kinfo->flash_class == FC_FLEX_NVM) {
605 uint8_t ftfx_fstat;
606
607 LOG_DEBUG("flash write into FlexNVM @%08" PRIX32, offset);
608
609 /* make flex ram available */
610 result = kinetis_ftfx_command(bank, FTFx_CMD_SETFLEXRAM, 0x00ff0000, 0, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat);
611
612 if (result != ERROR_OK)
613 return ERROR_FLASH_OPERATION_FAILED;
614
615 /* check if ram ready */
616 result = target_read_memory(bank->target, FTFx_FCNFG, 1, 1, buf);
617
618 if (result != ERROR_OK)
619 return result;
620
621 if (!(buf[0] & (1 << 1))) {
622 /* fallback to longword write */
623 fallback = 1;
624
625 LOG_WARNING("ram not ready, fallback to slow longword write (FCNFG: %02X)", buf[0]);
626 }
627 } else {
628 LOG_DEBUG("flash write into PFLASH @08%" PRIX32, offset);
629 }
630
631
632 /* program section command */
633 if (fallback == 0) {
634 /*
635 * Kinetis uses different terms for the granularity of
636 * sector writes, e.g. "phrase" or "128 bits". We use
637 * the generic term "chunk". The largest possible
638 * Kinetis "chunk" is 16 bytes (128 bits).
639 */
640 unsigned prog_section_chunk_bytes = kinfo->sector_size >> 8;
641 /* assume the NVM sector size is half the FlexRAM size */
642 unsigned prog_size_bytes = MIN(kinfo->sector_size,
643 kinetis_flash_params[kinfo->granularity].nvm_sector_size_bytes);
644 for (i = 0; i < count; i += prog_size_bytes) {
645 uint8_t residual_buffer[16];
646 uint8_t ftfx_fstat;
647 uint32_t section_count = prog_size_bytes / prog_section_chunk_bytes;
648 uint32_t residual_wc = 0;
649
650 /*
651 * Assume the word count covers an entire
652 * sector.
653 */
654 wc = prog_size_bytes / 4;
655
656 /*
657 * If bytes to be programmed are less than the
658 * full sector, then determine the number of
659 * full-words to program, and put together the
660 * residual buffer so that a full "section"
661 * may always be programmed.
662 */
663 if ((count - i) < prog_size_bytes) {
664 /* number of bytes to program beyond full section */
665 unsigned residual_bc = (count-i) % prog_section_chunk_bytes;
666
667 /* number of complete words to copy directly from buffer */
668 wc = (count - i) / 4;
669
670 /* number of total sections to write, including residual */
671 section_count = DIV_ROUND_UP((count-i), prog_section_chunk_bytes);
672
673 /* any residual bytes delivers a whole residual section */
674 residual_wc = (residual_bc ? prog_section_chunk_bytes : 0)/4;
675
676 /* clear residual buffer then populate residual bytes */
677 (void) memset(residual_buffer, 0xff, prog_section_chunk_bytes);
678 (void) memcpy(residual_buffer, &buffer[i+4*wc], residual_bc);
679 }
680
681 LOG_DEBUG("write section @ %08" PRIX32 " with length %" PRIu32 " bytes",
682 offset + i, (uint32_t)wc*4);
683
684 /* write data to flexram as whole-words */
685 result = target_write_memory(bank->target, FLEXRAM, 4, wc,
686 buffer + i);
687
688 if (result != ERROR_OK) {
689 LOG_ERROR("target_write_memory failed");
690 return result;
691 }
692
693 /* write the residual words to the flexram */
694 if (residual_wc) {
695 result = target_write_memory(bank->target,
696 FLEXRAM+4*wc,
697 4, residual_wc,
698 residual_buffer);
699
700 if (result != ERROR_OK) {
701 LOG_ERROR("target_write_memory failed");
702 return result;
703 }
704 }
705
706 /* execute section-write command */
707 result = kinetis_ftfx_command(bank, FTFx_CMD_SECTWRITE, bank->base + offset + i,
708 section_count>>8, section_count, 0, 0,
709 0, 0, 0, 0, &ftfx_fstat);
710
711 if (result != ERROR_OK)
712 return ERROR_FLASH_OPERATION_FAILED;
713 }
714 }
715 /* program longword command, not supported in "SF3" devices */
716 else if ((kinfo->granularity != 3) || (kinfo->klxx)) {
717
718 if (count & 0x3) {
719 uint32_t old_count = count;
720 count = (old_count | 3) + 1;
721 new_buffer = malloc(count);
722 if (new_buffer == NULL) {
723 LOG_ERROR("odd number of bytes to write and no memory "
724 "for padding buffer");
725 return ERROR_FAIL;
726 }
727 LOG_INFO("odd number of bytes to write (%" PRIu32 "), extending to %" PRIu32 " "
728 "and padding with 0xff", old_count, count);
729 memset(buffer, 0xff, count);
730 buffer = memcpy(new_buffer, buffer, old_count);
731 }
732
733 uint32_t words_remaining = count / 4;
734
735 /* try using a block write */
736 int retval = kinetis_write_block(bank, buffer, offset, words_remaining);
737
738 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
739 /* if block write failed (no sufficient working area),
740 * we use normal (slow) single word accesses */
741 LOG_WARNING("couldn't use block writes, falling back to single "
742 "memory accesses");
743
744 for (i = 0; i < count; i += 4) {
745 uint8_t ftfx_fstat;
746
747 LOG_DEBUG("write longword @ %08" PRIX32, (uint32_t)(offset + i));
748
749 uint8_t padding[4] = {0xff, 0xff, 0xff, 0xff};
750 memcpy(padding, buffer + i, MIN(4, count-i));
751
752 result = kinetis_ftfx_command(bank, FTFx_CMD_LWORDPROG, bank->base + offset + i,
753 padding[3], padding[2], padding[1], padding[0],
754 0, 0, 0, 0, &ftfx_fstat);
755
756 if (result != ERROR_OK)
757 return ERROR_FLASH_OPERATION_FAILED;
758 }
759 }
760
761 } else {
762 LOG_ERROR("Flash write strategy not implemented");
763 return ERROR_FLASH_OPERATION_FAILED;
764 }
765
766 return ERROR_OK;
767 }
768
769 static int kinetis_read_part_info(struct flash_bank *bank)
770 {
771 int result, i;
772 uint32_t offset = 0;
773 uint8_t fcfg1_nvmsize, fcfg1_pfsize, fcfg1_eesize, fcfg2_pflsh;
774 uint32_t nvm_size = 0, pf_size = 0, ee_size = 0;
775 unsigned granularity, num_blocks = 0, num_pflash_blocks = 0, num_nvm_blocks = 0,
776 first_nvm_bank = 0, reassign = 0;
777 struct target *target = bank->target;
778 struct kinetis_flash_bank *kinfo = bank->driver_priv;
779
780 result = target_read_u32(target, SIM_SDID, &kinfo->sim_sdid);
781 if (result != ERROR_OK)
782 return result;
783
784 kinfo->klxx = 0;
785
786 /* K-series MCU? */
787 if ((kinfo->sim_sdid & (~KINETIS_SDID_K_SERIES_MASK)) == 0) {
788 uint32_t mcu_type = kinfo->sim_sdid & KINETIS_K_SDID_TYPE_MASK;
789
790 switch (mcu_type) {
791 case KINETIS_K_SDID_K20:
792 /* 1kB sectors */
793 granularity = 0;
794 break;
795 case KINETIS_K_SDID_K30:
796 case KINETIS_K_SDID_K40:
797 case KINETIS_K_SDID_K50:
798 /* 2kB sectors, 1kB FlexNVM sectors */
799 granularity = 1;
800 break;
801 case KINETIS_K_SDID_K11:
802 case KINETIS_K_SDID_K12:
803 case KINETIS_K_SDID_K21:
804 case KINETIS_K_SDID_K22:
805 case KINETIS_K_SDID_K51:
806 case KINETIS_K_SDID_K53:
807 case KINETIS_K_SDID_K60:
808 /* 2kB sectors */
809 granularity = 2;
810 break;
811 case KINETIS_K_SDID_K10:
812 case KINETIS_K_SDID_K70:
813 /* 4kB sectors */
814 granularity = 3;
815 break;
816 default:
817 LOG_ERROR("Unsupported K-family FAMID");
818 return ERROR_FLASH_OPER_UNSUPPORTED;
819 }
820 }
821 /* KL-series? */
822 else if ((kinfo->sim_sdid & KINETIS_KL_SDID_SERIESID_MASK) == KINETIS_KL_SDID_SERIESID_KL) {
823 kinfo->klxx = 1;
824 granularity = 0;
825 } else {
826 LOG_ERROR("MCU is unsupported");
827 return ERROR_FLASH_OPER_UNSUPPORTED;
828 }
829
830 result = target_read_u32(target, SIM_FCFG1, &kinfo->sim_fcfg1);
831 if (result != ERROR_OK)
832 return result;
833
834 result = target_read_u32(target, SIM_FCFG2, &kinfo->sim_fcfg2);
835 if (result != ERROR_OK)
836 return result;
837 fcfg2_pflsh = (kinfo->sim_fcfg2 >> 23) & 0x01;
838
839 LOG_DEBUG("SDID: 0x%08" PRIX32 " FCFG1: 0x%08" PRIX32 " FCFG2: 0x%08" PRIX32, kinfo->sim_sdid,
840 kinfo->sim_fcfg1, kinfo->sim_fcfg2);
841
842 fcfg1_nvmsize = (uint8_t)((kinfo->sim_fcfg1 >> 28) & 0x0f);
843 fcfg1_pfsize = (uint8_t)((kinfo->sim_fcfg1 >> 24) & 0x0f);
844 fcfg1_eesize = (uint8_t)((kinfo->sim_fcfg1 >> 16) & 0x0f);
845
846 /* when the PFLSH bit is set, there is no FlexNVM/FlexRAM */
847 if (!fcfg2_pflsh) {
848 switch (fcfg1_nvmsize) {
849 case 0x03:
850 case 0x07:
851 case 0x09:
852 case 0x0b:
853 nvm_size = 1 << (14 + (fcfg1_nvmsize >> 1));
854 break;
855 case 0x0f:
856 if (granularity == 3)
857 nvm_size = 512<<10;
858 else
859 nvm_size = 256<<10;
860 break;
861 default:
862 nvm_size = 0;
863 break;
864 }
865
866 switch (fcfg1_eesize) {
867 case 0x00:
868 case 0x01:
869 case 0x02:
870 case 0x03:
871 case 0x04:
872 case 0x05:
873 case 0x06:
874 case 0x07:
875 case 0x08:
876 case 0x09:
877 ee_size = (16 << (10 - fcfg1_eesize));
878 break;
879 default:
880 ee_size = 0;
881 break;
882 }
883 }
884
885 switch (fcfg1_pfsize) {
886 case 0x03:
887 case 0x05:
888 case 0x07:
889 case 0x09:
890 case 0x0b:
891 case 0x0d:
892 pf_size = 1 << (14 + (fcfg1_pfsize >> 1));
893 break;
894 case 0x0f:
895 if (granularity == 3)
896 pf_size = 1024<<10;
897 else if (fcfg2_pflsh)
898 pf_size = 512<<10;
899 else
900 pf_size = 256<<10;
901 break;
902 default:
903 pf_size = 0;
904 break;
905 }
906
907 LOG_DEBUG("FlexNVM: %" PRIu32 " PFlash: %" PRIu32 " FlexRAM: %" PRIu32 " PFLSH: %d",
908 nvm_size, pf_size, ee_size, fcfg2_pflsh);
909 if (kinfo->klxx)
910 num_blocks = 1;
911 else
912 num_blocks = kinetis_flash_params[granularity].num_blocks;
913
914 num_pflash_blocks = num_blocks / (2 - fcfg2_pflsh);
915 first_nvm_bank = num_pflash_blocks;
916 num_nvm_blocks = num_blocks - num_pflash_blocks;
917
918 LOG_DEBUG("%d blocks total: %d PFlash, %d FlexNVM",
919 num_blocks, num_pflash_blocks, num_nvm_blocks);
920
921 /*
922 * If the flash class is already assigned, verify the
923 * parameters.
924 */
925 if (kinfo->flash_class != FC_AUTO) {
926 if (kinfo->bank_ordinal != (unsigned) bank->bank_number) {
927 LOG_WARNING("Flash ordinal/bank number mismatch");
928 reassign = 1;
929 } else if (kinfo->granularity != granularity) {
930 LOG_WARNING("Flash granularity mismatch");
931 reassign = 1;
932 } else {
933 switch (kinfo->flash_class) {
934 case FC_PFLASH:
935 if (kinfo->bank_ordinal >= first_nvm_bank) {
936 LOG_WARNING("Class mismatch, bank %d is not PFlash", bank->bank_number);
937 reassign = 1;
938 } else if (bank->size != (pf_size / num_pflash_blocks)) {
939 LOG_WARNING("PFlash size mismatch");
940 reassign = 1;
941 } else if (bank->base !=
942 (0x00000000 + bank->size * kinfo->bank_ordinal)) {
943 LOG_WARNING("PFlash address range mismatch");
944 reassign = 1;
945 } else if (kinfo->sector_size !=
946 kinetis_flash_params[granularity].pflash_sector_size_bytes) {
947 LOG_WARNING("PFlash sector size mismatch");
948 reassign = 1;
949 } else {
950 LOG_DEBUG("PFlash bank %d already configured okay",
951 kinfo->bank_ordinal);
952 }
953 break;
954 case FC_FLEX_NVM:
955 if ((kinfo->bank_ordinal >= num_blocks) ||
956 (kinfo->bank_ordinal < first_nvm_bank)) {
957 LOG_WARNING("Class mismatch, bank %d is not FlexNVM", bank->bank_number);
958 reassign = 1;
959 } else if (bank->size != (nvm_size / num_nvm_blocks)) {
960 LOG_WARNING("FlexNVM size mismatch");
961 reassign = 1;
962 } else if (bank->base !=
963 (0x10000000 + bank->size * kinfo->bank_ordinal)) {
964 LOG_WARNING("FlexNVM address range mismatch");
965 reassign = 1;
966 } else if (kinfo->sector_size !=
967 kinetis_flash_params[granularity].nvm_sector_size_bytes) {
968 LOG_WARNING("FlexNVM sector size mismatch");
969 reassign = 1;
970 } else {
971 LOG_DEBUG("FlexNVM bank %d already configured okay",
972 kinfo->bank_ordinal);
973 }
974 break;
975 case FC_FLEX_RAM:
976 if (kinfo->bank_ordinal != num_blocks) {
977 LOG_WARNING("Class mismatch, bank %d is not FlexRAM", bank->bank_number);
978 reassign = 1;
979 } else if (bank->size != ee_size) {
980 LOG_WARNING("FlexRAM size mismatch");
981 reassign = 1;
982 } else if (bank->base != FLEXRAM) {
983 LOG_WARNING("FlexRAM address mismatch");
984 reassign = 1;
985 } else if (kinfo->sector_size !=
986 kinetis_flash_params[granularity].nvm_sector_size_bytes) {
987 LOG_WARNING("FlexRAM sector size mismatch");
988 reassign = 1;
989 } else {
990 LOG_DEBUG("FlexRAM bank %d already configured okay", kinfo->bank_ordinal);
991 }
992 break;
993
994 default:
995 LOG_WARNING("Unknown or inconsistent flash class");
996 reassign = 1;
997 break;
998 }
999 }
1000 } else {
1001 LOG_INFO("Probing flash info for bank %d", bank->bank_number);
1002 reassign = 1;
1003 }
1004
1005 if (!reassign)
1006 return ERROR_OK;
1007
1008 kinfo->granularity = granularity;
1009
1010 if ((unsigned)bank->bank_number < num_pflash_blocks) {
1011 /* pflash, banks start at address zero */
1012 kinfo->flash_class = FC_PFLASH;
1013 bank->size = (pf_size / num_pflash_blocks);
1014 bank->base = 0x00000000 + bank->size * bank->bank_number;
1015 kinfo->sector_size = kinetis_flash_params[granularity].pflash_sector_size_bytes;
1016 kinfo->protection_size = pf_size / 32;
1017 } else if ((unsigned)bank->bank_number < num_blocks) {
1018 /* nvm, banks start at address 0x10000000 */
1019 kinfo->flash_class = FC_FLEX_NVM;
1020 bank->size = (nvm_size / num_nvm_blocks);
1021 bank->base = 0x10000000 + bank->size * (bank->bank_number - first_nvm_bank);
1022 kinfo->sector_size = kinetis_flash_params[granularity].nvm_sector_size_bytes;
1023 kinfo->protection_size = 0; /* FIXME: TODO: depends on DEPART bits, chip */
1024 } else if ((unsigned)bank->bank_number == num_blocks) {
1025 LOG_ERROR("FlexRAM support not yet implemented");
1026 return ERROR_FLASH_OPER_UNSUPPORTED;
1027 } else {
1028 LOG_ERROR("Cannot determine parameters for bank %d, only %d banks on device",
1029 bank->bank_number, num_blocks);
1030 return ERROR_FLASH_BANK_INVALID;
1031 }
1032
1033 if (bank->sectors) {
1034 free(bank->sectors);
1035 bank->sectors = NULL;
1036 }
1037
1038 bank->num_sectors = bank->size / kinfo->sector_size;
1039 assert(bank->num_sectors > 0);
1040 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
1041
1042 for (i = 0; i < bank->num_sectors; i++) {
1043 bank->sectors[i].offset = offset;
1044 bank->sectors[i].size = kinfo->sector_size;
1045 offset += kinfo->sector_size;
1046 bank->sectors[i].is_erased = -1;
1047 bank->sectors[i].is_protected = 1;
1048 }
1049
1050 return ERROR_OK;
1051 }
1052
1053 static int kinetis_probe(struct flash_bank *bank)
1054 {
1055 if (bank->target->state != TARGET_HALTED) {
1056 LOG_WARNING("Cannot communicate... target not halted.");
1057 return ERROR_TARGET_NOT_HALTED;
1058 }
1059
1060 return kinetis_read_part_info(bank);
1061 }
1062
1063 static int kinetis_auto_probe(struct flash_bank *bank)
1064 {
1065 struct kinetis_flash_bank *kinfo = bank->driver_priv;
1066
1067 if (kinfo->sim_sdid)
1068 return ERROR_OK;
1069
1070 return kinetis_probe(bank);
1071 }
1072
1073 static int kinetis_info(struct flash_bank *bank, char *buf, int buf_size)
1074 {
1075 const char *bank_class_names[] = {
1076 "(ANY)", "PFlash", "FlexNVM", "FlexRAM"
1077 };
1078
1079 struct kinetis_flash_bank *kinfo = bank->driver_priv;
1080
1081 (void) snprintf(buf, buf_size,
1082 "%s driver for %s flash bank %s at 0x%8.8" PRIx32 "",
1083 bank->driver->name, bank_class_names[kinfo->flash_class],
1084 bank->name, bank->base);
1085
1086 return ERROR_OK;
1087 }
1088
1089 static int kinetis_blank_check(struct flash_bank *bank)
1090 {
1091 struct kinetis_flash_bank *kinfo = bank->driver_priv;
1092
1093 if (bank->target->state != TARGET_HALTED) {
1094 LOG_ERROR("Target not halted");
1095 return ERROR_TARGET_NOT_HALTED;
1096 }
1097
1098 if (kinfo->flash_class == FC_PFLASH) {
1099 int result;
1100 uint8_t ftfx_fstat;
1101
1102 /* check if whole bank is blank */
1103 result = kinetis_ftfx_command(bank, FTFx_CMD_BLOCKSTAT, bank->base, 0, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat);
1104
1105 if (result != ERROR_OK)
1106 return result;
1107
1108 if (ftfx_fstat & 0x01) {
1109 /* the whole bank is not erased, check sector-by-sector */
1110 int i;
1111 for (i = 0; i < bank->num_sectors; i++) {
1112 /* normal margin */
1113 result = kinetis_ftfx_command(bank, FTFx_CMD_SECTSTAT, bank->base + bank->sectors[i].offset,
1114 1, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat);
1115
1116 if (result == ERROR_OK) {
1117 bank->sectors[i].is_erased = !(ftfx_fstat & 0x01);
1118 } else {
1119 LOG_DEBUG("Ignoring errored PFlash sector blank-check");
1120 bank->sectors[i].is_erased = -1;
1121 }
1122 }
1123 } else {
1124 /* the whole bank is erased, update all sectors */
1125 int i;
1126 for (i = 0; i < bank->num_sectors; i++)
1127 bank->sectors[i].is_erased = 1;
1128 }
1129 } else {
1130 LOG_WARNING("kinetis_blank_check not supported yet for FlexNVM");
1131 return ERROR_FLASH_OPERATION_FAILED;
1132 }
1133
1134 return ERROR_OK;
1135 }
1136
1137 struct flash_driver kinetis_flash = {
1138 .name = "kinetis",
1139 .flash_bank_command = kinetis_flash_bank_command,
1140 .erase = kinetis_erase,
1141 .protect = kinetis_protect,
1142 .write = kinetis_write,
1143 .read = default_flash_read,
1144 .probe = kinetis_probe,
1145 .auto_probe = kinetis_auto_probe,
1146 .erase_check = kinetis_blank_check,
1147 .protect_check = kinetis_protect_check,
1148 .info = kinetis_info,
1149 };

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)