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 const struct cortex_m_common *cortex_m = target_to_cm(bank->target);
255
256 switch (cortex_m->core_info->partno) {
257 case CORTEX_M3_PARTNO:
258 case CORTEX_M4_PARTNO:
259 case CORTEX_M0P_PARTNO:
260 break;
261 default:
262 LOG_ERROR("Target is not Cortex-Mx Device");
263 return ERROR_FAIL;
264 }
265
266 ret = efm32x_get_flash_size(bank, &(efm32_info->flash_sz_kib));
267 if (ret != ERROR_OK)
268 return ret;
269
270 ret = efm32x_get_ram_size(bank, &(efm32_info->ram_sz_kib));
271 if (ret != ERROR_OK)
272 return ret;
273
274 ret = efm32x_get_part_num(bank, &(efm32_info->part_num));
275 if (ret != ERROR_OK)
276 return ret;
277
278 ret = efm32x_get_part_family(bank, &(efm32_info->part_family));
279 if (ret != ERROR_OK)
280 return ret;
281
282 ret = efm32x_get_prod_rev(bank, &(efm32_info->prod_rev));
283 if (ret != ERROR_OK)
284 return ret;
285
286 for (size_t i = 0; i < ARRAY_SIZE(efm32_families); i++) {
287 if (efm32_families[i].family_id == efm32_info->part_family)
288 efm32_info->family_data = &efm32_families[i];
289 }
290
291 if (!efm32_info->family_data) {
292 LOG_ERROR("Unknown MCU family %d", efm32_info->part_family);
293 return ERROR_FAIL;
294 }
295
296 switch (efm32_info->family_data->series) {
297 case 0:
298 efm32x_info->reg_base = EFM32_MSC_REGBASE;
299 efm32x_info->reg_lock = EFM32_MSC_REG_LOCK;
300 break;
301 case 1:
302 efm32x_info->reg_base = EFM32_MSC_REGBASE_SERIES1;
303 efm32x_info->reg_lock = EFM32_MSC_REG_LOCK_SERIES1;
304 break;
305 }
306
307 if (efm32_info->family_data->msc_regbase != 0)
308 efm32x_info->reg_base = efm32_info->family_data->msc_regbase;
309
310 if (efm32_info->family_data->page_size != 0) {
311 efm32_info->page_size = efm32_info->family_data->page_size;
312 } else {
313 uint8_t pg_size = 0;
314 ret = target_read_u8(bank->target, EFM32_MSC_DI_PAGE_SIZE,
315 &pg_size);
316 if (ret != ERROR_OK)
317 return ret;
318
319 efm32_info->page_size = (1 << ((pg_size+10) & 0xff));
320
321 if (efm32_info->part_family == EFM_FAMILY_ID_GIANT_GECKO ||
322 efm32_info->part_family == EFM_FAMILY_ID_LEOPARD_GECKO) {
323 /* Giant or Leopard Gecko */
324 if (efm32_info->prod_rev < 18) {
325 /* EFM32 GG/LG errata: MEM_INFO_PAGE_SIZE is invalid
326 for MCUs with PROD_REV < 18 */
327 if (efm32_info->flash_sz_kib < 512)
328 efm32_info->page_size = 2048;
329 else
330 efm32_info->page_size = 4096;
331 }
332 }
333
334 if ((efm32_info->page_size != 2048) &&
335 (efm32_info->page_size != 4096)) {
336 LOG_ERROR("Invalid page size %u", efm32_info->page_size);
337 return ERROR_FAIL;
338 }
339 }
340
341 return ERROR_OK;
342 }
343
344 /* flash bank efm32 <base> <size> 0 0 <target#> */
345 FLASH_BANK_COMMAND_HANDLER(efm32x_flash_bank_command)
346 {
347 struct efm32x_flash_chip *efm32x_info = NULL;
348
349 if (CMD_ARGC < 6)
350 return ERROR_COMMAND_SYNTAX_ERROR;
351
352 int bank_index = efm32x_get_bank_index(bank->base);
353 if (bank_index < 0) {
354 LOG_ERROR("Flash bank with base address %" PRIx32 " is not supported",
355 (uint32_t) bank->base);
356 return ERROR_FAIL;
357 }
358
359 /* look for an existing flash structure matching target */
360 for (struct flash_bank *bank_iter = flash_bank_list(); bank_iter; bank_iter = bank_iter->next) {
361 if (bank_iter->driver == &efm32_flash
362 && bank_iter->target == bank->target
363 && bank->driver_priv) {
364 efm32x_info = bank->driver_priv;
365 break;
366 }
367 }
368
369 if (!efm32x_info) {
370 /* target not matched, make a new one */
371 efm32x_info = calloc(1, sizeof(struct efm32x_flash_chip));
372
373 memset(efm32x_info->lb_page, 0xff, LOCKWORDS_SZ);
374 }
375
376 ++efm32x_info->refcount;
377 bank->driver_priv = efm32x_info;
378
379 return ERROR_OK;
380 }
381
382 /**
383 * Remove flash structure corresponding to this bank,
384 * if and only if it's not used by any others
385 */
386 static void efm32x_free_driver_priv(struct flash_bank *bank)
387 {
388 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
389
390 if (efm32x_info) {
391 /* Use ref count to determine if it can be freed; scanning bank list doesn't work,
392 * because this function can be called after some banks in the list have been
393 * already destroyed */
394 --efm32x_info->refcount;
395 if (efm32x_info->refcount == 0) {
396 free(efm32x_info);
397 bank->driver_priv = NULL;
398 }
399 }
400 }
401
402 /* set or reset given bits in a register */
403 static int efm32x_set_reg_bits(struct flash_bank *bank, uint32_t reg,
404 uint32_t bitmask, int set)
405 {
406 int ret = 0;
407 uint32_t reg_val = 0;
408
409 ret = efm32x_read_reg_u32(bank, reg, &reg_val);
410 if (ret != ERROR_OK)
411 return ret;
412
413 if (set)
414 reg_val |= bitmask;
415 else
416 reg_val &= ~bitmask;
417
418 return efm32x_write_reg_u32(bank, reg, reg_val);
419 }
420
421 static int efm32x_set_wren(struct flash_bank *bank, int write_enable)
422 {
423 return efm32x_set_reg_bits(bank, EFM32_MSC_REG_WRITECTRL,
424 EFM32_MSC_WRITECTRL_WREN_MASK, write_enable);
425 }
426
427 static int efm32x_msc_lock(struct flash_bank *bank, int lock)
428 {
429 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
430 return efm32x_write_reg_u32(bank, efm32x_info->reg_lock,
431 (lock ? 0 : EFM32_MSC_LOCK_LOCKKEY));
432 }
433
434 static int efm32x_wait_status(struct flash_bank *bank, int timeout,
435 uint32_t wait_mask, int wait_for_set)
436 {
437 int ret = 0;
438 uint32_t status = 0;
439
440 while (1) {
441 ret = efm32x_read_reg_u32(bank, EFM32_MSC_REG_STATUS, &status);
442 if (ret != ERROR_OK)
443 break;
444
445 LOG_DEBUG("status: 0x%" PRIx32 "", status);
446
447 if (((status & wait_mask) == 0) && (wait_for_set == 0))
448 break;
449 else if (((status & wait_mask) != 0) && wait_for_set)
450 break;
451
452 if (timeout-- <= 0) {
453 LOG_ERROR("timed out waiting for MSC status");
454 return ERROR_FAIL;
455 }
456
457 alive_sleep(1);
458 }
459
460 if (status & EFM32_MSC_STATUS_ERASEABORTED_MASK)
461 LOG_WARNING("page erase was aborted");
462
463 return ret;
464 }
465
466 static int efm32x_erase_page(struct flash_bank *bank, uint32_t addr)
467 {
468 /* this function DOES NOT set WREN; must be set already */
469 /* 1. write address to ADDRB
470 2. write LADDRIM
471 3. check status (INVADDR, LOCKED)
472 4. write ERASEPAGE
473 5. wait until !STATUS_BUSY
474 */
475 int ret = 0;
476 uint32_t status = 0;
477 LOG_DEBUG("erasing flash page at 0x%08" PRIx32, addr);
478
479 ret = efm32x_write_reg_u32(bank, EFM32_MSC_REG_ADDRB, addr);
480 if (ret != ERROR_OK)
481 return ret;
482
483 ret = efm32x_set_reg_bits(bank, EFM32_MSC_REG_WRITECMD,
484 EFM32_MSC_WRITECMD_LADDRIM_MASK, 1);
485 if (ret != ERROR_OK)
486 return ret;
487
488 ret = efm32x_read_reg_u32(bank, EFM32_MSC_REG_STATUS, &status);
489 if (ret != ERROR_OK)
490 return ret;
491
492 LOG_DEBUG("status 0x%" PRIx32, status);
493
494 if (status & EFM32_MSC_STATUS_LOCKED_MASK) {
495 LOG_ERROR("Page is locked");
496 return ERROR_FAIL;
497 } else if (status & EFM32_MSC_STATUS_INVADDR_MASK) {
498 LOG_ERROR("Invalid address 0x%" PRIx32, addr);
499 return ERROR_FAIL;
500 }
501
502 ret = efm32x_set_reg_bits(bank, EFM32_MSC_REG_WRITECMD,
503 EFM32_MSC_WRITECMD_ERASEPAGE_MASK, 1);
504 if (ret != ERROR_OK)
505 return ret;
506
507 return efm32x_wait_status(bank, EFM32_FLASH_ERASE_TMO,
508 EFM32_MSC_STATUS_BUSY_MASK, 0);
509 }
510
511 static int efm32x_erase(struct flash_bank *bank, unsigned int first,
512 unsigned int last)
513 {
514 struct target *target = bank->target;
515 int ret = 0;
516
517 if (target->state != TARGET_HALTED) {
518 LOG_ERROR("Target not halted");
519 return ERROR_TARGET_NOT_HALTED;
520 }
521
522 efm32x_msc_lock(bank, 0);
523 ret = efm32x_set_wren(bank, 1);
524 if (ret != ERROR_OK) {
525 LOG_ERROR("Failed to enable MSC write");
526 return ret;
527 }
528
529 for (unsigned int i = first; i <= last; i++) {
530 ret = efm32x_erase_page(bank, bank->base + bank->sectors[i].offset);
531 if (ret != ERROR_OK)
532 LOG_ERROR("Failed to erase page %d", i);
533 }
534
535 ret = efm32x_set_wren(bank, 0);
536 efm32x_msc_lock(bank, 1);
537 if (ret != ERROR_OK)
538 return ret;
539
540 if (bank->base == EFM32_MSC_LOCK_BITS) {
541 ret = efm32x_write_only_lockbits(bank);
542 if (ret != ERROR_OK)
543 LOG_ERROR("Failed to restore lockbits after erase");
544 }
545
546 return ret;
547 }
548
549 static int efm32x_read_lock_data(struct flash_bank *bank)
550 {
551 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
552 struct target *target = bank->target;
553 int data_size = 0;
554 uint32_t *ptr = NULL;
555 int ret = 0;
556
557 assert(bank->num_sectors > 0);
558
559 /* calculate the number of 32-bit words to read (one lock bit per sector) */
560 data_size = (bank->num_sectors + 31) / 32;
561
562 ptr = efm32x_info->lb_page;
563
564 for (int i = 0; i < data_size; i++, ptr++) {
565 ret = target_read_u32(target, EFM32_MSC_LOCK_BITS+i*4, ptr);
566 if (ret != ERROR_OK) {
567 LOG_ERROR("Failed to read PLW %d", i);
568 return ret;
569 }
570 }
571
572 /* also, read ULW, DLW, MLW, ALW and CLW words */
573
574 /* ULW, word 126 */
575 ptr = efm32x_info->lb_page + 126;
576 ret = target_read_u32(target, EFM32_MSC_LOCK_BITS+126*4, ptr);
577 if (ret != ERROR_OK) {
578 LOG_ERROR("Failed to read ULW");
579 return ret;
580 }
581
582 /* DLW, word 127 */
583 ptr = efm32x_info->lb_page + 127;
584 ret = target_read_u32(target, EFM32_MSC_LOCK_BITS+127*4, ptr);
585 if (ret != ERROR_OK) {
586 LOG_ERROR("Failed to read DLW");
587 return ret;
588 }
589
590 /* MLW, word 125, present in GG, LG, PG, JG, EFR32 */
591 ptr = efm32x_info->lb_page + 125;
592 ret = target_read_u32(target, EFM32_MSC_LOCK_BITS+125*4, ptr);
593 if (ret != ERROR_OK) {
594 LOG_ERROR("Failed to read MLW");
595 return ret;
596 }
597
598 /* ALW, word 124, present in GG, LG, PG, JG, EFR32 */
599 ptr = efm32x_info->lb_page + 124;
600 ret = target_read_u32(target, EFM32_MSC_LOCK_BITS+124*4, ptr);
601 if (ret != ERROR_OK) {
602 LOG_ERROR("Failed to read ALW");
603 return ret;
604 }
605
606 /* CLW1, word 123, present in EFR32 */
607 ptr = efm32x_info->lb_page + 123;
608 ret = target_read_u32(target, EFM32_MSC_LOCK_BITS+123*4, ptr);
609 if (ret != ERROR_OK) {
610 LOG_ERROR("Failed to read CLW1");
611 return ret;
612 }
613
614 /* CLW0, word 122, present in GG, LG, PG, JG, EFR32 */
615 ptr = efm32x_info->lb_page + 122;
616 ret = target_read_u32(target, EFM32_MSC_LOCK_BITS+122*4, ptr);
617 if (ret != ERROR_OK) {
618 LOG_ERROR("Failed to read CLW0");
619 return ret;
620 }
621
622 return ERROR_OK;
623 }
624
625 static int efm32x_write_only_lockbits(struct flash_bank *bank)
626 {
627 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
628 return efm32x_priv_write(bank, (uint8_t *)efm32x_info->lb_page, EFM32_MSC_LOCK_BITS, LOCKWORDS_SZ);
629 }
630
631 static int efm32x_write_lock_data(struct flash_bank *bank)
632 {
633 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
634 int ret = 0;
635
636 /* Preserve any data written to the high portion of the lockbits page */
637 assert(efm32x_info->info.page_size >= LOCKWORDS_SZ);
638 uint32_t extra_bytes = efm32x_info->info.page_size - LOCKWORDS_SZ;
639 uint8_t *extra_data = NULL;
640 if (extra_bytes) {
641 extra_data = malloc(extra_bytes);
642 ret = target_read_buffer(bank->target, EFM32_MSC_LOCK_BITS_EXTRA, extra_bytes, extra_data);
643 if (ret != ERROR_OK) {
644 LOG_ERROR("Failed to read extra contents of LB page");
645 free(extra_data);
646 return ret;
647 }
648 }
649
650 ret = efm32x_erase_page(bank, EFM32_MSC_LOCK_BITS);
651 if (ret != ERROR_OK) {
652 LOG_ERROR("Failed to erase LB page");
653 if (extra_data)
654 free(extra_data);
655 return ret;
656 }
657
658 if (extra_data) {
659 ret = efm32x_priv_write(bank, extra_data, EFM32_MSC_LOCK_BITS_EXTRA, extra_bytes);
660 free(extra_data);
661 if (ret != ERROR_OK) {
662 LOG_ERROR("Failed to restore extra contents of LB page");
663 return ret;
664 }
665 }
666
667 return efm32x_write_only_lockbits(bank);
668 }
669
670 static int efm32x_get_page_lock(struct flash_bank *bank, size_t page)
671 {
672 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
673 uint32_t dw = 0;
674 uint32_t mask = 0;
675
676 switch (bank->base) {
677 case EFM32_FLASH_BASE:
678 dw = efm32x_info->lb_page[page >> 5];
679 mask = 1 << (page & 0x1f);
680 break;
681 case EFM32_MSC_USER_DATA:
682 dw = efm32x_info->lb_page[126];
683 mask = 0x1;
684 break;
685 case EFM32_MSC_LOCK_BITS:
686 dw = efm32x_info->lb_page[126];
687 mask = 0x2;
688 break;
689 }
690
691 return (dw & mask) ? 0 : 1;
692 }
693
694 static int efm32x_set_page_lock(struct flash_bank *bank, size_t page, int set)
695 {
696 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
697
698 if (bank->base != EFM32_FLASH_BASE) {
699 LOG_ERROR("Locking user and lockbits pages is not supported yet");
700 return ERROR_FAIL;
701 }
702
703 uint32_t *dw = &efm32x_info->lb_page[page >> 5];
704 uint32_t mask = 0;
705
706 mask = 1 << (page & 0x1f);
707
708 if (!set)
709 *dw |= mask;
710 else
711 *dw &= ~mask;
712
713 return ERROR_OK;
714 }
715
716 static int efm32x_protect(struct flash_bank *bank, int set, unsigned int first,
717 unsigned int last)
718 {
719 struct target *target = bank->target;
720 int ret = 0;
721
722 if (target->state != TARGET_HALTED) {
723 LOG_ERROR("Target not halted");
724 return ERROR_TARGET_NOT_HALTED;
725 }
726
727 for (unsigned int i = first; i <= last; i++) {
728 ret = efm32x_set_page_lock(bank, i, set);
729 if (ret != ERROR_OK) {
730 LOG_ERROR("Failed to set lock on page %d", i);
731 return ret;
732 }
733 }
734
735 ret = efm32x_write_lock_data(bank);
736 if (ret != ERROR_OK) {
737 LOG_ERROR("Failed to write LB page");
738 return ret;
739 }
740
741 return ERROR_OK;
742 }
743
744 static int efm32x_write_block(struct flash_bank *bank, const uint8_t *buf,
745 uint32_t address, uint32_t count)
746 {
747 struct target *target = bank->target;
748 uint32_t buffer_size = 16384;
749 struct working_area *write_algorithm;
750 struct working_area *source;
751 struct reg_param reg_params[5];
752 struct armv7m_algorithm armv7m_info;
753 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
754 int ret = ERROR_OK;
755
756 /* see contrib/loaders/flash/efm32.S for src */
757 static const uint8_t efm32x_flash_write_code[] = {
758 /* #define EFM32_MSC_WRITECTRL_OFFSET 0x008 */
759 /* #define EFM32_MSC_WRITECMD_OFFSET 0x00c */
760 /* #define EFM32_MSC_ADDRB_OFFSET 0x010 */
761 /* #define EFM32_MSC_WDATA_OFFSET 0x018 */
762 /* #define EFM32_MSC_STATUS_OFFSET 0x01c */
763
764 0x01, 0x26, /* movs r6, #1 */
765 0x86, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECTRL_OFFSET] */
766
767 /* wait_fifo: */
768 0x16, 0x68, /* ldr r6, [r2, #0] */
769 0x00, 0x2e, /* cmp r6, #0 */
770 0x22, 0xd0, /* beq exit */
771 0x55, 0x68, /* ldr r5, [r2, #4] */
772 0xb5, 0x42, /* cmp r5, r6 */
773 0xf9, 0xd0, /* beq wait_fifo */
774
775 0x04, 0x61, /* str r4, [r0, #EFM32_MSC_ADDRB_OFFSET] */
776 0x01, 0x26, /* movs r6, #1 */
777 0xc6, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] */
778 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
779 0x06, 0x27, /* movs r7, #6 */
780 0x3e, 0x42, /* tst r6, r7 */
781 0x16, 0xd1, /* bne error */
782
783 /* wait_wdataready: */
784 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
785 0x08, 0x27, /* movs r7, #8 */
786 0x3e, 0x42, /* tst r6, r7 */
787 0xfb, 0xd0, /* beq wait_wdataready */
788
789 0x2e, 0x68, /* ldr r6, [r5] */
790 0x86, 0x61, /* str r6, [r0, #EFM32_MSC_WDATA_OFFSET] */
791 0x08, 0x26, /* movs r6, #8 */
792 0xc6, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] */
793
794 0x04, 0x35, /* adds r5, #4 */
795 0x04, 0x34, /* adds r4, #4 */
796
797 /* busy: */
798 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
799 0x01, 0x27, /* movs r7, #1 */
800 0x3e, 0x42, /* tst r6, r7 */
801 0xfb, 0xd1, /* bne busy */
802
803 0x9d, 0x42, /* cmp r5, r3 */
804 0x01, 0xd3, /* bcc no_wrap */
805 0x15, 0x46, /* mov r5, r2 */
806 0x08, 0x35, /* adds r5, #8 */
807
808 /* no_wrap: */
809 0x55, 0x60, /* str r5, [r2, #4] */
810 0x01, 0x39, /* subs r1, r1, #1 */
811 0x00, 0x29, /* cmp r1, #0 */
812 0x02, 0xd0, /* beq exit */
813 0xdb, 0xe7, /* b wait_fifo */
814
815 /* error: */
816 0x00, 0x20, /* movs r0, #0 */
817 0x50, 0x60, /* str r0, [r2, #4] */
818
819 /* exit: */
820 0x30, 0x46, /* mov r0, r6 */
821 0x00, 0xbe, /* bkpt #0 */
822 };
823
824
825 /* flash write code */
826 if (target_alloc_working_area(target, sizeof(efm32x_flash_write_code),
827 &write_algorithm) != ERROR_OK) {
828 LOG_WARNING("no working area available, can't do block memory writes");
829 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
830 }
831
832 ret = target_write_buffer(target, write_algorithm->address,
833 sizeof(efm32x_flash_write_code), efm32x_flash_write_code);
834 if (ret != ERROR_OK)
835 return ret;
836
837 /* memory buffer */
838 while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {
839 buffer_size /= 2;
840 buffer_size &= ~3UL; /* Make sure it's 4 byte aligned */
841 if (buffer_size <= 256) {
842 /* we already allocated the writing code, but failed to get a
843 * buffer, free the algorithm */
844 target_free_working_area(target, write_algorithm);
845
846 LOG_WARNING("no large enough working area available, can't do block memory writes");
847 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
848 }
849 }
850
851 init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* flash base (in), status (out) */
852 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* count (word-32bit) */
853 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* buffer start */
854 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT); /* buffer end */
855 init_reg_param(&reg_params[4], "r4", 32, PARAM_IN_OUT); /* target address */
856
857 buf_set_u32(reg_params[0].value, 0, 32, efm32x_info->reg_base);
858 buf_set_u32(reg_params[1].value, 0, 32, count);
859 buf_set_u32(reg_params[2].value, 0, 32, source->address);
860 buf_set_u32(reg_params[3].value, 0, 32, source->address + source->size);
861 buf_set_u32(reg_params[4].value, 0, 32, address);
862
863 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
864 armv7m_info.core_mode = ARM_MODE_THREAD;
865
866 ret = target_run_flash_async_algorithm(target, buf, count, 4,
867 0, NULL,
868 5, reg_params,
869 source->address, source->size,
870 write_algorithm->address, 0,
871 &armv7m_info);
872
873 if (ret == ERROR_FLASH_OPERATION_FAILED) {
874 LOG_ERROR("flash write failed at address 0x%"PRIx32,
875 buf_get_u32(reg_params[4].value, 0, 32));
876
877 if (buf_get_u32(reg_params[0].value, 0, 32) &
878 EFM32_MSC_STATUS_LOCKED_MASK) {
879 LOG_ERROR("flash memory write protected");
880 }
881
882 if (buf_get_u32(reg_params[0].value, 0, 32) &
883 EFM32_MSC_STATUS_INVADDR_MASK) {
884 LOG_ERROR("invalid flash memory write address");
885 }
886 }
887
888 target_free_working_area(target, source);
889 target_free_working_area(target, write_algorithm);
890
891 destroy_reg_param(&reg_params[0]);
892 destroy_reg_param(&reg_params[1]);
893 destroy_reg_param(&reg_params[2]);
894 destroy_reg_param(&reg_params[3]);
895 destroy_reg_param(&reg_params[4]);
896
897 return ret;
898 }
899
900 static int efm32x_write_word(struct flash_bank *bank, uint32_t addr,
901 uint32_t val)
902 {
903 /* this function DOES NOT set WREN; must be set already */
904 /* 1. write address to ADDRB
905 2. write LADDRIM
906 3. check status (INVADDR, LOCKED)
907 4. wait for WDATAREADY
908 5. write data to WDATA
909 6. write WRITECMD_WRITEONCE to WRITECMD
910 7. wait until !STATUS_BUSY
911 */
912
913 /* FIXME: EFM32G ref states (7.3.2) that writes should be
914 * performed twice per dword */
915
916 int ret = 0;
917 uint32_t status = 0;
918
919 /* if not called, GDB errors will be reported during large writes */
920 keep_alive();
921
922 ret = efm32x_write_reg_u32(bank, EFM32_MSC_REG_ADDRB, addr);
923 if (ret != ERROR_OK)
924 return ret;
925
926 ret = efm32x_set_reg_bits(bank, EFM32_MSC_REG_WRITECMD,
927 EFM32_MSC_WRITECMD_LADDRIM_MASK, 1);
928 if (ret != ERROR_OK)
929 return ret;
930
931 ret = efm32x_read_reg_u32(bank, EFM32_MSC_REG_STATUS, &status);
932 if (ret != ERROR_OK)
933 return ret;
934
935 LOG_DEBUG("status 0x%" PRIx32, status);
936
937 if (status & EFM32_MSC_STATUS_LOCKED_MASK) {
938 LOG_ERROR("Page is locked");
939 return ERROR_FAIL;
940 } else if (status & EFM32_MSC_STATUS_INVADDR_MASK) {
941 LOG_ERROR("Invalid address 0x%" PRIx32, addr);
942 return ERROR_FAIL;
943 }
944
945 ret = efm32x_wait_status(bank, EFM32_FLASH_WDATAREADY_TMO,
946 EFM32_MSC_STATUS_WDATAREADY_MASK, 1);
947 if (ret != ERROR_OK) {
948 LOG_ERROR("Wait for WDATAREADY failed");
949 return ret;
950 }
951
952 ret = efm32x_write_reg_u32(bank, EFM32_MSC_REG_WDATA, val);
953 if (ret != ERROR_OK) {
954 LOG_ERROR("WDATA write failed");
955 return ret;
956 }
957
958 ret = efm32x_write_reg_u32(bank, EFM32_MSC_REG_WRITECMD,
959 EFM32_MSC_WRITECMD_WRITEONCE_MASK);
960 if (ret != ERROR_OK) {
961 LOG_ERROR("WRITECMD write failed");
962 return ret;
963 }
964
965 ret = efm32x_wait_status(bank, EFM32_FLASH_WRITE_TMO,
966 EFM32_MSC_STATUS_BUSY_MASK, 0);
967 if (ret != ERROR_OK) {
968 LOG_ERROR("Wait for BUSY failed");
969 return ret;
970 }
971
972 return ERROR_OK;
973 }
974
975 static int efm32x_priv_write(struct flash_bank *bank, const uint8_t *buffer,
976 uint32_t addr, uint32_t count)
977 {
978 struct target *target = bank->target;
979 uint8_t *new_buffer = NULL;
980
981 if (target->state != TARGET_HALTED) {
982 LOG_ERROR("Target not halted");
983 return ERROR_TARGET_NOT_HALTED;
984 }
985
986 if (addr & 0x3) {
987 LOG_ERROR("addr 0x%" PRIx32 " breaks required 4-byte "
988 "alignment", addr);
989 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
990 }
991
992 if (count & 0x3) {
993 uint32_t old_count = count;
994 count = (old_count | 3) + 1;
995 new_buffer = malloc(count);
996 if (!new_buffer) {
997 LOG_ERROR("odd number of bytes to write and no memory "
998 "for padding buffer");
999 return ERROR_FAIL;
1000 }
1001 LOG_INFO("odd number of bytes to write (%" PRIu32 "), extending to %" PRIu32 " "
1002 "and padding with 0xff", old_count, count);
1003 memset(new_buffer, 0xff, count);
1004 buffer = memcpy(new_buffer, buffer, old_count);
1005 }
1006
1007 uint32_t words_remaining = count / 4;
1008 int retval, retval2;
1009
1010 /* unlock flash registers */
1011 efm32x_msc_lock(bank, 0);
1012 retval = efm32x_set_wren(bank, 1);
1013 if (retval != ERROR_OK)
1014 goto cleanup;
1015
1016 /* try using a block write */
1017 retval = efm32x_write_block(bank, buffer, addr, words_remaining);
1018
1019 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
1020 /* if block write failed (no sufficient working area),
1021 * we use normal (slow) single word accesses */
1022 LOG_WARNING("couldn't use block writes, falling back to single "
1023 "memory accesses");
1024
1025 while (words_remaining > 0) {
1026 uint32_t value;
1027 memcpy(&value, buffer, sizeof(uint32_t));
1028
1029 retval = efm32x_write_word(bank, addr, value);
1030 if (retval != ERROR_OK)
1031 goto reset_pg_and_lock;
1032
1033 words_remaining--;
1034 buffer += 4;
1035 addr += 4;
1036 }
1037 }
1038
1039 reset_pg_and_lock:
1040 retval2 = efm32x_set_wren(bank, 0);
1041 efm32x_msc_lock(bank, 1);
1042 if (retval == ERROR_OK)
1043 retval = retval2;
1044
1045 cleanup:
1046 free(new_buffer);
1047 return retval;
1048 }
1049
1050 static int efm32x_write(struct flash_bank *bank, const uint8_t *buffer,
1051 uint32_t offset, uint32_t count)
1052 {
1053 if (bank->base == EFM32_MSC_LOCK_BITS && offset < LOCKWORDS_SZ) {
1054 LOG_ERROR("Cannot write to lock words");
1055 return ERROR_FAIL;
1056 }
1057 return efm32x_priv_write(bank, buffer, bank->base + offset, count);
1058 }
1059
1060 static int efm32x_probe(struct flash_bank *bank)
1061 {
1062 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
1063 struct efm32_info *efm32_mcu_info = &(efm32x_info->info);
1064 int ret;
1065
1066 int bank_index = efm32x_get_bank_index(bank->base);
1067 assert(bank_index >= 0);
1068
1069 efm32x_info->probed[bank_index] = false;
1070 memset(efm32x_info->lb_page, 0xff, LOCKWORDS_SZ);
1071
1072 ret = efm32x_read_info(bank);
1073 if (ret != ERROR_OK)
1074 return ret;
1075
1076 LOG_INFO("detected part: %s Gecko, rev %d",
1077 efm32_mcu_info->family_data->name, efm32_mcu_info->prod_rev);
1078 LOG_INFO("flash size = %d KiB", efm32_mcu_info->flash_sz_kib);
1079 LOG_INFO("flash page size = %d B", efm32_mcu_info->page_size);
1080
1081 assert(efm32_mcu_info->page_size != 0);
1082
1083 free(bank->sectors);
1084 bank->sectors = NULL;
1085
1086 if (bank->base == EFM32_FLASH_BASE) {
1087 bank->num_sectors = efm32_mcu_info->flash_sz_kib * 1024 /
1088 efm32_mcu_info->page_size;
1089 assert(bank->num_sectors > 0);
1090
1091 ret = efm32x_read_lock_data(bank);
1092 if (ret != ERROR_OK) {
1093 LOG_ERROR("Failed to read LB data");
1094 return ret;
1095 }
1096 } else
1097 bank->num_sectors = 1;
1098 bank->size = bank->num_sectors * efm32_mcu_info->page_size;
1099 bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
1100
1101 for (uint32_t i = 0; i < bank->num_sectors; i++) {
1102 bank->sectors[i].offset = i * efm32_mcu_info->page_size;
1103 bank->sectors[i].size = efm32_mcu_info->page_size;
1104 bank->sectors[i].is_erased = -1;
1105 bank->sectors[i].is_protected = 1;
1106 }
1107
1108 efm32x_info->probed[bank_index] = true;
1109
1110 return ERROR_OK;
1111 }
1112
1113 static int efm32x_auto_probe(struct flash_bank *bank)
1114 {
1115 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
1116
1117 int bank_index = efm32x_get_bank_index(bank->base);
1118 assert(bank_index >= 0);
1119
1120 if (efm32x_info->probed[bank_index])
1121 return ERROR_OK;
1122 return efm32x_probe(bank);
1123 }
1124
1125 static int efm32x_protect_check(struct flash_bank *bank)
1126 {
1127 struct target *target = bank->target;
1128 int ret = 0;
1129
1130 if (target->state != TARGET_HALTED) {
1131 LOG_ERROR("Target not halted");
1132 return ERROR_TARGET_NOT_HALTED;
1133 }
1134
1135 ret = efm32x_read_lock_data(bank);
1136 if (ret != ERROR_OK) {
1137 LOG_ERROR("Failed to read LB data");
1138 return ret;
1139 }
1140
1141 assert(bank->sectors);
1142
1143 for (unsigned int i = 0; i < bank->num_sectors; i++)
1144 bank->sectors[i].is_protected = efm32x_get_page_lock(bank, i);
1145
1146 return ERROR_OK;
1147 }
1148
1149 static int get_efm32x_info(struct flash_bank *bank, struct command_invocation *cmd)
1150 {
1151 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
1152 int ret;
1153
1154 ret = efm32x_read_info(bank);
1155 if (ret != ERROR_OK) {
1156 LOG_ERROR("Failed to read EFM32 info");
1157 return ret;
1158 }
1159
1160 command_print_sameline(cmd, "%s Gecko, rev %d", efm32x_info->info.family_data->name,
1161 efm32x_info->info.prod_rev);
1162 return ERROR_OK;
1163 }
1164
1165 COMMAND_HANDLER(efm32x_handle_debuglock_command)
1166 {
1167 struct target *target = NULL;
1168
1169 if (CMD_ARGC < 1)
1170 return ERROR_COMMAND_SYNTAX_ERROR;
1171
1172 struct flash_bank *bank;
1173 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1174 if (retval != ERROR_OK)
1175 return retval;
1176
1177 struct efm32x_flash_chip *efm32x_info = bank->driver_priv;
1178
1179 target = bank->target;
1180
1181 if (target->state != TARGET_HALTED) {
1182 LOG_ERROR("Target not halted");
1183 return ERROR_TARGET_NOT_HALTED;
1184 }
1185
1186 uint32_t *ptr;
1187 ptr = efm32x_info->lb_page + 127;
1188 *ptr = 0;
1189
1190 retval = efm32x_write_lock_data(bank);
1191 if (retval != ERROR_OK) {
1192 LOG_ERROR("Failed to write LB page");
1193 return retval;
1194 }
1195
1196 command_print(CMD, "efm32x debug interface locked, reset the device to apply");
1197
1198 return ERROR_OK;
1199 }
1200
1201 static const struct command_registration efm32x_exec_command_handlers[] = {
1202 {
1203 .name = "debuglock",
1204 .handler = efm32x_handle_debuglock_command,
1205 .mode = COMMAND_EXEC,
1206 .usage = "bank_id",
1207 .help = "Lock the debug interface of the device.",
1208 },
1209 COMMAND_REGISTRATION_DONE
1210 };
1211
1212 static const struct command_registration efm32x_command_handlers[] = {
1213 {
1214 .name = "efm32",
1215 .mode = COMMAND_ANY,
1216 .help = "efm32 flash command group",
1217 .usage = "",
1218 .chain = efm32x_exec_command_handlers,
1219 },
1220 COMMAND_REGISTRATION_DONE
1221 };
1222
1223 const struct flash_driver efm32_flash = {
1224 .name = "efm32",
1225 .commands = efm32x_command_handlers,
1226 .flash_bank_command = efm32x_flash_bank_command,
1227 .erase = efm32x_erase,
1228 .protect = efm32x_protect,
1229 .write = efm32x_write,
1230 .read = default_flash_read,
1231 .probe = efm32x_probe,
1232 .auto_probe = efm32x_auto_probe,
1233 .erase_check = default_flash_blank_check,
1234 .protect_check = efm32x_protect_check,
1235 .info = get_efm32x_info,
1236 .free_driver_priv = efm32x_free_driver_priv,
1237 };

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)