build: cleanup src/flash/nor directory
[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 fallback = 1;
324 }
325
326
327 /* program section command */
328 if (fallback == 0) {
329 for (i = 0; i < count; i += (2 * 1024)) {
330 wc = 512;
331
332 if ((count - i) < (2 * 1024)) {
333 wc = count - i;
334 wc /= 4;
335 }
336
337 LOG_DEBUG("write section @ %08X with length %d",
338 offset + i, wc * 4);
339
340 /* write data to flexram */
341 result =
342 target_write_memory(bank->target, 0x14000000, 4, wc,
343 buffer + i);
344
345 if (result != ERROR_OK) {
346 LOG_ERROR("target_write_memory failed");
347
348 return result;
349 }
350
351 /* execute section command */
352 w0 = (0x0b << 24) | (offset + i);
353 w1 = (256 << 16);
354
355 result = kinetis_ftfl_command(bank, w0, w1, w2);
356
357 if (result != ERROR_OK)
358 return ERROR_FLASH_OPERATION_FAILED;
359 }
360 }
361 /* program longword command */
362 else {
363 for (i = 0; i < count; i += 4) {
364 LOG_DEBUG("write longword @ %08X", offset + i);
365
366 w0 = (0x06 << 24) | (offset + i);
367 w1 = buf_get_u32(buffer + offset + i, 0, 32);
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 return ERROR_OK;
377 }
378
379 static int kinetis_probe(struct flash_bank *bank)
380 {
381 struct flash_bank *master_bank;
382 int result, i;
383 uint8_t buf[4];
384 uint32_t sim_sdid, sim_fcfg1, sim_fcfg2, offset = 0;
385 uint32_t nvm_size, pf_size, ee_size;
386
387 if (bank->target->state != TARGET_HALTED) {
388 LOG_ERROR("Target not halted");
389 return ERROR_TARGET_NOT_HALTED;
390 }
391
392 result = kinetis_get_master_bank(bank, &master_bank);
393
394 if (result != ERROR_OK)
395 return result;
396
397 result = target_read_memory(bank->target, 0x40048024, 1, 4, buf);
398 if (result != ERROR_OK)
399 return result;
400 sim_sdid = target_buffer_get_u32(bank->target, buf);
401 result = target_read_memory(bank->target, 0x4004804c, 1, 4, buf);
402 if (result != ERROR_OK)
403 return result;
404 sim_fcfg1 = target_buffer_get_u32(bank->target, buf);
405 result = target_read_memory(bank->target, 0x40048050, 1, 4, buf);
406 if (result != ERROR_OK)
407 return result;
408 sim_fcfg2 = target_buffer_get_u32(bank->target, buf);
409
410 LOG_DEBUG("SDID: %08X FCFG1: %08X FCFG2: %08X", sim_sdid, sim_fcfg1,
411 sim_fcfg2);
412
413 switch ((sim_fcfg1 >> 28) & 0x0f) {
414 case 0x07:
415 nvm_size = 128 * 1024;
416 break;
417 case 0x09:
418 case 0x0f:
419 nvm_size = 256 * 1024;
420 break;
421 default:
422 nvm_size = 0;
423 break;
424 }
425
426 switch ((sim_fcfg1 >> 24) & 0x0f) {
427 case 0x07:
428 pf_size = 128 * 1024;
429 break;
430 case 0x09:
431 pf_size = 256 * 1024;
432 break;
433 case 0x0b:
434 case 0x0f:
435 pf_size = 512 * 1024;
436 break;
437 default:
438 pf_size = 0;
439 break;
440 }
441
442 switch ((sim_fcfg1 >> 16) & 0x0f) {
443 case 0x02:
444 ee_size = 4 * 1024;
445 break;
446 case 0x03:
447 ee_size = 2 * 1024;
448 break;
449 case 0x04:
450 ee_size = 1 * 1024;
451 break;
452 case 0x05:
453 ee_size = 512;
454 break;
455 case 0x06:
456 ee_size = 256;
457 break;
458 case 0x07:
459 ee_size = 128;
460 break;
461 case 0x08:
462 ee_size = 64;
463 break;
464 case 0x09:
465 ee_size = 32;
466 break;
467 default:
468 ee_size = 0;
469 break;
470 }
471
472 ((struct kinetis_flash_bank *) bank->driver_priv)->nvm_start =
473 pf_size - nvm_size;
474
475 LOG_DEBUG("NVM: %d PF: %d EE: %d BL1: %d", nvm_size, pf_size, ee_size,
476 (sim_fcfg2 >> 23) & 1);
477
478 if (pf_size != bank->size) {
479 LOG_WARNING("flash size is different %d != %d", pf_size,
480 bank->size);
481 }
482
483 bank->num_sectors = bank->size / (2 * 1024);
484 assert(bank->num_sectors > 0);
485 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
486
487 for (i = 0; i < bank->num_sectors; i++) {
488 bank->sectors[i].offset = offset;
489 bank->sectors[i].size = 2 * 1024;
490 offset += bank->sectors[i].size;
491 bank->sectors[i].is_erased = -1;
492 bank->sectors[i].is_protected = 1;
493 }
494
495 /* update the info we do not have */
496 return kinetis_update_bank_info(bank);
497 }
498
499 static int kinetis_auto_probe(struct flash_bank *bank)
500 {
501 return kinetis_probe(bank);
502 }
503
504 static int kinetis_info(struct flash_bank *bank, char *buf, int buf_size)
505 {
506 int result;
507 struct flash_bank *master_bank;
508
509 result = kinetis_get_master_bank(bank, &master_bank);
510
511 if (result != ERROR_OK)
512 return result;
513
514 snprintf(buf, buf_size,
515 "%s driver for flash bank %s at 0x%8.8" PRIx32 "",
516 bank->driver->name, master_bank->name, master_bank->base);
517
518 return ERROR_OK;
519 }
520
521 static int kinetis_blank_check(struct flash_bank *bank)
522 {
523 int result;
524 struct flash_bank *master_bank;
525
526 LOG_WARNING("kinetis_blank_check not supported yet");
527
528 if (bank->target->state != TARGET_HALTED) {
529 LOG_ERROR("Target not halted");
530 return ERROR_TARGET_NOT_HALTED;
531 }
532
533 result = kinetis_get_master_bank(bank, &master_bank);
534
535 if (result != ERROR_OK)
536 return result;
537
538 return ERROR_OK;
539 }
540
541 static int kinetis_flash_read(struct flash_bank *bank,
542 uint8_t *buffer, uint32_t offset, uint32_t count)
543 {
544 int result;
545 struct flash_bank *master_bank;
546
547 LOG_WARNING("kinetis_flash_read 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 return ERROR_OK;
560 }
561
562 struct flash_driver kinetis_flash = {
563 .name = "kinetis",
564 .flash_bank_command = kinetis_flash_bank_command,
565 .erase = kinetis_erase,
566 .protect = kinetis_protect,
567 .write = kinetis_write,
568 .read = kinetis_flash_read,
569 .probe = kinetis_probe,
570 .auto_probe = kinetis_auto_probe,
571 .erase_check = kinetis_blank_check,
572 .protect_check = kinetis_protect_check,
573 .info = kinetis_info,
574 };

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)