d618cfdd2ccfdc34195b36d99400312ec7bda60b
[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 * Copyright (C) 2012 by Christopher D. Kilgour *
9 * techie at whiterocker.com *
10 * *
11 * Copyright (C) 2013 Nemui Trinomius *
12 * nemuisan_kawausogasuki@live.jp *
13 * *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
18 * *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program; if not, write to the *
26 * Free Software Foundation, Inc., *
27 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
28 ***************************************************************************/
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include "jtag/interface.h"
35 #include "imp.h"
36 #include <helper/binarybuffer.h>
37 #include <target/target_type.h>
38 #include <target/algorithm.h>
39 #include <target/armv7m.h>
40 #include <target/cortex_m.h>
41
42 /*
43 * Implementation Notes
44 *
45 * The persistent memories in the Kinetis chip families K10 through
46 * K70 are all manipulated with the Flash Memory Module. Some
47 * variants call this module the FTFE, others call it the FTFL. To
48 * indicate that both are considered here, we use FTFX.
49 *
50 * Within the module, according to the chip variant, the persistent
51 * memory is divided into what Freescale terms Program Flash, FlexNVM,
52 * and FlexRAM. All chip variants have Program Flash. Some chip
53 * variants also have FlexNVM and FlexRAM, which always appear
54 * together.
55 *
56 * A given Kinetis chip may have 1, 2 or 4 blocks of flash. Here we map
57 * each block to a separate bank. Each block size varies by chip and
58 * may be determined by the read-only SIM_FCFG1 register. The sector
59 * size within each bank/block varies by chip, and may be 1, 2 or 4k.
60 * The sector size may be different for flash and FlexNVM.
61 *
62 * The first half of the flash (1 or 2 blocks) is always Program Flash
63 * and always starts at address 0x00000000. The "PFLSH" flag, bit 23
64 * of the read-only SIM_FCFG2 register, determines whether the second
65 * half of the flash is also Program Flash or FlexNVM+FlexRAM. When
66 * PFLSH is set, the second from the first half. When PFLSH is clear,
67 * the second half of flash is FlexNVM and always starts at address
68 * 0x10000000. FlexRAM, which is also present when PFLSH is clear,
69 * always starts at address 0x14000000.
70 *
71 * The Flash Memory Module provides a register set where flash
72 * commands are loaded to perform flash operations like erase and
73 * program. Different commands are available depending on whether
74 * Program Flash or FlexNVM/FlexRAM is being manipulated. Although
75 * the commands used are quite consistent between flash blocks, the
76 * parameters they accept differ according to the flash sector size.
77 *
78 */
79
80 /* Addressess */
81 #define FLEXRAM 0x14000000
82 #define FTFx_FSTAT 0x40020000
83 #define FTFx_FCNFG 0x40020001
84 #define FTFx_FCCOB3 0x40020004
85 #define FTFx_FPROT3 0x40020010
86 #define SIM_SDID 0x40048024
87 #define SIM_SOPT1 0x40047000
88 #define SIM_FCFG1 0x4004804c
89 #define SIM_FCFG2 0x40048050
90 #define WDOG_STCTRH 0x40052000
91
92 /* Commands */
93 #define FTFx_CMD_BLOCKSTAT 0x00
94 #define FTFx_CMD_SECTSTAT 0x01
95 #define FTFx_CMD_LWORDPROG 0x06
96 #define FTFx_CMD_SECTERASE 0x09
97 #define FTFx_CMD_SECTWRITE 0x0b
98 #define FTFx_CMD_SETFLEXRAM 0x81
99 #define FTFx_CMD_MASSERASE 0x44
100
101 /* The older Kinetis K series uses the following SDID layout :
102 * Bit 31-16 : 0
103 * Bit 15-12 : REVID
104 * Bit 11-7 : DIEID
105 * Bit 6-4 : FAMID
106 * Bit 3-0 : PINID
107 *
108 * The newer Kinetis series uses the following SDID layout :
109 * Bit 31-28 : FAMID
110 * Bit 27-24 : SUBFAMID
111 * Bit 23-20 : SERIESID
112 * Bit 19-16 : SRAMSIZE
113 * Bit 15-12 : REVID
114 * Bit 6-4 : Reserved (0)
115 * Bit 3-0 : PINID
116 *
117 * We assume that if bits 31-16 are 0 then it's an older
118 * K-series MCU.
119 */
120
121 #define KINETIS_SOPT1_RAMSIZE_MASK 0x0000F000
122 #define KINETIS_SOPT1_RAMSIZE_K24FN1M 0x0000B000
123
124 #define KINETIS_SDID_K_SERIES_MASK 0x0000FFFF
125
126 #define KINETIS_SDID_DIEID_MASK 0x00000F80
127
128 #define KINETIS_SDID_DIEID_K22FN128 0x00000680 /* smaller pflash with FTFA */
129 #define KINETIS_SDID_DIEID_K22FN256 0x00000A80
130 #define KINETIS_SDID_DIEID_K22FN512 0x00000E80
131 #define KINETIS_SDID_DIEID_K24FN256 0x00000700
132
133 #define KINETIS_SDID_DIEID_K24FN1M 0x00000300 /* Detect Errata 7534 */
134
135 /* We can't rely solely on the FAMID field to determine the MCU
136 * type since some FAMID values identify multiple MCUs with
137 * different flash sector sizes (K20 and K22 for instance).
138 * Therefore we combine it with the DIEID bits which may possibly
139 * break if Freescale bumps the DIEID for a particular MCU. */
140 #define KINETIS_K_SDID_TYPE_MASK 0x00000FF0
141 #define KINETIS_K_SDID_K10_M50 0x00000000
142 #define KINETIS_K_SDID_K10_M72 0x00000080
143 #define KINETIS_K_SDID_K10_M100 0x00000100
144 #define KINETIS_K_SDID_K10_M120 0x00000180
145 #define KINETIS_K_SDID_K11 0x00000220
146 #define KINETIS_K_SDID_K12 0x00000200
147 #define KINETIS_K_SDID_K20_M50 0x00000010
148 #define KINETIS_K_SDID_K20_M72 0x00000090
149 #define KINETIS_K_SDID_K20_M100 0x00000110
150 #define KINETIS_K_SDID_K20_M120 0x00000190
151 #define KINETIS_K_SDID_K21_M50 0x00000230
152 #define KINETIS_K_SDID_K21_M120 0x00000330
153 #define KINETIS_K_SDID_K22_M50 0x00000210
154 #define KINETIS_K_SDID_K22_M120 0x00000310
155 #define KINETIS_K_SDID_K30_M72 0x000000A0
156 #define KINETIS_K_SDID_K30_M100 0x00000120
157 #define KINETIS_K_SDID_K40_M72 0x000000B0
158 #define KINETIS_K_SDID_K40_M100 0x00000130
159 #define KINETIS_K_SDID_K50_M72 0x000000E0
160 #define KINETIS_K_SDID_K51_M72 0x000000F0
161 #define KINETIS_K_SDID_K53 0x00000170
162 #define KINETIS_K_SDID_K60_M100 0x00000140
163 #define KINETIS_K_SDID_K60_M150 0x000001C0
164 #define KINETIS_K_SDID_K70_M150 0x000001D0
165
166 #define KINETIS_SDID_SERIESID_MASK 0x00F00000
167 #define KINETIS_SDID_SERIESID_K 0x00000000
168 #define KINETIS_SDID_SERIESID_KL 0x00100000
169 #define KINETIS_SDID_SERIESID_KW 0x00500000
170 #define KINETIS_SDID_SERIESID_KV 0x00600000
171
172 #define KINETIS_SDID_SUBFAMID_MASK 0x0F000000
173 #define KINETIS_SDID_SUBFAMID_KX0 0x00000000
174 #define KINETIS_SDID_SUBFAMID_KX1 0x01000000
175 #define KINETIS_SDID_SUBFAMID_KX2 0x02000000
176 #define KINETIS_SDID_SUBFAMID_KX3 0x03000000
177 #define KINETIS_SDID_SUBFAMID_KX4 0x04000000
178 #define KINETIS_SDID_SUBFAMID_KX5 0x05000000
179 #define KINETIS_SDID_SUBFAMID_KX6 0x06000000
180
181 #define KINETIS_SDID_FAMILYID_MASK 0xF0000000
182 #define KINETIS_SDID_FAMILYID_K0X 0x00000000
183 #define KINETIS_SDID_FAMILYID_K1X 0x10000000
184 #define KINETIS_SDID_FAMILYID_K2X 0x20000000
185 #define KINETIS_SDID_FAMILYID_K3X 0x30000000
186 #define KINETIS_SDID_FAMILYID_K4X 0x40000000
187 #define KINETIS_SDID_FAMILYID_K6X 0x60000000
188 #define KINETIS_SDID_FAMILYID_K7X 0x70000000
189
190 struct kinetis_flash_bank {
191 unsigned bank_ordinal;
192 uint32_t sector_size;
193 uint32_t max_flash_prog_size;
194 uint32_t protection_size;
195
196 uint32_t sim_sdid;
197 uint32_t sim_fcfg1;
198 uint32_t sim_fcfg2;
199
200 enum {
201 FC_AUTO = 0,
202 FC_PFLASH,
203 FC_FLEX_NVM,
204 FC_FLEX_RAM,
205 } flash_class;
206
207 enum {
208 FS_PROGRAM_SECTOR = 1,
209 FS_PROGRAM_LONGWORD = 2,
210 FS_PROGRAM_PHRASE = 4, /* Unsupported */
211 } flash_support;
212 };
213
214 #define MDM_REG_STAT 0x00
215 #define MDM_REG_CTRL 0x04
216 #define MDM_REG_ID 0xfc
217
218 #define MDM_STAT_FMEACK (1<<0)
219 #define MDM_STAT_FREADY (1<<1)
220 #define MDM_STAT_SYSSEC (1<<2)
221 #define MDM_STAT_SYSRES (1<<3)
222 #define MDM_STAT_FMEEN (1<<5)
223 #define MDM_STAT_BACKDOOREN (1<<6)
224 #define MDM_STAT_LPEN (1<<7)
225 #define MDM_STAT_VLPEN (1<<8)
226 #define MDM_STAT_LLSMODEXIT (1<<9)
227 #define MDM_STAT_VLLSXMODEXIT (1<<10)
228 #define MDM_STAT_CORE_HALTED (1<<16)
229 #define MDM_STAT_CORE_SLEEPDEEP (1<<17)
230 #define MDM_STAT_CORESLEEPING (1<<18)
231
232 #define MEM_CTRL_FMEIP (1<<0)
233 #define MEM_CTRL_DBG_DIS (1<<1)
234 #define MEM_CTRL_DBG_REQ (1<<2)
235 #define MEM_CTRL_SYS_RES_REQ (1<<3)
236 #define MEM_CTRL_CORE_HOLD_RES (1<<4)
237 #define MEM_CTRL_VLLSX_DBG_REQ (1<<5)
238 #define MEM_CTRL_VLLSX_DBG_ACK (1<<6)
239 #define MEM_CTRL_VLLSX_STAT_ACK (1<<7)
240
241 #define MDM_ACCESS_TIMEOUT 3000 /* iterations */
242
243 static int kinetis_mdm_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value)
244 {
245 int retval;
246 LOG_DEBUG("MDM_REG[0x%02x] <- %08" PRIX32, reg, value);
247
248 retval = dap_queue_ap_write(dap_ap(dap, 1), reg, value);
249 if (retval != ERROR_OK) {
250 LOG_DEBUG("MDM: failed to queue a write request");
251 return retval;
252 }
253
254 retval = dap_run(dap);
255 if (retval != ERROR_OK) {
256 LOG_DEBUG("MDM: dap_run failed");
257 return retval;
258 }
259
260
261 return ERROR_OK;
262 }
263
264 static int kinetis_mdm_read_register(struct adiv5_dap *dap, unsigned reg, uint32_t *result)
265 {
266 int retval;
267
268 retval = dap_queue_ap_read(dap_ap(dap, 1), reg, result);
269 if (retval != ERROR_OK) {
270 LOG_DEBUG("MDM: failed to queue a read request");
271 return retval;
272 }
273
274 retval = dap_run(dap);
275 if (retval != ERROR_OK) {
276 LOG_DEBUG("MDM: dap_run failed");
277 return retval;
278 }
279
280 LOG_DEBUG("MDM_REG[0x%02x]: %08" PRIX32, reg, *result);
281 return ERROR_OK;
282 }
283
284 static int kinetis_mdm_poll_register(struct adiv5_dap *dap, unsigned reg, uint32_t mask, uint32_t value)
285 {
286 uint32_t val;
287 int retval;
288 int timeout = MDM_ACCESS_TIMEOUT;
289
290 do {
291 retval = kinetis_mdm_read_register(dap, reg, &val);
292 if (retval != ERROR_OK || (val & mask) == value)
293 return retval;
294
295 alive_sleep(1);
296 } while (timeout--);
297
298 LOG_DEBUG("MDM: polling timed out");
299 return ERROR_FAIL;
300 }
301
302 /*
303 * This function implements the procedure to mass erase the flash via
304 * SWD/JTAG on Kinetis K and L series of devices as it is described in
305 * AN4835 "Production Flash Programming Best Practices for Kinetis K-
306 * and L-series MCUs" Section 4.2.1
307 */
308 COMMAND_HANDLER(kinetis_mdm_mass_erase)
309 {
310 struct target *target = get_current_target(CMD_CTX);
311 struct cortex_m_common *cortex_m = target_to_cm(target);
312 struct adiv5_dap *dap = cortex_m->armv7m.arm.dap;
313
314 if (!dap) {
315 LOG_ERROR("Cannot perform mass erase with a high-level adapter");
316 return ERROR_FAIL;
317 }
318
319 int retval;
320
321 /*
322 * ... Power on the processor, or if power has already been
323 * applied, assert the RESET pin to reset the processor. For
324 * devices that do not have a RESET pin, write the System
325 * Reset Request bit in the MDM-AP control register after
326 * establishing communication...
327 */
328
329 /* assert SRST */
330 if (jtag_get_reset_config() & RESET_HAS_SRST)
331 adapter_assert_reset();
332 else
333 LOG_WARNING("Attempting mass erase without hardware reset. This is not reliable; "
334 "it's recommended you connect SRST and use ``reset_config srst_only''.");
335
336 retval = kinetis_mdm_write_register(dap, MDM_REG_CTRL, MEM_CTRL_SYS_RES_REQ);
337 if (retval != ERROR_OK)
338 return retval;
339
340 /*
341 * ... Read the MDM-AP status register until the Flash Ready bit sets...
342 */
343 retval = kinetis_mdm_poll_register(dap, MDM_REG_STAT,
344 MDM_STAT_FREADY | MDM_STAT_SYSRES,
345 MDM_STAT_FREADY);
346 if (retval != ERROR_OK) {
347 LOG_ERROR("MDM : flash ready timeout");
348 return retval;
349 }
350
351 /*
352 * ... Write the MDM-AP control register to set the Flash Mass
353 * Erase in Progress bit. This will start the mass erase
354 * process...
355 */
356 retval = kinetis_mdm_write_register(dap, MDM_REG_CTRL,
357 MEM_CTRL_SYS_RES_REQ | MEM_CTRL_FMEIP);
358 if (retval != ERROR_OK)
359 return retval;
360
361 /* As a sanity check make sure that device started mass erase procedure */
362 retval = kinetis_mdm_poll_register(dap, MDM_REG_STAT,
363 MDM_STAT_FMEACK, MDM_STAT_FMEACK);
364 if (retval != ERROR_OK)
365 return retval;
366
367 /*
368 * ... Read the MDM-AP control register until the Flash Mass
369 * Erase in Progress bit clears...
370 */
371 retval = kinetis_mdm_poll_register(dap, MDM_REG_CTRL,
372 MEM_CTRL_FMEIP,
373 0);
374 if (retval != ERROR_OK)
375 return retval;
376
377 /*
378 * ... Negate the RESET signal or clear the System Reset Request
379 * bit in the MDM-AP control register...
380 */
381 retval = kinetis_mdm_write_register(dap, MDM_REG_CTRL, 0);
382 if (retval != ERROR_OK)
383 return retval;
384
385 if (jtag_get_reset_config() & RESET_HAS_SRST) {
386 /* halt MCU otherwise it loops in hard fault - WDOG reset cycle */
387 target->reset_halt = true;
388 target->type->assert_reset(target);
389 target->type->deassert_reset(target);
390 }
391
392 return ERROR_OK;
393 }
394
395 static const uint32_t kinetis_known_mdm_ids[] = {
396 0x001C0000, /* Kinetis-K Series */
397 0x001C0020, /* Kinetis-L/M/V/E Series */
398 };
399
400 /*
401 * This function implements the procedure to connect to
402 * SWD/JTAG on Kinetis K and L series of devices as it is described in
403 * AN4835 "Production Flash Programming Best Practices for Kinetis K-
404 * and L-series MCUs" Section 4.1.1
405 */
406 COMMAND_HANDLER(kinetis_check_flash_security_status)
407 {
408 struct target *target = get_current_target(CMD_CTX);
409 struct cortex_m_common *cortex_m = target_to_cm(target);
410 struct adiv5_dap *dap = cortex_m->armv7m.arm.dap;
411
412 if (!dap) {
413 LOG_WARNING("Cannot check flash security status with a high-level adapter");
414 return ERROR_OK;
415 }
416
417 uint32_t val;
418 int retval;
419
420 /*
421 * ... The MDM-AP ID register can be read to verify that the
422 * connection is working correctly...
423 */
424 retval = kinetis_mdm_read_register(dap, MDM_REG_ID, &val);
425 if (retval != ERROR_OK) {
426 LOG_ERROR("MDM: failed to read ID register");
427 goto fail;
428 }
429
430 bool found = false;
431 for (size_t i = 0; i < ARRAY_SIZE(kinetis_known_mdm_ids); i++) {
432 if (val == kinetis_known_mdm_ids[i]) {
433 found = true;
434 break;
435 }
436 }
437
438 if (!found)
439 LOG_WARNING("MDM: unknown ID %08" PRIX32, val);
440
441 /*
442 * ... Read the MDM-AP status register until the Flash Ready bit sets...
443 */
444 retval = kinetis_mdm_poll_register(dap, MDM_REG_STAT,
445 MDM_STAT_FREADY,
446 MDM_STAT_FREADY);
447 if (retval != ERROR_OK) {
448 LOG_ERROR("MDM: flash ready timeout");
449 goto fail;
450 }
451
452 /*
453 * ... Read the System Security bit to determine if security is enabled.
454 * If System Security = 0, then proceed. If System Security = 1, then
455 * communication with the internals of the processor, including the
456 * flash, will not be possible without issuing a mass erase command or
457 * unsecuring the part through other means (backdoor key unlock)...
458 */
459 retval = kinetis_mdm_read_register(dap, MDM_REG_STAT, &val);
460 if (retval != ERROR_OK) {
461 LOG_ERROR("MDM: failed to read MDM_REG_STAT");
462 goto fail;
463 }
464
465 if ((val & (MDM_STAT_SYSSEC | MDM_STAT_CORE_HALTED)) == MDM_STAT_SYSSEC) {
466 LOG_WARNING("MDM: Secured MCU state detected however it may be a false alarm");
467 LOG_WARNING("MDM: Halting target to detect secured state reliably");
468
469 retval = target_halt(target);
470 if (retval == ERROR_OK)
471 retval = target_wait_state(target, TARGET_HALTED, 100);
472
473 if (retval != ERROR_OK) {
474 LOG_WARNING("MDM: Target not halted, trying reset halt");
475 target->reset_halt = true;
476 target->type->assert_reset(target);
477 target->type->deassert_reset(target);
478 }
479
480 /* re-read status */
481 retval = kinetis_mdm_read_register(dap, MDM_REG_STAT, &val);
482 if (retval != ERROR_OK) {
483 LOG_ERROR("MDM: failed to read MDM_REG_STAT");
484 goto fail;
485 }
486 }
487
488 if (val & MDM_STAT_SYSSEC) {
489 jtag_poll_set_enabled(false);
490
491 LOG_WARNING("*********** ATTENTION! ATTENTION! ATTENTION! ATTENTION! **********");
492 LOG_WARNING("**** ****");
493 LOG_WARNING("**** Your Kinetis MCU is in secured state, which means that, ****");
494 LOG_WARNING("**** with exception for very basic communication, JTAG/SWD ****");
495 LOG_WARNING("**** interface will NOT work. In order to restore its ****");
496 LOG_WARNING("**** functionality please issue 'kinetis mdm mass_erase' ****");
497 LOG_WARNING("**** command, power cycle the MCU and restart OpenOCD. ****");
498 LOG_WARNING("**** ****");
499 LOG_WARNING("*********** ATTENTION! ATTENTION! ATTENTION! ATTENTION! **********");
500 } else {
501 LOG_INFO("MDM: Chip is unsecured. Continuing.");
502 jtag_poll_set_enabled(true);
503 }
504
505 return ERROR_OK;
506
507 fail:
508 LOG_ERROR("MDM: Failed to check security status of the MCU. Cannot proceed further");
509 jtag_poll_set_enabled(false);
510 return retval;
511 }
512
513 FLASH_BANK_COMMAND_HANDLER(kinetis_flash_bank_command)
514 {
515 struct kinetis_flash_bank *bank_info;
516
517 if (CMD_ARGC < 6)
518 return ERROR_COMMAND_SYNTAX_ERROR;
519
520 LOG_INFO("add flash_bank kinetis %s", bank->name);
521
522 bank_info = malloc(sizeof(struct kinetis_flash_bank));
523
524 memset(bank_info, 0, sizeof(struct kinetis_flash_bank));
525
526 bank->driver_priv = bank_info;
527
528 return ERROR_OK;
529 }
530
531 /* Disable the watchdog on Kinetis devices */
532 int kinetis_disable_wdog(struct target *target, uint32_t sim_sdid)
533 {
534 struct working_area *wdog_algorithm;
535 struct armv7m_algorithm armv7m_info;
536 uint16_t wdog;
537 int retval;
538
539 static const uint8_t kinetis_unlock_wdog_code[] = {
540 /* WDOG_UNLOCK = 0xC520 */
541 0x4f, 0xf4, 0x00, 0x53, /* mov.w r3, #8192 ; 0x2000 */
542 0xc4, 0xf2, 0x05, 0x03, /* movt r3, #16389 ; 0x4005 */
543 0x4c, 0xf2, 0x20, 0x52, /* movw r2, #50464 ; 0xc520 */
544 0xda, 0x81, /* strh r2, [r3, #14] */
545
546 /* WDOG_UNLOCK = 0xD928 */
547 0x4f, 0xf4, 0x00, 0x53, /* mov.w r3, #8192 ; 0x2000 */
548 0xc4, 0xf2, 0x05, 0x03, /* movt r3, #16389 ; 0x4005 */
549 0x4d, 0xf6, 0x28, 0x12, /* movw r2, #55592 ; 0xd928 */
550 0xda, 0x81, /* strh r2, [r3, #14] */
551
552 /* WDOG_SCR = 0x1d2 */
553 0x4f, 0xf4, 0x00, 0x53, /* mov.w r3, #8192 ; 0x2000 */
554 0xc4, 0xf2, 0x05, 0x03, /* movt r3, #16389 ; 0x4005 */
555 0x4f, 0xf4, 0xe9, 0x72, /* mov.w r2, #466 ; 0x1d2 */
556 0x1a, 0x80, /* strh r2, [r3, #0] */
557
558 /* END */
559 0x00, 0xBE, /* bkpt #0 */
560 };
561
562 /* Decide whether the connected device needs watchdog disabling.
563 * Disable for all Kx devices, i.e., return if it is a KLx */
564
565 if ((sim_sdid & KINETIS_SDID_SERIESID_MASK) == KINETIS_SDID_SERIESID_KL)
566 return ERROR_OK;
567
568 /* The connected device requires watchdog disabling. */
569 retval = target_read_u16(target, WDOG_STCTRH, &wdog);
570 if (retval != ERROR_OK)
571 return retval;
572
573 if ((wdog & 0x1) == 0) {
574 /* watchdog already disabled */
575 return ERROR_OK;
576 }
577 LOG_INFO("Disabling Kinetis watchdog (initial WDOG_STCTRLH = 0x%x)", wdog);
578
579 if (target->state != TARGET_HALTED) {
580 LOG_ERROR("Target not halted");
581 return ERROR_TARGET_NOT_HALTED;
582 }
583
584 retval = target_alloc_working_area(target, sizeof(kinetis_unlock_wdog_code), &wdog_algorithm);
585 if (retval != ERROR_OK)
586 return retval;
587
588 retval = target_write_buffer(target, wdog_algorithm->address,
589 sizeof(kinetis_unlock_wdog_code), (uint8_t *)kinetis_unlock_wdog_code);
590 if (retval != ERROR_OK) {
591 target_free_working_area(target, wdog_algorithm);
592 return retval;
593 }
594
595 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
596 armv7m_info.core_mode = ARM_MODE_THREAD;
597
598 retval = target_run_algorithm(target, 0, NULL, 0, NULL, wdog_algorithm->address,
599 wdog_algorithm->address + (sizeof(kinetis_unlock_wdog_code) - 2),
600 10000, &armv7m_info);
601
602 if (retval != ERROR_OK)
603 LOG_ERROR("error executing kinetis wdog unlock algorithm");
604
605 retval = target_read_u16(target, WDOG_STCTRH, &wdog);
606 if (retval != ERROR_OK)
607 return retval;
608 LOG_INFO("WDOG_STCTRLH = 0x%x", wdog);
609
610 target_free_working_area(target, wdog_algorithm);
611
612 return retval;
613 }
614
615 COMMAND_HANDLER(kinetis_disable_wdog_handler)
616 {
617 int result;
618 uint32_t sim_sdid;
619 struct target *target = get_current_target(CMD_CTX);
620
621 if (CMD_ARGC > 0)
622 return ERROR_COMMAND_SYNTAX_ERROR;
623
624 result = target_read_u32(target, SIM_SDID, &sim_sdid);
625 if (result != ERROR_OK) {
626 LOG_ERROR("Failed to read SIMSDID");
627 return result;
628 }
629
630 result = kinetis_disable_wdog(target, sim_sdid);
631 return result;
632 }
633
634
635 /* Kinetis Program-LongWord Microcodes */
636 static const uint8_t kinetis_flash_write_code[] = {
637 /* Params:
638 * r0 - workarea buffer
639 * r1 - target address
640 * r2 - wordcount
641 * Clobbered:
642 * r4 - tmp
643 * r5 - tmp
644 * r6 - tmp
645 * r7 - tmp
646 */
647
648 /* .L1: */
649 /* for(register uint32_t i=0;i<wcount;i++){ */
650 0x04, 0x1C, /* mov r4, r0 */
651 0x00, 0x23, /* mov r3, #0 */
652 /* .L2: */
653 0x0E, 0x1A, /* sub r6, r1, r0 */
654 0xA6, 0x19, /* add r6, r4, r6 */
655 0x93, 0x42, /* cmp r3, r2 */
656 0x16, 0xD0, /* beq .L9 */
657 /* .L5: */
658 /* while((FTFx_FSTAT&FTFA_FSTAT_CCIF_MASK) != FTFA_FSTAT_CCIF_MASK){}; */
659 0x0B, 0x4D, /* ldr r5, .L10 */
660 0x2F, 0x78, /* ldrb r7, [r5] */
661 0x7F, 0xB2, /* sxtb r7, r7 */
662 0x00, 0x2F, /* cmp r7, #0 */
663 0xFA, 0xDA, /* bge .L5 */
664 /* FTFx_FSTAT = FTFA_FSTAT_ACCERR_MASK|FTFA_FSTAT_FPVIOL_MASK|FTFA_FSTAT_RDCO */
665 0x70, 0x27, /* mov r7, #112 */
666 0x2F, 0x70, /* strb r7, [r5] */
667 /* FTFx_FCCOB3 = faddr; */
668 0x09, 0x4F, /* ldr r7, .L10+4 */
669 0x3E, 0x60, /* str r6, [r7] */
670 0x06, 0x27, /* mov r7, #6 */
671 /* FTFx_FCCOB0 = 0x06; */
672 0x08, 0x4E, /* ldr r6, .L10+8 */
673 0x37, 0x70, /* strb r7, [r6] */
674 /* FTFx_FCCOB7 = *pLW; */
675 0x80, 0xCC, /* ldmia r4!, {r7} */
676 0x08, 0x4E, /* ldr r6, .L10+12 */
677 0x37, 0x60, /* str r7, [r6] */
678 /* FTFx_FSTAT = FTFA_FSTAT_CCIF_MASK; */
679 0x80, 0x27, /* mov r7, #128 */
680 0x2F, 0x70, /* strb r7, [r5] */
681 /* .L4: */
682 /* while((FTFx_FSTAT&FTFA_FSTAT_CCIF_MASK) != FTFA_FSTAT_CCIF_MASK){}; */
683 0x2E, 0x78, /* ldrb r6, [r5] */
684 0x77, 0xB2, /* sxtb r7, r6 */
685 0x00, 0x2F, /* cmp r7, #0 */
686 0xFB, 0xDA, /* bge .L4 */
687 0x01, 0x33, /* add r3, r3, #1 */
688 0xE4, 0xE7, /* b .L2 */
689 /* .L9: */
690 0x00, 0xBE, /* bkpt #0 */
691 /* .L10: */
692 0x00, 0x00, 0x02, 0x40, /* .word 1073872896 */
693 0x04, 0x00, 0x02, 0x40, /* .word 1073872900 */
694 0x07, 0x00, 0x02, 0x40, /* .word 1073872903 */
695 0x08, 0x00, 0x02, 0x40, /* .word 1073872904 */
696 };
697
698 /* Program LongWord Block Write */
699 static int kinetis_write_block(struct flash_bank *bank, const uint8_t *buffer,
700 uint32_t offset, uint32_t wcount)
701 {
702 struct target *target = bank->target;
703 uint32_t buffer_size = 2048; /* Default minimum value */
704 struct working_area *write_algorithm;
705 struct working_area *source;
706 uint32_t address = bank->base + offset;
707 struct reg_param reg_params[3];
708 struct armv7m_algorithm armv7m_info;
709 int retval = ERROR_OK;
710
711 /* Params:
712 * r0 - workarea buffer
713 * r1 - target address
714 * r2 - wordcount
715 * Clobbered:
716 * r4 - tmp
717 * r5 - tmp
718 * r6 - tmp
719 * r7 - tmp
720 */
721
722 /* Increase buffer_size if needed */
723 if (buffer_size < (target->working_area_size/2))
724 buffer_size = (target->working_area_size/2);
725
726 LOG_INFO("Kinetis: FLASH Write ...");
727
728 /* check code alignment */
729 if (offset & 0x1) {
730 LOG_WARNING("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset);
731 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
732 }
733
734 /* allocate working area with flash programming code */
735 if (target_alloc_working_area(target, sizeof(kinetis_flash_write_code),
736 &write_algorithm) != ERROR_OK) {
737 LOG_WARNING("no working area available, can't do block memory writes");
738 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
739 }
740
741 retval = target_write_buffer(target, write_algorithm->address,
742 sizeof(kinetis_flash_write_code), kinetis_flash_write_code);
743 if (retval != ERROR_OK)
744 return retval;
745
746 /* memory buffer */
747 while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) {
748 buffer_size /= 4;
749 if (buffer_size <= 256) {
750 /* free working area, write algorithm already allocated */
751 target_free_working_area(target, write_algorithm);
752
753 LOG_WARNING("No large enough working area available, can't do block memory writes");
754 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
755 }
756 }
757
758 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
759 armv7m_info.core_mode = ARM_MODE_THREAD;
760
761 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT); /* *pLW (*buffer) */
762 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* faddr */
763 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* number of words to program */
764
765 /* write code buffer and use Flash programming code within kinetis */
766 /* Set breakpoint to 0 with time-out of 1000 ms */
767 while (wcount > 0) {
768 uint32_t thisrun_count = (wcount > (buffer_size / 4)) ? (buffer_size / 4) : wcount;
769
770 retval = target_write_buffer(target, source->address, thisrun_count * 4, buffer);
771 if (retval != ERROR_OK)
772 break;
773
774 buf_set_u32(reg_params[0].value, 0, 32, source->address);
775 buf_set_u32(reg_params[1].value, 0, 32, address);
776 buf_set_u32(reg_params[2].value, 0, 32, thisrun_count);
777
778 retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
779 write_algorithm->address, 0, 100000, &armv7m_info);
780 if (retval != ERROR_OK) {
781 LOG_ERROR("Error executing kinetis Flash programming algorithm");
782 retval = ERROR_FLASH_OPERATION_FAILED;
783 break;
784 }
785
786 buffer += thisrun_count * 4;
787 address += thisrun_count * 4;
788 wcount -= thisrun_count;
789 }
790
791 target_free_working_area(target, source);
792 target_free_working_area(target, write_algorithm);
793
794 destroy_reg_param(&reg_params[0]);
795 destroy_reg_param(&reg_params[1]);
796 destroy_reg_param(&reg_params[2]);
797
798 return retval;
799 }
800
801 static int kinetis_protect(struct flash_bank *bank, int set, int first, int last)
802 {
803 LOG_WARNING("kinetis_protect not supported yet");
804 /* FIXME: TODO */
805
806 if (bank->target->state != TARGET_HALTED) {
807 LOG_ERROR("Target not halted");
808 return ERROR_TARGET_NOT_HALTED;
809 }
810
811 return ERROR_FLASH_BANK_INVALID;
812 }
813
814 static int kinetis_protect_check(struct flash_bank *bank)
815 {
816 struct kinetis_flash_bank *kinfo = bank->driver_priv;
817
818 if (bank->target->state != TARGET_HALTED) {
819 LOG_ERROR("Target not halted");
820 return ERROR_TARGET_NOT_HALTED;
821 }
822
823 if (kinfo->flash_class == FC_PFLASH) {
824 int result;
825 uint8_t buffer[4];
826 uint32_t fprot, psec;
827 int i, b;
828
829 /* read protection register */
830 result = target_read_memory(bank->target, FTFx_FPROT3, 1, 4, buffer);
831
832 if (result != ERROR_OK)
833 return result;
834
835 fprot = target_buffer_get_u32(bank->target, buffer);
836
837 /*
838 * Every bit protects 1/32 of the full flash (not necessarily
839 * just this bank), but we enforce the bank ordinals for
840 * PFlash to start at zero.
841 */
842 b = kinfo->bank_ordinal * (bank->size / kinfo->protection_size);
843 for (psec = 0, i = 0; i < bank->num_sectors; i++) {
844 if ((fprot >> b) & 1)
845 bank->sectors[i].is_protected = 0;
846 else
847 bank->sectors[i].is_protected = 1;
848
849 psec += bank->sectors[i].size;
850
851 if (psec >= kinfo->protection_size) {
852 psec = 0;
853 b++;
854 }
855 }
856 } else {
857 LOG_ERROR("Protection checks for FlexNVM not yet supported");
858 return ERROR_FLASH_BANK_INVALID;
859 }
860
861 return ERROR_OK;
862 }
863
864 static int kinetis_ftfx_command(struct flash_bank *bank, uint8_t fcmd, uint32_t faddr,
865 uint8_t fccob4, uint8_t fccob5, uint8_t fccob6, uint8_t fccob7,
866 uint8_t fccob8, uint8_t fccob9, uint8_t fccoba, uint8_t fccobb,
867 uint8_t *ftfx_fstat)
868 {
869 uint8_t command[12] = {faddr & 0xff, (faddr >> 8) & 0xff, (faddr >> 16) & 0xff, fcmd,
870 fccob7, fccob6, fccob5, fccob4,
871 fccobb, fccoba, fccob9, fccob8};
872 int result, i;
873 uint8_t buffer;
874
875 /* wait for done */
876 for (i = 0; i < 50; i++) {
877 result =
878 target_read_memory(bank->target, FTFx_FSTAT, 1, 1, &buffer);
879
880 if (result != ERROR_OK)
881 return result;
882
883 if (buffer & 0x80)
884 break;
885
886 buffer = 0x00;
887 }
888
889 if (buffer != 0x80) {
890 /* reset error flags */
891 buffer = 0x30;
892 result =
893 target_write_memory(bank->target, FTFx_FSTAT, 1, 1, &buffer);
894 if (result != ERROR_OK)
895 return result;
896 }
897
898 result = target_write_memory(bank->target, FTFx_FCCOB3, 4, 3, command);
899
900 if (result != ERROR_OK)
901 return result;
902
903 /* start command */
904 buffer = 0x80;
905 result = target_write_memory(bank->target, FTFx_FSTAT, 1, 1, &buffer);
906 if (result != ERROR_OK)
907 return result;
908
909 /* wait for done */
910 for (i = 0; i < 240; i++) { /* Need longtime for "Mass Erase" Command Nemui Changed */
911 result =
912 target_read_memory(bank->target, FTFx_FSTAT, 1, 1, ftfx_fstat);
913
914 if (result != ERROR_OK)
915 return result;
916
917 if (*ftfx_fstat & 0x80)
918 break;
919 }
920
921 if ((*ftfx_fstat & 0xf0) != 0x80) {
922 LOG_ERROR
923 ("ftfx command failed FSTAT: %02X FCCOB: %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X",
924 *ftfx_fstat, command[3], command[2], command[1], command[0],
925 command[7], command[6], command[5], command[4],
926 command[11], command[10], command[9], command[8]);
927 return ERROR_FLASH_OPERATION_FAILED;
928 }
929
930 return ERROR_OK;
931 }
932
933 COMMAND_HANDLER(kinetis_securing_test)
934 {
935 int result;
936 uint8_t ftfx_fstat;
937 struct target *target = get_current_target(CMD_CTX);
938 struct flash_bank *bank = NULL;
939
940 result = get_flash_bank_by_addr(target, 0x00000000, true, &bank);
941 if (result != ERROR_OK)
942 return result;
943
944 assert(bank != NULL);
945
946 if (target->state != TARGET_HALTED) {
947 LOG_ERROR("Target not halted");
948 return ERROR_TARGET_NOT_HALTED;
949 }
950
951 return kinetis_ftfx_command(bank, FTFx_CMD_SECTERASE, bank->base + 0x00000400,
952 0, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat);
953 }
954
955 static int kinetis_erase(struct flash_bank *bank, int first, int last)
956 {
957 int result, i;
958
959 if (bank->target->state != TARGET_HALTED) {
960 LOG_ERROR("Target not halted");
961 return ERROR_TARGET_NOT_HALTED;
962 }
963
964 if ((first > bank->num_sectors) || (last > bank->num_sectors))
965 return ERROR_FLASH_OPERATION_FAILED;
966
967 /*
968 * FIXME: TODO: use the 'Erase Flash Block' command if the
969 * requested erase is PFlash or NVM and encompasses the entire
970 * block. Should be quicker.
971 */
972 for (i = first; i <= last; i++) {
973 uint8_t ftfx_fstat;
974 /* set command and sector address */
975 result = kinetis_ftfx_command(bank, FTFx_CMD_SECTERASE, bank->base + bank->sectors[i].offset,
976 0, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat);
977
978 if (result != ERROR_OK) {
979 LOG_WARNING("erase sector %d failed", i);
980 return ERROR_FLASH_OPERATION_FAILED;
981 }
982
983 bank->sectors[i].is_erased = 1;
984 }
985
986 if (first == 0) {
987 LOG_WARNING
988 ("flash configuration field erased, please reset the device");
989 }
990
991 return ERROR_OK;
992 }
993
994 static int kinetis_write(struct flash_bank *bank, const uint8_t *buffer,
995 uint32_t offset, uint32_t count)
996 {
997 unsigned int i, result, fallback = 0;
998 uint8_t buf[8];
999 uint32_t wc;
1000 struct kinetis_flash_bank *kinfo = bank->driver_priv;
1001 uint8_t *new_buffer = NULL;
1002
1003 if (bank->target->state != TARGET_HALTED) {
1004 LOG_ERROR("Target not halted");
1005 return ERROR_TARGET_NOT_HALTED;
1006 }
1007
1008 if (!(kinfo->flash_support & FS_PROGRAM_SECTOR)) {
1009 /* fallback to longword write */
1010 fallback = 1;
1011 LOG_WARNING("This device supports Program Longword execution only.");
1012 LOG_DEBUG("flash write into PFLASH @08%" PRIX32, offset);
1013
1014 } else if (kinfo->flash_class == FC_FLEX_NVM) {
1015 uint8_t ftfx_fstat;
1016
1017 LOG_DEBUG("flash write into FlexNVM @%08" PRIX32, offset);
1018
1019 /* make flex ram available */
1020 result = kinetis_ftfx_command(bank, FTFx_CMD_SETFLEXRAM, 0x00ff0000, 0, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat);
1021
1022 if (result != ERROR_OK)
1023 return ERROR_FLASH_OPERATION_FAILED;
1024
1025 /* check if ram ready */
1026 result = target_read_memory(bank->target, FTFx_FCNFG, 1, 1, buf);
1027
1028 if (result != ERROR_OK)
1029 return result;
1030
1031 if (!(buf[0] & (1 << 1))) {
1032 /* fallback to longword write */
1033 fallback = 1;
1034
1035 LOG_WARNING("ram not ready, fallback to slow longword write (FCNFG: %02X)", buf[0]);
1036 }
1037 } else {
1038 LOG_DEBUG("flash write into PFLASH @08%" PRIX32, offset);
1039 }
1040
1041
1042 /* program section command */
1043 if (fallback == 0) {
1044 /*
1045 * Kinetis uses different terms for the granularity of
1046 * sector writes, e.g. "phrase" or "128 bits". We use
1047 * the generic term "chunk". The largest possible
1048 * Kinetis "chunk" is 16 bytes (128 bits).
1049 */
1050 unsigned prog_section_chunk_bytes = kinfo->sector_size >> 8;
1051 unsigned prog_size_bytes = kinfo->max_flash_prog_size;
1052 for (i = 0; i < count; i += prog_size_bytes) {
1053 uint8_t residual_buffer[16];
1054 uint8_t ftfx_fstat;
1055 uint32_t section_count = prog_size_bytes / prog_section_chunk_bytes;
1056 uint32_t residual_wc = 0;
1057
1058 /*
1059 * Assume the word count covers an entire
1060 * sector.
1061 */
1062 wc = prog_size_bytes / 4;
1063
1064 /*
1065 * If bytes to be programmed are less than the
1066 * full sector, then determine the number of
1067 * full-words to program, and put together the
1068 * residual buffer so that a full "section"
1069 * may always be programmed.
1070 */
1071 if ((count - i) < prog_size_bytes) {
1072 /* number of bytes to program beyond full section */
1073 unsigned residual_bc = (count-i) % prog_section_chunk_bytes;
1074
1075 /* number of complete words to copy directly from buffer */
1076 wc = (count - i - residual_bc) / 4;
1077
1078 /* number of total sections to write, including residual */
1079 section_count = DIV_ROUND_UP((count-i), prog_section_chunk_bytes);
1080
1081 /* any residual bytes delivers a whole residual section */
1082 residual_wc = (residual_bc ? prog_section_chunk_bytes : 0)/4;
1083
1084 /* clear residual buffer then populate residual bytes */
1085 (void) memset(residual_buffer, 0xff, prog_section_chunk_bytes);
1086 (void) memcpy(residual_buffer, &buffer[i+4*wc], residual_bc);
1087 }
1088
1089 LOG_DEBUG("write section @ %08" PRIX32 " with length %" PRIu32 " bytes",
1090 offset + i, (uint32_t)wc*4);
1091
1092 /* write data to flexram as whole-words */
1093 result = target_write_memory(bank->target, FLEXRAM, 4, wc,
1094 buffer + i);
1095
1096 if (result != ERROR_OK) {
1097 LOG_ERROR("target_write_memory failed");
1098 return result;
1099 }
1100
1101 /* write the residual words to the flexram */
1102 if (residual_wc) {
1103 result = target_write_memory(bank->target,
1104 FLEXRAM+4*wc,
1105 4, residual_wc,
1106 residual_buffer);
1107
1108 if (result != ERROR_OK) {
1109 LOG_ERROR("target_write_memory failed");
1110 return result;
1111 }
1112 }
1113
1114 /* execute section-write command */
1115 result = kinetis_ftfx_command(bank, FTFx_CMD_SECTWRITE, bank->base + offset + i,
1116 section_count>>8, section_count, 0, 0,
1117 0, 0, 0, 0, &ftfx_fstat);
1118
1119 if (result != ERROR_OK)
1120 return ERROR_FLASH_OPERATION_FAILED;
1121 }
1122 }
1123 /* program longword command, not supported in "SF3" devices */
1124 else if (kinfo->flash_support & FS_PROGRAM_LONGWORD) {
1125 if (count & 0x3) {
1126 uint32_t old_count = count;
1127 count = (old_count | 3) + 1;
1128 new_buffer = malloc(count);
1129 if (new_buffer == NULL) {
1130 LOG_ERROR("odd number of bytes to write and no memory "
1131 "for padding buffer");
1132 return ERROR_FAIL;
1133 }
1134 LOG_INFO("odd number of bytes to write (%" PRIu32 "), extending to %" PRIu32 " "
1135 "and padding with 0xff", old_count, count);
1136 memset(new_buffer, 0xff, count);
1137 buffer = memcpy(new_buffer, buffer, old_count);
1138 }
1139
1140 uint32_t words_remaining = count / 4;
1141
1142 kinetis_disable_wdog(bank->target, kinfo->sim_sdid);
1143
1144 /* try using a block write */
1145 int retval = kinetis_write_block(bank, buffer, offset, words_remaining);
1146
1147 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
1148 /* if block write failed (no sufficient working area),
1149 * we use normal (slow) single word accesses */
1150 LOG_WARNING("couldn't use block writes, falling back to single "
1151 "memory accesses");
1152
1153 for (i = 0; i < count; i += 4) {
1154 uint8_t ftfx_fstat;
1155
1156 LOG_DEBUG("write longword @ %08" PRIX32, (uint32_t)(offset + i));
1157
1158 uint8_t padding[4] = {0xff, 0xff, 0xff, 0xff};
1159 memcpy(padding, buffer + i, MIN(4, count-i));
1160
1161 result = kinetis_ftfx_command(bank, FTFx_CMD_LWORDPROG, bank->base + offset + i,
1162 padding[3], padding[2], padding[1], padding[0],
1163 0, 0, 0, 0, &ftfx_fstat);
1164
1165 if (result != ERROR_OK)
1166 return ERROR_FLASH_OPERATION_FAILED;
1167 }
1168 }
1169 } else {
1170 LOG_ERROR("Flash write strategy not implemented");
1171 return ERROR_FLASH_OPERATION_FAILED;
1172 }
1173
1174 return ERROR_OK;
1175 }
1176
1177 static int kinetis_read_part_info(struct flash_bank *bank)
1178 {
1179 int result, i;
1180 uint32_t offset = 0;
1181 uint8_t fcfg1_nvmsize, fcfg1_pfsize, fcfg1_eesize, fcfg2_pflsh;
1182 uint32_t nvm_size = 0, pf_size = 0, ee_size = 0;
1183 unsigned num_blocks = 0, num_pflash_blocks = 0, num_nvm_blocks = 0, first_nvm_bank = 0,
1184 reassign = 0, pflash_sector_size_bytes = 0, nvm_sector_size_bytes = 0;
1185 struct target *target = bank->target;
1186 struct kinetis_flash_bank *kinfo = bank->driver_priv;
1187
1188 result = target_read_u32(target, SIM_SDID, &kinfo->sim_sdid);
1189 if (result != ERROR_OK)
1190 return result;
1191
1192 if ((kinfo->sim_sdid & (~KINETIS_SDID_K_SERIES_MASK)) == 0) {
1193 /* older K-series MCU */
1194 uint32_t mcu_type = kinfo->sim_sdid & KINETIS_K_SDID_TYPE_MASK;
1195
1196 switch (mcu_type) {
1197 case KINETIS_K_SDID_K10_M50:
1198 case KINETIS_K_SDID_K20_M50:
1199 /* 1kB sectors */
1200 pflash_sector_size_bytes = 1<<10;
1201 nvm_sector_size_bytes = 1<<10;
1202 num_blocks = 2;
1203 kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR;
1204 break;
1205 case KINETIS_K_SDID_K10_M72:
1206 case KINETIS_K_SDID_K20_M72:
1207 case KINETIS_K_SDID_K30_M72:
1208 case KINETIS_K_SDID_K30_M100:
1209 case KINETIS_K_SDID_K40_M72:
1210 case KINETIS_K_SDID_K40_M100:
1211 case KINETIS_K_SDID_K50_M72:
1212 /* 2kB sectors, 1kB FlexNVM sectors */
1213 pflash_sector_size_bytes = 2<<10;
1214 nvm_sector_size_bytes = 1<<10;
1215 num_blocks = 2;
1216 kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR;
1217 kinfo->max_flash_prog_size = 1<<10;
1218 break;
1219 case KINETIS_K_SDID_K10_M100:
1220 case KINETIS_K_SDID_K20_M100:
1221 case KINETIS_K_SDID_K11:
1222 case KINETIS_K_SDID_K12:
1223 case KINETIS_K_SDID_K21_M50:
1224 case KINETIS_K_SDID_K22_M50:
1225 case KINETIS_K_SDID_K51_M72:
1226 case KINETIS_K_SDID_K53:
1227 case KINETIS_K_SDID_K60_M100:
1228 /* 2kB sectors */
1229 pflash_sector_size_bytes = 2<<10;
1230 nvm_sector_size_bytes = 2<<10;
1231 num_blocks = 2;
1232 kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR;
1233 break;
1234 case KINETIS_K_SDID_K21_M120:
1235 case KINETIS_K_SDID_K22_M120:
1236 /* 4kB sectors (MK21FN1M0, MK21FX512, MK22FN1M0, MK22FX512) */
1237 pflash_sector_size_bytes = 4<<10;
1238 kinfo->max_flash_prog_size = 1<<10;
1239 nvm_sector_size_bytes = 4<<10;
1240 num_blocks = 2;
1241 kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
1242 break;
1243 case KINETIS_K_SDID_K10_M120:
1244 case KINETIS_K_SDID_K20_M120:
1245 case KINETIS_K_SDID_K60_M150:
1246 case KINETIS_K_SDID_K70_M150:
1247 /* 4kB sectors */
1248 pflash_sector_size_bytes = 4<<10;
1249 nvm_sector_size_bytes = 4<<10;
1250 num_blocks = 4;
1251 kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
1252 break;
1253 default:
1254 LOG_ERROR("Unsupported K-family FAMID");
1255 }
1256 } else {
1257 /* Newer K-series or KL series MCU */
1258 switch (kinfo->sim_sdid & KINETIS_SDID_SERIESID_MASK) {
1259 case KINETIS_SDID_SERIESID_K:
1260 switch (kinfo->sim_sdid & (KINETIS_SDID_FAMILYID_MASK | KINETIS_SDID_SUBFAMID_MASK)) {
1261 case KINETIS_SDID_FAMILYID_K0X | KINETIS_SDID_SUBFAMID_KX2:
1262 /* K02FN64, K02FN128: FTFA, 2kB sectors */
1263 pflash_sector_size_bytes = 2<<10;
1264 num_blocks = 1;
1265 kinfo->flash_support = FS_PROGRAM_LONGWORD;
1266 break;
1267
1268 case KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX2: {
1269 /* MK24FN1M reports as K22, this should detect it (according to errata note 1N83J) */
1270 uint32_t sopt1;
1271 result = target_read_u32(target, SIM_SOPT1, &sopt1);
1272 if (result != ERROR_OK)
1273 return result;
1274
1275 if (((kinfo->sim_sdid & (KINETIS_SDID_DIEID_MASK)) == KINETIS_SDID_DIEID_K24FN1M) &&
1276 ((sopt1 & KINETIS_SOPT1_RAMSIZE_MASK) == KINETIS_SOPT1_RAMSIZE_K24FN1M)) {
1277 /* MK24FN1M */
1278 pflash_sector_size_bytes = 4<<10;
1279 num_blocks = 2;
1280 kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
1281 kinfo->max_flash_prog_size = 1<<10;
1282 break;
1283 }
1284 if ((kinfo->sim_sdid & (KINETIS_SDID_DIEID_MASK)) == KINETIS_SDID_DIEID_K22FN128
1285 || (kinfo->sim_sdid & (KINETIS_SDID_DIEID_MASK)) == KINETIS_SDID_DIEID_K22FN256
1286 || (kinfo->sim_sdid & (KINETIS_SDID_DIEID_MASK)) == KINETIS_SDID_DIEID_K22FN512) {
1287 /* K22 with new-style SDID - smaller pflash with FTFA, 2kB sectors */
1288 pflash_sector_size_bytes = 2<<10;
1289 num_blocks = 2; /* 1 or 2 blocks */
1290 kinfo->flash_support = FS_PROGRAM_LONGWORD;
1291 break;
1292 }
1293 LOG_ERROR("Unsupported Kinetis K22 DIEID");
1294 break;
1295 }
1296 case KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX4:
1297 pflash_sector_size_bytes = 4<<10;
1298 if ((kinfo->sim_sdid & (KINETIS_SDID_DIEID_MASK)) == KINETIS_SDID_DIEID_K24FN256) {
1299 /* K24FN256 - smaller pflash with FTFA */
1300 num_blocks = 1;
1301 kinfo->flash_support = FS_PROGRAM_LONGWORD;
1302 break;
1303 }
1304 /* K24FN1M without errata 7534 */
1305 num_blocks = 2;
1306 kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
1307 kinfo->max_flash_prog_size = 1<<10;
1308 break;
1309
1310 case KINETIS_SDID_FAMILYID_K6X | KINETIS_SDID_SUBFAMID_KX3:
1311 case KINETIS_SDID_FAMILYID_K6X | KINETIS_SDID_SUBFAMID_KX1: /* errata 7534 - should be K63 */
1312 /* K63FN1M0 */
1313 case KINETIS_SDID_FAMILYID_K6X | KINETIS_SDID_SUBFAMID_KX4:
1314 case KINETIS_SDID_FAMILYID_K6X | KINETIS_SDID_SUBFAMID_KX2: /* errata 7534 - should be K64 */
1315 /* K64FN1M0, K64FX512 */
1316 pflash_sector_size_bytes = 4<<10;
1317 nvm_sector_size_bytes = 4<<10;
1318 kinfo->max_flash_prog_size = 1<<10;
1319 num_blocks = 2;
1320 kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
1321 break;
1322
1323 case KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX6:
1324 /* K26FN2M0 */
1325 case KINETIS_SDID_FAMILYID_K6X | KINETIS_SDID_SUBFAMID_KX6:
1326 /* K66FN2M0, K66FX1M0 */
1327 pflash_sector_size_bytes = 4<<10;
1328 nvm_sector_size_bytes = 4<<10;
1329 kinfo->max_flash_prog_size = 1<<10;
1330 num_blocks = 4;
1331 kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
1332 break;
1333 default:
1334 LOG_ERROR("Unsupported Kinetis FAMILYID SUBFAMID");
1335 }
1336 break;
1337 case KINETIS_SDID_SERIESID_KL:
1338 /* KL-series */
1339 pflash_sector_size_bytes = 1<<10;
1340 nvm_sector_size_bytes = 1<<10;
1341 num_blocks = 1;
1342 kinfo->flash_support = FS_PROGRAM_LONGWORD;
1343 break;
1344 default:
1345 LOG_ERROR("Unsupported K-series");
1346 }
1347 }
1348
1349 if (pflash_sector_size_bytes == 0) {
1350 LOG_ERROR("MCU is unsupported, SDID 0x%08" PRIx32, kinfo->sim_sdid);
1351 return ERROR_FLASH_OPER_UNSUPPORTED;
1352 }
1353
1354 result = target_read_u32(target, SIM_FCFG1, &kinfo->sim_fcfg1);
1355 if (result != ERROR_OK)
1356 return result;
1357
1358 result = target_read_u32(target, SIM_FCFG2, &kinfo->sim_fcfg2);
1359 if (result != ERROR_OK)
1360 return result;
1361 fcfg2_pflsh = (kinfo->sim_fcfg2 >> 23) & 0x01;
1362
1363 LOG_DEBUG("SDID: 0x%08" PRIX32 " FCFG1: 0x%08" PRIX32 " FCFG2: 0x%08" PRIX32, kinfo->sim_sdid,
1364 kinfo->sim_fcfg1, kinfo->sim_fcfg2);
1365
1366 fcfg1_nvmsize = (uint8_t)((kinfo->sim_fcfg1 >> 28) & 0x0f);
1367 fcfg1_pfsize = (uint8_t)((kinfo->sim_fcfg1 >> 24) & 0x0f);
1368 fcfg1_eesize = (uint8_t)((kinfo->sim_fcfg1 >> 16) & 0x0f);
1369
1370 /* when the PFLSH bit is set, there is no FlexNVM/FlexRAM */
1371 if (!fcfg2_pflsh) {
1372 switch (fcfg1_nvmsize) {
1373 case 0x03:
1374 case 0x07:
1375 case 0x09:
1376 case 0x0b:
1377 nvm_size = 1 << (14 + (fcfg1_nvmsize >> 1));
1378 break;
1379 case 0x0f:
1380 if (pflash_sector_size_bytes >= 4<<10)
1381 nvm_size = 512<<10;
1382 else
1383 /* K20_100 */
1384 nvm_size = 256<<10;
1385 break;
1386 default:
1387 nvm_size = 0;
1388 break;
1389 }
1390
1391 switch (fcfg1_eesize) {
1392 case 0x00:
1393 case 0x01:
1394 case 0x02:
1395 case 0x03:
1396 case 0x04:
1397 case 0x05:
1398 case 0x06:
1399 case 0x07:
1400 case 0x08:
1401 case 0x09:
1402 ee_size = (16 << (10 - fcfg1_eesize));
1403 break;
1404 default:
1405 ee_size = 0;
1406 break;
1407 }
1408 }
1409
1410 switch (fcfg1_pfsize) {
1411 case 0x03:
1412 case 0x05:
1413 case 0x07:
1414 case 0x09:
1415 case 0x0b:
1416 case 0x0d:
1417 pf_size = 1 << (14 + (fcfg1_pfsize >> 1));
1418 break;
1419 case 0x0f:
1420 if (pflash_sector_size_bytes >= 4<<10)
1421 pf_size = 1024<<10;
1422 else if (fcfg2_pflsh)
1423 pf_size = 512<<10;
1424 else
1425 pf_size = 256<<10;
1426 break;
1427 default:
1428 pf_size = 0;
1429 break;
1430 }
1431
1432 LOG_DEBUG("FlexNVM: %" PRIu32 " PFlash: %" PRIu32 " FlexRAM: %" PRIu32 " PFLSH: %d",
1433 nvm_size, pf_size, ee_size, fcfg2_pflsh);
1434
1435 num_pflash_blocks = num_blocks / (2 - fcfg2_pflsh);
1436 first_nvm_bank = num_pflash_blocks;
1437 num_nvm_blocks = num_blocks - num_pflash_blocks;
1438
1439 LOG_DEBUG("%d blocks total: %d PFlash, %d FlexNVM",
1440 num_blocks, num_pflash_blocks, num_nvm_blocks);
1441
1442 /*
1443 * If the flash class is already assigned, verify the
1444 * parameters.
1445 */
1446 if (kinfo->flash_class != FC_AUTO) {
1447 if (kinfo->bank_ordinal != (unsigned) bank->bank_number) {
1448 LOG_WARNING("Flash ordinal/bank number mismatch");
1449 reassign = 1;
1450 } else {
1451 switch (kinfo->flash_class) {
1452 case FC_PFLASH:
1453 if (kinfo->bank_ordinal >= first_nvm_bank) {
1454 LOG_WARNING("Class mismatch, bank %d is not PFlash", bank->bank_number);
1455 reassign = 1;
1456 } else if (bank->size != (pf_size / num_pflash_blocks)) {
1457 LOG_WARNING("PFlash size mismatch");
1458 reassign = 1;
1459 } else if (bank->base !=
1460 (0x00000000 + bank->size * kinfo->bank_ordinal)) {
1461 LOG_WARNING("PFlash address range mismatch");
1462 reassign = 1;
1463 } else if (kinfo->sector_size != pflash_sector_size_bytes) {
1464 LOG_WARNING("PFlash sector size mismatch");
1465 reassign = 1;
1466 } else {
1467 LOG_DEBUG("PFlash bank %d already configured okay",
1468 kinfo->bank_ordinal);
1469 }
1470 break;
1471 case FC_FLEX_NVM:
1472 if ((kinfo->bank_ordinal >= num_blocks) ||
1473 (kinfo->bank_ordinal < first_nvm_bank)) {
1474 LOG_WARNING("Class mismatch, bank %d is not FlexNVM", bank->bank_number);
1475 reassign = 1;
1476 } else if (bank->size != (nvm_size / num_nvm_blocks)) {
1477 LOG_WARNING("FlexNVM size mismatch");
1478 reassign = 1;
1479 } else if (bank->base !=
1480 (0x10000000 + bank->size * kinfo->bank_ordinal)) {
1481 LOG_WARNING("FlexNVM address range mismatch");
1482 reassign = 1;
1483 } else if (kinfo->sector_size != nvm_sector_size_bytes) {
1484 LOG_WARNING("FlexNVM sector size mismatch");
1485 reassign = 1;
1486 } else {
1487 LOG_DEBUG("FlexNVM bank %d already configured okay",
1488 kinfo->bank_ordinal);
1489 }
1490 break;
1491 case FC_FLEX_RAM:
1492 if (kinfo->bank_ordinal != num_blocks) {
1493 LOG_WARNING("Class mismatch, bank %d is not FlexRAM", bank->bank_number);
1494 reassign = 1;
1495 } else if (bank->size != ee_size) {
1496 LOG_WARNING("FlexRAM size mismatch");
1497 reassign = 1;
1498 } else if (bank->base != FLEXRAM) {
1499 LOG_WARNING("FlexRAM address mismatch");
1500 reassign = 1;
1501 } else if (kinfo->sector_size != nvm_sector_size_bytes) {
1502 LOG_WARNING("FlexRAM sector size mismatch");
1503 reassign = 1;
1504 } else {
1505 LOG_DEBUG("FlexRAM bank %d already configured okay", kinfo->bank_ordinal);
1506 }
1507 break;
1508
1509 default:
1510 LOG_WARNING("Unknown or inconsistent flash class");
1511 reassign = 1;
1512 break;
1513 }
1514 }
1515 } else {
1516 LOG_INFO("Probing flash info for bank %d", bank->bank_number);
1517 reassign = 1;
1518 }
1519
1520 if (!reassign)
1521 return ERROR_OK;
1522
1523 if ((unsigned)bank->bank_number < num_pflash_blocks) {
1524 /* pflash, banks start at address zero */
1525 kinfo->flash_class = FC_PFLASH;
1526 bank->size = (pf_size / num_pflash_blocks);
1527 bank->base = 0x00000000 + bank->size * bank->bank_number;
1528 kinfo->sector_size = pflash_sector_size_bytes;
1529 kinfo->protection_size = pf_size / 32;
1530 } else if ((unsigned)bank->bank_number < num_blocks) {
1531 /* nvm, banks start at address 0x10000000 */
1532 kinfo->flash_class = FC_FLEX_NVM;
1533 bank->size = (nvm_size / num_nvm_blocks);
1534 bank->base = 0x10000000 + bank->size * (bank->bank_number - first_nvm_bank);
1535 kinfo->sector_size = nvm_sector_size_bytes;
1536 kinfo->protection_size = 0; /* FIXME: TODO: depends on DEPART bits, chip */
1537 } else if ((unsigned)bank->bank_number == num_blocks) {
1538 LOG_ERROR("FlexRAM support not yet implemented");
1539 return ERROR_FLASH_OPER_UNSUPPORTED;
1540 } else {
1541 LOG_ERROR("Cannot determine parameters for bank %d, only %d banks on device",
1542 bank->bank_number, num_blocks);
1543 return ERROR_FLASH_BANK_INVALID;
1544 }
1545
1546 if (bank->sectors) {
1547 free(bank->sectors);
1548 bank->sectors = NULL;
1549 }
1550
1551 if (kinfo->sector_size == 0) {
1552 LOG_ERROR("Unknown sector size for bank %d", bank->bank_number);
1553 return ERROR_FLASH_BANK_INVALID;
1554 }
1555
1556 if (kinfo->flash_support & FS_PROGRAM_SECTOR
1557 && kinfo->max_flash_prog_size == 0) {
1558 kinfo->max_flash_prog_size = kinfo->sector_size;
1559 /* Program section size is equal to sector size by default */
1560 }
1561
1562 bank->num_sectors = bank->size / kinfo->sector_size;
1563 assert(bank->num_sectors > 0);
1564 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
1565
1566 for (i = 0; i < bank->num_sectors; i++) {
1567 bank->sectors[i].offset = offset;
1568 bank->sectors[i].size = kinfo->sector_size;
1569 offset += kinfo->sector_size;
1570 bank->sectors[i].is_erased = -1;
1571 bank->sectors[i].is_protected = 1;
1572 }
1573
1574 return ERROR_OK;
1575 }
1576
1577 static int kinetis_probe(struct flash_bank *bank)
1578 {
1579 if (bank->target->state != TARGET_HALTED) {
1580 LOG_WARNING("Cannot communicate... target not halted.");
1581 return ERROR_TARGET_NOT_HALTED;
1582 }
1583
1584 return kinetis_read_part_info(bank);
1585 }
1586
1587 static int kinetis_auto_probe(struct flash_bank *bank)
1588 {
1589 struct kinetis_flash_bank *kinfo = bank->driver_priv;
1590
1591 if (kinfo->sim_sdid)
1592 return ERROR_OK;
1593
1594 return kinetis_probe(bank);
1595 }
1596
1597 static int kinetis_info(struct flash_bank *bank, char *buf, int buf_size)
1598 {
1599 const char *bank_class_names[] = {
1600 "(ANY)", "PFlash", "FlexNVM", "FlexRAM"
1601 };
1602
1603 struct kinetis_flash_bank *kinfo = bank->driver_priv;
1604
1605 (void) snprintf(buf, buf_size,
1606 "%s driver for %s flash bank %s at 0x%8.8" PRIx32 "",
1607 bank->driver->name, bank_class_names[kinfo->flash_class],
1608 bank->name, bank->base);
1609
1610 return ERROR_OK;
1611 }
1612
1613 static int kinetis_blank_check(struct flash_bank *bank)
1614 {
1615 struct kinetis_flash_bank *kinfo = bank->driver_priv;
1616
1617 if (bank->target->state != TARGET_HALTED) {
1618 LOG_ERROR("Target not halted");
1619 return ERROR_TARGET_NOT_HALTED;
1620 }
1621
1622 if (kinfo->flash_class == FC_PFLASH) {
1623 int result;
1624 uint8_t ftfx_fstat;
1625
1626 /* check if whole bank is blank */
1627 result = kinetis_ftfx_command(bank, FTFx_CMD_BLOCKSTAT, bank->base, 0, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat);
1628
1629 if (result != ERROR_OK)
1630 return result;
1631
1632 if (ftfx_fstat & 0x01) {
1633 /* the whole bank is not erased, check sector-by-sector */
1634 int i;
1635 for (i = 0; i < bank->num_sectors; i++) {
1636 /* normal margin */
1637 result = kinetis_ftfx_command(bank, FTFx_CMD_SECTSTAT, bank->base + bank->sectors[i].offset,
1638 1, 0, 0, 0, 0, 0, 0, 0, &ftfx_fstat);
1639
1640 if (result == ERROR_OK) {
1641 bank->sectors[i].is_erased = !(ftfx_fstat & 0x01);
1642 } else {
1643 LOG_DEBUG("Ignoring errored PFlash sector blank-check");
1644 bank->sectors[i].is_erased = -1;
1645 }
1646 }
1647 } else {
1648 /* the whole bank is erased, update all sectors */
1649 int i;
1650 for (i = 0; i < bank->num_sectors; i++)
1651 bank->sectors[i].is_erased = 1;
1652 }
1653 } else {
1654 LOG_WARNING("kinetis_blank_check not supported yet for FlexNVM");
1655 return ERROR_FLASH_OPERATION_FAILED;
1656 }
1657
1658 return ERROR_OK;
1659 }
1660
1661 static const struct command_registration kinetis_securtiy_command_handlers[] = {
1662 {
1663 .name = "check_security",
1664 .mode = COMMAND_EXEC,
1665 .help = "",
1666 .usage = "",
1667 .handler = kinetis_check_flash_security_status,
1668 },
1669 {
1670 .name = "mass_erase",
1671 .mode = COMMAND_EXEC,
1672 .help = "",
1673 .usage = "",
1674 .handler = kinetis_mdm_mass_erase,
1675 },
1676 {
1677 .name = "test_securing",
1678 .mode = COMMAND_EXEC,
1679 .help = "",
1680 .usage = "",
1681 .handler = kinetis_securing_test,
1682 },
1683 COMMAND_REGISTRATION_DONE
1684 };
1685
1686 static const struct command_registration kinetis_exec_command_handlers[] = {
1687 {
1688 .name = "mdm",
1689 .mode = COMMAND_ANY,
1690 .help = "",
1691 .usage = "",
1692 .chain = kinetis_securtiy_command_handlers,
1693 },
1694 {
1695 .name = "disable_wdog",
1696 .mode = COMMAND_EXEC,
1697 .help = "Disable the watchdog timer",
1698 .usage = "",
1699 .handler = kinetis_disable_wdog_handler,
1700 },
1701 COMMAND_REGISTRATION_DONE
1702 };
1703
1704 static const struct command_registration kinetis_command_handler[] = {
1705 {
1706 .name = "kinetis",
1707 .mode = COMMAND_ANY,
1708 .help = "kinetis NAND flash controller commands",
1709 .usage = "",
1710 .chain = kinetis_exec_command_handlers,
1711 },
1712 COMMAND_REGISTRATION_DONE
1713 };
1714
1715
1716
1717 struct flash_driver kinetis_flash = {
1718 .name = "kinetis",
1719 .commands = kinetis_command_handler,
1720 .flash_bank_command = kinetis_flash_bank_command,
1721 .erase = kinetis_erase,
1722 .protect = kinetis_protect,
1723 .write = kinetis_write,
1724 .read = default_flash_read,
1725 .probe = kinetis_probe,
1726 .auto_probe = kinetis_auto_probe,
1727 .erase_check = kinetis_blank_check,
1728 .protect_check = kinetis_protect_check,
1729 .info = kinetis_info,
1730 };

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)