jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / flash / nor / efm32.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4 * Copyright (C) 2005 by Dominic Rath *
5 * Dominic.Rath@gmx.de *
6 * *
7 * Copyright (C) 2008 by Spencer Oliver *
8 * spen@spen-soft.co.uk *
9 * *
10 * Copyright (C) 2011 by Andreas Fritiofson *
11 * andreas.fritiofson@gmail.com *
12 * *
13 * Copyright (C) 2013 by Roman Dmitrienko *
14 * me@iamroman.org *
15 * *
16 * Copyright (C) 2014 Nemui Trinomius *
17 * nemuisan_kawausogasuki@live.jp *
18 * *
19 * Copyright (C) 2021 Doug Brunner *
20 * doug.a.brunner@gmail.com *
21 ***************************************************************************/
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "imp.h"
28 #include <helper/binarybuffer.h>
29 #include <target/algorithm.h>
30 #include <target/armv7m.h>
31 #include <target/cortex_m.h>
32
33 #define EFM_FAMILY_ID_GIANT_GECKO 72
34 #define EFM_FAMILY_ID_LEOPARD_GECKO 74
35
36 #define EFM32_FLASH_ERASE_TMO 100
37 #define EFM32_FLASH_WDATAREADY_TMO 100
38 #define EFM32_FLASH_WRITE_TMO 100
39
40 #define EFM32_FLASH_BASE 0
41
42 /* size in bytes, not words; must fit all Gecko devices */
43 #define LOCKWORDS_SZ 512
44
45 #define EFM32_MSC_INFO_BASE 0x0fe00000
46
47 #define EFM32_MSC_USER_DATA EFM32_MSC_INFO_BASE
48 #define EFM32_MSC_LOCK_BITS (EFM32_MSC_INFO_BASE+0x4000)
49 #define EFM32_MSC_LOCK_BITS_EXTRA (EFM32_MSC_LOCK_BITS+LOCKWORDS_SZ)
50 #define EFM32_MSC_DEV_INFO (EFM32_MSC_INFO_BASE+0x8000)
51
52 /* PAGE_SIZE is not present in Zero, Happy and the original Gecko MCU */
53 #define EFM32_MSC_DI_PAGE_SIZE (EFM32_MSC_DEV_INFO+0x1e7)
54 #define EFM32_MSC_DI_FLASH_SZ (EFM32_MSC_DEV_INFO+0x1f8)
55 #define EFM32_MSC_DI_RAM_SZ (EFM32_MSC_DEV_INFO+0x1fa)
56 #define EFM32_MSC_DI_PART_NUM (EFM32_MSC_DEV_INFO+0x1fc)
57 #define EFM32_MSC_DI_PART_FAMILY (EFM32_MSC_DEV_INFO+0x1fe)
58 #define EFM32_MSC_DI_PROD_REV (EFM32_MSC_DEV_INFO+0x1ff)
59
60 #define EFM32_MSC_REGBASE 0x400c0000
61 #define EFM32_MSC_REGBASE_SERIES1 0x400e0000
62 #define EFM32_MSC_REG_WRITECTRL 0x008
63 #define EFM32_MSC_WRITECTRL_WREN_MASK 0x1
64 #define EFM32_MSC_REG_WRITECMD 0x00c
65 #define EFM32_MSC_WRITECMD_LADDRIM_MASK 0x1
66 #define EFM32_MSC_WRITECMD_ERASEPAGE_MASK 0x2
67 #define EFM32_MSC_WRITECMD_WRITEONCE_MASK 0x8
68 #define EFM32_MSC_REG_ADDRB 0x010
69 #define EFM32_MSC_REG_WDATA 0x018
70 #define EFM32_MSC_REG_STATUS 0x01c
71 #define EFM32_MSC_STATUS_BUSY_MASK 0x1
72 #define EFM32_MSC_STATUS_LOCKED_MASK 0x2
73 #define EFM32_MSC_STATUS_INVADDR_MASK 0x4
74 #define EFM32_MSC_STATUS_WDATAREADY_MASK 0x8
75 #define EFM32_MSC_STATUS_WORDTIMEOUT_MASK 0x10
76 #define EFM32_MSC_STATUS_ERASEABORTED_MASK 0x20
77 #define EFM32_MSC_REG_LOCK 0x03c
78 #define EFM32_MSC_REG_LOCK_SERIES1 0x040
79 #define EFM32_MSC_LOCK_LOCKKEY 0x1b71
80
81 enum efm32_bank_index {
82 EFM32_BANK_INDEX_MAIN,
83 EFM32_BANK_INDEX_USER_DATA,
84 EFM32_BANK_INDEX_LOCK_BITS,
85 EFM32_N_BANKS
86 };
87
88 static int efm32x_get_bank_index(target_addr_t base)
89 {
90 switch (base) {
91 case EFM32_FLASH_BASE:
92 return EFM32_BANK_INDEX_MAIN;
93 case EFM32_MSC_USER_DATA:
94 return EFM32_BANK_INDEX_USER_DATA;
95 case EFM32_MSC_LOCK_BITS:
96 return EFM32_BANK_INDEX_LOCK_BITS;
97 default:
98 return ERROR_FAIL;
99 }
100 }
101
102 struct efm32_family_data {
103 int family_id;
104 const char *name;
105
106 /* EFM32 series (EFM32LG995F is the "old" series 0, while EFR32MG12P132
107 is the "new" series 1). Determines location of MSC registers. */
108 int series;
109
110 /* Page size in bytes, or 0 to read from EFM32_MSC_DI_PAGE_SIZE */
111 int page_size;
112
113 /* MSC register base address, or 0 to use default */
114 uint32_t msc_regbase;
115 };
116
117 struct efm32_info {
118 const struct efm32_family_data *family_data;
119 uint16_t flash_sz_kib;
120 uint16_t ram_sz_kib;
121 uint16_t part_num;
122 uint8_t part_family;
123 uint8_t prod_rev;
124 uint16_t page_size;
125 };
126
127 struct efm32x_flash_chip {
128 struct efm32_info info;
129 bool probed[EFM32_N_BANKS];
130 uint32_t lb_page[LOCKWORDS_SZ/4];
131 uint32_t reg_base;
132 uint32_t reg_lock;
133 uint32_t refcount;
134 };
135
136 static const struct efm32_family_data efm32_families[] = {
137 { 16, "EFR32MG1P Mighty", .series = 1 },
138 { 17, "EFR32MG1B Mighty", .series = 1 },
139 { 18, "EFR32MG1V Mighty", .series = 1 },
140 { 19, "EFR32BG1P Blue", .series = 1 },
141 { 20, "EFR32BG1B Blue", .series = 1 },
142 { 21, "EFR32BG1V Blue", .series = 1 },
143 { 25, "EFR32FG1P Flex", .series = 1 },
144 { 26, "EFR32FG1B Flex", .series = 1 },
145 { 27, "EFR32FG1V Flex", .series = 1 },
146 { 28, "EFR32MG2P Mighty", .series = 1 },
147 { 29, "EFR32MG2B Mighty", .series = 1 },
148 { 30, "EFR32MG2V Mighty", .series = 1 },
149 { 31, "EFR32BG12P Blue", .series = 1 },
150 { 32, "EFR32BG12B Blue", .series = 1 },
151 { 33, "EFR32BG12V Blue", .series = 1 },
152 { 37, "EFR32FG12P Flex", .series = 1 },
153 { 38, "EFR32FG12B Flex", .series = 1 },
154 { 39, "EFR32FG12V Flex", .series = 1 },
155 { 40, "EFR32MG13P Mighty", .series = 1 },
156 { 41, "EFR32MG13B Mighty", .series = 1 },
157 { 42, "EFR32MG13V Mighty", .series = 1 },
158 { 43, "EFR32BG13P Blue", .series = 1 },
159 { 44, "EFR32BG13B Blue", .series = 1 },
160 { 45, "EFR32BG13V Blue", .series = 1 },
161 { 46, "EFR32ZG13P Zen", .series = 1 },
162 { 49, "EFR32FG13P Flex", .series = 1 },
163 { 50, "EFR32FG13B Flex", .series = 1 },
164 { 51, "EFR32FG13V Flex", .series = 1 },
165 { 52, "EFR32MG14P Mighty", .series = 1 },
166 { 53, "EFR32MG14B Mighty", .series = 1 },
167 { 54, "EFR32MG14V Mighty", .series = 1 },
168 { 55, "EFR32BG14P Blue", .series = 1 },
169 { 56, "EFR32BG14B Blue", .series = 1 },
170 { 57, "EFR32BG14V Blue", .series = 1 },
171 { 58, "EFR32ZG14P Zen", .series = 1 },
172 { 61, "EFR32FG14P Flex", .series = 1 },
173 { 62, "EFR32FG14B Flex", .series = 1 },
174 { 63, "EFR32FG14V Flex", .series = 1 },
175 { 71, "EFM32G", .series = 0, .page_size = 512 },
176 { 72, "EFM32GG Giant", .series = 0 },
177 { 73, "EFM32TG Tiny", .series = 0, .page_size = 512 },
178 { 74, "EFM32LG Leopard", .series = 0 },
179 { 75, "EFM32WG Wonder", .series = 0 },
180 { 76, "EFM32ZG Zero", .series = 0, .page_size = 1024 },
181 { 77, "EFM32HG Happy", .series = 0, .page_size = 1024 },
182 { 81, "EFM32PG1B Pearl", .series = 1 },
183 { 83, "EFM32JG1B Jade", .series = 1 },
184 { 85, "EFM32PG12B Pearl", .series = 1 },
185 { 87, "EFM32JG12B Jade", .series = 1 },
186 { 89, "EFM32PG13B Pearl", .series = 1 },
187 { 91, "EFM32JG13B Jade", .series = 1 },
188 { 100, "EFM32GG11B Giant", .series = 1, .msc_regbase = 0x40000000 },
189 { 103, "EFM32TG11B Tiny", .series = 1, .msc_regbase = 0x40000000 },
190 { 106, "EFM32GG12B Giant", .series = 1, .msc_regbase = 0x40000000 },
191 { 120, "EZR32WG Wonder", .series = 0 },
192 { 121, "EZR32LG Leopard", .series = 0 },
193 { 122, "EZR32HG Happy", .series = 0, .page_size = 1024 },
194 };
195
196 const struct flash_driver efm32_flash;
197
198 static int efm32x_priv_write(struct flash_bank *bank, const uint8_t *buffer,
199 uint32_t addr, uint32_t count);
200
201 static int efm32x_write_only_lockbits(struct flash_bank *bank);
202
203 static int efm32x_get_flash_size(struct flash_bank *bank, uint16_t *flash_sz)
204 {
205 return target_read_u16(bank->target, EFM32_MSC_DI_FLASH_SZ, flash_sz);
206 }
207
208 static int efm32x_get_ram_size(struct flash_bank *bank, uint16_t *ram_sz)
209 {
210 return target_read_u16(bank->target, EFM32_MSC_DI_RAM_SZ, ram_sz);
211 }
212
213 static int efm32x_get_part_num(struct flash_bank *bank, uint16_t *pnum)
214 {
215 return target_read_u16(bank->target, EFM32_MSC_DI_PART_NUM, pnum);
216 }
217
218 static int efm32x_get_part_family(struct flash_bank *bank, uint8_t *pfamily)
219 {
220 return target_read_u8(bank->target, EFM32_MSC_DI_PART_FAMILY, pfamily);
221 }
222
223 static int efm32x_get_prod_rev(struct flash_bank *bank, uint8_t *prev)
224 {
225 return target_read_u8(bank->target, EFM32_MSC_DI_PROD_REV, prev);
226 }
227
228 static int efm32x_read_reg_u32(struct flash_bank *bank, target_addr_t offset,
229 uint32_t *value)
230 {
231 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
232 uint32_t base = efm32x_info->reg_base;
233
234 return target_read_u32(bank->target, base + offset, value);
235 }
236
237 static int efm32x_write_reg_u32(struct flash_bank *bank, target_addr_t offset,
238 uint32_t value)
239 {
240 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
241 uint32_t base = efm32x_info->reg_base;
242
243 return target_write_u32(bank->target, base + offset, value);
244 }
245
246 static int efm32x_read_info(struct flash_bank *bank)
247 {
248 int ret;
249 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
250 struct efm32_info *efm32_info = &(efm32x_info->info);
251
252 memset(efm32_info, 0, sizeof(struct efm32_info));
253
254 ret = efm32x_get_flash_size(bank, &(efm32_info->flash_sz_kib));
255 if (ret != ERROR_OK)
256 return ret;
257
258 ret = efm32x_get_ram_size(bank, &(efm32_info->ram_sz_kib));
259 if (ret != ERROR_OK)
260 return ret;
261
262 ret = efm32x_get_part_num(bank, &(efm32_info->part_num));
263 if (ret != ERROR_OK)
264 return ret;
265
266 ret = efm32x_get_part_family(bank, &(efm32_info->part_family));
267 if (ret != ERROR_OK)
268 return ret;
269
270 ret = efm32x_get_prod_rev(bank, &(efm32_info->prod_rev));
271 if (ret != ERROR_OK)
272 return ret;
273
274 for (size_t i = 0; i < ARRAY_SIZE(efm32_families); i++) {
275 if (efm32_families[i].family_id == efm32_info->part_family)
276 efm32_info->family_data = &efm32_families[i];
277 }
278
279 if (!efm32_info->family_data) {
280 LOG_ERROR("Unknown MCU family %d", efm32_info->part_family);
281 return ERROR_FAIL;
282 }
283
284 switch (efm32_info->family_data->series) {
285 case 0:
286 efm32x_info->reg_base = EFM32_MSC_REGBASE;
287 efm32x_info->reg_lock = EFM32_MSC_REG_LOCK;
288 break;
289 case 1:
290 efm32x_info->reg_base = EFM32_MSC_REGBASE_SERIES1;
291 efm32x_info->reg_lock = EFM32_MSC_REG_LOCK_SERIES1;
292 break;
293 }
294
295 if (efm32_info->family_data->msc_regbase != 0)
296 efm32x_info->reg_base = efm32_info->family_data->msc_regbase;
297
298 if (efm32_info->family_data->page_size != 0) {
299 efm32_info->page_size = efm32_info->family_data->page_size;
300 } else {
301 uint8_t pg_size = 0;
302 ret = target_read_u8(bank->target, EFM32_MSC_DI_PAGE_SIZE,
303 &pg_size);
304 if (ret != ERROR_OK)
305 return ret;
306
307 efm32_info->page_size = (1 << ((pg_size+10) & 0xff));
308
309 if (efm32_info->part_family == EFM_FAMILY_ID_GIANT_GECKO ||
310 efm32_info->part_family == EFM_FAMILY_ID_LEOPARD_GECKO) {
311 /* Giant or Leopard Gecko */
312 if (efm32_info->prod_rev < 18) {
313 /* EFM32 GG/LG errata: MEM_INFO_PAGE_SIZE is invalid
314 for MCUs with PROD_REV < 18 */
315 if (efm32_info->flash_sz_kib < 512)
316 efm32_info->page_size = 2048;
317 else
318 efm32_info->page_size = 4096;
319 }
320 }
321
322 if ((efm32_info->page_size != 2048) &&
323 (efm32_info->page_size != 4096)) {
324 LOG_ERROR("Invalid page size %u", efm32_info->page_size);
325 return ERROR_FAIL;
326 }
327 }
328
329 return ERROR_OK;
330 }
331
332 /* flash bank efm32 <base> <size> 0 0 <target#> */
333 FLASH_BANK_COMMAND_HANDLER(efm32x_flash_bank_command)
334 {
335 struct efm32x_flash_chip *efm32x_info = NULL;
336
337 if (CMD_ARGC < 6)
338 return ERROR_COMMAND_SYNTAX_ERROR;
339
340 int bank_index = efm32x_get_bank_index(bank->base);
341 if (bank_index < 0) {
342 LOG_ERROR("Flash bank with base address %" PRIx32 " is not supported",
343 (uint32_t) bank->base);
344 return ERROR_FAIL;
345 }
346
347 /* look for an existing flash structure matching target */
348 for (struct flash_bank *bank_iter = flash_bank_list(); bank_iter; bank_iter = bank_iter->next) {
349 if (bank_iter->driver == &efm32_flash
350 && bank_iter->target == bank->target
351 && bank->driver_priv) {
352 efm32x_info = bank->driver_priv;
353 break;
354 }
355 }
356
357 if (!efm32x_info) {
358 /* target not matched, make a new one */
359 efm32x_info = calloc(1, sizeof(struct efm32x_flash_chip));
360
361 memset(efm32x_info->lb_page, 0xff, LOCKWORDS_SZ);
362 }
363
364 ++efm32x_info->refcount;
365 bank->driver_priv = efm32x_info;
366
367 return ERROR_OK;
368 }
369
370 /**
371 * Remove flash structure corresponding to this bank,
372 * if and only if it's not used by any others
373 */
374 static void efm32x_free_driver_priv(struct flash_bank *bank)
375 {
376 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
377
378 if (efm32x_info) {
379 /* Use ref count to determine if it can be freed; scanning bank list doesn't work,
380 * because this function can be called after some banks in the list have been
381 * already destroyed */
382 --efm32x_info->refcount;
383 if (efm32x_info->refcount == 0) {
384 free(efm32x_info);
385 bank->driver_priv = NULL;
386 }
387 }
388 }
389
390 /* set or reset given bits in a register */
391 static int efm32x_set_reg_bits(struct flash_bank *bank, uint32_t reg,
392 uint32_t bitmask, int set)
393 {
394 int ret = 0;
395 uint32_t reg_val = 0;
396
397 ret = efm32x_read_reg_u32(bank, reg, &reg_val);
398 if (ret != ERROR_OK)
399 return ret;
400
401 if (set)
402 reg_val |= bitmask;
403 else
404 reg_val &= ~bitmask;
405
406 return efm32x_write_reg_u32(bank, reg, reg_val);
407 }
408
409 static int efm32x_set_wren(struct flash_bank *bank, int write_enable)
410 {
411 return efm32x_set_reg_bits(bank, EFM32_MSC_REG_WRITECTRL,
412 EFM32_MSC_WRITECTRL_WREN_MASK, write_enable);
413 }
414
415 static int efm32x_msc_lock(struct flash_bank *bank, int lock)
416 {
417 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
418 return efm32x_write_reg_u32(bank, efm32x_info->reg_lock,
419 (lock ? 0 : EFM32_MSC_LOCK_LOCKKEY));
420 }
421
422 static int efm32x_wait_status(struct flash_bank *bank, int timeout,
423 uint32_t wait_mask, int wait_for_set)
424 {
425 int ret = 0;
426 uint32_t status = 0;
427
428 while (1) {
429 ret = efm32x_read_reg_u32(bank, EFM32_MSC_REG_STATUS, &status);
430 if (ret != ERROR_OK)
431 break;
432
433 LOG_DEBUG("status: 0x%" PRIx32 "", status);
434
435 if (((status & wait_mask) == 0) && (wait_for_set == 0))
436 break;
437 else if (((status & wait_mask) != 0) && wait_for_set)
438 break;
439
440 if (timeout-- <= 0) {
441 LOG_ERROR("timed out waiting for MSC status");
442 return ERROR_FAIL;
443 }
444
445 alive_sleep(1);
446 }
447
448 if (status & EFM32_MSC_STATUS_ERASEABORTED_MASK)
449 LOG_WARNING("page erase was aborted");
450
451 return ret;
452 }
453
454 static int efm32x_erase_page(struct flash_bank *bank, uint32_t addr)
455 {
456 /* this function DOES NOT set WREN; must be set already */
457 /* 1. write address to ADDRB
458 2. write LADDRIM
459 3. check status (INVADDR, LOCKED)
460 4. write ERASEPAGE
461 5. wait until !STATUS_BUSY
462 */
463 int ret = 0;
464 uint32_t status = 0;
465 LOG_DEBUG("erasing flash page at 0x%08" PRIx32, addr);
466
467 ret = efm32x_write_reg_u32(bank, EFM32_MSC_REG_ADDRB, addr);
468 if (ret != ERROR_OK)
469 return ret;
470
471 ret = efm32x_set_reg_bits(bank, EFM32_MSC_REG_WRITECMD,
472 EFM32_MSC_WRITECMD_LADDRIM_MASK, 1);
473 if (ret != ERROR_OK)
474 return ret;
475
476 ret = efm32x_read_reg_u32(bank, EFM32_MSC_REG_STATUS, &status);
477 if (ret != ERROR_OK)
478 return ret;
479
480 LOG_DEBUG("status 0x%" PRIx32, status);
481
482 if (status & EFM32_MSC_STATUS_LOCKED_MASK) {
483 LOG_ERROR("Page is locked");
484 return ERROR_FAIL;
485 } else if (status & EFM32_MSC_STATUS_INVADDR_MASK) {
486 LOG_ERROR("Invalid address 0x%" PRIx32, addr);
487 return ERROR_FAIL;
488 }
489
490 ret = efm32x_set_reg_bits(bank, EFM32_MSC_REG_WRITECMD,
491 EFM32_MSC_WRITECMD_ERASEPAGE_MASK, 1);
492 if (ret != ERROR_OK)
493 return ret;
494
495 return efm32x_wait_status(bank, EFM32_FLASH_ERASE_TMO,
496 EFM32_MSC_STATUS_BUSY_MASK, 0);
497 }
498
499 static int efm32x_erase(struct flash_bank *bank, unsigned int first,
500 unsigned int last)
501 {
502 struct target *target = bank->target;
503 int ret = 0;
504
505 if (target->state != TARGET_HALTED) {
506 LOG_ERROR("Target not halted");
507 return ERROR_TARGET_NOT_HALTED;
508 }
509
510 efm32x_msc_lock(bank, 0);
511 ret = efm32x_set_wren(bank, 1);
512 if (ret != ERROR_OK) {
513 LOG_ERROR("Failed to enable MSC write");
514 return ret;
515 }
516
517 for (unsigned int i = first; i <= last; i++) {
518 ret = efm32x_erase_page(bank, bank->base + bank->sectors[i].offset);
519 if (ret != ERROR_OK)
520 LOG_ERROR("Failed to erase page %d", i);
521 }
522
523 ret = efm32x_set_wren(bank, 0);
524 efm32x_msc_lock(bank, 1);
525 if (ret != ERROR_OK)
526 return ret;
527
528 if (bank->base == EFM32_MSC_LOCK_BITS) {
529 ret = efm32x_write_only_lockbits(bank);
530 if (ret != ERROR_OK)
531 LOG_ERROR("Failed to restore lockbits after erase");
532 }
533
534 return ret;
535 }
536
537 static int efm32x_read_lock_data(struct flash_bank *bank)
538 {
539 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
540 struct target *target = bank->target;
541 int data_size = 0;
542 uint32_t *ptr = NULL;
543 int ret = 0;
544
545 assert(bank->num_sectors > 0);
546
547 /* calculate the number of 32-bit words to read (one lock bit per sector) */
548 data_size = (bank->num_sectors + 31) / 32;
549
550 ptr = efm32x_info->lb_page;
551
552 for (int i = 0; i < data_size; i++, ptr++) {
553 ret = target_read_u32(target, EFM32_MSC_LOCK_BITS+i*4, ptr);
554 if (ret != ERROR_OK) {
555 LOG_ERROR("Failed to read PLW %d", i);
556 return ret;
557 }
558 }
559
560 /* also, read ULW, DLW, MLW, ALW and CLW words */
561
562 /* ULW, word 126 */
563 ptr = efm32x_info->lb_page + 126;
564 ret = target_read_u32(target, EFM32_MSC_LOCK_BITS+126*4, ptr);
565 if (ret != ERROR_OK) {
566 LOG_ERROR("Failed to read ULW");
567 return ret;
568 }
569
570 /* DLW, word 127 */
571 ptr = efm32x_info->lb_page + 127;
572 ret = target_read_u32(target, EFM32_MSC_LOCK_BITS+127*4, ptr);
573 if (ret != ERROR_OK) {
574 LOG_ERROR("Failed to read DLW");
575 return ret;
576 }
577
578 /* MLW, word 125, present in GG, LG, PG, JG, EFR32 */
579 ptr = efm32x_info->lb_page + 125;
580 ret = target_read_u32(target, EFM32_MSC_LOCK_BITS+125*4, ptr);
581 if (ret != ERROR_OK) {
582 LOG_ERROR("Failed to read MLW");
583 return ret;
584 }
585
586 /* ALW, word 124, present in GG, LG, PG, JG, EFR32 */
587 ptr = efm32x_info->lb_page + 124;
588 ret = target_read_u32(target, EFM32_MSC_LOCK_BITS+124*4, ptr);
589 if (ret != ERROR_OK) {
590 LOG_ERROR("Failed to read ALW");
591 return ret;
592 }
593
594 /* CLW1, word 123, present in EFR32 */
595 ptr = efm32x_info->lb_page + 123;
596 ret = target_read_u32(target, EFM32_MSC_LOCK_BITS+123*4, ptr);
597 if (ret != ERROR_OK) {
598 LOG_ERROR("Failed to read CLW1");
599 return ret;
600 }
601
602 /* CLW0, word 122, present in GG, LG, PG, JG, EFR32 */
603 ptr = efm32x_info->lb_page + 122;
604 ret = target_read_u32(target, EFM32_MSC_LOCK_BITS+122*4, ptr);
605 if (ret != ERROR_OK) {
606 LOG_ERROR("Failed to read CLW0");
607 return ret;
608 }
609
610 return ERROR_OK;
611 }
612
613 static int efm32x_write_only_lockbits(struct flash_bank *bank)
614 {
615 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
616 return efm32x_priv_write(bank, (uint8_t *)efm32x_info->lb_page, EFM32_MSC_LOCK_BITS, LOCKWORDS_SZ);
617 }
618
619 static int efm32x_write_lock_data(struct flash_bank *bank)
620 {
621 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
622 int ret = 0;
623
624 /* Preserve any data written to the high portion of the lockbits page */
625 assert(efm32x_info->info.page_size >= LOCKWORDS_SZ);
626 uint32_t extra_bytes = efm32x_info->info.page_size - LOCKWORDS_SZ;
627 uint8_t *extra_data = NULL;
628 if (extra_bytes) {
629 extra_data = malloc(extra_bytes);
630 ret = target_read_buffer(bank->target, EFM32_MSC_LOCK_BITS_EXTRA, extra_bytes, extra_data);
631 if (ret != ERROR_OK) {
632 LOG_ERROR("Failed to read extra contents of LB page");
633 free(extra_data);
634 return ret;
635 }
636 }
637
638 ret = efm32x_erase_page(bank, EFM32_MSC_LOCK_BITS);
639 if (ret != ERROR_OK) {
640 LOG_ERROR("Failed to erase LB page");
641 if (extra_data)
642 free(extra_data);
643 return ret;
644 }
645
646 if (extra_data) {
647 ret = efm32x_priv_write(bank, extra_data, EFM32_MSC_LOCK_BITS_EXTRA, extra_bytes);
648 free(extra_data);
649 if (ret != ERROR_OK) {
650 LOG_ERROR("Failed to restore extra contents of LB page");
651 return ret;
652 }
653 }
654
655 return efm32x_write_only_lockbits(bank);
656 }
657
658 static int efm32x_get_page_lock(struct flash_bank *bank, size_t page)
659 {
660 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
661 uint32_t dw = 0;
662 uint32_t mask = 0;
663
664 switch (bank->base) {
665 case EFM32_FLASH_BASE:
666 dw = efm32x_info->lb_page[page >> 5];
667 mask = 1 << (page & 0x1f);
668 break;
669 case EFM32_MSC_USER_DATA:
670 dw = efm32x_info->lb_page[126];
671 mask = 0x1;
672 break;
673 case EFM32_MSC_LOCK_BITS:
674 dw = efm32x_info->lb_page[126];
675 mask = 0x2;
676 break;
677 }
678
679 return (dw & mask) ? 0 : 1;
680 }
681
682 static int efm32x_set_page_lock(struct flash_bank *bank, size_t page, int set)
683 {
684 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
685
686 if (bank->base != EFM32_FLASH_BASE) {
687 LOG_ERROR("Locking user and lockbits pages is not supported yet");
688 return ERROR_FAIL;
689 }
690
691 uint32_t *dw = &efm32x_info->lb_page[page >> 5];
692 uint32_t mask = 0;
693
694 mask = 1 << (page & 0x1f);
695
696 if (!set)
697 *dw |= mask;
698 else
699 *dw &= ~mask;
700
701 return ERROR_OK;
702 }
703
704 static int efm32x_protect(struct flash_bank *bank, int set, unsigned int first,
705 unsigned int last)
706 {
707 struct target *target = bank->target;
708 int ret = 0;
709
710 if (target->state != TARGET_HALTED) {
711 LOG_ERROR("Target not halted");
712 return ERROR_TARGET_NOT_HALTED;
713 }
714
715 for (unsigned int i = first; i <= last; i++) {
716 ret = efm32x_set_page_lock(bank, i, set);
717 if (ret != ERROR_OK) {
718 LOG_ERROR("Failed to set lock on page %d", i);
719 return ret;
720 }
721 }
722
723 ret = efm32x_write_lock_data(bank);
724 if (ret != ERROR_OK) {
725 LOG_ERROR("Failed to write LB page");
726 return ret;
727 }
728
729 return ERROR_OK;
730 }
731
732 static int efm32x_write_block(struct flash_bank *bank, const uint8_t *buf,
733 uint32_t address, uint32_t count)
734 {
735 struct target *target = bank->target;
736 uint32_t buffer_size = 16384;
737 struct working_area *write_algorithm;
738 struct working_area *source;
739 struct reg_param reg_params[5];
740 struct armv7m_algorithm armv7m_info;
741 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
742 int ret = ERROR_OK;
743
744 /* see contrib/loaders/flash/efm32.S for src */
745 static const uint8_t efm32x_flash_write_code[] = {
746 /* #define EFM32_MSC_WRITECTRL_OFFSET 0x008 */
747 /* #define EFM32_MSC_WRITECMD_OFFSET 0x00c */
748 /* #define EFM32_MSC_ADDRB_OFFSET 0x010 */
749 /* #define EFM32_MSC_WDATA_OFFSET 0x018 */
750 /* #define EFM32_MSC_STATUS_OFFSET 0x01c */
751
752 0x01, 0x26, /* movs r6, #1 */
753 0x86, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECTRL_OFFSET] */
754
755 /* wait_fifo: */
756 0x16, 0x68, /* ldr r6, [r2, #0] */
757 0x00, 0x2e, /* cmp r6, #0 */
758 0x22, 0xd0, /* beq exit */
759 0x55, 0x68, /* ldr r5, [r2, #4] */
760 0xb5, 0x42, /* cmp r5, r6 */
761 0xf9, 0xd0, /* beq wait_fifo */
762
763 0x04, 0x61, /* str r4, [r0, #EFM32_MSC_ADDRB_OFFSET] */
764 0x01, 0x26, /* movs r6, #1 */
765 0xc6, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] */
766 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
767 0x06, 0x27, /* movs r7, #6 */
768 0x3e, 0x42, /* tst r6, r7 */
769 0x16, 0xd1, /* bne error */
770
771 /* wait_wdataready: */
772 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
773 0x08, 0x27, /* movs r7, #8 */
774 0x3e, 0x42, /* tst r6, r7 */
775 0xfb, 0xd0, /* beq wait_wdataready */
776
777 0x2e, 0x68, /* ldr r6, [r5] */
778 0x86, 0x61, /* str r6, [r0, #EFM32_MSC_WDATA_OFFSET] */
779 0x08, 0x26, /* movs r6, #8 */
780 0xc6, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] */
781
782 0x04, 0x35, /* adds r5, #4 */
783 0x04, 0x34, /* adds r4, #4 */
784
785 /* busy: */
786 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
787 0x01, 0x27, /* movs r7, #1 */
788 0x3e, 0x42, /* tst r6, r7 */
789 0xfb, 0xd1, /* bne busy */
790
791 0x9d, 0x42, /* cmp r5, r3 */
792 0x01, 0xd3, /* bcc no_wrap */
793 0x15, 0x46, /* mov r5, r2 */
794 0x08, 0x35, /* adds r5, #8 */
795
796 /* no_wrap: */
797 0x55, 0x60, /* str r5, [r2, #4] */
798 0x01, 0x39, /* subs r1, r1, #1 */
799 0x00, 0x29, /* cmp r1, #0 */
800 0x02, 0xd0, /* beq exit */
801 0xdb, 0xe7, /* b wait_fifo */
802
803 /* error: */
804 0x00, 0x20, /* movs r0, #0 */
805 0x50, 0x60, /* str r0, [r2, #4] */
806
807 /* exit: */
808 0x30, 0x46, /* mov r0, r6 */
809 0x00, 0xbe, /* bkpt #0 */
810 };
811
812
813 /* flash write code */
814 if (target_alloc_working_area(target, sizeof(efm32x_flash_write_code),
815 &write_algorithm) != ERROR_OK) {
816 LOG_WARNING("no working area available, can't do block memory writes");
817 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
818 }
819
820 ret = target_write_buffer(target, write_algorithm->address,
821 sizeof(efm32x_flash_write_code), efm32x_flash_write_code);
822 if (ret != ERROR_OK)
823 return ret;
824
825 /* memory buffer */
826 while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {
827 buffer_size /= 2;
828 buffer_size &= ~3UL; /* Make sure it's 4 byte aligned */
829 if (buffer_size <= 256) {
830 /* we already allocated the writing code, but failed to get a
831 * buffer, free the algorithm */
832 target_free_working_area(target, write_algorithm);
833
834 LOG_WARNING("no large enough working area available, can't do block memory writes");
835 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
836 }
837 }
838
839 init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* flash base (in), status (out) */
840 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* count (word-32bit) */
841 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* buffer start */
842 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT); /* buffer end */
843 init_reg_param(&reg_params[4], "r4", 32, PARAM_IN_OUT); /* target address */
844
845 buf_set_u32(reg_params[0].value, 0, 32, efm32x_info->reg_base);
846 buf_set_u32(reg_params[1].value, 0, 32, count);
847 buf_set_u32(reg_params[2].value, 0, 32, source->address);
848 buf_set_u32(reg_params[3].value, 0, 32, source->address + source->size);
849 buf_set_u32(reg_params[4].value, 0, 32, address);
850
851 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
852 armv7m_info.core_mode = ARM_MODE_THREAD;
853
854 ret = target_run_flash_async_algorithm(target, buf, count, 4,
855 0, NULL,
856 5, reg_params,
857 source->address, source->size,
858 write_algorithm->address, 0,
859 &armv7m_info);
860
861 if (ret == ERROR_FLASH_OPERATION_FAILED) {
862 LOG_ERROR("flash write failed at address 0x%"PRIx32,
863 buf_get_u32(reg_params[4].value, 0, 32));
864
865 if (buf_get_u32(reg_params[0].value, 0, 32) &
866 EFM32_MSC_STATUS_LOCKED_MASK) {
867 LOG_ERROR("flash memory write protected");
868 }
869
870 if (buf_get_u32(reg_params[0].value, 0, 32) &
871 EFM32_MSC_STATUS_INVADDR_MASK) {
872 LOG_ERROR("invalid flash memory write address");
873 }
874 }
875
876 target_free_working_area(target, source);
877 target_free_working_area(target, write_algorithm);
878
879 destroy_reg_param(&reg_params[0]);
880 destroy_reg_param(&reg_params[1]);
881 destroy_reg_param(&reg_params[2]);
882 destroy_reg_param(&reg_params[3]);
883 destroy_reg_param(&reg_params[4]);
884
885 return ret;
886 }
887
888 static int efm32x_write_word(struct flash_bank *bank, uint32_t addr,
889 uint32_t val)
890 {
891 /* this function DOES NOT set WREN; must be set already */
892 /* 1. write address to ADDRB
893 2. write LADDRIM
894 3. check status (INVADDR, LOCKED)
895 4. wait for WDATAREADY
896 5. write data to WDATA
897 6. write WRITECMD_WRITEONCE to WRITECMD
898 7. wait until !STATUS_BUSY
899 */
900
901 /* FIXME: EFM32G ref states (7.3.2) that writes should be
902 * performed twice per dword */
903
904 int ret = 0;
905 uint32_t status = 0;
906
907 /* if not called, GDB errors will be reported during large writes */
908 keep_alive();
909
910 ret = efm32x_write_reg_u32(bank, EFM32_MSC_REG_ADDRB, addr);
911 if (ret != ERROR_OK)
912 return ret;
913
914 ret = efm32x_set_reg_bits(bank, EFM32_MSC_REG_WRITECMD,
915 EFM32_MSC_WRITECMD_LADDRIM_MASK, 1);
916 if (ret != ERROR_OK)
917 return ret;
918
919 ret = efm32x_read_reg_u32(bank, EFM32_MSC_REG_STATUS, &status);
920 if (ret != ERROR_OK)
921 return ret;
922
923 LOG_DEBUG("status 0x%" PRIx32, status);
924
925 if (status & EFM32_MSC_STATUS_LOCKED_MASK) {
926 LOG_ERROR("Page is locked");
927 return ERROR_FAIL;
928 } else if (status & EFM32_MSC_STATUS_INVADDR_MASK) {
929 LOG_ERROR("Invalid address 0x%" PRIx32, addr);
930 return ERROR_FAIL;
931 }
932
933 ret = efm32x_wait_status(bank, EFM32_FLASH_WDATAREADY_TMO,
934 EFM32_MSC_STATUS_WDATAREADY_MASK, 1);
935 if (ret != ERROR_OK) {
936 LOG_ERROR("Wait for WDATAREADY failed");
937 return ret;
938 }
939
940 ret = efm32x_write_reg_u32(bank, EFM32_MSC_REG_WDATA, val);
941 if (ret != ERROR_OK) {
942 LOG_ERROR("WDATA write failed");
943 return ret;
944 }
945
946 ret = efm32x_write_reg_u32(bank, EFM32_MSC_REG_WRITECMD,
947 EFM32_MSC_WRITECMD_WRITEONCE_MASK);
948 if (ret != ERROR_OK) {
949 LOG_ERROR("WRITECMD write failed");
950 return ret;
951 }
952
953 ret = efm32x_wait_status(bank, EFM32_FLASH_WRITE_TMO,
954 EFM32_MSC_STATUS_BUSY_MASK, 0);
955 if (ret != ERROR_OK) {
956 LOG_ERROR("Wait for BUSY failed");
957 return ret;
958 }
959
960 return ERROR_OK;
961 }
962
963 static int efm32x_priv_write(struct flash_bank *bank, const uint8_t *buffer,
964 uint32_t addr, uint32_t count)
965 {
966 struct target *target = bank->target;
967 uint8_t *new_buffer = NULL;
968
969 if (target->state != TARGET_HALTED) {
970 LOG_ERROR("Target not halted");
971 return ERROR_TARGET_NOT_HALTED;
972 }
973
974 if (addr & 0x3) {
975 LOG_ERROR("addr 0x%" PRIx32 " breaks required 4-byte "
976 "alignment", addr);
977 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
978 }
979
980 if (count & 0x3) {
981 uint32_t old_count = count;
982 count = (old_count | 3) + 1;
983 new_buffer = malloc(count);
984 if (!new_buffer) {
985 LOG_ERROR("odd number of bytes to write and no memory "
986 "for padding buffer");
987 return ERROR_FAIL;
988 }
989 LOG_INFO("odd number of bytes to write (%" PRIu32 "), extending to %" PRIu32 " "
990 "and padding with 0xff", old_count, count);
991 memset(new_buffer, 0xff, count);
992 buffer = memcpy(new_buffer, buffer, old_count);
993 }
994
995 uint32_t words_remaining = count / 4;
996 int retval, retval2;
997
998 /* unlock flash registers */
999 efm32x_msc_lock(bank, 0);
1000 retval = efm32x_set_wren(bank, 1);
1001 if (retval != ERROR_OK)
1002 goto cleanup;
1003
1004 /* try using a block write */
1005 retval = efm32x_write_block(bank, buffer, addr, words_remaining);
1006
1007 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
1008 /* if block write failed (no sufficient working area),
1009 * we use normal (slow) single word accesses */
1010 LOG_WARNING("couldn't use block writes, falling back to single "
1011 "memory accesses");
1012
1013 while (words_remaining > 0) {
1014 uint32_t value;
1015 memcpy(&value, buffer, sizeof(uint32_t));
1016
1017 retval = efm32x_write_word(bank, addr, value);
1018 if (retval != ERROR_OK)
1019 goto reset_pg_and_lock;
1020
1021 words_remaining--;
1022 buffer += 4;
1023 addr += 4;
1024 }
1025 }
1026
1027 reset_pg_and_lock:
1028 retval2 = efm32x_set_wren(bank, 0);
1029 efm32x_msc_lock(bank, 1);
1030 if (retval == ERROR_OK)
1031 retval = retval2;
1032
1033 cleanup:
1034 free(new_buffer);
1035 return retval;
1036 }
1037
1038 static int efm32x_write(struct flash_bank *bank, const uint8_t *buffer,
1039 uint32_t offset, uint32_t count)
1040 {
1041 if (bank->base == EFM32_MSC_LOCK_BITS && offset < LOCKWORDS_SZ) {
1042 LOG_ERROR("Cannot write to lock words");
1043 return ERROR_FAIL;
1044 }
1045 return efm32x_priv_write(bank, buffer, bank->base + offset, count);
1046 }
1047
1048 static int efm32x_probe(struct flash_bank *bank)
1049 {
1050 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
1051 struct efm32_info *efm32_mcu_info = &(efm32x_info->info);
1052 int ret;
1053
1054 int bank_index = efm32x_get_bank_index(bank->base);
1055 assert(bank_index >= 0);
1056
1057 efm32x_info->probed[bank_index] = false;
1058 memset(efm32x_info->lb_page, 0xff, LOCKWORDS_SZ);
1059
1060 ret = efm32x_read_info(bank);
1061 if (ret != ERROR_OK)
1062 return ret;
1063
1064 LOG_INFO("detected part: %s Gecko, rev %d",
1065 efm32_mcu_info->family_data->name, efm32_mcu_info->prod_rev);
1066 LOG_INFO("flash size = %d KiB", efm32_mcu_info->flash_sz_kib);
1067 LOG_INFO("flash page size = %d B", efm32_mcu_info->page_size);
1068
1069 assert(efm32_mcu_info->page_size != 0);
1070
1071 free(bank->sectors);
1072 bank->sectors = NULL;
1073
1074 if (bank->base == EFM32_FLASH_BASE) {
1075 bank->num_sectors = efm32_mcu_info->flash_sz_kib * 1024 /
1076 efm32_mcu_info->page_size;
1077 assert(bank->num_sectors > 0);
1078
1079 ret = efm32x_read_lock_data(bank);
1080 if (ret != ERROR_OK) {
1081 LOG_ERROR("Failed to read LB data");
1082 return ret;
1083 }
1084 } else
1085 bank->num_sectors = 1;
1086 bank->size = bank->num_sectors * efm32_mcu_info->page_size;
1087 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
1088
1089 for (uint32_t i = 0; i < bank->num_sectors; i++) {
1090 bank->sectors[i].offset = i * efm32_mcu_info->page_size;
1091 bank->sectors[i].size = efm32_mcu_info->page_size;
1092 bank->sectors[i].is_erased = -1;
1093 bank->sectors[i].is_protected = 1;
1094 }
1095
1096 efm32x_info->probed[bank_index] = true;
1097
1098 return ERROR_OK;
1099 }
1100
1101 static int efm32x_auto_probe(struct flash_bank *bank)
1102 {
1103 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
1104
1105 int bank_index = efm32x_get_bank_index(bank->base);
1106 assert(bank_index >= 0);
1107
1108 if (efm32x_info->probed[bank_index])
1109 return ERROR_OK;
1110 return efm32x_probe(bank);
1111 }
1112
1113 static int efm32x_protect_check(struct flash_bank *bank)
1114 {
1115 struct target *target = bank->target;
1116 int ret = 0;
1117
1118 if (target->state != TARGET_HALTED) {
1119 LOG_ERROR("Target not halted");
1120 return ERROR_TARGET_NOT_HALTED;
1121 }
1122
1123 ret = efm32x_read_lock_data(bank);
1124 if (ret != ERROR_OK) {
1125 LOG_ERROR("Failed to read LB data");
1126 return ret;
1127 }
1128
1129 assert(bank->sectors);
1130
1131 for (unsigned int i = 0; i < bank->num_sectors; i++)
1132 bank->sectors[i].is_protected = efm32x_get_page_lock(bank, i);
1133
1134 return ERROR_OK;
1135 }
1136
1137 static int get_efm32x_info(struct flash_bank *bank, struct command_invocation *cmd)
1138 {
1139 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
1140 int ret;
1141
1142 ret = efm32x_read_info(bank);
1143 if (ret != ERROR_OK) {
1144 LOG_ERROR("Failed to read EFM32 info");
1145 return ret;
1146 }
1147
1148 command_print_sameline(cmd, "%s Gecko, rev %d", efm32x_info->info.family_data->name,
1149 efm32x_info->info.prod_rev);
1150 return ERROR_OK;
1151 }
1152
1153 COMMAND_HANDLER(efm32x_handle_debuglock_command)
1154 {
1155 struct target *target = NULL;
1156
1157 if (CMD_ARGC < 1)
1158 return ERROR_COMMAND_SYNTAX_ERROR;
1159
1160 struct flash_bank *bank;
1161 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1162 if (retval != ERROR_OK)
1163 return retval;
1164
1165 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
1166
1167 target = bank->target;
1168
1169 if (target->state != TARGET_HALTED) {
1170 LOG_ERROR("Target not halted");
1171 return ERROR_TARGET_NOT_HALTED;
1172 }
1173
1174 uint32_t *ptr;
1175 ptr = efm32x_info->lb_page + 127;
1176 *ptr = 0;
1177
1178 retval = efm32x_write_lock_data(bank);
1179 if (retval != ERROR_OK) {
1180 LOG_ERROR("Failed to write LB page");
1181 return retval;
1182 }
1183
1184 command_print(CMD, "efm32x debug interface locked, reset the device to apply");
1185
1186 return ERROR_OK;
1187 }
1188
1189 static const struct command_registration efm32x_exec_command_handlers[] = {
1190 {
1191 .name = "debuglock",
1192 .handler = efm32x_handle_debuglock_command,
1193 .mode = COMMAND_EXEC,
1194 .usage = "bank_id",
1195 .help = "Lock the debug interface of the device.",
1196 },
1197 COMMAND_REGISTRATION_DONE
1198 };
1199
1200 static const struct command_registration efm32x_command_handlers[] = {
1201 {
1202 .name = "efm32",
1203 .mode = COMMAND_ANY,
1204 .help = "efm32 flash command group",
1205 .usage = "",
1206 .chain = efm32x_exec_command_handlers,
1207 },
1208 COMMAND_REGISTRATION_DONE
1209 };
1210
1211 const struct flash_driver efm32_flash = {
1212 .name = "efm32",
1213 .commands = efm32x_command_handlers,
1214 .flash_bank_command = efm32x_flash_bank_command,
1215 .erase = efm32x_erase,
1216 .protect = efm32x_protect,
1217 .write = efm32x_write,
1218 .read = default_flash_read,
1219 .probe = efm32x_probe,
1220 .auto_probe = efm32x_auto_probe,
1221 .erase_check = default_flash_blank_check,
1222 .protect_check = efm32x_protect_check,
1223 .info = get_efm32x_info,
1224 .free_driver_priv = efm32x_free_driver_priv,
1225 };

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)