stm32l4x: Fix stm32l4x dual bank support
[openocd.git] / src / flash / nor / nrf5.c
1 /***************************************************************************
2 * Copyright (C) 2013 Synapse Product Development *
3 * Andrey Smirnov <andrew.smironv@gmail.com> *
4 * Angus Gratton <gus@projectgus.com> *
5 * Erdem U. Altunyurt <spamjunkeater@gmail.com> *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19 ***************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include "imp.h"
26 #include <target/algorithm.h>
27 #include <target/armv7m.h>
28 #include <helper/types.h>
29 #include <helper/time_support.h>
30
31 enum {
32 NRF5_FLASH_BASE = 0x00000000,
33 };
34
35 enum nrf5_ficr_registers {
36 NRF5_FICR_BASE = 0x10000000, /* Factory Information Configuration Registers */
37
38 #define NRF5_FICR_REG(offset) (NRF5_FICR_BASE + offset)
39
40 NRF5_FICR_CODEPAGESIZE = NRF5_FICR_REG(0x010),
41 NRF5_FICR_CODESIZE = NRF5_FICR_REG(0x014),
42 NRF5_FICR_CLENR0 = NRF5_FICR_REG(0x028),
43 NRF5_FICR_PPFC = NRF5_FICR_REG(0x02C),
44 NRF5_FICR_NUMRAMBLOCK = NRF5_FICR_REG(0x034),
45 NRF5_FICR_SIZERAMBLOCK0 = NRF5_FICR_REG(0x038),
46 NRF5_FICR_SIZERAMBLOCK1 = NRF5_FICR_REG(0x03C),
47 NRF5_FICR_SIZERAMBLOCK2 = NRF5_FICR_REG(0x040),
48 NRF5_FICR_SIZERAMBLOCK3 = NRF5_FICR_REG(0x044),
49 NRF5_FICR_CONFIGID = NRF5_FICR_REG(0x05C),
50 NRF5_FICR_DEVICEID0 = NRF5_FICR_REG(0x060),
51 NRF5_FICR_DEVICEID1 = NRF5_FICR_REG(0x064),
52 NRF5_FICR_ER0 = NRF5_FICR_REG(0x080),
53 NRF5_FICR_ER1 = NRF5_FICR_REG(0x084),
54 NRF5_FICR_ER2 = NRF5_FICR_REG(0x088),
55 NRF5_FICR_ER3 = NRF5_FICR_REG(0x08C),
56 NRF5_FICR_IR0 = NRF5_FICR_REG(0x090),
57 NRF5_FICR_IR1 = NRF5_FICR_REG(0x094),
58 NRF5_FICR_IR2 = NRF5_FICR_REG(0x098),
59 NRF5_FICR_IR3 = NRF5_FICR_REG(0x09C),
60 NRF5_FICR_DEVICEADDRTYPE = NRF5_FICR_REG(0x0A0),
61 NRF5_FICR_DEVICEADDR0 = NRF5_FICR_REG(0x0A4),
62 NRF5_FICR_DEVICEADDR1 = NRF5_FICR_REG(0x0A8),
63 NRF5_FICR_OVERRIDEN = NRF5_FICR_REG(0x0AC),
64 NRF5_FICR_NRF_1MBIT0 = NRF5_FICR_REG(0x0B0),
65 NRF5_FICR_NRF_1MBIT1 = NRF5_FICR_REG(0x0B4),
66 NRF5_FICR_NRF_1MBIT2 = NRF5_FICR_REG(0x0B8),
67 NRF5_FICR_NRF_1MBIT3 = NRF5_FICR_REG(0x0BC),
68 NRF5_FICR_NRF_1MBIT4 = NRF5_FICR_REG(0x0C0),
69 NRF5_FICR_BLE_1MBIT0 = NRF5_FICR_REG(0x0EC),
70 NRF5_FICR_BLE_1MBIT1 = NRF5_FICR_REG(0x0F0),
71 NRF5_FICR_BLE_1MBIT2 = NRF5_FICR_REG(0x0F4),
72 NRF5_FICR_BLE_1MBIT3 = NRF5_FICR_REG(0x0F8),
73 NRF5_FICR_BLE_1MBIT4 = NRF5_FICR_REG(0x0FC),
74 };
75
76 enum nrf5_uicr_registers {
77 NRF5_UICR_BASE = 0x10001000, /* User Information
78 * Configuration Regsters */
79
80 NRF5_UICR_SIZE = 0x100,
81
82 #define NRF5_UICR_REG(offset) (NRF5_UICR_BASE + offset)
83
84 NRF5_UICR_CLENR0 = NRF5_UICR_REG(0x000),
85 NRF5_UICR_RBPCONF = NRF5_UICR_REG(0x004),
86 NRF5_UICR_XTALFREQ = NRF5_UICR_REG(0x008),
87 NRF5_UICR_FWID = NRF5_UICR_REG(0x010),
88 };
89
90 enum nrf5_nvmc_registers {
91 NRF5_NVMC_BASE = 0x4001E000, /* Non-Volatile Memory
92 * Controller Regsters */
93
94 #define NRF5_NVMC_REG(offset) (NRF5_NVMC_BASE + offset)
95
96 NRF5_NVMC_READY = NRF5_NVMC_REG(0x400),
97 NRF5_NVMC_CONFIG = NRF5_NVMC_REG(0x504),
98 NRF5_NVMC_ERASEPAGE = NRF5_NVMC_REG(0x508),
99 NRF5_NVMC_ERASEALL = NRF5_NVMC_REG(0x50C),
100 NRF5_NVMC_ERASEUICR = NRF5_NVMC_REG(0x514),
101 };
102
103 enum nrf5_nvmc_config_bits {
104 NRF5_NVMC_CONFIG_REN = 0x00,
105 NRF5_NVMC_CONFIG_WEN = 0x01,
106 NRF5_NVMC_CONFIG_EEN = 0x02,
107
108 };
109
110 struct nrf5_info {
111 uint32_t code_page_size;
112 uint32_t refcount;
113
114 struct {
115 bool probed;
116 int (*write) (struct flash_bank *bank,
117 struct nrf5_info *chip,
118 const uint8_t *buffer, uint32_t offset, uint32_t count);
119 } bank[2];
120 struct target *target;
121 };
122
123 struct nrf5_device_spec {
124 uint16_t hwid;
125 const char *part;
126 const char *variant;
127 const char *build_code;
128 unsigned int flash_size_kb;
129 };
130
131 #define NRF5_DEVICE_DEF(id, pt, var, bcode, fsize) \
132 { \
133 .hwid = (id), \
134 .part = pt, \
135 .variant = var, \
136 .build_code = bcode, \
137 .flash_size_kb = (fsize), \
138 }
139
140 /* The known devices table below is derived from the "nRF51 Series
141 * Compatibility Matrix" document, which can be found by searching for
142 * ATTN-51 on the Nordic Semi website:
143 *
144 * http://www.nordicsemi.com/eng/content/search?SearchText=ATTN-51
145 *
146 * Up to date with Matrix v2.0, plus some additional HWIDs.
147 *
148 * The additional HWIDs apply where the build code in the matrix is
149 * shown as Gx0, Bx0, etc. In these cases the HWID in the matrix is
150 * for x==0, x!=0 means different (unspecified) HWIDs.
151 */
152 static const struct nrf5_device_spec nrf5_known_devices_table[] = {
153 /* nRF51822 Devices (IC rev 1). */
154 NRF5_DEVICE_DEF(0x001D, "51822", "QFAA", "CA/C0", 256),
155 NRF5_DEVICE_DEF(0x0026, "51822", "QFAB", "AA", 128),
156 NRF5_DEVICE_DEF(0x0027, "51822", "QFAB", "A0", 128),
157 NRF5_DEVICE_DEF(0x0020, "51822", "CEAA", "BA", 256),
158 NRF5_DEVICE_DEF(0x002F, "51822", "CEAA", "B0", 256),
159
160 /* Some early nRF51-DK (PCA10028) & nRF51-Dongle (PCA10031) boards
161 with built-in jlink seem to use engineering samples not listed
162 in the nRF51 Series Compatibility Matrix V1.0. */
163 NRF5_DEVICE_DEF(0x0071, "51822", "QFAC", "AB", 256),
164
165 /* nRF51822 Devices (IC rev 2). */
166 NRF5_DEVICE_DEF(0x002A, "51822", "QFAA", "FA0", 256),
167 NRF5_DEVICE_DEF(0x0044, "51822", "QFAA", "GC0", 256),
168 NRF5_DEVICE_DEF(0x003C, "51822", "QFAA", "G0", 256),
169 NRF5_DEVICE_DEF(0x0057, "51822", "QFAA", "G2", 256),
170 NRF5_DEVICE_DEF(0x0058, "51822", "QFAA", "G3", 256),
171 NRF5_DEVICE_DEF(0x004C, "51822", "QFAB", "B0", 128),
172 NRF5_DEVICE_DEF(0x0040, "51822", "CEAA", "CA0", 256),
173 NRF5_DEVICE_DEF(0x0047, "51822", "CEAA", "DA0", 256),
174 NRF5_DEVICE_DEF(0x004D, "51822", "CEAA", "D00", 256),
175
176 /* nRF51822 Devices (IC rev 3). */
177 NRF5_DEVICE_DEF(0x0072, "51822", "QFAA", "H0", 256),
178 NRF5_DEVICE_DEF(0x00D1, "51822", "QFAA", "H2", 256),
179 NRF5_DEVICE_DEF(0x007B, "51822", "QFAB", "C0", 128),
180 NRF5_DEVICE_DEF(0x0083, "51822", "QFAC", "A0", 256),
181 NRF5_DEVICE_DEF(0x0084, "51822", "QFAC", "A1", 256),
182 NRF5_DEVICE_DEF(0x007D, "51822", "CDAB", "A0", 128),
183 NRF5_DEVICE_DEF(0x0079, "51822", "CEAA", "E0", 256),
184 NRF5_DEVICE_DEF(0x0087, "51822", "CFAC", "A0", 256),
185 NRF5_DEVICE_DEF(0x008F, "51822", "QFAA", "H1", 256),
186
187 /* nRF51422 Devices (IC rev 1). */
188 NRF5_DEVICE_DEF(0x001E, "51422", "QFAA", "CA", 256),
189 NRF5_DEVICE_DEF(0x0024, "51422", "QFAA", "C0", 256),
190 NRF5_DEVICE_DEF(0x0031, "51422", "CEAA", "A0A", 256),
191
192 /* nRF51422 Devices (IC rev 2). */
193 NRF5_DEVICE_DEF(0x002D, "51422", "QFAA", "DAA", 256),
194 NRF5_DEVICE_DEF(0x002E, "51422", "QFAA", "E0", 256),
195 NRF5_DEVICE_DEF(0x0061, "51422", "QFAB", "A00", 128),
196 NRF5_DEVICE_DEF(0x0050, "51422", "CEAA", "B0", 256),
197
198 /* nRF51422 Devices (IC rev 3). */
199 NRF5_DEVICE_DEF(0x0073, "51422", "QFAA", "F0", 256),
200 NRF5_DEVICE_DEF(0x007C, "51422", "QFAB", "B0", 128),
201 NRF5_DEVICE_DEF(0x0085, "51422", "QFAC", "A0", 256),
202 NRF5_DEVICE_DEF(0x0086, "51422", "QFAC", "A1", 256),
203 NRF5_DEVICE_DEF(0x007E, "51422", "CDAB", "A0", 128),
204 NRF5_DEVICE_DEF(0x007A, "51422", "CEAA", "C0", 256),
205 NRF5_DEVICE_DEF(0x0088, "51422", "CFAC", "A0", 256),
206
207 /* nRF52810 Devices */
208 NRF5_DEVICE_DEF(0x0142, "52810", "QFAA", "B0", 192),
209 NRF5_DEVICE_DEF(0x0143, "52810", "QCAA", "C0", 192),
210
211 /* nRF52832 Devices */
212 NRF5_DEVICE_DEF(0x00C7, "52832", "QFAA", "B0", 512),
213 NRF5_DEVICE_DEF(0x0139, "52832", "QFAA", "E0", 512),
214
215 /* nRF52840 Devices */
216 NRF5_DEVICE_DEF(0x0150, "52840", "QIAA", "C0", 1024),
217 };
218
219 static int nrf5_bank_is_probed(struct flash_bank *bank)
220 {
221 struct nrf5_info *chip = bank->driver_priv;
222
223 assert(chip != NULL);
224
225 return chip->bank[bank->bank_number].probed;
226 }
227 static int nrf5_probe(struct flash_bank *bank);
228
229 static int nrf5_get_probed_chip_if_halted(struct flash_bank *bank, struct nrf5_info **chip)
230 {
231 if (bank->target->state != TARGET_HALTED) {
232 LOG_ERROR("Target not halted");
233 return ERROR_TARGET_NOT_HALTED;
234 }
235
236 *chip = bank->driver_priv;
237
238 int probed = nrf5_bank_is_probed(bank);
239 if (probed < 0)
240 return probed;
241 else if (!probed)
242 return nrf5_probe(bank);
243 else
244 return ERROR_OK;
245 }
246
247 static int nrf5_wait_for_nvmc(struct nrf5_info *chip)
248 {
249 uint32_t ready;
250 int res;
251 int timeout_ms = 200;
252 int64_t ts_start = timeval_ms();
253
254 do {
255 res = target_read_u32(chip->target, NRF5_NVMC_READY, &ready);
256 if (res != ERROR_OK) {
257 LOG_ERROR("Couldn't read NVMC_READY register");
258 return res;
259 }
260
261 if (ready == 0x00000001)
262 return ERROR_OK;
263
264 keep_alive();
265
266 } while ((timeval_ms()-ts_start) < timeout_ms);
267
268 LOG_DEBUG("Timed out waiting for NVMC_READY");
269 return ERROR_FLASH_BUSY;
270 }
271
272 static int nrf5_nvmc_erase_enable(struct nrf5_info *chip)
273 {
274 int res;
275 res = target_write_u32(chip->target,
276 NRF5_NVMC_CONFIG,
277 NRF5_NVMC_CONFIG_EEN);
278
279 if (res != ERROR_OK) {
280 LOG_ERROR("Failed to enable erase operation");
281 return res;
282 }
283
284 /*
285 According to NVMC examples in Nordic SDK busy status must be
286 checked after writing to NVMC_CONFIG
287 */
288 res = nrf5_wait_for_nvmc(chip);
289 if (res != ERROR_OK)
290 LOG_ERROR("Erase enable did not complete");
291
292 return res;
293 }
294
295 static int nrf5_nvmc_write_enable(struct nrf5_info *chip)
296 {
297 int res;
298 res = target_write_u32(chip->target,
299 NRF5_NVMC_CONFIG,
300 NRF5_NVMC_CONFIG_WEN);
301
302 if (res != ERROR_OK) {
303 LOG_ERROR("Failed to enable write operation");
304 return res;
305 }
306
307 /*
308 According to NVMC examples in Nordic SDK busy status must be
309 checked after writing to NVMC_CONFIG
310 */
311 res = nrf5_wait_for_nvmc(chip);
312 if (res != ERROR_OK)
313 LOG_ERROR("Write enable did not complete");
314
315 return res;
316 }
317
318 static int nrf5_nvmc_read_only(struct nrf5_info *chip)
319 {
320 int res;
321 res = target_write_u32(chip->target,
322 NRF5_NVMC_CONFIG,
323 NRF5_NVMC_CONFIG_REN);
324
325 if (res != ERROR_OK) {
326 LOG_ERROR("Failed to enable read-only operation");
327 return res;
328 }
329 /*
330 According to NVMC examples in Nordic SDK busy status must be
331 checked after writing to NVMC_CONFIG
332 */
333 res = nrf5_wait_for_nvmc(chip);
334 if (res != ERROR_OK)
335 LOG_ERROR("Read only enable did not complete");
336
337 return res;
338 }
339
340 static int nrf5_nvmc_generic_erase(struct nrf5_info *chip,
341 uint32_t erase_register, uint32_t erase_value)
342 {
343 int res;
344
345 res = nrf5_nvmc_erase_enable(chip);
346 if (res != ERROR_OK)
347 goto error;
348
349 res = target_write_u32(chip->target,
350 erase_register,
351 erase_value);
352 if (res != ERROR_OK)
353 goto set_read_only;
354
355 res = nrf5_wait_for_nvmc(chip);
356 if (res != ERROR_OK)
357 goto set_read_only;
358
359 return nrf5_nvmc_read_only(chip);
360
361 set_read_only:
362 nrf5_nvmc_read_only(chip);
363 error:
364 LOG_ERROR("Failed to erase reg: 0x%08"PRIx32" val: 0x%08"PRIx32,
365 erase_register, erase_value);
366 return ERROR_FAIL;
367 }
368
369 static int nrf5_protect_check(struct flash_bank *bank)
370 {
371 int res;
372 uint32_t clenr0;
373
374 /* UICR cannot be write protected so just return early */
375 if (bank->base == NRF5_UICR_BASE)
376 return ERROR_OK;
377
378 struct nrf5_info *chip = bank->driver_priv;
379
380 assert(chip != NULL);
381
382 res = target_read_u32(chip->target, NRF5_FICR_CLENR0,
383 &clenr0);
384 if (res != ERROR_OK) {
385 LOG_ERROR("Couldn't read code region 0 size[FICR]");
386 return res;
387 }
388
389 if (clenr0 == 0xFFFFFFFF) {
390 res = target_read_u32(chip->target, NRF5_UICR_CLENR0,
391 &clenr0);
392 if (res != ERROR_OK) {
393 LOG_ERROR("Couldn't read code region 0 size[UICR]");
394 return res;
395 }
396 }
397
398 for (int i = 0; i < bank->num_sectors; i++)
399 bank->sectors[i].is_protected =
400 clenr0 != 0xFFFFFFFF && bank->sectors[i].offset < clenr0;
401
402 return ERROR_OK;
403 }
404
405 static int nrf5_protect(struct flash_bank *bank, int set, int first, int last)
406 {
407 int res;
408 uint32_t clenr0, ppfc;
409 struct nrf5_info *chip;
410
411 /* UICR cannot be write protected so just bail out early */
412 if (bank->base == NRF5_UICR_BASE)
413 return ERROR_FAIL;
414
415 res = nrf5_get_probed_chip_if_halted(bank, &chip);
416 if (res != ERROR_OK)
417 return res;
418
419 if (first != 0) {
420 LOG_ERROR("Code region 0 must start at the begining of the bank");
421 return ERROR_FAIL;
422 }
423
424 res = target_read_u32(chip->target, NRF5_FICR_PPFC,
425 &ppfc);
426 if (res != ERROR_OK) {
427 LOG_ERROR("Couldn't read PPFC register");
428 return res;
429 }
430
431 if ((ppfc & 0xFF) == 0x00) {
432 LOG_ERROR("Code region 0 size was pre-programmed at the factory, can't change flash protection settings");
433 return ERROR_FAIL;
434 }
435
436 res = target_read_u32(chip->target, NRF5_UICR_CLENR0,
437 &clenr0);
438 if (res != ERROR_OK) {
439 LOG_ERROR("Couldn't read code region 0 size[UICR]");
440 return res;
441 }
442
443 if (clenr0 == 0xFFFFFFFF) {
444 res = target_write_u32(chip->target, NRF5_UICR_CLENR0,
445 clenr0);
446 if (res != ERROR_OK) {
447 LOG_ERROR("Couldn't write code region 0 size[UICR]");
448 return res;
449 }
450
451 } else {
452 LOG_ERROR("You need to perform chip erase before changing the protection settings");
453 }
454
455 nrf5_protect_check(bank);
456
457 return ERROR_OK;
458 }
459
460 static int nrf5_probe(struct flash_bank *bank)
461 {
462 uint32_t hwid;
463 int res;
464 struct nrf5_info *chip = bank->driver_priv;
465
466 res = target_read_u32(chip->target, NRF5_FICR_CONFIGID, &hwid);
467 if (res != ERROR_OK) {
468 LOG_ERROR("Couldn't read CONFIGID register");
469 return res;
470 }
471
472 hwid &= 0xFFFF; /* HWID is stored in the lower two
473 * bytes of the CONFIGID register */
474
475 const struct nrf5_device_spec *spec = NULL;
476 for (size_t i = 0; i < ARRAY_SIZE(nrf5_known_devices_table); i++) {
477 if (hwid == nrf5_known_devices_table[i].hwid) {
478 spec = &nrf5_known_devices_table[i];
479 break;
480 }
481 }
482
483 if (!chip->bank[0].probed && !chip->bank[1].probed) {
484 if (spec)
485 LOG_INFO("nRF%s-%s(build code: %s) %ukB Flash",
486 spec->part, spec->variant, spec->build_code,
487 spec->flash_size_kb);
488 else
489 LOG_WARNING("Unknown device (HWID 0x%08" PRIx32 ")", hwid);
490 }
491
492 if (bank->base == NRF5_FLASH_BASE) {
493 /* The value stored in NRF5_FICR_CODEPAGESIZE is the number of bytes in one page of FLASH. */
494 res = target_read_u32(chip->target, NRF5_FICR_CODEPAGESIZE,
495 &chip->code_page_size);
496 if (res != ERROR_OK) {
497 LOG_ERROR("Couldn't read code page size");
498 return res;
499 }
500
501 /* Note the register name is misleading,
502 * NRF5_FICR_CODESIZE is the number of pages in flash memory, not the number of bytes! */
503 uint32_t num_sectors;
504 res = target_read_u32(chip->target, NRF5_FICR_CODESIZE, &num_sectors);
505 if (res != ERROR_OK) {
506 LOG_ERROR("Couldn't read code memory size");
507 return res;
508 }
509
510 bank->num_sectors = num_sectors;
511 bank->size = num_sectors * chip->code_page_size;
512
513 if (spec && bank->size / 1024 != spec->flash_size_kb)
514 LOG_WARNING("Chip's reported Flash capacity does not match expected one");
515
516 bank->sectors = calloc(bank->num_sectors,
517 sizeof((bank->sectors)[0]));
518 if (!bank->sectors)
519 return ERROR_FLASH_BANK_NOT_PROBED;
520
521 /* Fill out the sector information: all NRF5 sectors are the same size and
522 * there is always a fixed number of them. */
523 for (int i = 0; i < bank->num_sectors; i++) {
524 bank->sectors[i].size = chip->code_page_size;
525 bank->sectors[i].offset = i * chip->code_page_size;
526
527 /* mark as unknown */
528 bank->sectors[i].is_erased = -1;
529 bank->sectors[i].is_protected = -1;
530 }
531
532 nrf5_protect_check(bank);
533
534 chip->bank[0].probed = true;
535 } else {
536 bank->size = NRF5_UICR_SIZE;
537 bank->num_sectors = 1;
538 bank->sectors = calloc(bank->num_sectors,
539 sizeof((bank->sectors)[0]));
540 if (!bank->sectors)
541 return ERROR_FLASH_BANK_NOT_PROBED;
542
543 bank->sectors[0].size = bank->size;
544 bank->sectors[0].offset = 0;
545
546 bank->sectors[0].is_erased = 0;
547 bank->sectors[0].is_protected = 0;
548
549 chip->bank[1].probed = true;
550 }
551
552 return ERROR_OK;
553 }
554
555 static int nrf5_auto_probe(struct flash_bank *bank)
556 {
557 int probed = nrf5_bank_is_probed(bank);
558
559 if (probed < 0)
560 return probed;
561 else if (probed)
562 return ERROR_OK;
563 else
564 return nrf5_probe(bank);
565 }
566
567 static int nrf5_erase_all(struct nrf5_info *chip)
568 {
569 LOG_DEBUG("Erasing all non-volatile memory");
570 return nrf5_nvmc_generic_erase(chip,
571 NRF5_NVMC_ERASEALL,
572 0x00000001);
573 }
574
575 static int nrf5_erase_page(struct flash_bank *bank,
576 struct nrf5_info *chip,
577 struct flash_sector *sector)
578 {
579 int res;
580
581 LOG_DEBUG("Erasing page at 0x%"PRIx32, sector->offset);
582 if (sector->is_protected) {
583 LOG_ERROR("Cannot erase protected sector at 0x%" PRIx32, sector->offset);
584 return ERROR_FAIL;
585 }
586
587 if (bank->base == NRF5_UICR_BASE) {
588 uint32_t ppfc;
589 res = target_read_u32(chip->target, NRF5_FICR_PPFC,
590 &ppfc);
591 if (res != ERROR_OK) {
592 LOG_ERROR("Couldn't read PPFC register");
593 return res;
594 }
595
596 if ((ppfc & 0xFF) == 0xFF) {
597 /* We can't erase the UICR. Double-check to
598 see if it's already erased before complaining. */
599 default_flash_blank_check(bank);
600 if (sector->is_erased == 1)
601 return ERROR_OK;
602
603 LOG_ERROR("The chip was not pre-programmed with SoftDevice stack and UICR cannot be erased separately. Please issue mass erase before trying to write to this region");
604 return ERROR_FAIL;
605 }
606
607 res = nrf5_nvmc_generic_erase(chip,
608 NRF5_NVMC_ERASEUICR,
609 0x00000001);
610
611
612 } else {
613 res = nrf5_nvmc_generic_erase(chip,
614 NRF5_NVMC_ERASEPAGE,
615 sector->offset);
616 }
617
618 return res;
619 }
620
621 static const uint8_t nrf5_flash_write_code[] = {
622 /* See contrib/loaders/flash/cortex-m0.S */
623 /* <wait_fifo>: */
624 0x0d, 0x68, /* ldr r5, [r1, #0] */
625 0x00, 0x2d, /* cmp r5, #0 */
626 0x0b, 0xd0, /* beq.n 1e <exit> */
627 0x4c, 0x68, /* ldr r4, [r1, #4] */
628 0xac, 0x42, /* cmp r4, r5 */
629 0xf9, 0xd0, /* beq.n 0 <wait_fifo> */
630 0x20, 0xcc, /* ldmia r4!, {r5} */
631 0x20, 0xc3, /* stmia r3!, {r5} */
632 0x94, 0x42, /* cmp r4, r2 */
633 0x01, 0xd3, /* bcc.n 18 <no_wrap> */
634 0x0c, 0x46, /* mov r4, r1 */
635 0x08, 0x34, /* adds r4, #8 */
636 /* <no_wrap>: */
637 0x4c, 0x60, /* str r4, [r1, #4] */
638 0x04, 0x38, /* subs r0, #4 */
639 0xf0, 0xd1, /* bne.n 0 <wait_fifo> */
640 /* <exit>: */
641 0x00, 0xbe /* bkpt 0x0000 */
642 };
643
644
645 /* Start a low level flash write for the specified region */
646 static int nrf5_ll_flash_write(struct nrf5_info *chip, uint32_t offset, const uint8_t *buffer, uint32_t bytes)
647 {
648 struct target *target = chip->target;
649 uint32_t buffer_size = 8192;
650 struct working_area *write_algorithm;
651 struct working_area *source;
652 uint32_t address = NRF5_FLASH_BASE + offset;
653 struct reg_param reg_params[4];
654 struct armv7m_algorithm armv7m_info;
655 int retval = ERROR_OK;
656
657
658 LOG_DEBUG("Writing buffer to flash offset=0x%"PRIx32" bytes=0x%"PRIx32, offset, bytes);
659 assert(bytes % 4 == 0);
660
661 /* allocate working area with flash programming code */
662 if (target_alloc_working_area(target, sizeof(nrf5_flash_write_code),
663 &write_algorithm) != ERROR_OK) {
664 LOG_WARNING("no working area available, falling back to slow memory writes");
665
666 for (; bytes > 0; bytes -= 4) {
667 retval = target_write_memory(chip->target, offset, 4, 1, buffer);
668 if (retval != ERROR_OK)
669 return retval;
670
671 retval = nrf5_wait_for_nvmc(chip);
672 if (retval != ERROR_OK)
673 return retval;
674
675 offset += 4;
676 buffer += 4;
677 }
678
679 return ERROR_OK;
680 }
681
682 LOG_WARNING("using fast async flash loader. This is currently supported");
683 LOG_WARNING("only with ST-Link and CMSIS-DAP. If you have issues, add");
684 LOG_WARNING("\"set WORKAREASIZE 0\" before sourcing nrf51.cfg/nrf52.cfg to disable it");
685
686 retval = target_write_buffer(target, write_algorithm->address,
687 sizeof(nrf5_flash_write_code),
688 nrf5_flash_write_code);
689 if (retval != ERROR_OK)
690 return retval;
691
692 /* memory buffer */
693 while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) {
694 buffer_size /= 2;
695 buffer_size &= ~3UL; /* Make sure it's 4 byte aligned */
696 if (buffer_size <= 256) {
697 /* free working area, write algorithm already allocated */
698 target_free_working_area(target, write_algorithm);
699
700 LOG_WARNING("No large enough working area available, can't do block memory writes");
701 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
702 }
703 }
704
705 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
706 armv7m_info.core_mode = ARM_MODE_THREAD;
707
708 init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* byte count */
709 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* buffer start */
710 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* buffer end */
711 init_reg_param(&reg_params[3], "r3", 32, PARAM_IN_OUT); /* target address */
712
713 buf_set_u32(reg_params[0].value, 0, 32, bytes);
714 buf_set_u32(reg_params[1].value, 0, 32, source->address);
715 buf_set_u32(reg_params[2].value, 0, 32, source->address + source->size);
716 buf_set_u32(reg_params[3].value, 0, 32, address);
717
718 retval = target_run_flash_async_algorithm(target, buffer, bytes/4, 4,
719 0, NULL,
720 4, reg_params,
721 source->address, source->size,
722 write_algorithm->address, 0,
723 &armv7m_info);
724
725 target_free_working_area(target, source);
726 target_free_working_area(target, write_algorithm);
727
728 destroy_reg_param(&reg_params[0]);
729 destroy_reg_param(&reg_params[1]);
730 destroy_reg_param(&reg_params[2]);
731 destroy_reg_param(&reg_params[3]);
732
733 return retval;
734 }
735
736 /* Check and erase flash sectors in specified range then start a low level page write.
737 start/end must be sector aligned.
738 */
739 static int nrf5_write_pages(struct flash_bank *bank, uint32_t start, uint32_t end, const uint8_t *buffer)
740 {
741 int res = ERROR_FAIL;
742 struct nrf5_info *chip = bank->driver_priv;
743
744 assert(start % chip->code_page_size == 0);
745 assert(end % chip->code_page_size == 0);
746
747 res = nrf5_nvmc_write_enable(chip);
748 if (res != ERROR_OK)
749 goto error;
750
751 res = nrf5_ll_flash_write(chip, start, buffer, (end - start));
752 if (res != ERROR_OK)
753 goto error;
754
755 return nrf5_nvmc_read_only(chip);
756
757 error:
758 nrf5_nvmc_read_only(chip);
759 LOG_ERROR("Failed to write to nrf5 flash");
760 return res;
761 }
762
763 static int nrf5_erase(struct flash_bank *bank, int first, int last)
764 {
765 int res;
766 struct nrf5_info *chip;
767
768 res = nrf5_get_probed_chip_if_halted(bank, &chip);
769 if (res != ERROR_OK)
770 return res;
771
772 /* For each sector to be erased */
773 for (int s = first; s <= last && res == ERROR_OK; s++)
774 res = nrf5_erase_page(bank, chip, &bank->sectors[s]);
775
776 return res;
777 }
778
779 static int nrf5_code_flash_write(struct flash_bank *bank,
780 struct nrf5_info *chip,
781 const uint8_t *buffer, uint32_t offset, uint32_t count)
782 {
783
784 int res;
785 /* Need to perform reads to fill any gaps we need to preserve in the first page,
786 before the start of buffer, or in the last page, after the end of buffer */
787 uint32_t first_page = offset/chip->code_page_size;
788 uint32_t last_page = DIV_ROUND_UP(offset+count, chip->code_page_size);
789
790 uint32_t first_page_offset = first_page * chip->code_page_size;
791 uint32_t last_page_offset = last_page * chip->code_page_size;
792
793 LOG_DEBUG("Padding write from 0x%08"PRIx32"-0x%08"PRIx32" as 0x%08"PRIx32"-0x%08"PRIx32,
794 offset, offset+count, first_page_offset, last_page_offset);
795
796 uint32_t page_cnt = last_page - first_page;
797 uint8_t buffer_to_flash[page_cnt*chip->code_page_size];
798
799 /* Fill in any space between start of first page and start of buffer */
800 uint32_t pre = offset - first_page_offset;
801 if (pre > 0) {
802 res = target_read_memory(bank->target,
803 first_page_offset,
804 1,
805 pre,
806 buffer_to_flash);
807 if (res != ERROR_OK)
808 return res;
809 }
810
811 /* Fill in main contents of buffer */
812 memcpy(buffer_to_flash+pre, buffer, count);
813
814 /* Fill in any space between end of buffer and end of last page */
815 uint32_t post = last_page_offset - (offset+count);
816 if (post > 0) {
817 /* Retrieve the full row contents from Flash */
818 res = target_read_memory(bank->target,
819 offset + count,
820 1,
821 post,
822 buffer_to_flash+pre+count);
823 if (res != ERROR_OK)
824 return res;
825 }
826
827 return nrf5_write_pages(bank, first_page_offset, last_page_offset, buffer_to_flash);
828 }
829
830 static int nrf5_uicr_flash_write(struct flash_bank *bank,
831 struct nrf5_info *chip,
832 const uint8_t *buffer, uint32_t offset, uint32_t count)
833 {
834 int res;
835 uint8_t uicr[NRF5_UICR_SIZE];
836 struct flash_sector *sector = &bank->sectors[0];
837
838 if ((offset + count) > NRF5_UICR_SIZE)
839 return ERROR_FAIL;
840
841 res = target_read_memory(bank->target,
842 NRF5_UICR_BASE,
843 1,
844 NRF5_UICR_SIZE,
845 uicr);
846
847 if (res != ERROR_OK)
848 return res;
849
850 res = nrf5_erase_page(bank, chip, sector);
851 if (res != ERROR_OK)
852 return res;
853
854 res = nrf5_nvmc_write_enable(chip);
855 if (res != ERROR_OK)
856 return res;
857
858 memcpy(&uicr[offset], buffer, count);
859
860 res = nrf5_ll_flash_write(chip, NRF5_UICR_BASE, uicr, NRF5_UICR_SIZE);
861 if (res != ERROR_OK) {
862 nrf5_nvmc_read_only(chip);
863 return res;
864 }
865
866 return nrf5_nvmc_read_only(chip);
867 }
868
869
870 static int nrf5_write(struct flash_bank *bank, const uint8_t *buffer,
871 uint32_t offset, uint32_t count)
872 {
873 int res;
874 struct nrf5_info *chip;
875
876 res = nrf5_get_probed_chip_if_halted(bank, &chip);
877 if (res != ERROR_OK)
878 return res;
879
880 return chip->bank[bank->bank_number].write(bank, chip, buffer, offset, count);
881 }
882
883 static void nrf5_free_driver_priv(struct flash_bank *bank)
884 {
885 struct nrf5_info *chip = bank->driver_priv;
886 if (chip == NULL)
887 return;
888
889 chip->refcount--;
890 if (chip->refcount == 0) {
891 free(chip);
892 bank->driver_priv = NULL;
893 }
894 }
895
896 FLASH_BANK_COMMAND_HANDLER(nrf5_flash_bank_command)
897 {
898 static struct nrf5_info *chip;
899
900 switch (bank->base) {
901 case NRF5_FLASH_BASE:
902 bank->bank_number = 0;
903 break;
904 case NRF5_UICR_BASE:
905 bank->bank_number = 1;
906 break;
907 default:
908 LOG_ERROR("Invalid bank address 0x%08" PRIx32, bank->base);
909 return ERROR_FAIL;
910 }
911
912 if (!chip) {
913 /* Create a new chip */
914 chip = calloc(1, sizeof(*chip));
915 if (!chip)
916 return ERROR_FAIL;
917
918 chip->target = bank->target;
919 }
920
921 switch (bank->base) {
922 case NRF5_FLASH_BASE:
923 chip->bank[bank->bank_number].write = nrf5_code_flash_write;
924 break;
925 case NRF5_UICR_BASE:
926 chip->bank[bank->bank_number].write = nrf5_uicr_flash_write;
927 break;
928 }
929
930 chip->refcount++;
931 chip->bank[bank->bank_number].probed = false;
932 bank->driver_priv = chip;
933
934 return ERROR_OK;
935 }
936
937 COMMAND_HANDLER(nrf5_handle_mass_erase_command)
938 {
939 int res;
940 struct flash_bank *bank = NULL;
941 struct target *target = get_current_target(CMD_CTX);
942
943 res = get_flash_bank_by_addr(target, NRF5_FLASH_BASE, true, &bank);
944 if (res != ERROR_OK)
945 return res;
946
947 assert(bank != NULL);
948
949 struct nrf5_info *chip;
950
951 res = nrf5_get_probed_chip_if_halted(bank, &chip);
952 if (res != ERROR_OK)
953 return res;
954
955 uint32_t ppfc;
956
957 res = target_read_u32(target, NRF5_FICR_PPFC,
958 &ppfc);
959 if (res != ERROR_OK) {
960 LOG_ERROR("Couldn't read PPFC register");
961 return res;
962 }
963
964 if ((ppfc & 0xFF) == 0x00) {
965 LOG_ERROR("Code region 0 size was pre-programmed at the factory, "
966 "mass erase command won't work.");
967 return ERROR_FAIL;
968 }
969
970 res = nrf5_erase_all(chip);
971 if (res != ERROR_OK) {
972 LOG_ERROR("Failed to erase the chip");
973 nrf5_protect_check(bank);
974 return res;
975 }
976
977 res = nrf5_protect_check(bank);
978 if (res != ERROR_OK) {
979 LOG_ERROR("Failed to check chip's write protection");
980 return res;
981 }
982
983 res = get_flash_bank_by_addr(target, NRF5_UICR_BASE, true, &bank);
984 if (res != ERROR_OK)
985 return res;
986
987 return ERROR_OK;
988 }
989
990 static int nrf5_info(struct flash_bank *bank, char *buf, int buf_size)
991 {
992 int res;
993
994 struct nrf5_info *chip;
995
996 res = nrf5_get_probed_chip_if_halted(bank, &chip);
997 if (res != ERROR_OK)
998 return res;
999
1000 static struct {
1001 const uint32_t address;
1002 uint32_t value;
1003 } ficr[] = {
1004 { .address = NRF5_FICR_CODEPAGESIZE },
1005 { .address = NRF5_FICR_CODESIZE },
1006 { .address = NRF5_FICR_CLENR0 },
1007 { .address = NRF5_FICR_PPFC },
1008 { .address = NRF5_FICR_NUMRAMBLOCK },
1009 { .address = NRF5_FICR_SIZERAMBLOCK0 },
1010 { .address = NRF5_FICR_SIZERAMBLOCK1 },
1011 { .address = NRF5_FICR_SIZERAMBLOCK2 },
1012 { .address = NRF5_FICR_SIZERAMBLOCK3 },
1013 { .address = NRF5_FICR_CONFIGID },
1014 { .address = NRF5_FICR_DEVICEID0 },
1015 { .address = NRF5_FICR_DEVICEID1 },
1016 { .address = NRF5_FICR_ER0 },
1017 { .address = NRF5_FICR_ER1 },
1018 { .address = NRF5_FICR_ER2 },
1019 { .address = NRF5_FICR_ER3 },
1020 { .address = NRF5_FICR_IR0 },
1021 { .address = NRF5_FICR_IR1 },
1022 { .address = NRF5_FICR_IR2 },
1023 { .address = NRF5_FICR_IR3 },
1024 { .address = NRF5_FICR_DEVICEADDRTYPE },
1025 { .address = NRF5_FICR_DEVICEADDR0 },
1026 { .address = NRF5_FICR_DEVICEADDR1 },
1027 { .address = NRF5_FICR_OVERRIDEN },
1028 { .address = NRF5_FICR_NRF_1MBIT0 },
1029 { .address = NRF5_FICR_NRF_1MBIT1 },
1030 { .address = NRF5_FICR_NRF_1MBIT2 },
1031 { .address = NRF5_FICR_NRF_1MBIT3 },
1032 { .address = NRF5_FICR_NRF_1MBIT4 },
1033 { .address = NRF5_FICR_BLE_1MBIT0 },
1034 { .address = NRF5_FICR_BLE_1MBIT1 },
1035 { .address = NRF5_FICR_BLE_1MBIT2 },
1036 { .address = NRF5_FICR_BLE_1MBIT3 },
1037 { .address = NRF5_FICR_BLE_1MBIT4 },
1038 }, uicr[] = {
1039 { .address = NRF5_UICR_CLENR0, },
1040 { .address = NRF5_UICR_RBPCONF },
1041 { .address = NRF5_UICR_XTALFREQ },
1042 { .address = NRF5_UICR_FWID },
1043 };
1044
1045 for (size_t i = 0; i < ARRAY_SIZE(ficr); i++) {
1046 res = target_read_u32(chip->target, ficr[i].address,
1047 &ficr[i].value);
1048 if (res != ERROR_OK) {
1049 LOG_ERROR("Couldn't read %" PRIx32, ficr[i].address);
1050 return res;
1051 }
1052 }
1053
1054 for (size_t i = 0; i < ARRAY_SIZE(uicr); i++) {
1055 res = target_read_u32(chip->target, uicr[i].address,
1056 &uicr[i].value);
1057 if (res != ERROR_OK) {
1058 LOG_ERROR("Couldn't read %" PRIx32, uicr[i].address);
1059 return res;
1060 }
1061 }
1062
1063 snprintf(buf, buf_size,
1064 "\n[factory information control block]\n\n"
1065 "code page size: %"PRIu32"B\n"
1066 "code memory size: %"PRIu32"kB\n"
1067 "code region 0 size: %"PRIu32"kB\n"
1068 "pre-programmed code: %s\n"
1069 "number of ram blocks: %"PRIu32"\n"
1070 "ram block 0 size: %"PRIu32"B\n"
1071 "ram block 1 size: %"PRIu32"B\n"
1072 "ram block 2 size: %"PRIu32"B\n"
1073 "ram block 3 size: %"PRIu32 "B\n"
1074 "config id: %" PRIx32 "\n"
1075 "device id: 0x%"PRIx32"%08"PRIx32"\n"
1076 "encryption root: 0x%08"PRIx32"%08"PRIx32"%08"PRIx32"%08"PRIx32"\n"
1077 "identity root: 0x%08"PRIx32"%08"PRIx32"%08"PRIx32"%08"PRIx32"\n"
1078 "device address type: 0x%"PRIx32"\n"
1079 "device address: 0x%"PRIx32"%08"PRIx32"\n"
1080 "override enable: %"PRIx32"\n"
1081 "NRF_1MBIT values: %"PRIx32" %"PRIx32" %"PRIx32" %"PRIx32" %"PRIx32"\n"
1082 "BLE_1MBIT values: %"PRIx32" %"PRIx32" %"PRIx32" %"PRIx32" %"PRIx32"\n"
1083 "\n[user information control block]\n\n"
1084 "code region 0 size: %"PRIu32"kB\n"
1085 "read back protection configuration: %"PRIx32"\n"
1086 "reset value for XTALFREQ: %"PRIx32"\n"
1087 "firmware id: 0x%04"PRIx32,
1088 ficr[0].value,
1089 (ficr[1].value * ficr[0].value) / 1024,
1090 (ficr[2].value == 0xFFFFFFFF) ? 0 : ficr[2].value / 1024,
1091 ((ficr[3].value & 0xFF) == 0x00) ? "present" : "not present",
1092 ficr[4].value,
1093 ficr[5].value,
1094 (ficr[6].value == 0xFFFFFFFF) ? 0 : ficr[6].value,
1095 (ficr[7].value == 0xFFFFFFFF) ? 0 : ficr[7].value,
1096 (ficr[8].value == 0xFFFFFFFF) ? 0 : ficr[8].value,
1097 ficr[9].value,
1098 ficr[10].value, ficr[11].value,
1099 ficr[12].value, ficr[13].value, ficr[14].value, ficr[15].value,
1100 ficr[16].value, ficr[17].value, ficr[18].value, ficr[19].value,
1101 ficr[20].value,
1102 ficr[21].value, ficr[22].value,
1103 ficr[23].value,
1104 ficr[24].value, ficr[25].value, ficr[26].value, ficr[27].value, ficr[28].value,
1105 ficr[29].value, ficr[30].value, ficr[31].value, ficr[32].value, ficr[33].value,
1106 (uicr[0].value == 0xFFFFFFFF) ? 0 : uicr[0].value / 1024,
1107 uicr[1].value & 0xFFFF,
1108 uicr[2].value & 0xFF,
1109 uicr[3].value & 0xFFFF);
1110
1111 return ERROR_OK;
1112 }
1113
1114 static const struct command_registration nrf5_exec_command_handlers[] = {
1115 {
1116 .name = "mass_erase",
1117 .handler = nrf5_handle_mass_erase_command,
1118 .mode = COMMAND_EXEC,
1119 .help = "Erase all flash contents of the chip.",
1120 },
1121 COMMAND_REGISTRATION_DONE
1122 };
1123
1124 static const struct command_registration nrf5_command_handlers[] = {
1125 {
1126 .name = "nrf5",
1127 .mode = COMMAND_ANY,
1128 .help = "nrf5 flash command group",
1129 .usage = "",
1130 .chain = nrf5_exec_command_handlers,
1131 },
1132 {
1133 .name = "nrf51",
1134 .mode = COMMAND_ANY,
1135 .help = "nrf51 flash command group",
1136 .usage = "",
1137 .chain = nrf5_exec_command_handlers,
1138 },
1139 COMMAND_REGISTRATION_DONE
1140 };
1141
1142 struct flash_driver nrf5_flash = {
1143 .name = "nrf5",
1144 .commands = nrf5_command_handlers,
1145 .flash_bank_command = nrf5_flash_bank_command,
1146 .info = nrf5_info,
1147 .erase = nrf5_erase,
1148 .protect = nrf5_protect,
1149 .write = nrf5_write,
1150 .read = default_flash_read,
1151 .probe = nrf5_probe,
1152 .auto_probe = nrf5_auto_probe,
1153 .erase_check = default_flash_blank_check,
1154 .protect_check = nrf5_protect_check,
1155 .free_driver_priv = nrf5_free_driver_priv,
1156 };
1157
1158 /* We need to retain the flash-driver name as well as the commands
1159 * for backwards compatability */
1160 struct flash_driver nrf51_flash = {
1161 .name = "nrf51",
1162 .commands = nrf5_command_handlers,
1163 .flash_bank_command = nrf5_flash_bank_command,
1164 .info = nrf5_info,
1165 .erase = nrf5_erase,
1166 .protect = nrf5_protect,
1167 .write = nrf5_write,
1168 .read = default_flash_read,
1169 .probe = nrf5_probe,
1170 .auto_probe = nrf5_auto_probe,
1171 .erase_check = default_flash_blank_check,
1172 .protect_check = nrf5_protect_check,
1173 .free_driver_priv = nrf5_free_driver_priv,
1174 };

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)