1897549804eff51650e5b7fdda45c5f9d0d690b7
[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 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "imp.h"
28 #include "helper/binarybuffer.h"
29
30 struct kinetis_flash_bank {
31 uint32_t nvm_start;
32 };
33
34 static int kinetis_get_master_bank(struct flash_bank *bank,
35 struct flash_bank **master_bank)
36 {
37 *master_bank = get_flash_bank_by_name_noprobe(bank->name);
38 if (*master_bank == NULL) {
39 LOG_ERROR("master flash bank '%s' does not exist",
40 (char *)bank->driver_priv);
41 return ERROR_FLASH_OPERATION_FAILED;
42 }
43
44 return ERROR_OK;
45 }
46
47 static int kinetis_update_bank_info(struct flash_bank *bank)
48 {
49 int result;
50 struct flash_bank *master_bank;
51
52 result = kinetis_get_master_bank(bank, &master_bank);
53
54 if (result != ERROR_OK) {
55 return result;
56 }
57
58 /* update the info we do not have */
59 bank->size = master_bank->size;
60 bank->chip_width = master_bank->chip_width;
61 bank->bus_width = master_bank->bus_width;
62 bank->num_sectors = master_bank->num_sectors;
63 bank->sectors = master_bank->sectors;
64
65 return ERROR_OK;
66 }
67
68 FLASH_BANK_COMMAND_HANDLER(kinetis_flash_bank_command)
69 {
70 struct kinetis_flash_bank *bank_info;
71
72 if (CMD_ARGC < 6) {
73 LOG_ERROR("incomplete flash_bank kinetis configuration %d",
74 CMD_ARGC);
75 return ERROR_FLASH_OPERATION_FAILED;
76 }
77
78 LOG_INFO("add flash_bank kinetis %s", bank->name);
79
80 bank_info = malloc(sizeof(struct kinetis_flash_bank));
81
82 memset(bank_info, 0, sizeof(struct kinetis_flash_bank));
83
84 bank->driver_priv = bank_info;
85
86 return ERROR_OK;
87 }
88
89 static int kinetis_protect(struct flash_bank *bank, int set, int first,
90 int last)
91 {
92 int result;
93 struct flash_bank *master_bank;
94
95 result = kinetis_get_master_bank(bank, &master_bank);
96
97 if (result != ERROR_OK) {
98 return result;
99 }
100
101 LOG_WARNING("kinetis_protect not supported yet");
102
103 if (bank->target->state != TARGET_HALTED) {
104 LOG_ERROR("Target not halted");
105 return ERROR_TARGET_NOT_HALTED;
106 }
107
108 return ERROR_OK;
109 }
110
111 static int kinetis_protect_check(struct flash_bank *bank)
112 {
113 int result;
114 struct flash_bank *master_bank;
115 uint8_t buffer[4];
116 uint32_t fprot, psize, psec;
117 int i, b;
118
119 if (bank->target->state != TARGET_HALTED) {
120 LOG_ERROR("Target not halted");
121 return ERROR_TARGET_NOT_HALTED;
122 }
123
124 result = kinetis_get_master_bank(bank, &master_bank);
125
126 if (result != ERROR_OK) {
127 return result;
128 }
129
130 /* read protection register FTFL_FPROT */
131 result = target_read_memory(bank->target, 0x40020010, 1, 4, buffer);
132
133 if (result != ERROR_OK) {
134 return result;
135 }
136
137 fprot = target_buffer_get_u32(bank->target, buffer);
138
139 /* every bit protect 1/32 of the full flash */
140 psize = bank->size / 32;
141 psec = 0;
142 b = 0;
143
144 for (i = 0; i < bank->num_sectors; i++) {
145 if ((fprot >> b) & 1)
146 bank->sectors[i].is_protected = 0;
147 else
148 bank->sectors[i].is_protected = 1;
149
150 psec += bank->sectors[i].size;
151
152 if (psec >= psize) {
153 psec = 0;
154 b++;
155 }
156 }
157
158 return ERROR_OK;
159 }
160
161 static int kinetis_ftfl_command(struct flash_bank *bank, uint32_t w0,
162 uint32_t w1, uint32_t w2)
163 {
164 uint8_t buffer[12];
165 int result, i;
166
167 /* wait for done */
168 for (i = 0; i < 50; i++) {
169 result =
170 target_read_memory(bank->target, 0x40020000, 1, 1, buffer);
171
172 if (result != ERROR_OK) {
173 return result;
174 }
175
176 if (buffer[0] & 0x80)
177 break;
178
179 buffer[0] = 0x00;
180 }
181
182 if (buffer[0] != 0x80) {
183 /* reset error flags */
184 buffer[0] = 0x30;
185 result =
186 target_write_memory(bank->target, 0x40020000, 1, 1, buffer);
187 if (result != ERROR_OK) {
188 return result;
189 }
190 }
191
192 target_buffer_set_u32(bank->target, buffer, w0);
193 target_buffer_set_u32(bank->target, buffer + 4, w1);
194 target_buffer_set_u32(bank->target, buffer + 8, w2);
195
196 result = target_write_memory(bank->target, 0x40020004, 4, 3, buffer);
197
198 if (result != ERROR_OK) {
199 return result;
200 }
201
202 /* start command */
203 buffer[0] = 0x80;
204 result = target_write_memory(bank->target, 0x40020000, 1, 1, buffer);
205 if (result != ERROR_OK) {
206 return result;
207 }
208
209 /* wait for done */
210 for (i = 0; i < 50; i++) {
211 result =
212 target_read_memory(bank->target, 0x40020000, 1, 1, buffer);
213
214 if (result != ERROR_OK) {
215 return result;
216 }
217
218 if (buffer[0] & 0x80)
219 break;
220
221 buffer[0] = 0x00;
222 }
223
224 if (buffer[0] != 0x80) {
225 LOG_ERROR
226 ("ftfl command failed FSTAT: %02X W0: %08X W1: %08X W2: %08X",
227 buffer[0], w0, w1, w2);
228
229 return ERROR_FLASH_OPERATION_FAILED;
230 }
231
232 return ERROR_OK;
233 }
234
235 static int kinetis_erase(struct flash_bank *bank, int first, int last)
236 {
237 struct flash_bank *master_bank;
238 int result, i;
239 uint32_t w0 = 0, w1 = 0, w2 = 0;
240
241 if (bank->target->state != TARGET_HALTED) {
242 LOG_ERROR("Target not halted");
243 return ERROR_TARGET_NOT_HALTED;
244 }
245
246 result = kinetis_get_master_bank(bank, &master_bank);
247
248 if (result != ERROR_OK) {
249 return result;
250 }
251
252 if ((first > bank->num_sectors) || (last > bank->num_sectors)) {
253 return ERROR_FLASH_OPERATION_FAILED;
254 }
255
256 for (i = first; i <= last; i++) {
257 /* set command and sector address */
258 w0 = (0x09 << 24) | bank->sectors[i].offset;
259
260 result = kinetis_ftfl_command(bank, w0, w1, w2);
261
262 if (result != ERROR_OK) {
263 LOG_WARNING("erase sector %d failed", i);
264 return ERROR_FLASH_OPERATION_FAILED;
265 }
266
267 bank->sectors[i].is_erased = 1;
268 }
269
270 if (first == 0) {
271 LOG_WARNING
272 ("flash configuration field erased, please reset the device");
273 }
274
275 return ERROR_OK;
276 }
277
278 static int kinetis_write(struct flash_bank *bank, uint8_t * buffer,
279 uint32_t offset, uint32_t count)
280 {
281 struct flash_bank *master_bank;
282 unsigned int i, result, fallback = 0, nvm = 0;
283 uint8_t buf[8];
284 uint32_t wc, w0 = 0, w1 = 0, w2 = 0;
285 struct kinetis_flash_bank * kbank = (struct kinetis_flash_bank *)
286 bank->driver_priv;
287
288 if (bank->target->state != TARGET_HALTED) {
289 LOG_ERROR("Target not halted");
290 return ERROR_TARGET_NOT_HALTED;
291 }
292
293 result = kinetis_get_master_bank(bank, &master_bank);
294
295 if (result != ERROR_OK) {
296 return result;
297 }
298
299 if (offset >= kbank->nvm_start)
300 nvm = 1;
301
302 if (!nvm && (offset + count) > kbank->nvm_start) {
303 /* we could flash this in two goes, but if the segment
304 spans across the pflash/nvm boundary, something is probably
305 not right.
306 */
307 LOG_ERROR("Segment spans NVM boundary");
308 return ERROR_FLASH_DST_OUT_OF_BANK;
309 }
310
311 if (nvm) {
312 LOG_DEBUG("flash write into NVM @%08X", offset);
313
314 /* make flex ram available */
315 w0 = (0x81 << 24) | 0x00ff0000;
316
317 result = kinetis_ftfl_command(bank, w0, w1, w2);
318
319 if (result != ERROR_OK)
320 return ERROR_FLASH_OPERATION_FAILED;
321
322 /* check if ram ready */
323 result = target_read_memory(bank->target, 0x40020001, 1, 1, buf);
324
325 if (result != ERROR_OK)
326 return result;
327
328 if (!(buf[0] & (1 << 1))) {
329 /* fallback to longword write */
330 fallback = 1;
331
332 LOG_WARNING("ram not ready, fallback to slow longword write (FCNFG: %02X)",
333 buf[0]);
334 }
335 } else {
336 LOG_DEBUG("flash write into PFLASH @08%X", offset);
337 fallback = 1;
338 }
339
340
341 /* program section command */
342 if (fallback == 0) {
343 for (i = 0; i < count; i += (2 * 1024)) {
344 wc = 512;
345
346 if ((count - i) < (2 * 1024)) {
347 wc = count - i;
348 wc /= 4;
349 }
350
351 LOG_DEBUG("write section @ %08X with length %d",
352 offset + i, wc * 4);
353
354 /* write data to flexram */
355 result =
356 target_write_memory(bank->target, 0x14000000, 4, wc,
357 buffer + i);
358
359 if (result != ERROR_OK) {
360 LOG_ERROR("target_write_memory failed");
361
362 return result;
363 }
364
365 /* execute section command */
366 w0 = (0x0b << 24) | (offset + i);
367 w1 = (256 << 16);
368
369 result = kinetis_ftfl_command(bank, w0, w1, w2);
370
371 if (result != ERROR_OK) {
372 return ERROR_FLASH_OPERATION_FAILED;
373 }
374 }
375 }
376 /* program longword command */
377 else {
378 for (i = 0; i < count; i += 4) {
379 LOG_DEBUG("write longword @ %08X", offset + i);
380
381 w0 = (0x06 << 24) | (offset + i);
382 w1 = buf_get_u32(buffer + offset + i, 0, 32);
383
384 result = kinetis_ftfl_command(bank, w0, w1, w2);
385
386 if (result != ERROR_OK) {
387 return ERROR_FLASH_OPERATION_FAILED;
388 }
389 }
390 }
391
392 return ERROR_OK;
393 }
394
395 static int kinetis_probe(struct flash_bank *bank)
396 {
397 struct flash_bank *master_bank;
398 int result, i;
399 uint8_t buf[4];
400 uint32_t sim_sdid, sim_fcfg1, sim_fcfg2, offset = 0;
401 uint32_t nvm_size, pf_size, ee_size;
402
403 if (bank->target->state != TARGET_HALTED) {
404 LOG_ERROR("Target not halted");
405 return ERROR_TARGET_NOT_HALTED;
406 }
407
408 result = kinetis_get_master_bank(bank, &master_bank);
409
410 if (result != ERROR_OK) {
411 return result;
412 }
413
414 result = target_read_memory(bank->target, 0x40048024, 1, 4, buf);
415 if (result != ERROR_OK) {
416 return result;
417 }
418 sim_sdid = target_buffer_get_u32(bank->target, buf);
419 result = target_read_memory(bank->target, 0x4004804c, 1, 4, buf);
420 if (result != ERROR_OK) {
421 return result;
422 }
423 sim_fcfg1 = target_buffer_get_u32(bank->target, buf);
424 result = target_read_memory(bank->target, 0x40048050, 1, 4, buf);
425 if (result != ERROR_OK) {
426 return result;
427 }
428 sim_fcfg2 = target_buffer_get_u32(bank->target, buf);
429
430 LOG_DEBUG("SDID: %08X FCFG1: %08X FCFG2: %08X", sim_sdid, sim_fcfg1,
431 sim_fcfg2);
432
433 switch ((sim_fcfg1 >> 28) & 0x0f) {
434 case 0x07:
435 nvm_size = 128 * 1024;
436 break;
437 case 0x09:
438 case 0x0f:
439 nvm_size = 256 * 1024;
440 break;
441 default:
442 nvm_size = 0;
443 break;
444 }
445
446 switch ((sim_fcfg1 >> 24) & 0x0f) {
447 case 0x07:
448 pf_size = 128 * 1024;
449 break;
450 case 0x09:
451 pf_size = 256 * 1024;
452 break;
453 case 0x0b:
454 case 0x0f:
455 pf_size = 512 * 1024;
456 break;
457 default:
458 pf_size = 0;
459 break;
460 }
461
462 switch ((sim_fcfg1 >> 16) & 0x0f) {
463 case 0x02:
464 ee_size = 4 * 1024;
465 break;
466 case 0x03:
467 ee_size = 2 * 1024;
468 break;
469 case 0x04:
470 ee_size = 1 * 1024;
471 break;
472 case 0x05:
473 ee_size = 512;
474 break;
475 case 0x06:
476 ee_size = 256;
477 break;
478 case 0x07:
479 ee_size = 128;
480 break;
481 case 0x08:
482 ee_size = 64;
483 break;
484 case 0x09:
485 ee_size = 32;
486 break;
487 default:
488 ee_size = 0;
489 break;
490 }
491
492 ((struct kinetis_flash_bank *) bank->driver_priv)->nvm_start =
493 pf_size - nvm_size;
494
495 LOG_DEBUG("NVM: %d PF: %d EE: %d BL1: %d", nvm_size, pf_size, ee_size,
496 (sim_fcfg2 >> 23) & 1);
497
498 if (pf_size != bank->size) {
499 LOG_WARNING("flash size is different %d != %d", pf_size,
500 bank->size);
501 }
502
503 bank->num_sectors = bank->size / (2 * 1024);
504 assert(bank->num_sectors > 0);
505 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
506
507 for (i = 0; i < bank->num_sectors; i++) {
508 bank->sectors[i].offset = offset;
509 bank->sectors[i].size = 2 * 1024;
510 offset += bank->sectors[i].size;
511 bank->sectors[i].is_erased = -1;
512 bank->sectors[i].is_protected = 1;
513 }
514
515 /* update the info we do not have */
516 return kinetis_update_bank_info(bank);
517 }
518
519 static int kinetis_auto_probe(struct flash_bank *bank)
520 {
521 return kinetis_probe(bank);
522 }
523
524 static int kinetis_info(struct flash_bank *bank, char *buf, int buf_size)
525 {
526 int result;
527 struct flash_bank *master_bank;
528
529 result = kinetis_get_master_bank(bank, &master_bank);
530
531 if (result != ERROR_OK) {
532 return result;
533 }
534
535 snprintf(buf, buf_size,
536 "%s driver for flash bank %s at 0x%8.8" PRIx32 "",
537 bank->driver->name, master_bank->name, master_bank->base);
538
539 return ERROR_OK;
540 }
541
542 static int kinetis_blank_check(struct flash_bank *bank)
543 {
544 int result;
545 struct flash_bank *master_bank;
546
547 LOG_WARNING("kinetis_blank_check not supported yet");
548
549 if (bank->target->state != TARGET_HALTED) {
550 LOG_ERROR("Target not halted");
551 return ERROR_TARGET_NOT_HALTED;
552 }
553
554 result = kinetis_get_master_bank(bank, &master_bank);
555
556 if (result != ERROR_OK) {
557 return result;
558 }
559
560 return ERROR_OK;
561 }
562
563 static int kinetis_flash_read(struct flash_bank *bank,
564 uint8_t * buffer, uint32_t offset, uint32_t count)
565 {
566 int result;
567 struct flash_bank *master_bank;
568
569 LOG_WARNING("kinetis_flash_read not supported yet");
570
571 if (bank->target->state != TARGET_HALTED) {
572 LOG_ERROR("Target not halted");
573 return ERROR_TARGET_NOT_HALTED;
574 }
575
576 result = kinetis_get_master_bank(bank, &master_bank);
577
578 if (result != ERROR_OK) {
579 return result;
580 }
581
582 return ERROR_OK;
583 }
584
585 struct flash_driver kinetis_flash = {
586 .name = "kinetis",
587 .flash_bank_command = kinetis_flash_bank_command,
588 .erase = kinetis_erase,
589 .protect = kinetis_protect,
590 .write = kinetis_write,
591 .read = kinetis_flash_read,
592 .probe = kinetis_probe,
593 .auto_probe = kinetis_auto_probe,
594 .erase_check = kinetis_blank_check,
595 .protect_check = kinetis_protect_check,
596 .info = kinetis_info,
597 };

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)