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

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)