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

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)