jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / flash / nor / kinetis_ke.c
1 /***************************************************************************
2 * Copyright (C) 2015 by Ivan Meleca *
3 * ivan@artekit.eu *
4 * *
5 * Modified from kinetis.c *
6 * *
7 * Copyright (C) 2011 by Mathias Kuester *
8 * kesmtp@freenet.de *
9 * *
10 * Copyright (C) 2011 sleep(5) ltd *
11 * tomas@sleepfive.com *
12 * *
13 * Copyright (C) 2012 by Christopher D. Kilgour *
14 * techie at whiterocker.com *
15 * *
16 * Copyright (C) 2013 Nemui Trinomius *
17 * nemuisan_kawausogasuki@live.jp *
18 * *
19 * Copyright (C) 2015 Tomas Vanek *
20 * vanekt@fbl.cz *
21 * *
22 * This program is free software; you can redistribute it and/or modify *
23 * it under the terms of the GNU General Public License as published by *
24 * the Free Software Foundation; either version 2 of the License, or *
25 * (at your option) any later version. *
26 * *
27 * This program is distributed in the hope that it will be useful, *
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
30 * GNU General Public License for more details. *
31 * *
32 * You should have received a copy of the GNU General Public License *
33 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
34 ***************************************************************************/
35
36 #ifdef HAVE_CONFIG_H
37 #include "config.h"
38 #endif
39
40 #include "jtag/interface.h"
41 #include "imp.h"
42 #include <helper/binarybuffer.h>
43 #include <target/algorithm.h>
44 #include <target/arm_adi_v5.h>
45 #include <target/armv7m.h>
46 #include <target/cortex_m.h>
47
48 /* Addresses */
49 #define SIM_SRSID 0x40048000
50 #define ICS_C1 0x40064000
51 #define ICS_C2 0x40064001
52 #define ICS_C3 0x40064002
53 #define ICS_C4 0x40064003
54 #define ICS_S 0x40064004
55 #define SIM_BUSDIV 0x40048018
56 #define SIM_CLKDIV_KE06 0x40048024
57 #define SIM_CLKDIV_KE04_44_64_80 0x40048024
58 #define SIM_CLKDIV_KE04_16_20_24 0x4004801C
59 #define WDOG_CS1 0x40052000
60
61 #define ICS_C2_BDIV_MASK 0xE0
62 #define ICS_C2_BDIV_SHIFT 5
63 #define ICS_C2_BDIV(x) (((uint8_t)(((uint8_t)(x))<<ICS_C2_BDIV_SHIFT))&ICS_C2_BDIV_MASK)
64 #define ICS_S_LOCK_MASK 0x40
65 #define ICS_C4_SCFTRIM_MASK 0x1
66 #define SIM_CLKDIV_OUTDIV2_MASK 0x1000000
67 #define FTMRX_FCLKDIV_FDIV_MASK 0x3F
68 #define FTMRX_FCLKDIV_FDIV_SHIFT 0
69 #define FTMRX_FCLKDIV_FDIV(x) (((uint8_t)(((uint8_t)(x))<<FTMRX_FCLKDIV_FDIV_SHIFT))&FTMRX_FCLKDIV_FDIV_MASK)
70 #define FTMRX_FCLKDIV_FDIVLCK_MASK 0x40
71 #define FTMRX_FCLKDIV_FDIVLCK_SHIFT 6
72 #define FTMRX_FCLKDIV_FDIVLD_MASK 0x80
73 #define FTMRX_FCLKDIV_FDIVLD_SHIFT 7
74 #define FTMRX_FSTAT_CCIF_MASK 0x80
75 #define FTMRX_FSTAT_MGSTAT0_MASK 0x01
76 #define FTMRX_FSTAT_MGSTAT1_MASK 0x02
77
78 /* Commands */
79 #define FTMRX_CMD_ALLERASED 0x01
80 #define FTMRX_CMD_BLOCKERASED 0x02
81 #define FTMRX_CMD_SECTIONERASED 0x03
82 #define FTMRX_CMD_READONCE 0x04
83 #define FTMRX_CMD_PROGFLASH 0x06
84 #define FTMRX_CMD_PROGONCE 0x07
85 #define FTMRX_CMD_ERASEALL 0x08
86 #define FTMRX_CMD_ERASEBLOCK 0x09
87 #define FTMRX_CMD_ERASESECTOR 0x0A
88 #define FTMRX_CMD_UNSECURE 0x0B
89 #define FTMRX_CMD_VERIFYACCESS 0x0C
90 #define FTMRX_CMD_SETMARGINLVL 0x0D
91 #define FTMRX_CMD_SETFACTORYLVL 0x0E
92 #define FTMRX_CMD_CONFIGNVM 0x0F
93
94 /* Error codes */
95 #define FTMRX_ERROR_ACCERR 0x20
96 #define FTMRX_ERROR_FPVIOL 0x10
97
98 #define KINETIS_KE_SRSID_FAMID(x) ((x >> 28) & 0x0F)
99 #define KINETIS_KE_SRSID_SUBFAMID(x) ((x >> 24) & 0x0F)
100 #define KINETIS_KE_SRSID_PINCOUNT(x) ((x >> 16) & 0x0F)
101
102 #define KINETIS_KE_SRSID_KEX2 0x02
103 #define KINETIS_KE_SRSID_KEX4 0x04
104 #define KINETIS_KE_SRSID_KEX6 0x06
105
106 struct kinetis_ke_flash_bank {
107 uint32_t sector_size;
108 uint32_t protection_size;
109
110 uint32_t sim_srsid;
111 uint32_t ftmrx_fclkdiv_addr;
112 uint32_t ftmrx_fccobix_addr;
113 uint32_t ftmrx_fstat_addr;
114 uint32_t ftmrx_fprot_addr;
115 uint32_t ftmrx_fccobhi_addr;
116 uint32_t ftmrx_fccoblo_addr;
117 };
118
119 #define MDM_REG_STAT 0x00
120 #define MDM_REG_CTRL 0x04
121 #define MDM_REG_ID 0xfc
122
123 #define MDM_STAT_FMEACK (1<<0)
124 #define MDM_STAT_FREADY (1<<1)
125 #define MDM_STAT_SYSSEC (1<<2)
126 #define MDM_STAT_SYSRES (1<<3)
127 #define MDM_STAT_FMEEN (1<<5)
128 #define MDM_STAT_BACKDOOREN (1<<6)
129 #define MDM_STAT_LPEN (1<<7)
130 #define MDM_STAT_VLPEN (1<<8)
131 #define MDM_STAT_LLSMODEXIT (1<<9)
132 #define MDM_STAT_VLLSXMODEXIT (1<<10)
133 #define MDM_STAT_CORE_HALTED (1<<16)
134 #define MDM_STAT_CORE_SLEEPDEEP (1<<17)
135 #define MDM_STAT_CORESLEEPING (1<<18)
136
137 #define MEM_CTRL_FMEIP (1<<0)
138 #define MEM_CTRL_DBG_DIS (1<<1)
139 #define MEM_CTRL_DBG_REQ (1<<2)
140 #define MEM_CTRL_SYS_RES_REQ (1<<3)
141 #define MEM_CTRL_CORE_HOLD_RES (1<<4)
142 #define MEM_CTRL_VLLSX_DBG_REQ (1<<5)
143 #define MEM_CTRL_VLLSX_DBG_ACK (1<<6)
144 #define MEM_CTRL_VLLSX_STAT_ACK (1<<7)
145
146 #define MDM_ACCESS_TIMEOUT 3000 /* iterations */
147
148 static int kinetis_ke_mdm_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value)
149 {
150 LOG_DEBUG("MDM_REG[0x%02x] <- %08" PRIX32, reg, value);
151
152 struct adiv5_ap *ap = dap_get_ap(dap, 1);
153 if (!ap) {
154 LOG_DEBUG("MDM: failed to get AP");
155 return ERROR_FAIL;
156 }
157
158 int retval = dap_queue_ap_write(ap, reg, value);
159 if (retval != ERROR_OK) {
160 LOG_DEBUG("MDM: failed to queue a write request");
161 dap_put_ap(ap);
162 return retval;
163 }
164
165 retval = dap_run(dap);
166 dap_put_ap(ap);
167 if (retval != ERROR_OK) {
168 LOG_DEBUG("MDM: dap_run failed");
169 return retval;
170 }
171
172 return ERROR_OK;
173 }
174
175 static int kinetis_ke_mdm_read_register(struct adiv5_dap *dap, unsigned reg, uint32_t *result)
176 {
177 struct adiv5_ap *ap = dap_get_ap(dap, 1);
178 if (!ap) {
179 LOG_DEBUG("MDM: failed to get AP");
180 return ERROR_FAIL;
181 }
182
183 int retval = dap_queue_ap_read(ap, reg, result);
184 if (retval != ERROR_OK) {
185 LOG_DEBUG("MDM: failed to queue a read request");
186 dap_put_ap(ap);
187 return retval;
188 }
189
190 retval = dap_run(dap);
191 dap_put_ap(ap);
192 if (retval != ERROR_OK) {
193 LOG_DEBUG("MDM: dap_run failed");
194 return retval;
195 }
196
197 LOG_DEBUG("MDM_REG[0x%02x]: %08" PRIX32, reg, *result);
198 return ERROR_OK;
199 }
200
201 static int kinetis_ke_mdm_poll_register(struct adiv5_dap *dap, unsigned reg, uint32_t mask, uint32_t value)
202 {
203 uint32_t val;
204 int retval;
205 int timeout = MDM_ACCESS_TIMEOUT;
206
207 do {
208 retval = kinetis_ke_mdm_read_register(dap, reg, &val);
209 if (retval != ERROR_OK || (val & mask) == value)
210 return retval;
211
212 alive_sleep(1);
213 } while (timeout--);
214
215 LOG_DEBUG("MDM: polling timed out");
216 return ERROR_FAIL;
217 }
218
219 static int kinetis_ke_prepare_flash(struct flash_bank *bank)
220 {
221 struct target *target = bank->target;
222 struct kinetis_ke_flash_bank *kinfo = bank->driver_priv;
223 uint8_t c2, c3, c4, s = 0;
224 uint16_t trim_value = 0;
225 uint16_t timeout = 0;
226 uint32_t bus_clock = 0;
227 uint32_t bus_reg_val = 0;
228 uint32_t bus_reg_addr = 0;
229 uint32_t flash_clk_div;
230 uint8_t fclkdiv;
231 int result;
232
233 /*
234 * The RM states that the flash clock has to be set to 1MHz for writing and
235 * erasing operations (otherwise it can damage the flash).
236 * This function configures the entire clock tree to make sure we
237 * run at the specified clock. We'll set FEI mode running from the ~32KHz
238 * internal clock. So we need to:
239 * - Trim internal clock.
240 * - Configure the divider for ICSOUTCLK (ICS module).
241 * - Configure the divider to get a bus clock (SIM module).
242 * - Configure the flash clock that depends on the bus clock.
243 *
244 * For MKE02_40 and MKE02_20 we set ICSOUTCLK = 20MHz and bus clock = 20MHz.
245 * For MKE04 and MKE06 we run at ICSOUTCLK = 48MHz and bus clock = 24MHz.
246 */
247
248 /*
249 * Trim internal clock
250 */
251 switch (KINETIS_KE_SRSID_SUBFAMID(kinfo->sim_srsid)) {
252
253 case KINETIS_KE_SRSID_KEX2:
254 /* Both KE02_20 and KE02_40 should get the same trim value */
255 trim_value = 0x4C;
256 break;
257
258 case KINETIS_KE_SRSID_KEX4:
259 trim_value = 0x54;
260 break;
261
262 case KINETIS_KE_SRSID_KEX6:
263 trim_value = 0x58;
264 break;
265 }
266
267 result = target_read_u8(target, ICS_C4, &c4);
268 if (result != ERROR_OK)
269 return result;
270
271 c3 = trim_value;
272 c4 = (c4 & ~(ICS_C4_SCFTRIM_MASK)) | ((trim_value >> 8) & 0x01);
273
274 result = target_write_u8(target, ICS_C3, c3);
275 if (result != ERROR_OK)
276 return result;
277
278 result = target_write_u8(target, ICS_C4, c4);
279 if (result != ERROR_OK)
280 return result;
281
282 result = target_read_u8(target, ICS_S, &s);
283 if (result != ERROR_OK)
284 return result;
285
286 /* Wait */
287 while (!(s & ICS_S_LOCK_MASK)) {
288
289 if (timeout <= 1000) {
290 timeout++;
291 alive_sleep(1);
292 } else {
293 return ERROR_FAIL;
294 }
295
296 result = target_read_u8(target, ICS_S, &s);
297 if (result != ERROR_OK)
298 return result;
299 }
300
301 /* ... trim done ... */
302
303 /*
304 * Configure SIM (bus clock)
305 */
306 switch (KINETIS_KE_SRSID_SUBFAMID(kinfo->sim_srsid)) {
307
308 /* KE02 sub-family operates on SIM_BUSDIV */
309 case KINETIS_KE_SRSID_KEX2:
310 bus_reg_val = 0;
311 bus_reg_addr = SIM_BUSDIV;
312 bus_clock = 20000000;
313 break;
314
315 /* KE04 and KE06 sub-family operates on SIM_CLKDIV
316 * Clocks are divided by:
317 * DIV1 = core clock = 48MHz
318 * DIV2 = bus clock = 24Mhz
319 * DIV3 = timer clocks
320 * So we need to configure SIM_CLKDIV, DIV1 and DIV2 value
321 */
322 case KINETIS_KE_SRSID_KEX4:
323 /* KE04 devices have the SIM_CLKDIV register at a different offset
324 * depending on the pin count. */
325 switch (KINETIS_KE_SRSID_PINCOUNT(kinfo->sim_srsid)) {
326
327 /* 16, 20 and 24 pins */
328 case 1:
329 case 2:
330 case 3:
331 bus_reg_addr = SIM_CLKDIV_KE04_16_20_24;
332 break;
333
334 /* 44, 64 and 80 pins */
335 case 5:
336 case 7:
337 case 8:
338 bus_reg_addr = SIM_CLKDIV_KE04_44_64_80;
339 break;
340
341 default:
342 LOG_ERROR("KE04 - Unknown pin count");
343 return ERROR_FAIL;
344 }
345
346 bus_reg_val = SIM_CLKDIV_OUTDIV2_MASK;
347 bus_clock = 24000000;
348 break;
349
350 case KINETIS_KE_SRSID_KEX6:
351 bus_reg_val = SIM_CLKDIV_OUTDIV2_MASK;
352 bus_reg_addr = SIM_CLKDIV_KE06;
353 bus_clock = 24000000;
354 break;
355 }
356
357 result = target_write_u32(target, bus_reg_addr, bus_reg_val);
358 if (result != ERROR_OK)
359 return result;
360
361 /*
362 * Configure ICS to FEI (internal source)
363 */
364 result = target_read_u8(target, ICS_C2, &c2);
365 if (result != ERROR_OK)
366 return result;
367
368 c2 &= ~ICS_C2_BDIV_MASK;
369
370 switch (KINETIS_KE_SRSID_SUBFAMID(kinfo->sim_srsid)) {
371
372 case KINETIS_KE_SRSID_KEX2:
373 /* Note: since there are two KE02 types, the KE02_40 @ 40MHz and the
374 * KE02_20 @ 20MHz, we divide here the ~40MHz ICSFLLCLK down to 20MHz,
375 * for compatibility.
376 */
377 c2 |= ICS_C2_BDIV(1);
378 break;
379
380 case KINETIS_KE_SRSID_KEX4:
381 case KINETIS_KE_SRSID_KEX6:
382 /* For KE04 and KE06, the ICSFLLCLK can be 48MHz. */
383 c2 |= ICS_C2_BDIV(0);
384 break;
385 }
386
387 result = target_write_u8(target, ICS_C2, c2);
388 if (result != ERROR_OK)
389 return result;
390
391 /* Internal clock as reference (IREFS = 1) */
392 result = target_write_u8(target, ICS_C1, 4);
393 if (result != ERROR_OK)
394 return result;
395
396 /* Wait for FLL to lock */
397 result = target_read_u8(target, ICS_S, &s);
398 if (result != ERROR_OK)
399 return result;
400
401 while (!(s & ICS_S_LOCK_MASK)) {
402
403 if (timeout <= 1000) {
404 timeout++;
405 alive_sleep(1);
406 } else {
407 return ERROR_FLASH_OPERATION_FAILED;
408 }
409
410 result = target_read_u8(target, ICS_S, &s);
411 if (result != ERROR_OK)
412 return result;
413 }
414
415 /*
416 * Configure flash clock to 1MHz.
417 */
418 flash_clk_div = bus_clock / 1000000L - 1;
419
420 /* Check if the FCLKDIV register is locked */
421 result = target_read_u8(target, kinfo->ftmrx_fclkdiv_addr, &fclkdiv);
422 if (result != ERROR_OK)
423 return result;
424
425 if (!(fclkdiv & FTMRX_FCLKDIV_FDIVLCK_MASK)) {
426 /* Unlocked. Check if the register was configured, and if so, if it has the right value */
427 if ((fclkdiv & FTMRX_FCLKDIV_FDIVLD_MASK) &&
428 ((fclkdiv & FTMRX_FCLKDIV_FDIV_MASK) != FTMRX_FCLKDIV_FDIV(flash_clk_div))) {
429 LOG_WARNING("Flash clock was already set and contains an invalid value.");
430 LOG_WARNING("Please reset the target.");
431 return ERROR_FAIL;
432 }
433
434 /* Finally, configure the flash clock */
435 fclkdiv = (fclkdiv & ~(FTMRX_FCLKDIV_FDIV_MASK)) | FTMRX_FCLKDIV_FDIV(flash_clk_div);
436 result = target_write_u8(target, kinfo->ftmrx_fclkdiv_addr, fclkdiv);
437 if (result != ERROR_OK)
438 return result;
439 } else {
440 /* Locked. Check if the current value is correct. */
441 if ((fclkdiv & FTMRX_FCLKDIV_FDIV_MASK) != FTMRX_FCLKDIV_FDIV(flash_clk_div)) {
442 LOG_WARNING("Flash clock register is locked and contains an invalid value.");
443 LOG_WARNING("Please reset the target.");
444 return ERROR_FAIL;
445 }
446 }
447
448 LOG_INFO("Flash clock ready");
449 return ERROR_OK;
450 }
451
452 static int kinetis_ke_stop_watchdog(struct target *target)
453 {
454 struct working_area *watchdog_algorithm;
455 struct armv7m_algorithm armv7m_info;
456 int retval;
457 uint8_t cs1;
458
459 static const uint8_t watchdog_code[] = {
460 #include "../../../contrib/loaders/flash/kinetis_ke/kinetis_ke_watchdog.inc"
461 };
462
463 if (target->state != TARGET_HALTED) {
464 LOG_ERROR("Target not halted");
465 return ERROR_TARGET_NOT_HALTED;
466 }
467
468 /* Check if the watchdog is enabled */
469 retval = target_read_u8(target, WDOG_CS1, &cs1);
470 if (retval != ERROR_OK)
471 return retval;
472
473 if (!(cs1 & 0x80)) {
474 /* Already stopped */
475 return ERROR_OK;
476 }
477
478 /* allocate working area with watchdog code */
479 if (target_alloc_working_area(target, sizeof(watchdog_code), &watchdog_algorithm) != ERROR_OK) {
480 LOG_WARNING("No working area available for watchdog algorithm");
481 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
482 }
483
484 retval = target_write_buffer(target, watchdog_algorithm->address,
485 sizeof(watchdog_code), watchdog_code);
486 if (retval != ERROR_OK)
487 return retval;
488
489 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
490 armv7m_info.core_mode = ARM_MODE_THREAD;
491
492 retval = target_run_algorithm(target, 0, NULL, 0, NULL,
493 watchdog_algorithm->address, 0, 100000, &armv7m_info);
494 if (retval != ERROR_OK) {
495 LOG_ERROR("Error executing Kinetis KE watchdog algorithm");
496 } else {
497 LOG_INFO("Watchdog stopped");
498 }
499
500 target_free_working_area(target, watchdog_algorithm);
501
502 return retval;
503 }
504
505 COMMAND_HANDLER(kinetis_ke_disable_wdog_handler)
506 {
507 struct target *target = get_current_target(CMD_CTX);
508
509 if (CMD_ARGC > 0)
510 return ERROR_COMMAND_SYNTAX_ERROR;
511
512 return kinetis_ke_stop_watchdog(target);
513 }
514
515 COMMAND_HANDLER(kinetis_ke_mdm_mass_erase)
516 {
517 struct target *target = get_current_target(CMD_CTX);
518 struct cortex_m_common *cortex_m = target_to_cm(target);
519 struct adiv5_dap *dap = cortex_m->armv7m.arm.dap;
520
521 if (!dap) {
522 LOG_ERROR("Cannot perform mass erase with a high-level adapter");
523 return ERROR_FAIL;
524 }
525
526 int retval;
527
528 /* According to chapter 18.3.7.2 of the KE02 reference manual */
529
530 /* assert SRST */
531 if (jtag_get_reset_config() & RESET_HAS_SRST)
532 adapter_assert_reset();
533
534 /*
535 * 1. Reset the device by asserting RESET pin or DAP_CTRL[3]
536 */
537 retval = kinetis_ke_mdm_write_register(dap, MDM_REG_CTRL, MEM_CTRL_SYS_RES_REQ);
538 if (retval != ERROR_OK)
539 return retval;
540
541 /*
542 * ... Read the MDM-AP status register until the Flash Ready bit sets...
543 */
544 retval = kinetis_ke_mdm_poll_register(dap, MDM_REG_STAT,
545 MDM_STAT_FREADY | MDM_STAT_SYSRES,
546 MDM_STAT_FREADY);
547 if (retval != ERROR_OK) {
548 LOG_ERROR("MDM : flash ready timeout");
549 return retval;
550 }
551
552 /*
553 * 2. Set DAP_CTRL[0] bit to invoke debug mass erase via SWD
554 * 3. Release reset by deasserting RESET pin or DAP_CTRL[3] bit via SWD.
555 */
556 retval = kinetis_ke_mdm_write_register(dap, MDM_REG_CTRL, MEM_CTRL_FMEIP);
557 if (retval != ERROR_OK)
558 return retval;
559
560 /* As a sanity check make sure that device started mass erase procedure */
561 retval = kinetis_ke_mdm_poll_register(dap, MDM_REG_STAT,
562 MDM_STAT_FMEACK, MDM_STAT_FMEACK);
563 if (retval != ERROR_OK)
564 return retval;
565
566 /*
567 * 4. Wait till DAP_CTRL[0] bit is cleared (after mass erase completes,
568 * DAP_CTRL[0] bit is cleared automatically).
569 */
570 retval = kinetis_ke_mdm_poll_register(dap, MDM_REG_CTRL,
571 MEM_CTRL_FMEIP,
572 0);
573 if (retval != ERROR_OK)
574 return retval;
575
576 if (jtag_get_reset_config() & RESET_HAS_SRST)
577 adapter_deassert_reset();
578
579 return ERROR_OK;
580 }
581
582 static const uint32_t kinetis_ke_known_mdm_ids[] = {
583 0x001C0020, /* Kinetis-L/M/V/E/KE Series */
584 };
585
586 /*
587 * This function implements the procedure to connect to
588 * SWD/JTAG on Kinetis K and L series of devices as it is described in
589 * AN4835 "Production Flash Programming Best Practices for Kinetis K-
590 * and L-series MCUs" Section 4.1.1
591 */
592 COMMAND_HANDLER(kinetis_ke_check_flash_security_status)
593 {
594 struct target *target = get_current_target(CMD_CTX);
595 struct cortex_m_common *cortex_m = target_to_cm(target);
596 struct adiv5_dap *dap = cortex_m->armv7m.arm.dap;
597
598 if (!dap) {
599 LOG_WARNING("Cannot check flash security status with a high-level adapter");
600 return ERROR_OK;
601 }
602
603 uint32_t val;
604 int retval;
605
606 /*
607 * ... The MDM-AP ID register can be read to verify that the
608 * connection is working correctly...
609 */
610 retval = kinetis_ke_mdm_read_register(dap, MDM_REG_ID, &val);
611 if (retval != ERROR_OK) {
612 LOG_ERROR("MDM: failed to read ID register");
613 goto fail;
614 }
615
616 bool found = false;
617 for (size_t i = 0; i < ARRAY_SIZE(kinetis_ke_known_mdm_ids); i++) {
618 if (val == kinetis_ke_known_mdm_ids[i]) {
619 found = true;
620 break;
621 }
622 }
623
624 if (!found)
625 LOG_WARNING("MDM: unknown ID %08" PRIX32, val);
626
627 /*
628 * ... Read the MDM-AP status register until the Flash Ready bit sets...
629 */
630 retval = kinetis_ke_mdm_poll_register(dap, MDM_REG_STAT,
631 MDM_STAT_FREADY,
632 MDM_STAT_FREADY);
633 if (retval != ERROR_OK) {
634 LOG_ERROR("MDM: flash ready timeout");
635 goto fail;
636 }
637
638 /*
639 * ... Read the System Security bit to determine if security is enabled.
640 * If System Security = 0, then proceed. If System Security = 1, then
641 * communication with the internals of the processor, including the
642 * flash, will not be possible without issuing a mass erase command or
643 * unsecuring the part through other means (backdoor key unlock)...
644 */
645 retval = kinetis_ke_mdm_read_register(dap, MDM_REG_STAT, &val);
646 if (retval != ERROR_OK) {
647 LOG_ERROR("MDM: failed to read MDM_REG_STAT");
648 goto fail;
649 }
650
651 if (val & MDM_STAT_SYSSEC) {
652 jtag_poll_set_enabled(false);
653
654 LOG_WARNING("*********** ATTENTION! ATTENTION! ATTENTION! ATTENTION! **********");
655 LOG_WARNING("**** ****");
656 LOG_WARNING("**** Your Kinetis MCU is in secured state, which means that, ****");
657 LOG_WARNING("**** with exception for very basic communication, JTAG/SWD ****");
658 LOG_WARNING("**** interface will NOT work. In order to restore its ****");
659 LOG_WARNING("**** functionality please issue 'kinetis_ke mdm mass_erase' ****");
660 LOG_WARNING("**** command, power cycle the MCU and restart OpenOCD. ****");
661 LOG_WARNING("**** ****");
662 LOG_WARNING("*********** ATTENTION! ATTENTION! ATTENTION! ATTENTION! **********");
663 } else {
664 LOG_INFO("MDM: Chip is unsecured. Continuing.");
665 jtag_poll_set_enabled(true);
666 }
667
668 return ERROR_OK;
669
670 fail:
671 LOG_ERROR("MDM: Failed to check security status of the MCU. Cannot proceed further");
672 jtag_poll_set_enabled(false);
673 return retval;
674 }
675
676 FLASH_BANK_COMMAND_HANDLER(kinetis_ke_flash_bank_command)
677 {
678 struct kinetis_ke_flash_bank *bank_info;
679
680 if (CMD_ARGC < 6)
681 return ERROR_COMMAND_SYNTAX_ERROR;
682
683 LOG_INFO("add flash_bank kinetis_ke %s", bank->name);
684
685 bank_info = malloc(sizeof(struct kinetis_ke_flash_bank));
686
687 memset(bank_info, 0, sizeof(struct kinetis_ke_flash_bank));
688
689 bank->driver_priv = bank_info;
690
691 return ERROR_OK;
692 }
693
694 /* Kinetis Program-LongWord Microcodes */
695 static uint8_t kinetis_ke_flash_write_code[] = {
696 #include "../../../contrib/loaders/flash/kinetis_ke/kinetis_ke_flash.inc"
697 };
698
699 static int kinetis_ke_write_words(struct flash_bank *bank, const uint8_t *buffer,
700 uint32_t offset, uint32_t words)
701 {
702 struct kinetis_ke_flash_bank *kinfo = bank->driver_priv;
703 struct target *target = bank->target;
704 uint32_t ram_buffer_size = 512 + 16;
705 struct working_area *write_algorithm;
706 struct working_area *source;
707 uint32_t address = bank->base + offset;
708 struct reg_param reg_params[4];
709 struct armv7m_algorithm armv7m_info;
710 int retval = ERROR_OK;
711 uint32_t flash_code_size;
712
713 LOG_INFO("Kinetis KE: FLASH Write ...");
714
715 /* allocate working area with flash programming code */
716 if (target_alloc_working_area(target, sizeof(kinetis_ke_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 /* Patch the FTMRx registers addresses */
723 flash_code_size = sizeof(kinetis_ke_flash_write_code);
724 buf_set_u32(&kinetis_ke_flash_write_code[flash_code_size-16], 0, 32, kinfo->ftmrx_fstat_addr);
725 buf_set_u32(&kinetis_ke_flash_write_code[flash_code_size-12], 0, 32, kinfo->ftmrx_fccobix_addr);
726 buf_set_u32(&kinetis_ke_flash_write_code[flash_code_size-8], 0, 32, kinfo->ftmrx_fccobhi_addr);
727 buf_set_u32(&kinetis_ke_flash_write_code[flash_code_size-4], 0, 32, kinfo->ftmrx_fccoblo_addr);
728
729 retval = target_write_buffer(target, write_algorithm->address,
730 sizeof(kinetis_ke_flash_write_code), kinetis_ke_flash_write_code);
731 if (retval != ERROR_OK)
732 return retval;
733
734 /* memory buffer */
735 if (target_alloc_working_area(target, ram_buffer_size, &source) != ERROR_OK) {
736 /* free working area, write algorithm already allocated */
737 target_free_working_area(target, write_algorithm);
738
739 LOG_WARNING("No large enough working area available, can't do block memory writes");
740 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
741 }
742
743 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
744 armv7m_info.core_mode = ARM_MODE_THREAD;
745
746 init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
747 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
748 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
749 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
750
751 buf_set_u32(reg_params[0].value, 0, 32, address);
752 buf_set_u32(reg_params[1].value, 0, 32, words);
753 buf_set_u32(reg_params[2].value, 0, 32, source->address);
754 buf_set_u32(reg_params[3].value, 0, 32, source->address + source->size);
755
756 retval = target_run_flash_async_algorithm(target, buffer, words, 4,
757 0, NULL,
758 4, reg_params,
759 source->address, source->size,
760 write_algorithm->address, 0,
761 &armv7m_info);
762
763 if (retval == ERROR_FLASH_OPERATION_FAILED) {
764 if (buf_get_u32(reg_params[0].value, 0, 32) & FTMRX_ERROR_ACCERR)
765 LOG_ERROR("flash access error");
766
767 if (buf_get_u32(reg_params[0].value, 0, 32) & FTMRX_ERROR_FPVIOL)
768 LOG_ERROR("flash protection violation");
769 }
770
771 target_free_working_area(target, source);
772 target_free_working_area(target, write_algorithm);
773
774 destroy_reg_param(&reg_params[0]);
775 destroy_reg_param(&reg_params[1]);
776 destroy_reg_param(&reg_params[2]);
777 destroy_reg_param(&reg_params[3]);
778
779 return retval;
780 }
781
782 static int kinetis_ke_protect(struct flash_bank *bank, int set,
783 unsigned int first, unsigned int last)
784 {
785 LOG_WARNING("kinetis_ke_protect not supported yet");
786 /* FIXME: TODO */
787
788 if (bank->target->state != TARGET_HALTED) {
789 LOG_ERROR("Target not halted");
790 return ERROR_TARGET_NOT_HALTED;
791 }
792
793 return ERROR_FLASH_BANK_INVALID;
794 }
795
796 static int kinetis_ke_protect_check(struct flash_bank *bank)
797 {
798 struct kinetis_ke_flash_bank *kinfo = bank->driver_priv;
799
800 if (bank->target->state != TARGET_HALTED) {
801 LOG_ERROR("Target not halted");
802 return ERROR_TARGET_NOT_HALTED;
803 }
804
805 int result;
806 uint8_t fprot;
807 uint8_t fpopen, fpldis, fphdis;
808 uint8_t fphs, fpls;
809 uint32_t lprot_size = 0, hprot_size = 0;
810 uint32_t lprot_to = 0, hprot_from = 0;
811
812 /* read protection register */
813 result = target_read_u8(bank->target, kinfo->ftmrx_fprot_addr, &fprot);
814
815 if (result != ERROR_OK)
816 return result;
817
818 fpopen = fprot & 0x80;
819 fpldis = fprot & 0x04;
820 fphdis = fprot & 0x20;
821 fphs = (fprot >> 3) & 0x03;
822 fpls = fprot & 0x03;
823
824 /* Fully unprotected? */
825 if (fpopen && fpldis && fphdis) {
826 LOG_WARNING("No flash protection found.");
827
828 for (unsigned int i = 0; i < bank->num_sectors; i++)
829 bank->sectors[i].is_protected = 0;
830
831 kinfo->protection_size = 0;
832 } else {
833 LOG_WARNING("Flash protected. FPOPEN=%i FPLDIS=%i FPHDIS=%i FPLS=%i FPHS=%i",
834 fpopen ? 1 : 0, fpldis ? 1 : 0, fphdis ? 1 : 0, fpls, fphs);
835
836 /* Retrieve which region is protected and how much */
837 if (fpopen) {
838 if (fpldis == 0)
839 lprot_size = (kinfo->sector_size * 4) << fpls;
840
841 if (fphdis == 0)
842 hprot_size = (kinfo->sector_size * 2) << fphs;
843 } else {
844 if (fpldis == 1)
845 lprot_size = (kinfo->sector_size * 4) << fpls;
846
847 if (fphdis == 1)
848 hprot_size = (kinfo->sector_size * 2) << fphs;
849 }
850
851 kinfo->protection_size = lprot_size + hprot_size;
852
853 /* lprot_to indicates up to where the lower region is protected */
854 lprot_to = lprot_size / kinfo->sector_size;
855
856 /* hprot_from indicates from where the upper region is protected */
857 hprot_from = (0x8000 - hprot_size) / kinfo->sector_size;
858
859 for (unsigned int i = 0; i < bank->num_sectors; i++) {
860
861 /* Check if the sector is in the lower region */
862 if (bank->sectors[i].offset < 0x4000) {
863 /* Compare the sector start address against lprot_to */
864 if (lprot_to && (i < lprot_to))
865 bank->sectors[i].is_protected = 1;
866 else
867 bank->sectors[i].is_protected = 0;
868
869 /* Check if the sector is between the lower and upper region
870 * OR after the upper region */
871 } else if (bank->sectors[i].offset < 0x6000 || bank->sectors[i].offset >= 0x8000) {
872 /* If fpopen is 1 then these regions are protected */
873 if (fpopen)
874 bank->sectors[i].is_protected = 0;
875 else
876 bank->sectors[i].is_protected = 1;
877
878 /* Check if the sector is in the upper region */
879 } else if (bank->sectors[i].offset < 0x8000) {
880 if (hprot_from && (i > hprot_from))
881 bank->sectors[i].is_protected = 1;
882 else
883 bank->sectors[i].is_protected = 0;
884 }
885 }
886 }
887
888 return ERROR_OK;
889 }
890
891 static int kinetis_ke_ftmrx_command(struct flash_bank *bank, uint8_t count,
892 uint8_t *FCCOBIX, uint8_t *FCCOBHI, uint8_t *FCCOBLO, uint8_t *fstat)
893 {
894 uint8_t i;
895 int result;
896 struct target *target = bank->target;
897 struct kinetis_ke_flash_bank *kinfo = bank->driver_priv;
898 uint32_t timeout = 0;
899
900 /* Clear error flags */
901 result = target_write_u8(target, kinfo->ftmrx_fstat_addr, 0x30);
902 if (result != ERROR_OK)
903 return result;
904
905 for (i = 0; i < count; i++) {
906 /* Write index */
907 result = target_write_u8(target, kinfo->ftmrx_fccobix_addr, FCCOBIX[i]);
908 if (result != ERROR_OK)
909 return result;
910
911 /* Write high part */
912 result = target_write_u8(target, kinfo->ftmrx_fccobhi_addr, FCCOBHI[i]);
913 if (result != ERROR_OK)
914 return result;
915
916 /* Write low part (that is not always required) */
917 if (FCCOBLO) {
918 result = target_write_u8(target, kinfo->ftmrx_fccoblo_addr, FCCOBLO[i]);
919 if (result != ERROR_OK)
920 return result;
921 }
922 }
923
924 /* Launch the command */
925 result = target_write_u8(target, kinfo->ftmrx_fstat_addr, 0x80);
926 if (result != ERROR_OK)
927 return result;
928
929 /* Wait for it to finish */
930 result = target_read_u8(target, kinfo->ftmrx_fstat_addr, fstat);
931 if (result != ERROR_OK)
932 return result;
933
934 while (!(*fstat & FTMRX_FSTAT_CCIF_MASK)) {
935 if (timeout <= 1000) {
936 timeout++;
937 alive_sleep(1);
938 } else {
939 return ERROR_FLASH_OPERATION_FAILED;
940 }
941
942 result = target_read_u8(target, kinfo->ftmrx_fstat_addr, fstat);
943 if (result != ERROR_OK)
944 return result;
945 }
946
947 return ERROR_OK;
948 }
949
950 static int kinetis_ke_erase(struct flash_bank *bank, unsigned int first,
951 unsigned int last)
952 {
953 int result;
954 uint8_t FCCOBIX[2], FCCOBHI[2], FCCOBLO[2], fstat;
955 bool fcf_erased = false;
956
957 if (bank->target->state != TARGET_HALTED) {
958 LOG_ERROR("Target not halted");
959 return ERROR_TARGET_NOT_HALTED;
960 }
961
962 if ((first > bank->num_sectors) || (last > bank->num_sectors))
963 return ERROR_FLASH_OPERATION_FAILED;
964
965 result = kinetis_ke_prepare_flash(bank);
966 if (result != ERROR_OK)
967 return result;
968
969 for (unsigned int i = first; i <= last; i++) {
970 FCCOBIX[0] = 0;
971 FCCOBHI[0] = FTMRX_CMD_ERASESECTOR;
972 FCCOBLO[0] = (bank->base + bank->sectors[i].offset) >> 16;
973
974 FCCOBIX[1] = 1;
975 FCCOBHI[1] = (bank->base + bank->sectors[i].offset) >> 8;
976 FCCOBLO[1] = (bank->base + bank->sectors[i].offset);
977
978 result = kinetis_ke_ftmrx_command(bank, 2, FCCOBIX, FCCOBHI, FCCOBLO, &fstat);
979
980 if (result != ERROR_OK) {
981 LOG_WARNING("erase sector %u failed", i);
982 return ERROR_FLASH_OPERATION_FAILED;
983 }
984
985 if (i == 2)
986 fcf_erased = true;
987 }
988
989 if (fcf_erased) {
990 LOG_WARNING
991 ("flash configuration field erased, please reset the device");
992 }
993
994 return ERROR_OK;
995 }
996
997 static int kinetis_ke_write(struct flash_bank *bank, const uint8_t *buffer,
998 uint32_t offset, uint32_t count)
999 {
1000 int result;
1001 uint8_t *new_buffer = NULL;
1002 uint32_t words = count / 4;
1003
1004 if (bank->target->state != TARGET_HALTED) {
1005 LOG_ERROR("Target not halted");
1006 return ERROR_TARGET_NOT_HALTED;
1007 }
1008
1009 if (offset > bank->size)
1010 return ERROR_FLASH_BANK_INVALID;
1011
1012 if (offset & 0x3) {
1013 LOG_WARNING("offset 0x%" PRIx32 " breaks the required alignment", offset);
1014 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
1015 }
1016
1017 result = kinetis_ke_stop_watchdog(bank->target);
1018 if (result != ERROR_OK)
1019 return result;
1020
1021 result = kinetis_ke_prepare_flash(bank);
1022 if (result != ERROR_OK)
1023 return result;
1024
1025 if (count & 0x3) {
1026 uint32_t old_count = count;
1027 count = (old_count | 3) + 1;
1028 new_buffer = malloc(count);
1029 if (!new_buffer) {
1030 LOG_ERROR("odd number of bytes to write and no memory "
1031 "for padding buffer");
1032 return ERROR_FAIL;
1033 }
1034
1035 LOG_INFO("odd number of bytes to write (%" PRIu32 "), extending to %" PRIu32 " "
1036 "and padding with 0xff", old_count, count);
1037
1038 memset(new_buffer, 0xff, count);
1039 buffer = memcpy(new_buffer, buffer, old_count);
1040 words++;
1041 }
1042
1043 result = kinetis_ke_write_words(bank, buffer, offset, words);
1044 free(new_buffer);
1045
1046 return result;
1047 }
1048
1049 static int kinetis_ke_probe(struct flash_bank *bank)
1050 {
1051 int result;
1052 uint32_t offset = 0;
1053 struct target *target = bank->target;
1054 struct kinetis_ke_flash_bank *kinfo = bank->driver_priv;
1055
1056 result = target_read_u32(target, SIM_SRSID, &kinfo->sim_srsid);
1057 if (result != ERROR_OK)
1058 return result;
1059
1060 if (KINETIS_KE_SRSID_FAMID(kinfo->sim_srsid) != 0x00) {
1061 LOG_ERROR("Unsupported KE family");
1062 return ERROR_FLASH_OPER_UNSUPPORTED;
1063 }
1064
1065 switch (KINETIS_KE_SRSID_SUBFAMID(kinfo->sim_srsid)) {
1066 case KINETIS_KE_SRSID_KEX2:
1067 LOG_INFO("KE02 sub-family");
1068 break;
1069
1070 case KINETIS_KE_SRSID_KEX4:
1071 LOG_INFO("KE04 sub-family");
1072 break;
1073
1074 case KINETIS_KE_SRSID_KEX6:
1075 LOG_INFO("KE06 sub-family");
1076 break;
1077
1078 default:
1079 LOG_ERROR("Unsupported KE sub-family");
1080 return ERROR_FLASH_OPER_UNSUPPORTED;
1081 }
1082
1083 /* We can only retrieve the ke0x part, but there is no way to know
1084 * the flash size, so assume the maximum flash size for the entire
1085 * sub family.
1086 */
1087 bank->base = 0x00000000;
1088 kinfo->sector_size = 512;
1089
1090 switch (KINETIS_KE_SRSID_SUBFAMID(kinfo->sim_srsid)) {
1091
1092 case KINETIS_KE_SRSID_KEX2:
1093 /* Max. 64KB */
1094 bank->size = 0x00010000;
1095 bank->num_sectors = 128;
1096
1097 /* KE02 uses the FTMRH flash controller,
1098 * and registers have a different offset from the
1099 * FTMRE flash controller. Sort this out here.
1100 */
1101 kinfo->ftmrx_fclkdiv_addr = 0x40020000;
1102 kinfo->ftmrx_fccobix_addr = 0x40020002;
1103 kinfo->ftmrx_fstat_addr = 0x40020006;
1104 kinfo->ftmrx_fprot_addr = 0x40020008;
1105 kinfo->ftmrx_fccobhi_addr = 0x4002000A;
1106 kinfo->ftmrx_fccoblo_addr = 0x4002000B;
1107 break;
1108
1109 case KINETIS_KE_SRSID_KEX6:
1110 case KINETIS_KE_SRSID_KEX4:
1111 /* Max. 128KB */
1112 bank->size = 0x00020000;
1113 bank->num_sectors = 256;
1114
1115 /* KE04 and KE06 use the FTMRE flash controller,
1116 * and registers have a different offset from the
1117 * FTMRH flash controller. Sort this out here.
1118 */
1119 kinfo->ftmrx_fclkdiv_addr = 0x40020003;
1120 kinfo->ftmrx_fccobix_addr = 0x40020001;
1121 kinfo->ftmrx_fstat_addr = 0x40020005;
1122 kinfo->ftmrx_fprot_addr = 0x4002000B;
1123 kinfo->ftmrx_fccobhi_addr = 0x40020009;
1124 kinfo->ftmrx_fccoblo_addr = 0x40020008;
1125 break;
1126 }
1127
1128 free(bank->sectors);
1129
1130 assert(bank->num_sectors > 0);
1131 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
1132
1133 for (unsigned int i = 0; i < bank->num_sectors; i++) {
1134 bank->sectors[i].offset = offset;
1135 bank->sectors[i].size = kinfo->sector_size;
1136 offset += kinfo->sector_size;
1137 bank->sectors[i].is_erased = -1;
1138 bank->sectors[i].is_protected = 1;
1139 }
1140
1141 return ERROR_OK;
1142 }
1143
1144 static int kinetis_ke_auto_probe(struct flash_bank *bank)
1145 {
1146 struct kinetis_ke_flash_bank *kinfo = bank->driver_priv;
1147
1148 if (kinfo->sim_srsid)
1149 return ERROR_OK;
1150
1151 return kinetis_ke_probe(bank);
1152 }
1153
1154 static int kinetis_ke_info(struct flash_bank *bank, struct command_invocation *cmd)
1155 {
1156 command_print_sameline(cmd, "%s driver for flash bank %s at " TARGET_ADDR_FMT,
1157 bank->driver->name, bank->name, bank->base);
1158
1159 return ERROR_OK;
1160 }
1161
1162 static int kinetis_ke_blank_check(struct flash_bank *bank)
1163 {
1164 uint8_t FCCOBIX[3], FCCOBHI[3], FCCOBLO[3], fstat;
1165 uint16_t longwords = 0;
1166 int result;
1167
1168 if (bank->target->state != TARGET_HALTED) {
1169 LOG_ERROR("Target not halted");
1170 return ERROR_TARGET_NOT_HALTED;
1171 }
1172
1173 result = kinetis_ke_prepare_flash(bank);
1174 if (result != ERROR_OK)
1175 return result;
1176
1177 /* check if whole bank is blank */
1178 FCCOBIX[0] = 0;
1179 FCCOBHI[0] = FTMRX_CMD_ALLERASED;
1180
1181 result = kinetis_ke_ftmrx_command(bank, 1, FCCOBIX, FCCOBHI, NULL, &fstat);
1182
1183 if (result != ERROR_OK)
1184 return result;
1185
1186 if (fstat & (FTMRX_FSTAT_MGSTAT0_MASK | FTMRX_FSTAT_MGSTAT1_MASK)) {
1187 /* the whole bank is not erased, check sector-by-sector */
1188 for (unsigned int i = 0; i < bank->num_sectors; i++) {
1189 FCCOBIX[0] = 0;
1190 FCCOBHI[0] = FTMRX_CMD_SECTIONERASED;
1191 FCCOBLO[0] = (bank->base + bank->sectors[i].offset) >> 16;
1192
1193 FCCOBIX[1] = 1;
1194 FCCOBHI[1] = (bank->base + bank->sectors[i].offset) >> 8;
1195 FCCOBLO[1] = (bank->base + bank->sectors[i].offset);
1196
1197 longwords = 128;
1198
1199 FCCOBIX[2] = 2;
1200 FCCOBHI[2] = longwords >> 8;
1201 FCCOBLO[2] = longwords;
1202
1203 result = kinetis_ke_ftmrx_command(bank, 3, FCCOBIX, FCCOBHI, FCCOBLO, &fstat);
1204
1205 if (result == ERROR_OK) {
1206 bank->sectors[i].is_erased = !(fstat & (FTMRX_FSTAT_MGSTAT0_MASK | FTMRX_FSTAT_MGSTAT1_MASK));
1207 } else {
1208 LOG_DEBUG("Ignoring error on PFlash sector blank-check");
1209 bank->sectors[i].is_erased = -1;
1210 }
1211 }
1212 } else {
1213 /* the whole bank is erased, update all sectors */
1214 for (unsigned int i = 0; i < bank->num_sectors; i++)
1215 bank->sectors[i].is_erased = 1;
1216 }
1217
1218 return ERROR_OK;
1219 }
1220
1221 static const struct command_registration kinetis_ke_security_command_handlers[] = {
1222 {
1223 .name = "check_security",
1224 .mode = COMMAND_EXEC,
1225 .help = "Check status of device security lock",
1226 .usage = "",
1227 .handler = kinetis_ke_check_flash_security_status,
1228 },
1229 {
1230 .name = "mass_erase",
1231 .mode = COMMAND_EXEC,
1232 .help = "Issue a complete flash erase via the MDM-AP",
1233 .usage = "",
1234 .handler = kinetis_ke_mdm_mass_erase,
1235 },
1236 COMMAND_REGISTRATION_DONE
1237 };
1238
1239 static const struct command_registration kinetis_ke_exec_command_handlers[] = {
1240 {
1241 .name = "mdm",
1242 .mode = COMMAND_ANY,
1243 .help = "MDM-AP command group",
1244 .usage = "",
1245 .chain = kinetis_ke_security_command_handlers,
1246 },
1247 {
1248 .name = "disable_wdog",
1249 .mode = COMMAND_EXEC,
1250 .help = "Disable the watchdog timer",
1251 .usage = "",
1252 .handler = kinetis_ke_disable_wdog_handler,
1253 },
1254 COMMAND_REGISTRATION_DONE
1255 };
1256
1257 static const struct command_registration kinetis_ke_command_handler[] = {
1258 {
1259 .name = "kinetis_ke",
1260 .mode = COMMAND_ANY,
1261 .help = "Kinetis KE flash controller commands",
1262 .usage = "",
1263 .chain = kinetis_ke_exec_command_handlers,
1264 },
1265 COMMAND_REGISTRATION_DONE
1266 };
1267
1268 const struct flash_driver kinetis_ke_flash = {
1269 .name = "kinetis_ke",
1270 .commands = kinetis_ke_command_handler,
1271 .flash_bank_command = kinetis_ke_flash_bank_command,
1272 .erase = kinetis_ke_erase,
1273 .protect = kinetis_ke_protect,
1274 .write = kinetis_ke_write,
1275 .read = default_flash_read,
1276 .probe = kinetis_ke_probe,
1277 .auto_probe = kinetis_ke_auto_probe,
1278 .erase_check = kinetis_ke_blank_check,
1279 .protect_check = kinetis_ke_protect_check,
1280 .info = kinetis_ke_info,
1281 .free_driver_priv = default_flash_free_driver_priv,
1282 };

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)