Clean up many C99 integer types format specifiers
[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 * 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 */
92
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 }
102 };
103
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
113
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
122
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;
129
130 uint32_t sim_sdid;
131 uint32_t sim_fcfg1;
132 uint32_t sim_fcfg2;
133
134 enum {
135 FC_AUTO = 0,
136 FC_PFLASH,
137 FC_FLEX_NVM,
138 FC_FLEX_RAM,
139 } flash_class;
140 };
141
142 FLASH_BANK_COMMAND_HANDLER(kinetis_flash_bank_command)
143 {
144 struct kinetis_flash_bank *bank_info;
145
146 if (CMD_ARGC < 6)
147 return ERROR_COMMAND_SYNTAX_ERROR;
148
149 LOG_INFO("add flash_bank kinetis %s", bank->name);
150
151 bank_info = malloc(sizeof(struct kinetis_flash_bank));
152
153 memset(bank_info, 0, sizeof(struct kinetis_flash_bank));
154
155 bank->driver_priv = bank_info;
156
157 return ERROR_OK;
158 }
159
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
171 */
172
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 */
221 };
222
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)
226 {
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;
235
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
245 */
246
247 /* Increase buffer_size if needed */
248 if (buffer_size < (target->working_area_size/2))
249 buffer_size = (target->working_area_size/2);
250
251 LOG_INFO("Kinetis: FLASH Write ...");
252
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;
257 }
258
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;
264 }
265
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;
270
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);
277
278 LOG_WARNING("No large enough working area available, can't do block memory writes");
279 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
280 }
281 }
282
283 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
284 armv7m_info.core_mode = ARM_MODE_THREAD;
285
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 */
289
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;
294
295 retval = target_write_buffer(target, write_algorithm->address, 8,
296 kinetis_flash_write_code);
297 if (retval != ERROR_OK)
298 break;
299
300 retval = target_write_buffer(target, source->address, thisrun_count * 4, buffer);
301 if (retval != ERROR_OK)
302 break;
303
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);
307
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;
314 }
315
316 buffer += thisrun_count * 4;
317 address += thisrun_count * 4;
318 wcount -= thisrun_count;
319 }
320
321 target_free_working_area(target, source);
322 target_free_working_area(target, write_algorithm);
323
324 destroy_reg_param(&reg_params[0]);
325 destroy_reg_param(&reg_params[1]);
326 destroy_reg_param(&reg_params[2]);
327
328 return retval;
329 }
330
331 static int kinetis_protect(struct flash_bank *bank, int set, int first, int last)
332 {
333 LOG_WARNING("kinetis_protect not supported yet");
334 /* FIXME: TODO */
335
336 if (bank->target->state != TARGET_HALTED) {
337 LOG_ERROR("Target not halted");
338 return ERROR_TARGET_NOT_HALTED;
339 }
340
341 return ERROR_FLASH_BANK_INVALID;
342 }
343
344 static int kinetis_protect_check(struct flash_bank *bank)
345 {
346 struct kinetis_flash_bank *kinfo = bank->driver_priv;
347
348 if (bank->target->state != TARGET_HALTED) {
349 LOG_ERROR("Target not halted");
350 return ERROR_TARGET_NOT_HALTED;
351 }
352
353 if (kinfo->flash_class == FC_PFLASH) {
354 int result;
355 uint8_t buffer[4];
356 uint32_t fprot, psec;
357 int i, b;
358
359 /* read protection register */
360 result = target_read_memory(bank->target, FTFx_FPROT3, 1, 4, buffer);
361
362 if (result != ERROR_OK)
363 return result;
364
365 fprot = target_buffer_get_u32(bank->target, buffer);
366
367 /*
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.
371 */
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;
378
379 psec += bank->sectors[i].size;
380
381 if (psec >= kinfo->protection_size) {
382 psec = 0;
383 b++;
384 }
385 }
386 } else {
387 LOG_ERROR("Protection checks for FlexNVM not yet supported");
388 return ERROR_FLASH_BANK_INVALID;
389 }
390
391 return ERROR_OK;
392 }
393
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)
398 {
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;
404
405 /* wait for done */
406 for (i = 0; i < 50; i++) {
407 result =
408 target_read_memory(bank->target, FTFx_FSTAT, 1, 1, &buffer);
409
410 if (result != ERROR_OK)
411 return result;
412
413 if (buffer & 0x80)
414 break;
415
416 buffer = 0x00;
417 }
418
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;
426 }
427
428 result = target_write_memory(bank->target, FTFx_FCCOB3, 4, 3, command);
429
430 if (result != ERROR_OK)
431 return result;
432
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;
438
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);
443
444 if (result != ERROR_OK)
445 return result;
446
447 if (*ftfx_fstat & 0x80)
448 break;
449 }
450
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;
458 }
459
460 return ERROR_OK;
461 }
462
463 static int kinetis_mass_erase(struct flash_bank *bank)
464 {
465 int result;
466 uint8_t ftfx_fstat;
467
468 if (bank->target->state != TARGET_HALTED) {
469 LOG_ERROR("Target not halted");
470 return ERROR_TARGET_NOT_HALTED;
471 }
472
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;*/
481
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 */
485
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;
491
492 return ERROR_OK;
493 }
494
495 static int kinetis_erase(struct flash_bank *bank, int first, int last)
496 {
497 int result, i;
498 struct kinetis_flash_bank *kinfo = bank->driver_priv;
499
500 if (bank->target->state != TARGET_HALTED) {
501 LOG_ERROR("Target not halted");
502 return ERROR_TARGET_NOT_HALTED;
503 }
504
505 if ((first > bank->num_sectors) || (last > bank->num_sectors))
506 return ERROR_FLASH_OPERATION_FAILED;
507
508 if ((first == 0) && (last == (bank->num_sectors - 1)) && (kinfo->klxx))
509 return kinetis_mass_erase(bank);
510
511 /*
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.
515 */
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);
521
522 if (result != ERROR_OK) {
523 LOG_WARNING("erase sector %d failed", i);
524 return ERROR_FLASH_OPERATION_FAILED;
525 }
526
527 bank->sectors[i].is_erased = 1;
528 }
529
530 if (first == 0) {
531 LOG_WARNING
532 ("flash configuration field erased, please reset the device");
533 }
534
535 return ERROR_OK;
536 }
537
538 static int kinetis_write(struct flash_bank *bank, uint8_t *buffer,
539 uint32_t offset, uint32_t count)
540 {
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;
546
547 if (bank->target->state != TARGET_HALTED) {
548 LOG_ERROR("Target not halted");
549 return ERROR_TARGET_NOT_HALTED;
550 }
551
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%" PRIX32, offset);
557
558 } else if (kinfo->flash_class == FC_FLEX_NVM) {
559 uint8_t ftfx_fstat;
560
561 LOG_DEBUG("flash write into FlexNVM @%08" PRIX32, offset);
562
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);
565
566 if (result != ERROR_OK)
567 return ERROR_FLASH_OPERATION_FAILED;
568
569 /* check if ram ready */
570 result = target_read_memory(bank->target, FTFx_FCNFG, 1, 1, buf);
571
572 if (result != ERROR_OK)
573 return result;
574
575 if (!(buf[0] & (1 << 1))) {
576 /* fallback to longword write */
577 fallback = 1;
578
579 LOG_WARNING("ram not ready, fallback to slow longword write (FCNFG: %02X)", buf[0]);
580 }
581 } else {
582 LOG_DEBUG("flash write into PFLASH @08%" PRIX32, offset);
583 }
584
585
586 /* program section command */
587 if (fallback == 0) {
588 /*
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).
593 */
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;
603
604 /*
605 * Assume the word count covers an entire
606 * sector.
607 */
608 wc = prog_size_bytes / 4;
609
610 /*
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.
616 */
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;
620
621 /* number of complete words to copy directly from buffer */
622 wc = (count - i) / 4;
623
624 /* number of total sections to write, including residual */
625 section_count = DIV_ROUND_UP((count-i), prog_section_chunk_bytes);
626
627 /* any residual bytes delivers a whole residual section */
628 residual_wc = (residual_bc ? prog_section_chunk_bytes : 0)/4;
629
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);
633 }
634
635 LOG_DEBUG("write section @ %08" PRIX32 " with length %" PRIu32 " bytes",
636 offset + i, (uint32_t)wc*4);
637
638 /* write data to flexram as whole-words */
639 result = target_write_memory(bank->target, FLEXRAM, 4, wc,
640 buffer + i);
641
642 if (result != ERROR_OK) {
643 LOG_ERROR("target_write_memory failed");
644 return result;
645 }
646
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);
653
654 if (result != ERROR_OK) {
655 LOG_ERROR("target_write_memory failed");
656 return result;
657 }
658 }
659
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);
664
665 if (result != ERROR_OK)
666 return ERROR_FLASH_OPERATION_FAILED;
667 }
668 }
669 /* program longword command, not supported in "SF3" devices */
670 else if ((kinfo->granularity != 3) || (kinfo->klxx)) {
671
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;
680 }
681 LOG_INFO("odd number of bytes to write (%" PRIu32 "), extending to %" PRIu32 " "
682 "and padding with 0xff", old_count, count);
683 memset(buffer, 0xff, count);
684 buffer = memcpy(new_buffer, buffer, old_count);
685 }
686
687 uint32_t words_remaining = count / 4;
688
689 /* try using a block write */
690 int retval = kinetis_write_block(bank, buffer, offset, words_remaining);
691
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");
697
698 for (i = 0; i < count; i += 4) {
699 uint8_t ftfx_fstat;
700
701 LOG_DEBUG("write longword @ %08" PRIX32, (uint32_t)(offset + i));
702
703 uint8_t padding[4] = {0xff, 0xff, 0xff, 0xff};
704 memcpy(padding, buffer + i, MIN(4, count-i));
705
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);
709
710 if (result != ERROR_OK)
711 return ERROR_FLASH_OPERATION_FAILED;
712 }
713 }
714
715 } else {
716 LOG_ERROR("Flash write strategy not implemented");
717 return ERROR_FLASH_OPERATION_FAILED;
718 }
719
720 return ERROR_OK;
721 }
722
723 static int kinetis_read_part_info(struct flash_bank *bank)
724 {
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;
733
734 result = target_read_u32(target, SIM_SDID, &kinfo->sim_sdid);
735 if (result != ERROR_OK)
736 return result;
737
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;
746
747 result = target_read_u32(target, SIM_FCFG1, &kinfo->sim_fcfg1);
748 if (result != ERROR_OK)
749 return result;
750
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;
755
756 LOG_DEBUG("SDID: 0x%08" PRIX32 " FCFG1: 0x%08" PRIX32 " FCFG2: 0x%08" PRIX32, kinfo->sim_sdid,
757 kinfo->sim_fcfg1, kinfo->sim_fcfg2);
758
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);
762
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;
781 }
782
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;
799 }
800 }
801
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;
822 }
823
824 LOG_DEBUG("FlexNVM: %" PRIu32 " PFlash: %" PRIu32 " FlexRAM: %" PRIu32 " 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;
830
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;
834
835 LOG_DEBUG("%d blocks total: %d PFlash, %d FlexNVM",
836 num_blocks, num_pflash_blocks, num_nvm_blocks);
837
838 /*
839 * If the flash class is already assigned, verify the
840 * parameters.
841 */
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);
869 }
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);
890 }
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);
908 }
909 break;
910
911 default:
912 LOG_WARNING("Unknown or inconsistent flash class");
913 reassign = 1;
914 break;
915 }
916 }
917 } else {
918 LOG_INFO("Probing flash info for bank %d", bank->bank_number);
919 reassign = 1;
920 }
921
922 if (!reassign)
923 return ERROR_OK;
924
925 kinfo->granularity = granularity;
926
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;
948 }
949
950 if (bank->sectors) {
951 free(bank->sectors);
952 bank->sectors = NULL;
953 }
954
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);
958
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;
965 }
966
967 return ERROR_OK;
968 }
969
970 static int kinetis_probe(struct flash_bank *bank)
971 {
972 if (bank->target->state != TARGET_HALTED) {
973 LOG_WARNING("Cannot communicate... target not halted.");
974 return ERROR_TARGET_NOT_HALTED;
975 }
976
977 return kinetis_read_part_info(bank);
978 }
979
980 static int kinetis_auto_probe(struct flash_bank *bank)
981 {
982 struct kinetis_flash_bank *kinfo = bank->driver_priv;
983
984 if (kinfo->sim_sdid)
985 return ERROR_OK;
986
987 return kinetis_probe(bank);
988 }
989
990 static int kinetis_info(struct flash_bank *bank, char *buf, int buf_size)
991 {
992 const char *bank_class_names[] = {
993 "(ANY)", "PFlash", "FlexNVM", "FlexRAM"
994 };
995
996 struct kinetis_flash_bank *kinfo = bank->driver_priv;
997
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);
1002
1003 return ERROR_OK;
1004 }
1005
1006 static int kinetis_blank_check(struct flash_bank *bank)
1007 {
1008 struct kinetis_flash_bank *kinfo = bank->driver_priv;
1009
1010 if (bank->target->state != TARGET_HALTED) {
1011 LOG_ERROR("Target not halted");
1012 return ERROR_TARGET_NOT_HALTED;
1013 }
1014
1015 if (kinfo->flash_class == FC_PFLASH) {
1016 int result;
1017 uint8_t ftfx_fstat;
1018
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);
1021
1022 if (result != ERROR_OK)
1023 return result;
1024
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);
1032
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;
1038 }
1039 }
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;
1045 }
1046 } else {
1047 LOG_WARNING("kinetis_blank_check not supported yet for FlexNVM");
1048 return ERROR_FLASH_OPERATION_FAILED;
1049 }
1050
1051 return ERROR_OK;
1052 }
1053
1054 static int kinetis_flash_read(struct flash_bank *bank,
1055 uint8_t *buffer, uint32_t offset, uint32_t count)
1056 {
1057 LOG_WARNING("kinetis_flash_read not supported yet");
1058
1059 if (bank->target->state != TARGET_HALTED) {
1060 LOG_ERROR("Target not halted");
1061 return ERROR_TARGET_NOT_HALTED;
1062 }
1063
1064 return ERROR_FLASH_OPERATION_FAILED;
1065 }
1066
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,
1079 };

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)