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 ***************************************************************************/
29 #include "helper/binarybuffer.h"
31 struct kinetis_flash_bank
{
35 static int kinetis_get_master_bank(struct flash_bank
*bank
,
36 struct flash_bank
**master_bank
)
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
;
48 static int kinetis_update_bank_info(struct flash_bank
*bank
)
51 struct flash_bank
*master_bank
;
53 result
= kinetis_get_master_bank(bank
, &master_bank
);
55 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
;
75 LOG_INFO("add flash_bank kinetis %s", bank
->name
);
77 bank_info
= malloc(sizeof(struct kinetis_flash_bank
));
79 memset(bank_info
, 0, sizeof(struct kinetis_flash_bank
));
81 bank
->driver_priv
= bank_info
;
86 static int kinetis_protect(struct flash_bank
*bank
, int set
, int first
,
90 struct flash_bank
*master_bank
;
92 result
= kinetis_get_master_bank(bank
, &master_bank
);
94 if (result
!= ERROR_OK
)
97 LOG_WARNING("kinetis_protect not supported yet");
99 if (bank
->target
->state
!= TARGET_HALTED
) {
100 LOG_ERROR("Target not halted");
101 return ERROR_TARGET_NOT_HALTED
;
107 static int kinetis_protect_check(struct flash_bank
*bank
)
110 struct flash_bank
*master_bank
;
112 uint32_t fprot
, psize
, psec
;
115 if (bank
->target
->state
!= TARGET_HALTED
) {
116 LOG_ERROR("Target not halted");
117 return ERROR_TARGET_NOT_HALTED
;
120 result
= kinetis_get_master_bank(bank
, &master_bank
);
122 if (result
!= ERROR_OK
)
125 /* read protection register FTFL_FPROT */
126 result
= target_read_memory(bank
->target
, 0x40020010, 1, 4, buffer
);
128 if (result
!= ERROR_OK
)
131 fprot
= target_buffer_get_u32(bank
->target
, buffer
);
133 /* every bit protect 1/32 of the full flash */
134 psize
= bank
->size
/ 32;
138 for (i
= 0; i
< bank
->num_sectors
; i
++) {
139 if ((fprot
>> b
) & 1)
140 bank
->sectors
[i
].is_protected
= 0;
142 bank
->sectors
[i
].is_protected
= 1;
144 psec
+= bank
->sectors
[i
].size
;
155 static int kinetis_ftfl_command(struct flash_bank
*bank
, uint32_t w0
,
156 uint32_t w1
, uint32_t w2
)
162 for (i
= 0; i
< 50; i
++) {
164 target_read_memory(bank
->target
, 0x40020000, 1, 1, buffer
);
166 if (result
!= ERROR_OK
)
169 if (buffer
[0] & 0x80)
175 if (buffer
[0] != 0x80) {
176 /* reset error flags */
179 target_write_memory(bank
->target
, 0x40020000, 1, 1, buffer
);
180 if (result
!= ERROR_OK
)
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
);
188 result
= target_write_memory(bank
->target
, 0x40020004, 4, 3, buffer
);
190 if (result
!= ERROR_OK
)
195 result
= target_write_memory(bank
->target
, 0x40020000, 1, 1, buffer
);
196 if (result
!= ERROR_OK
)
200 for (i
= 0; i
< 50; i
++) {
202 target_read_memory(bank
->target
, 0x40020000, 1, 1, buffer
);
204 if (result
!= ERROR_OK
)
207 if (buffer
[0] & 0x80)
213 if (buffer
[0] != 0x80) {
215 ("ftfl command failed FSTAT: %02X W0: %08X W1: %08X W2: %08X",
216 buffer
[0], w0
, w1
, w2
);
218 return ERROR_FLASH_OPERATION_FAILED
;
224 static int kinetis_erase(struct flash_bank
*bank
, int first
, int last
)
226 struct flash_bank
*master_bank
;
228 uint32_t w0
= 0, w1
= 0, w2
= 0;
230 if (bank
->target
->state
!= TARGET_HALTED
) {
231 LOG_ERROR("Target not halted");
232 return ERROR_TARGET_NOT_HALTED
;
235 result
= kinetis_get_master_bank(bank
, &master_bank
);
237 if (result
!= ERROR_OK
)
240 if ((first
> bank
->num_sectors
) || (last
> bank
->num_sectors
))
241 return ERROR_FLASH_OPERATION_FAILED
;
243 for (i
= first
; i
<= last
; i
++) {
244 /* set command and sector address */
245 w0
= (0x09 << 24) | bank
->sectors
[i
].offset
;
247 result
= kinetis_ftfl_command(bank
, w0
, w1
, w2
);
249 if (result
!= ERROR_OK
) {
250 LOG_WARNING("erase sector %d failed", i
);
251 return ERROR_FLASH_OPERATION_FAILED
;
254 bank
->sectors
[i
].is_erased
= 1;
259 ("flash configuration field erased, please reset the device");
265 static int kinetis_write(struct flash_bank
*bank
, uint8_t *buffer
,
266 uint32_t offset
, uint32_t count
)
268 struct flash_bank
*master_bank
;
269 unsigned int i
, result
, fallback
= 0, nvm
= 0;
271 uint32_t wc
, w0
= 0, w1
= 0, w2
= 0;
272 struct kinetis_flash_bank
*kbank
= (struct kinetis_flash_bank
*)
275 if (bank
->target
->state
!= TARGET_HALTED
) {
276 LOG_ERROR("Target not halted");
277 return ERROR_TARGET_NOT_HALTED
;
280 result
= kinetis_get_master_bank(bank
, &master_bank
);
282 if (result
!= ERROR_OK
)
285 if (offset
>= kbank
->nvm_start
)
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
293 LOG_ERROR("Segment spans NVM boundary");
294 return ERROR_FLASH_DST_OUT_OF_BANK
;
298 LOG_DEBUG("flash write into NVM @%08X", offset
);
300 /* make flex ram available */
301 w0
= (0x81 << 24) | 0x00ff0000;
303 result
= kinetis_ftfl_command(bank
, w0
, w1
, w2
);
305 if (result
!= ERROR_OK
)
306 return ERROR_FLASH_OPERATION_FAILED
;
308 /* check if ram ready */
309 result
= target_read_memory(bank
->target
, 0x40020001, 1, 1, buf
);
311 if (result
!= ERROR_OK
)
314 if (!(buf
[0] & (1 << 1))) {
315 /* fallback to longword write */
318 LOG_WARNING("ram not ready, fallback to slow longword write (FCNFG: %02X)",
322 LOG_DEBUG("flash write into PFLASH @08%X", offset
);
327 /* program section command */
329 for (i
= 0; i
< count
; i
+= (2 * 1024)) {
332 if ((count
- i
) < (2 * 1024)) {
337 LOG_DEBUG("write section @ %08X with length %d",
340 /* write data to flexram */
342 target_write_memory(bank
->target
, 0x14000000, 4, wc
,
345 if (result
!= ERROR_OK
) {
346 LOG_ERROR("target_write_memory failed");
351 /* execute section command */
352 w0
= (0x0b << 24) | (offset
+ i
);
355 result
= kinetis_ftfl_command(bank
, w0
, w1
, w2
);
357 if (result
!= ERROR_OK
)
358 return ERROR_FLASH_OPERATION_FAILED
;
361 /* program longword command */
363 for (i
= 0; i
< count
; i
+= 4) {
364 LOG_DEBUG("write longword @ %08X", offset
+ i
);
366 w0
= (0x06 << 24) | (offset
+ i
);
367 w1
= buf_get_u32(buffer
+ offset
+ i
, 0, 32);
369 result
= kinetis_ftfl_command(bank
, w0
, w1
, w2
);
371 if (result
!= ERROR_OK
)
372 return ERROR_FLASH_OPERATION_FAILED
;
379 static int kinetis_probe(struct flash_bank
*bank
)
381 struct flash_bank
*master_bank
;
384 uint32_t sim_sdid
, sim_fcfg1
, sim_fcfg2
, offset
= 0;
385 uint32_t nvm_size
, pf_size
, ee_size
;
387 if (bank
->target
->state
!= TARGET_HALTED
) {
388 LOG_ERROR("Target not halted");
389 return ERROR_TARGET_NOT_HALTED
;
392 result
= kinetis_get_master_bank(bank
, &master_bank
);
394 if (result
!= ERROR_OK
)
397 result
= target_read_memory(bank
->target
, 0x40048024, 1, 4, buf
);
398 if (result
!= ERROR_OK
)
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
)
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
)
408 sim_fcfg2
= target_buffer_get_u32(bank
->target
, buf
);
410 LOG_DEBUG("SDID: %08X FCFG1: %08X FCFG2: %08X", sim_sdid
, sim_fcfg1
,
413 switch ((sim_fcfg1
>> 28) & 0x0f) {
415 nvm_size
= 128 * 1024;
419 nvm_size
= 256 * 1024;
426 switch ((sim_fcfg1
>> 24) & 0x0f) {
428 pf_size
= 128 * 1024;
431 pf_size
= 256 * 1024;
435 pf_size
= 512 * 1024;
442 switch ((sim_fcfg1
>> 16) & 0x0f) {
472 ((struct kinetis_flash_bank
*) bank
->driver_priv
)->nvm_start
=
475 LOG_DEBUG("NVM: %d PF: %d EE: %d BL1: %d", nvm_size
, pf_size
, ee_size
,
476 (sim_fcfg2
>> 23) & 1);
478 if (pf_size
!= bank
->size
) {
479 LOG_WARNING("flash size is different %d != %d", pf_size
,
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
);
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;
495 /* update the info we do not have */
496 return kinetis_update_bank_info(bank
);
499 static int kinetis_auto_probe(struct flash_bank
*bank
)
501 return kinetis_probe(bank
);
504 static int kinetis_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
507 struct flash_bank
*master_bank
;
509 result
= kinetis_get_master_bank(bank
, &master_bank
);
511 if (result
!= ERROR_OK
)
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
);
521 static int kinetis_blank_check(struct flash_bank
*bank
)
524 struct flash_bank
*master_bank
;
526 LOG_WARNING("kinetis_blank_check not supported yet");
528 if (bank
->target
->state
!= TARGET_HALTED
) {
529 LOG_ERROR("Target not halted");
530 return ERROR_TARGET_NOT_HALTED
;
533 result
= kinetis_get_master_bank(bank
, &master_bank
);
535 if (result
!= ERROR_OK
)
541 static int kinetis_flash_read(struct flash_bank
*bank
,
542 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
545 struct flash_bank
*master_bank
;
547 LOG_WARNING("kinetis_flash_read 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
)
562 struct flash_driver kinetis_flash
= {
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
,
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)