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

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)