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
);
326 /* program section command */
328 for (i
= 0; i
< count
; i
+= (2 * 1024)) {
331 if ((count
- i
) < (2 * 1024)) {
336 LOG_DEBUG("write section @ %08X with length %d",
339 /* write data to flexram */
341 target_write_memory(bank
->target
, 0x14000000, 4, wc
,
344 if (result
!= ERROR_OK
) {
345 LOG_ERROR("target_write_memory failed");
350 /* execute section command */
351 w0
= (0x0b << 24) | (offset
+ i
);
354 result
= kinetis_ftfl_command(bank
, w0
, w1
, w2
);
356 if (result
!= ERROR_OK
)
357 return ERROR_FLASH_OPERATION_FAILED
;
360 /* program longword command */
362 for (i
= 0; i
< count
; i
+= 4) {
363 LOG_DEBUG("write longword @ %08X", offset
+ i
);
365 w0
= (0x06 << 24) | (offset
+ i
);
366 w1
= buf_get_u32(buffer
+ offset
+ i
, 0, 32);
368 result
= kinetis_ftfl_command(bank
, w0
, w1
, w2
);
370 if (result
!= ERROR_OK
)
371 return ERROR_FLASH_OPERATION_FAILED
;
378 static int kinetis_probe(struct flash_bank
*bank
)
380 struct flash_bank
*master_bank
;
383 uint32_t sim_sdid
, sim_fcfg1
, sim_fcfg2
, offset
= 0;
384 uint32_t nvm_size
, pf_size
, ee_size
;
386 if (bank
->target
->state
!= TARGET_HALTED
) {
387 LOG_ERROR("Target not halted");
388 return ERROR_TARGET_NOT_HALTED
;
391 result
= kinetis_get_master_bank(bank
, &master_bank
);
393 if (result
!= ERROR_OK
)
396 result
= target_read_memory(bank
->target
, 0x40048024, 1, 4, buf
);
397 if (result
!= ERROR_OK
)
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
)
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
)
407 sim_fcfg2
= target_buffer_get_u32(bank
->target
, buf
);
409 LOG_DEBUG("SDID: %08X FCFG1: %08X FCFG2: %08X", sim_sdid
, sim_fcfg1
,
412 switch ((sim_fcfg1
>> 28) & 0x0f) {
414 nvm_size
= 128 * 1024;
418 nvm_size
= 256 * 1024;
425 switch ((sim_fcfg1
>> 24) & 0x0f) {
427 pf_size
= 128 * 1024;
430 pf_size
= 256 * 1024;
434 pf_size
= 512 * 1024;
441 switch ((sim_fcfg1
>> 16) & 0x0f) {
471 ((struct kinetis_flash_bank
*) bank
->driver_priv
)->nvm_start
=
474 LOG_DEBUG("NVM: %d PF: %d EE: %d BL1: %d", nvm_size
, pf_size
, ee_size
,
475 (sim_fcfg2
>> 23) & 1);
477 if (pf_size
!= bank
->size
) {
478 LOG_WARNING("flash size is different %d != %d", pf_size
,
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
);
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;
494 /* update the info we do not have */
495 return kinetis_update_bank_info(bank
);
498 static int kinetis_auto_probe(struct flash_bank
*bank
)
500 return kinetis_probe(bank
);
503 static int kinetis_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
506 struct flash_bank
*master_bank
;
508 result
= kinetis_get_master_bank(bank
, &master_bank
);
510 if (result
!= ERROR_OK
)
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
);
520 static int kinetis_blank_check(struct flash_bank
*bank
)
523 struct flash_bank
*master_bank
;
525 LOG_WARNING("kinetis_blank_check not supported yet");
527 if (bank
->target
->state
!= TARGET_HALTED
) {
528 LOG_ERROR("Target not halted");
529 return ERROR_TARGET_NOT_HALTED
;
532 result
= kinetis_get_master_bank(bank
, &master_bank
);
534 if (result
!= ERROR_OK
)
540 static int kinetis_flash_read(struct flash_bank
*bank
,
541 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
544 struct flash_bank
*master_bank
;
546 LOG_WARNING("kinetis_flash_read not supported yet");
548 if (bank
->target
->state
!= TARGET_HALTED
) {
549 LOG_ERROR("Target not halted");
550 return ERROR_TARGET_NOT_HALTED
;
553 result
= kinetis_get_master_bank(bank
, &master_bank
);
555 if (result
!= ERROR_OK
)
561 struct flash_driver kinetis_flash
= {
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
,
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)