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 LOG_ERROR("incomplete flash_bank kinetis configuration %d",
75 return ERROR_FLASH_OPERATION_FAILED
;
78 LOG_INFO("add flash_bank kinetis %s", bank
->name
);
80 bank_info
= malloc(sizeof(struct kinetis_flash_bank
));
82 memset(bank_info
, 0, sizeof(struct kinetis_flash_bank
));
84 bank
->driver_priv
= bank_info
;
89 static int kinetis_protect(struct flash_bank
*bank
, int set
, int first
,
93 struct flash_bank
*master_bank
;
95 result
= kinetis_get_master_bank(bank
, &master_bank
);
97 if (result
!= ERROR_OK
) {
101 LOG_WARNING("kinetis_protect not supported yet");
103 if (bank
->target
->state
!= TARGET_HALTED
) {
104 LOG_ERROR("Target not halted");
105 return ERROR_TARGET_NOT_HALTED
;
111 static int kinetis_protect_check(struct flash_bank
*bank
)
114 struct flash_bank
*master_bank
;
116 uint32_t fprot
, psize
, psec
;
119 if (bank
->target
->state
!= TARGET_HALTED
) {
120 LOG_ERROR("Target not halted");
121 return ERROR_TARGET_NOT_HALTED
;
124 result
= kinetis_get_master_bank(bank
, &master_bank
);
126 if (result
!= ERROR_OK
) {
130 /* read protection register FTFL_FPROT */
131 result
= target_read_memory(bank
->target
, 0x40020010, 1, 4, buffer
);
133 if (result
!= ERROR_OK
) {
137 fprot
= target_buffer_get_u32(bank
->target
, buffer
);
139 /* every bit protect 1/32 of the full flash */
140 psize
= bank
->size
/ 32;
144 for (i
= 0; i
< bank
->num_sectors
; i
++) {
145 if ((fprot
>> b
) & 1)
146 bank
->sectors
[i
].is_protected
= 0;
148 bank
->sectors
[i
].is_protected
= 1;
150 psec
+= bank
->sectors
[i
].size
;
161 static int kinetis_ftfl_command(struct flash_bank
*bank
, uint32_t w0
,
162 uint32_t w1
, uint32_t w2
)
168 for (i
= 0; i
< 50; i
++) {
170 target_read_memory(bank
->target
, 0x40020000, 1, 1, buffer
);
172 if (result
!= ERROR_OK
) {
176 if (buffer
[0] & 0x80)
182 if (buffer
[0] != 0x80) {
183 /* reset error flags */
186 target_write_memory(bank
->target
, 0x40020000, 1, 1, buffer
);
187 if (result
!= ERROR_OK
) {
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
);
196 result
= target_write_memory(bank
->target
, 0x40020004, 4, 3, buffer
);
198 if (result
!= ERROR_OK
) {
204 result
= target_write_memory(bank
->target
, 0x40020000, 1, 1, buffer
);
205 if (result
!= ERROR_OK
) {
210 for (i
= 0; i
< 50; i
++) {
212 target_read_memory(bank
->target
, 0x40020000, 1, 1, buffer
);
214 if (result
!= ERROR_OK
) {
218 if (buffer
[0] & 0x80)
224 if (buffer
[0] != 0x80) {
226 ("ftfl command failed FSTAT: %02X W0: %08X W1: %08X W2: %08X",
227 buffer
[0], w0
, w1
, w2
);
229 return ERROR_FLASH_OPERATION_FAILED
;
235 static int kinetis_erase(struct flash_bank
*bank
, int first
, int last
)
237 struct flash_bank
*master_bank
;
239 uint32_t w0
= 0, w1
= 0, w2
= 0;
241 if (bank
->target
->state
!= TARGET_HALTED
) {
242 LOG_ERROR("Target not halted");
243 return ERROR_TARGET_NOT_HALTED
;
246 result
= kinetis_get_master_bank(bank
, &master_bank
);
248 if (result
!= ERROR_OK
) {
252 if ((first
> bank
->num_sectors
) || (last
> bank
->num_sectors
)) {
253 return ERROR_FLASH_OPERATION_FAILED
;
256 for (i
= first
; i
<= last
; i
++) {
257 /* set command and sector address */
258 w0
= (0x09 << 24) | bank
->sectors
[i
].offset
;
260 result
= kinetis_ftfl_command(bank
, w0
, w1
, w2
);
262 if (result
!= ERROR_OK
) {
263 LOG_WARNING("erase sector %d failed", i
);
264 return ERROR_FLASH_OPERATION_FAILED
;
267 bank
->sectors
[i
].is_erased
= 1;
272 ("flash configuration field erased, please reset the device");
278 static int kinetis_write(struct flash_bank
*bank
, uint8_t * buffer
,
279 uint32_t offset
, uint32_t count
)
281 struct flash_bank
*master_bank
;
282 unsigned int i
, result
, fallback
= 0, nvm
= 0;
284 uint32_t wc
, w0
= 0, w1
= 0, w2
= 0;
285 struct kinetis_flash_bank
* kbank
= (struct kinetis_flash_bank
*)
288 if (bank
->target
->state
!= TARGET_HALTED
) {
289 LOG_ERROR("Target not halted");
290 return ERROR_TARGET_NOT_HALTED
;
293 result
= kinetis_get_master_bank(bank
, &master_bank
);
295 if (result
!= ERROR_OK
) {
299 if (offset
>= kbank
->nvm_start
)
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
307 LOG_ERROR("Segment spans NVM boundary");
308 return ERROR_FLASH_DST_OUT_OF_BANK
;
312 LOG_DEBUG("flash write into NVM @%08X", offset
);
314 /* make flex ram available */
315 w0
= (0x81 << 24) | 0x00ff0000;
317 result
= kinetis_ftfl_command(bank
, w0
, w1
, w2
);
319 if (result
!= ERROR_OK
)
320 return ERROR_FLASH_OPERATION_FAILED
;
322 /* check if ram ready */
323 result
= target_read_memory(bank
->target
, 0x40020001, 1, 1, buf
);
325 if (result
!= ERROR_OK
)
328 if (!(buf
[0] & (1 << 1))) {
329 /* fallback to longword write */
332 LOG_WARNING("ram not ready, fallback to slow longword write (FCNFG: %02X)",
336 LOG_DEBUG("flash write into PFLASH @08%X", offset
);
341 /* program section command */
343 for (i
= 0; i
< count
; i
+= (2 * 1024)) {
346 if ((count
- i
) < (2 * 1024)) {
351 LOG_DEBUG("write section @ %08X with length %d",
354 /* write data to flexram */
356 target_write_memory(bank
->target
, 0x14000000, 4, wc
,
359 if (result
!= ERROR_OK
) {
360 LOG_ERROR("target_write_memory failed");
365 /* execute section command */
366 w0
= (0x0b << 24) | (offset
+ i
);
369 result
= kinetis_ftfl_command(bank
, w0
, w1
, w2
);
371 if (result
!= ERROR_OK
) {
372 return ERROR_FLASH_OPERATION_FAILED
;
376 /* program longword command */
378 for (i
= 0; i
< count
; i
+= 4) {
379 LOG_DEBUG("write longword @ %08X", offset
+ i
);
381 w0
= (0x06 << 24) | (offset
+ i
);
382 w1
= buf_get_u32(buffer
+ offset
+ i
, 0, 32);
384 result
= kinetis_ftfl_command(bank
, w0
, w1
, w2
);
386 if (result
!= ERROR_OK
) {
387 return ERROR_FLASH_OPERATION_FAILED
;
395 static int kinetis_probe(struct flash_bank
*bank
)
397 struct flash_bank
*master_bank
;
400 uint32_t sim_sdid
, sim_fcfg1
, sim_fcfg2
, offset
= 0;
401 uint32_t nvm_size
, pf_size
, ee_size
;
403 if (bank
->target
->state
!= TARGET_HALTED
) {
404 LOG_ERROR("Target not halted");
405 return ERROR_TARGET_NOT_HALTED
;
408 result
= kinetis_get_master_bank(bank
, &master_bank
);
410 if (result
!= ERROR_OK
) {
414 result
= target_read_memory(bank
->target
, 0x40048024, 1, 4, buf
);
415 if (result
!= ERROR_OK
) {
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
) {
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
) {
428 sim_fcfg2
= target_buffer_get_u32(bank
->target
, buf
);
430 LOG_DEBUG("SDID: %08X FCFG1: %08X FCFG2: %08X", sim_sdid
, sim_fcfg1
,
433 switch ((sim_fcfg1
>> 28) & 0x0f) {
435 nvm_size
= 128 * 1024;
439 nvm_size
= 256 * 1024;
446 switch ((sim_fcfg1
>> 24) & 0x0f) {
448 pf_size
= 128 * 1024;
451 pf_size
= 256 * 1024;
455 pf_size
= 512 * 1024;
462 switch ((sim_fcfg1
>> 16) & 0x0f) {
492 ((struct kinetis_flash_bank
*) bank
->driver_priv
)->nvm_start
=
495 LOG_DEBUG("NVM: %d PF: %d EE: %d BL1: %d", nvm_size
, pf_size
, ee_size
,
496 (sim_fcfg2
>> 23) & 1);
498 if (pf_size
!= bank
->size
) {
499 LOG_WARNING("flash size is different %d != %d", pf_size
,
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
);
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;
515 /* update the info we do not have */
516 return kinetis_update_bank_info(bank
);
519 static int kinetis_auto_probe(struct flash_bank
*bank
)
521 return kinetis_probe(bank
);
524 static int kinetis_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
527 struct flash_bank
*master_bank
;
529 result
= kinetis_get_master_bank(bank
, &master_bank
);
531 if (result
!= ERROR_OK
) {
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
);
542 static int kinetis_blank_check(struct flash_bank
*bank
)
545 struct flash_bank
*master_bank
;
547 LOG_WARNING("kinetis_blank_check not supported yet");
549 if (bank
->target
->state
!= TARGET_HALTED
) {
550 LOG_ERROR("Target not halted");
551 return ERROR_TARGET_NOT_HALTED
;
554 result
= kinetis_get_master_bank(bank
, &master_bank
);
556 if (result
!= ERROR_OK
) {
563 static int kinetis_flash_read(struct flash_bank
*bank
,
564 uint8_t * buffer
, uint32_t offset
, uint32_t count
)
567 struct flash_bank
*master_bank
;
569 LOG_WARNING("kinetis_flash_read not supported yet");
571 if (bank
->target
->state
!= TARGET_HALTED
) {
572 LOG_ERROR("Target not halted");
573 return ERROR_TARGET_NOT_HALTED
;
576 result
= kinetis_get_master_bank(bank
, &master_bank
);
578 if (result
!= ERROR_OK
) {
585 struct flash_driver kinetis_flash
= {
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
,
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)