1 /***************************************************************************
2 * Copyright (C) 2011 by Mathias Kuester *
5 * Copyright (C) 2011 sleep(5) ltd *
6 * tomas@sleepfive.com *
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. *
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. *
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 ***************************************************************************/
28 #include "helper/binarybuffer.h"
30 struct kinetis_flash_bank
{
34 static int kinetis_get_master_bank(struct flash_bank
*bank
,
35 struct flash_bank
**master_bank
)
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
;
47 static int kinetis_update_bank_info(struct flash_bank
*bank
)
50 struct flash_bank
*master_bank
;
52 result
= kinetis_get_master_bank(bank
, &master_bank
);
54 if (result
!= ERROR_OK
) {
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
;
68 FLASH_BANK_COMMAND_HANDLER(kinetis_flash_bank_command
)
70 struct kinetis_flash_bank
*bank_info
;
73 return ERROR_COMMAND_SYNTAX_ERROR
;
76 LOG_INFO("add flash_bank kinetis %s", bank
->name
);
78 bank_info
= malloc(sizeof(struct kinetis_flash_bank
));
80 memset(bank_info
, 0, sizeof(struct kinetis_flash_bank
));
82 bank
->driver_priv
= bank_info
;
87 static int kinetis_protect(struct flash_bank
*bank
, int set
, int first
,
91 struct flash_bank
*master_bank
;
93 result
= kinetis_get_master_bank(bank
, &master_bank
);
95 if (result
!= ERROR_OK
) {
99 LOG_WARNING("kinetis_protect not supported yet");
101 if (bank
->target
->state
!= TARGET_HALTED
) {
102 LOG_ERROR("Target not halted");
103 return ERROR_TARGET_NOT_HALTED
;
109 static int kinetis_protect_check(struct flash_bank
*bank
)
112 struct flash_bank
*master_bank
;
114 uint32_t fprot
, psize
, psec
;
117 if (bank
->target
->state
!= TARGET_HALTED
) {
118 LOG_ERROR("Target not halted");
119 return ERROR_TARGET_NOT_HALTED
;
122 result
= kinetis_get_master_bank(bank
, &master_bank
);
124 if (result
!= ERROR_OK
) {
128 /* read protection register FTFL_FPROT */
129 result
= target_read_memory(bank
->target
, 0x40020010, 1, 4, buffer
);
131 if (result
!= ERROR_OK
) {
135 fprot
= target_buffer_get_u32(bank
->target
, buffer
);
137 /* every bit protect 1/32 of the full flash */
138 psize
= bank
->size
/ 32;
142 for (i
= 0; i
< bank
->num_sectors
; i
++) {
143 if ((fprot
>> b
) & 1)
144 bank
->sectors
[i
].is_protected
= 0;
146 bank
->sectors
[i
].is_protected
= 1;
148 psec
+= bank
->sectors
[i
].size
;
159 static int kinetis_ftfl_command(struct flash_bank
*bank
, uint32_t w0
,
160 uint32_t w1
, uint32_t w2
)
166 for (i
= 0; i
< 50; i
++) {
168 target_read_memory(bank
->target
, 0x40020000, 1, 1, buffer
);
170 if (result
!= ERROR_OK
) {
174 if (buffer
[0] & 0x80)
180 if (buffer
[0] != 0x80) {
181 /* reset error flags */
184 target_write_memory(bank
->target
, 0x40020000, 1, 1, buffer
);
185 if (result
!= ERROR_OK
) {
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
);
194 result
= target_write_memory(bank
->target
, 0x40020004, 4, 3, buffer
);
196 if (result
!= ERROR_OK
) {
202 result
= target_write_memory(bank
->target
, 0x40020000, 1, 1, buffer
);
203 if (result
!= ERROR_OK
) {
208 for (i
= 0; i
< 50; i
++) {
210 target_read_memory(bank
->target
, 0x40020000, 1, 1, buffer
);
212 if (result
!= ERROR_OK
) {
216 if (buffer
[0] & 0x80)
222 if (buffer
[0] != 0x80) {
224 ("ftfl command failed FSTAT: %02X W0: %08X W1: %08X W2: %08X",
225 buffer
[0], w0
, w1
, w2
);
227 return ERROR_FLASH_OPERATION_FAILED
;
233 static int kinetis_erase(struct flash_bank
*bank
, int first
, int last
)
235 struct flash_bank
*master_bank
;
237 uint32_t w0
= 0, w1
= 0, w2
= 0;
239 if (bank
->target
->state
!= TARGET_HALTED
) {
240 LOG_ERROR("Target not halted");
241 return ERROR_TARGET_NOT_HALTED
;
244 result
= kinetis_get_master_bank(bank
, &master_bank
);
246 if (result
!= ERROR_OK
) {
250 if ((first
> bank
->num_sectors
) || (last
> bank
->num_sectors
)) {
251 return ERROR_FLASH_OPERATION_FAILED
;
254 for (i
= first
; i
<= last
; i
++) {
255 /* set command and sector address */
256 w0
= (0x09 << 24) | bank
->sectors
[i
].offset
;
258 result
= kinetis_ftfl_command(bank
, w0
, w1
, w2
);
260 if (result
!= ERROR_OK
) {
261 LOG_WARNING("erase sector %d failed", i
);
262 return ERROR_FLASH_OPERATION_FAILED
;
265 bank
->sectors
[i
].is_erased
= 1;
270 ("flash configuration field erased, please reset the device");
276 static int kinetis_write(struct flash_bank
*bank
, uint8_t * buffer
,
277 uint32_t offset
, uint32_t count
)
279 struct flash_bank
*master_bank
;
280 unsigned int i
, result
, fallback
= 0, nvm
= 0;
282 uint32_t wc
, w0
= 0, w1
= 0, w2
= 0;
283 struct kinetis_flash_bank
* kbank
= (struct kinetis_flash_bank
*)
286 if (bank
->target
->state
!= TARGET_HALTED
) {
287 LOG_ERROR("Target not halted");
288 return ERROR_TARGET_NOT_HALTED
;
291 result
= kinetis_get_master_bank(bank
, &master_bank
);
293 if (result
!= ERROR_OK
) {
297 if (offset
>= kbank
->nvm_start
)
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
305 LOG_ERROR("Segment spans NVM boundary");
306 return ERROR_FLASH_DST_OUT_OF_BANK
;
310 LOG_DEBUG("flash write into NVM @%08X", offset
);
312 /* make flex ram available */
313 w0
= (0x81 << 24) | 0x00ff0000;
315 result
= kinetis_ftfl_command(bank
, w0
, w1
, w2
);
317 if (result
!= ERROR_OK
)
318 return ERROR_FLASH_OPERATION_FAILED
;
320 /* check if ram ready */
321 result
= target_read_memory(bank
->target
, 0x40020001, 1, 1, buf
);
323 if (result
!= ERROR_OK
)
326 if (!(buf
[0] & (1 << 1))) {
327 /* fallback to longword write */
330 LOG_WARNING("ram not ready, fallback to slow longword write (FCNFG: %02X)",
334 LOG_DEBUG("flash write into PFLASH @08%X", offset
);
339 /* program section command */
341 for (i
= 0; i
< count
; i
+= (2 * 1024)) {
344 if ((count
- i
) < (2 * 1024)) {
349 LOG_DEBUG("write section @ %08X with length %d",
352 /* write data to flexram */
354 target_write_memory(bank
->target
, 0x14000000, 4, wc
,
357 if (result
!= ERROR_OK
) {
358 LOG_ERROR("target_write_memory failed");
363 /* execute section command */
364 w0
= (0x0b << 24) | (offset
+ i
);
367 result
= kinetis_ftfl_command(bank
, w0
, w1
, w2
);
369 if (result
!= ERROR_OK
) {
370 return ERROR_FLASH_OPERATION_FAILED
;
374 /* program longword command */
376 for (i
= 0; i
< count
; i
+= 4) {
377 LOG_DEBUG("write longword @ %08X", offset
+ i
);
379 w0
= (0x06 << 24) | (offset
+ i
);
380 w1
= buf_get_u32(buffer
+ offset
+ i
, 0, 32);
382 result
= kinetis_ftfl_command(bank
, w0
, w1
, w2
);
384 if (result
!= ERROR_OK
) {
385 return ERROR_FLASH_OPERATION_FAILED
;
393 static int kinetis_probe(struct flash_bank
*bank
)
395 struct flash_bank
*master_bank
;
398 uint32_t sim_sdid
, sim_fcfg1
, sim_fcfg2
, offset
= 0;
399 uint32_t nvm_size
, pf_size
, ee_size
;
401 if (bank
->target
->state
!= TARGET_HALTED
) {
402 LOG_ERROR("Target not halted");
403 return ERROR_TARGET_NOT_HALTED
;
406 result
= kinetis_get_master_bank(bank
, &master_bank
);
408 if (result
!= ERROR_OK
) {
412 result
= target_read_memory(bank
->target
, 0x40048024, 1, 4, buf
);
413 if (result
!= ERROR_OK
) {
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
) {
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
) {
426 sim_fcfg2
= target_buffer_get_u32(bank
->target
, buf
);
428 LOG_DEBUG("SDID: %08X FCFG1: %08X FCFG2: %08X", sim_sdid
, sim_fcfg1
,
431 switch ((sim_fcfg1
>> 28) & 0x0f) {
433 nvm_size
= 128 * 1024;
437 nvm_size
= 256 * 1024;
444 switch ((sim_fcfg1
>> 24) & 0x0f) {
446 pf_size
= 128 * 1024;
449 pf_size
= 256 * 1024;
453 pf_size
= 512 * 1024;
460 switch ((sim_fcfg1
>> 16) & 0x0f) {
490 ((struct kinetis_flash_bank
*) bank
->driver_priv
)->nvm_start
=
493 LOG_DEBUG("NVM: %d PF: %d EE: %d BL1: %d", nvm_size
, pf_size
, ee_size
,
494 (sim_fcfg2
>> 23) & 1);
496 if (pf_size
!= bank
->size
) {
497 LOG_WARNING("flash size is different %d != %d", pf_size
,
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
);
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;
513 /* update the info we do not have */
514 return kinetis_update_bank_info(bank
);
517 static int kinetis_auto_probe(struct flash_bank
*bank
)
519 return kinetis_probe(bank
);
522 static int kinetis_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
525 struct flash_bank
*master_bank
;
527 result
= kinetis_get_master_bank(bank
, &master_bank
);
529 if (result
!= ERROR_OK
) {
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
);
540 static int kinetis_blank_check(struct flash_bank
*bank
)
543 struct flash_bank
*master_bank
;
545 LOG_WARNING("kinetis_blank_check not supported yet");
547 if (bank
->target
->state
!= TARGET_HALTED
) {
548 LOG_ERROR("Target not halted");
549 return ERROR_TARGET_NOT_HALTED
;
552 result
= kinetis_get_master_bank(bank
, &master_bank
);
554 if (result
!= ERROR_OK
) {
561 static int kinetis_flash_read(struct flash_bank
*bank
,
562 uint8_t * buffer
, uint32_t offset
, uint32_t count
)
565 struct flash_bank
*master_bank
;
567 LOG_WARNING("kinetis_flash_read not supported yet");
569 if (bank
->target
->state
!= TARGET_HALTED
) {
570 LOG_ERROR("Target not halted");
571 return ERROR_TARGET_NOT_HALTED
;
574 result
= kinetis_get_master_bank(bank
, &master_bank
);
576 if (result
!= ERROR_OK
) {
583 struct flash_driver kinetis_flash
= {
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
,
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)