flash: efm32: Add support for EZR32LG and EZR32WG.
[openocd.git] / src / flash / nor / efm32.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
7 * *
8 * Copyright (C) 2011 by Andreas Fritiofson *
9 * andreas.fritiofson@gmail.com *
10 * *
11 * Copyright (C) 2013 by Roman Dmitrienko *
12 * me@iamroman.org *
13 * *
14 * Copyright (C) 2014 Nemui Trinomius *
15 * nemuisan_kawausogasuki@live.jp *
16 * *
17 * This program is free software; you can redistribute it and/or modify *
18 * it under the terms of the GNU General Public License as published by *
19 * the Free Software Foundation; either version 2 of the License, or *
20 * (at your option) any later version. *
21 * *
22 * This program is distributed in the hope that it will be useful, *
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
25 * GNU General Public License for more details. *
26 * *
27 * You should have received a copy of the GNU General Public License *
28 * along with this program; if not, write to the *
29 * Free Software Foundation, Inc., *
30 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
31 ***************************************************************************/
32
33 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #endif
36
37 #include "imp.h"
38 #include <helper/binarybuffer.h>
39 #include <target/algorithm.h>
40 #include <target/armv7m.h>
41 #include <target/cortex_m.h>
42
43 /* keep family IDs in decimal */
44 #define EFM_FAMILY_ID_GECKO 71
45 #define EFM_FAMILY_ID_GIANT_GECKO 72
46 #define EFM_FAMILY_ID_TINY_GECKO 73
47 #define EFM_FAMILY_ID_LEOPARD_GECKO 74
48 #define EFM_FAMILY_ID_WONDER_GECKO 75
49 #define EFM_FAMILY_ID_ZERO_GECKO 76
50 #define EZR_FAMILY_ID_WONDER_GECKO 120
51 #define EZR_FAMILY_ID_LEOPARD_GECKO 121
52
53 #define EFM32_FLASH_ERASE_TMO 100
54 #define EFM32_FLASH_WDATAREADY_TMO 100
55 #define EFM32_FLASH_WRITE_TMO 100
56
57 /* size in bytes, not words; must fit all Gecko devices */
58 #define LOCKBITS_PAGE_SZ 512
59
60 #define EFM32_MSC_INFO_BASE 0x0fe00000
61
62 #define EFM32_MSC_USER_DATA EFM32_MSC_INFO_BASE
63 #define EFM32_MSC_LOCK_BITS (EFM32_MSC_INFO_BASE+0x4000)
64 #define EFM32_MSC_DEV_INFO (EFM32_MSC_INFO_BASE+0x8000)
65
66 /* PAGE_SIZE is only present in Leopard, Giant and Wonder Gecko MCUs */
67 #define EFM32_MSC_DI_PAGE_SIZE (EFM32_MSC_DEV_INFO+0x1e7)
68 #define EFM32_MSC_DI_FLASH_SZ (EFM32_MSC_DEV_INFO+0x1f8)
69 #define EFM32_MSC_DI_RAM_SZ (EFM32_MSC_DEV_INFO+0x1fa)
70 #define EFM32_MSC_DI_PART_NUM (EFM32_MSC_DEV_INFO+0x1fc)
71 #define EFM32_MSC_DI_PART_FAMILY (EFM32_MSC_DEV_INFO+0x1fe)
72 #define EFM32_MSC_DI_PROD_REV (EFM32_MSC_DEV_INFO+0x1ff)
73
74 #define EFM32_MSC_REGBASE 0x400c0000
75 #define EFM32_MSC_WRITECTRL (EFM32_MSC_REGBASE+0x008)
76 #define EFM32_MSC_WRITECTRL_WREN_MASK 0x1
77 #define EFM32_MSC_WRITECMD (EFM32_MSC_REGBASE+0x00c)
78 #define EFM32_MSC_WRITECMD_LADDRIM_MASK 0x1
79 #define EFM32_MSC_WRITECMD_ERASEPAGE_MASK 0x2
80 #define EFM32_MSC_WRITECMD_WRITEONCE_MASK 0x8
81 #define EFM32_MSC_ADDRB (EFM32_MSC_REGBASE+0x010)
82 #define EFM32_MSC_WDATA (EFM32_MSC_REGBASE+0x018)
83 #define EFM32_MSC_STATUS (EFM32_MSC_REGBASE+0x01c)
84 #define EFM32_MSC_STATUS_BUSY_MASK 0x1
85 #define EFM32_MSC_STATUS_LOCKED_MASK 0x2
86 #define EFM32_MSC_STATUS_INVADDR_MASK 0x4
87 #define EFM32_MSC_STATUS_WDATAREADY_MASK 0x8
88 #define EFM32_MSC_STATUS_WORDTIMEOUT_MASK 0x10
89 #define EFM32_MSC_STATUS_ERASEABORTED_MASK 0x20
90 #define EFM32_MSC_LOCK (EFM32_MSC_REGBASE+0x03c)
91 #define EFM32_MSC_LOCK_LOCKKEY 0x1b71
92
93 struct efm32x_flash_bank {
94 int probed;
95 uint32_t lb_page[LOCKBITS_PAGE_SZ/4];
96 };
97
98 struct efm32_info {
99 uint16_t flash_sz_kib;
100 uint16_t ram_sz_kib;
101 uint16_t part_num;
102 uint8_t part_family;
103 uint8_t prod_rev;
104 uint16_t page_size;
105 };
106
107 static int efm32x_write(struct flash_bank *bank, const uint8_t *buffer,
108 uint32_t offset, uint32_t count);
109
110 static int efm32x_get_flash_size(struct flash_bank *bank, uint16_t *flash_sz)
111 {
112 return target_read_u16(bank->target, EFM32_MSC_DI_FLASH_SZ, flash_sz);
113 }
114
115 static int efm32x_get_ram_size(struct flash_bank *bank, uint16_t *ram_sz)
116 {
117 return target_read_u16(bank->target, EFM32_MSC_DI_RAM_SZ, ram_sz);
118 }
119
120 static int efm32x_get_part_num(struct flash_bank *bank, uint16_t *pnum)
121 {
122 return target_read_u16(bank->target, EFM32_MSC_DI_PART_NUM, pnum);
123 }
124
125 static int efm32x_get_part_family(struct flash_bank *bank, uint8_t *pfamily)
126 {
127 return target_read_u8(bank->target, EFM32_MSC_DI_PART_FAMILY, pfamily);
128 }
129
130 static int efm32x_get_prod_rev(struct flash_bank *bank, uint8_t *prev)
131 {
132 return target_read_u8(bank->target, EFM32_MSC_DI_PROD_REV, prev);
133 }
134
135 static int efm32x_read_info(struct flash_bank *bank,
136 struct efm32_info *efm32_info)
137 {
138 int ret;
139 uint32_t cpuid = 0;
140
141 memset(efm32_info, 0, sizeof(struct efm32_info));
142
143 ret = target_read_u32(bank->target, CPUID, &cpuid);
144 if (ERROR_OK != ret)
145 return ret;
146
147 if (((cpuid >> 4) & 0xfff) == 0xc23) {
148 /* Cortex M3 device */
149 } else if (((cpuid >> 4) & 0xfff) == 0xc24) {
150 /* Cortex M4 device(WONDER GECKO) */
151 } else if (((cpuid >> 4) & 0xfff) == 0xc60) {
152 /* Cortex M0plus device(ZERO GECKO) */
153 } else {
154 LOG_ERROR("Target is not Cortex-Mx Device");
155 return ERROR_FAIL;
156 }
157
158 ret = efm32x_get_flash_size(bank, &(efm32_info->flash_sz_kib));
159 if (ERROR_OK != ret)
160 return ret;
161
162 ret = efm32x_get_ram_size(bank, &(efm32_info->ram_sz_kib));
163 if (ERROR_OK != ret)
164 return ret;
165
166 ret = efm32x_get_part_num(bank, &(efm32_info->part_num));
167 if (ERROR_OK != ret)
168 return ret;
169
170 ret = efm32x_get_part_family(bank, &(efm32_info->part_family));
171 if (ERROR_OK != ret)
172 return ret;
173
174 ret = efm32x_get_prod_rev(bank, &(efm32_info->prod_rev));
175 if (ERROR_OK != ret)
176 return ret;
177
178 if (EFM_FAMILY_ID_GECKO == efm32_info->part_family ||
179 EFM_FAMILY_ID_TINY_GECKO == efm32_info->part_family)
180 efm32_info->page_size = 512;
181 else if (EFM_FAMILY_ID_ZERO_GECKO == efm32_info->part_family)
182 efm32_info->page_size = 1024;
183 else if (EFM_FAMILY_ID_GIANT_GECKO == efm32_info->part_family ||
184 EFM_FAMILY_ID_LEOPARD_GECKO == efm32_info->part_family) {
185 if (efm32_info->prod_rev >= 18) {
186 uint8_t pg_size = 0;
187 ret = target_read_u8(bank->target, EFM32_MSC_DI_PAGE_SIZE,
188 &pg_size);
189 if (ERROR_OK != ret)
190 return ret;
191
192 efm32_info->page_size = (1 << ((pg_size+10) & 0xff));
193 } else {
194 /* EFM32 GG/LG errata: MEM_INFO_PAGE_SIZE is invalid
195 for MCUs with PROD_REV < 18 */
196 if (efm32_info->flash_sz_kib < 512)
197 efm32_info->page_size = 2048;
198 else
199 efm32_info->page_size = 4096;
200 }
201
202 if ((2048 != efm32_info->page_size) &&
203 (4096 != efm32_info->page_size)) {
204 LOG_ERROR("Invalid page size %u", efm32_info->page_size);
205 return ERROR_FAIL;
206 }
207 } else if (EFM_FAMILY_ID_WONDER_GECKO == efm32_info->part_family ||
208 EZR_FAMILY_ID_WONDER_GECKO == efm32_info->part_family ||
209 EZR_FAMILY_ID_LEOPARD_GECKO == efm32_info->part_family) {
210 uint8_t pg_size = 0;
211 ret = target_read_u8(bank->target, EFM32_MSC_DI_PAGE_SIZE,
212 &pg_size);
213 if (ERROR_OK != ret)
214 return ret;
215
216 efm32_info->page_size = (1 << ((pg_size+10) & 0xff));
217 if (2048 != efm32_info->page_size) {
218 LOG_ERROR("Invalid page size %u", efm32_info->page_size);
219 return ERROR_FAIL;
220 }
221 } else {
222 LOG_ERROR("Unknown MCU family %d", efm32_info->part_family);
223 return ERROR_FAIL;
224 }
225
226 return ERROR_OK;
227 }
228
229 /* flash bank efm32 <base> <size> 0 0 <target#>
230 */
231 FLASH_BANK_COMMAND_HANDLER(efm32x_flash_bank_command)
232 {
233 struct efm32x_flash_bank *efm32x_info;
234
235 if (CMD_ARGC < 6)
236 return ERROR_COMMAND_SYNTAX_ERROR;
237
238 efm32x_info = malloc(sizeof(struct efm32x_flash_bank));
239
240 bank->driver_priv = efm32x_info;
241 efm32x_info->probed = 0;
242 memset(efm32x_info->lb_page, 0xff, LOCKBITS_PAGE_SZ);
243
244 return ERROR_OK;
245 }
246
247 /* set or reset given bits in a register */
248 static int efm32x_set_reg_bits(struct flash_bank *bank, uint32_t reg,
249 uint32_t bitmask, int set)
250 {
251 int ret = 0;
252 uint32_t reg_val = 0;
253
254 ret = target_read_u32(bank->target, reg, &reg_val);
255 if (ERROR_OK != ret)
256 return ret;
257
258 if (set)
259 reg_val |= bitmask;
260 else
261 reg_val &= ~bitmask;
262
263 return target_write_u32(bank->target, reg, reg_val);
264 }
265
266 static int efm32x_set_wren(struct flash_bank *bank, int write_enable)
267 {
268 return efm32x_set_reg_bits(bank, EFM32_MSC_WRITECTRL,
269 EFM32_MSC_WRITECTRL_WREN_MASK, write_enable);
270 }
271
272 static int efm32x_msc_lock(struct flash_bank *bank, int lock)
273 {
274 return target_write_u32(bank->target, EFM32_MSC_LOCK,
275 (lock ? 0 : EFM32_MSC_LOCK_LOCKKEY));
276 }
277
278 static int efm32x_wait_status(struct flash_bank *bank, int timeout,
279 uint32_t wait_mask, int wait_for_set)
280 {
281 int ret = 0;
282 uint32_t status = 0;
283
284 while (1) {
285 ret = target_read_u32(bank->target, EFM32_MSC_STATUS, &status);
286 if (ERROR_OK != ret)
287 break;
288
289 LOG_DEBUG("status: 0x%" PRIx32 "", status);
290
291 if (((status & wait_mask) == 0) && (0 == wait_for_set))
292 break;
293 else if (((status & wait_mask) != 0) && wait_for_set)
294 break;
295
296 if (timeout-- <= 0) {
297 LOG_ERROR("timed out waiting for MSC status");
298 return ERROR_FAIL;
299 }
300
301 alive_sleep(1);
302 }
303
304 if (status & EFM32_MSC_STATUS_ERASEABORTED_MASK)
305 LOG_WARNING("page erase was aborted");
306
307 return ret;
308 }
309
310 static int efm32x_erase_page(struct flash_bank *bank, uint32_t addr)
311 {
312 /* this function DOES NOT set WREN; must be set already */
313 /* 1. write address to ADDRB
314 2. write LADDRIM
315 3. check status (INVADDR, LOCKED)
316 4. write ERASEPAGE
317 5. wait until !STATUS_BUSY
318 */
319 int ret = 0;
320 uint32_t status = 0;
321
322 LOG_DEBUG("erasing flash page at 0x%08" PRIx32, addr);
323
324 ret = target_write_u32(bank->target, EFM32_MSC_ADDRB, addr);
325 if (ERROR_OK != ret)
326 return ret;
327
328 ret = efm32x_set_reg_bits(bank, EFM32_MSC_WRITECMD,
329 EFM32_MSC_WRITECMD_LADDRIM_MASK, 1);
330 if (ERROR_OK != ret)
331 return ret;
332
333 ret = target_read_u32(bank->target, EFM32_MSC_STATUS, &status);
334 if (ERROR_OK != ret)
335 return ret;
336
337 LOG_DEBUG("status 0x%" PRIx32, status);
338
339 if (status & EFM32_MSC_STATUS_LOCKED_MASK) {
340 LOG_ERROR("Page is locked");
341 return ERROR_FAIL;
342 } else if (status & EFM32_MSC_STATUS_INVADDR_MASK) {
343 LOG_ERROR("Invalid address 0x%" PRIx32, addr);
344 return ERROR_FAIL;
345 }
346
347 ret = efm32x_set_reg_bits(bank, EFM32_MSC_WRITECMD,
348 EFM32_MSC_WRITECMD_ERASEPAGE_MASK, 1);
349 if (ERROR_OK != ret)
350 return ret;
351
352 return efm32x_wait_status(bank, EFM32_FLASH_ERASE_TMO,
353 EFM32_MSC_STATUS_BUSY_MASK, 0);
354 }
355
356 static int efm32x_erase(struct flash_bank *bank, int first, int last)
357 {
358 struct target *target = bank->target;
359 int i = 0;
360 int ret = 0;
361
362 if (TARGET_HALTED != target->state) {
363 LOG_ERROR("Target not halted");
364 return ERROR_TARGET_NOT_HALTED;
365 }
366
367 efm32x_msc_lock(bank, 0);
368 ret = efm32x_set_wren(bank, 1);
369 if (ERROR_OK != ret) {
370 LOG_ERROR("Failed to enable MSC write");
371 return ret;
372 }
373
374 for (i = first; i <= last; i++) {
375 ret = efm32x_erase_page(bank, bank->sectors[i].offset);
376 if (ERROR_OK != ret)
377 LOG_ERROR("Failed to erase page %d", i);
378 }
379
380 ret = efm32x_set_wren(bank, 0);
381 efm32x_msc_lock(bank, 1);
382
383 return ret;
384 }
385
386 static int efm32x_read_lock_data(struct flash_bank *bank)
387 {
388 struct efm32x_flash_bank *efm32x_info = bank->driver_priv;
389 struct target *target = bank->target;
390 int i = 0;
391 int data_size = 0;
392 uint32_t *ptr = NULL;
393 int ret = 0;
394
395 assert(!(bank->num_sectors & 0x1f));
396
397 data_size = bank->num_sectors / 8; /* number of data bytes */
398 data_size /= 4; /* ...and data dwords */
399
400 ptr = efm32x_info->lb_page;
401
402 for (i = 0; i < data_size; i++, ptr++) {
403 ret = target_read_u32(target, EFM32_MSC_LOCK_BITS+i*4, ptr);
404 if (ERROR_OK != ret) {
405 LOG_ERROR("Failed to read PLW %d", i);
406 return ret;
407 }
408 }
409
410 /* also, read ULW, DLW and MLW */
411
412 /* ULW, word 126 */
413 ptr = efm32x_info->lb_page + 126;
414 ret = target_read_u32(target, EFM32_MSC_LOCK_BITS+126*4, ptr);
415 if (ERROR_OK != ret) {
416 LOG_ERROR("Failed to read ULW");
417 return ret;
418 }
419
420 /* DLW, word 127 */
421 ptr = efm32x_info->lb_page + 127;
422 ret = target_read_u32(target, EFM32_MSC_LOCK_BITS+127*4, ptr);
423 if (ERROR_OK != ret) {
424 LOG_ERROR("Failed to read DLW");
425 return ret;
426 }
427
428 /* MLW, word 125, present in GG and LG */
429 ptr = efm32x_info->lb_page + 125;
430 ret = target_read_u32(target, EFM32_MSC_LOCK_BITS+125*4, ptr);
431 if (ERROR_OK != ret) {
432 LOG_ERROR("Failed to read MLW");
433 return ret;
434 }
435
436 return ERROR_OK;
437 }
438
439 static int efm32x_write_lock_data(struct flash_bank *bank)
440 {
441 struct efm32x_flash_bank *efm32x_info = bank->driver_priv;
442 int ret = 0;
443
444 ret = efm32x_erase_page(bank, EFM32_MSC_LOCK_BITS);
445 if (ERROR_OK != ret) {
446 LOG_ERROR("Failed to erase LB page");
447 return ret;
448 }
449
450 return efm32x_write(bank, (uint8_t *)efm32x_info->lb_page, EFM32_MSC_LOCK_BITS,
451 LOCKBITS_PAGE_SZ);
452 }
453
454 static int efm32x_get_page_lock(struct flash_bank *bank, size_t page)
455 {
456 struct efm32x_flash_bank *efm32x_info = bank->driver_priv;
457 uint32_t dw = efm32x_info->lb_page[page >> 5];
458 uint32_t mask = 0;
459
460 mask = 1 << (page & 0x1f);
461
462 return (dw & mask) ? 0 : 1;
463 }
464
465 static int efm32x_set_page_lock(struct flash_bank *bank, size_t page, int set)
466 {
467 struct efm32x_flash_bank *efm32x_info = bank->driver_priv;
468 uint32_t *dw = &efm32x_info->lb_page[page >> 5];
469 uint32_t mask = 0;
470
471 mask = 1 << (page & 0x1f);
472
473 if (!set)
474 *dw |= mask;
475 else
476 *dw &= ~mask;
477
478 return ERROR_OK;
479 }
480
481 static int efm32x_protect(struct flash_bank *bank, int set, int first, int last)
482 {
483 struct target *target = bank->target;
484 int i = 0;
485 int ret = 0;
486
487 if (!set) {
488 LOG_ERROR("Erase device data to reset page locks");
489 return ERROR_FAIL;
490 }
491
492 if (target->state != TARGET_HALTED) {
493 LOG_ERROR("Target not halted");
494 return ERROR_TARGET_NOT_HALTED;
495 }
496
497 for (i = first; i <= last; i++) {
498 ret = efm32x_set_page_lock(bank, i, set);
499 if (ERROR_OK != ret) {
500 LOG_ERROR("Failed to set lock on page %d", i);
501 return ret;
502 }
503 }
504
505 ret = efm32x_write_lock_data(bank);
506 if (ERROR_OK != ret) {
507 LOG_ERROR("Failed to write LB page");
508 return ret;
509 }
510
511 return ERROR_OK;
512 }
513
514 static int efm32x_write_block(struct flash_bank *bank, const uint8_t *buf,
515 uint32_t offset, uint32_t count)
516 {
517 struct target *target = bank->target;
518 uint32_t buffer_size = 16384;
519 struct working_area *write_algorithm;
520 struct working_area *source;
521 uint32_t address = bank->base + offset;
522 struct reg_param reg_params[5];
523 struct armv7m_algorithm armv7m_info;
524 int ret = ERROR_OK;
525
526 /* see contrib/loaders/flash/efm32.S for src */
527 static const uint8_t efm32x_flash_write_code[] = {
528 /* #define EFM32_MSC_WRITECTRL_OFFSET 0x008 */
529 /* #define EFM32_MSC_WRITECMD_OFFSET 0x00c */
530 /* #define EFM32_MSC_ADDRB_OFFSET 0x010 */
531 /* #define EFM32_MSC_WDATA_OFFSET 0x018 */
532 /* #define EFM32_MSC_STATUS_OFFSET 0x01c */
533 /* #define EFM32_MSC_LOCK_OFFSET 0x03c */
534
535 0x15, 0x4e, /* ldr r6, =#0x1b71 */
536 0xc6, 0x63, /* str r6, [r0, #EFM32_MSC_LOCK_OFFSET] */
537 0x01, 0x26, /* movs r6, #1 */
538 0x86, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECTRL_OFFSET] */
539
540 /* wait_fifo: */
541 0x16, 0x68, /* ldr r6, [r2, #0] */
542 0x00, 0x2e, /* cmp r6, #0 */
543 0x22, 0xd0, /* beq exit */
544 0x55, 0x68, /* ldr r5, [r2, #4] */
545 0xb5, 0x42, /* cmp r5, r6 */
546 0xf9, 0xd0, /* beq wait_fifo */
547
548 0x04, 0x61, /* str r4, [r0, #EFM32_MSC_ADDRB_OFFSET] */
549 0x01, 0x26, /* movs r6, #1 */
550 0xc6, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] */
551 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
552 0x06, 0x27, /* movs r7, #6 */
553 0x3e, 0x42, /* tst r6, r7 */
554 0x16, 0xd1, /* bne error */
555
556 /* wait_wdataready: */
557 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
558 0x08, 0x27, /* movs r7, #8 */
559 0x3e, 0x42, /* tst r6, r7 */
560 0xfb, 0xd0, /* beq wait_wdataready */
561
562 0x2e, 0x68, /* ldr r6, [r5] */
563 0x86, 0x61, /* str r6, [r0, #EFM32_MSC_WDATA_OFFSET] */
564 0x08, 0x26, /* movs r6, #8 */
565 0xc6, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] */
566
567 0x04, 0x35, /* adds r5, #4 */
568 0x04, 0x34, /* adds r4, #4 */
569
570 /* busy: */
571 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
572 0x01, 0x27, /* movs r7, #1 */
573 0x3e, 0x42, /* tst r6, r7 */
574 0xfb, 0xd1, /* bne busy */
575
576 0x9d, 0x42, /* cmp r5, r3 */
577 0x01, 0xd3, /* bcc no_wrap */
578 0x15, 0x46, /* mov r5, r2 */
579 0x08, 0x35, /* adds r5, #8 */
580
581 /* no_wrap: */
582 0x55, 0x60, /* str r5, [r2, #4] */
583 0x01, 0x39, /* subs r1, r1, #1 */
584 0x00, 0x29, /* cmp r1, #0 */
585 0x02, 0xd0, /* beq exit */
586 0xdb, 0xe7, /* b wait_fifo */
587
588 /* error: */
589 0x00, 0x20, /* movs r0, #0 */
590 0x50, 0x60, /* str r0, [r2, #4] */
591
592 /* exit: */
593 0x30, 0x46, /* mov r0, r6 */
594 0x00, 0xbe, /* bkpt #0 */
595
596 /* LOCKKEY */
597 0x71, 0x1b, 0x00, 0x00
598 };
599
600 /* flash write code */
601 if (target_alloc_working_area(target, sizeof(efm32x_flash_write_code),
602 &write_algorithm) != ERROR_OK) {
603 LOG_WARNING("no working area available, can't do block memory writes");
604 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
605 };
606
607 ret = target_write_buffer(target, write_algorithm->address,
608 sizeof(efm32x_flash_write_code), efm32x_flash_write_code);
609 if (ret != ERROR_OK)
610 return ret;
611
612 /* memory buffer */
613 while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {
614 buffer_size /= 2;
615 buffer_size &= ~3UL; /* Make sure it's 4 byte aligned */
616 if (buffer_size <= 256) {
617 /* we already allocated the writing code, but failed to get a
618 * buffer, free the algorithm */
619 target_free_working_area(target, write_algorithm);
620
621 LOG_WARNING("no large enough working area available, can't do block memory writes");
622 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
623 }
624 };
625
626 init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* flash base (in), status (out) */
627 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* count (word-32bit) */
628 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* buffer start */
629 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT); /* buffer end */
630 init_reg_param(&reg_params[4], "r4", 32, PARAM_IN_OUT); /* target address */
631
632 buf_set_u32(reg_params[0].value, 0, 32, EFM32_MSC_REGBASE);
633 buf_set_u32(reg_params[1].value, 0, 32, count);
634 buf_set_u32(reg_params[2].value, 0, 32, source->address);
635 buf_set_u32(reg_params[3].value, 0, 32, source->address + source->size);
636 buf_set_u32(reg_params[4].value, 0, 32, address);
637
638 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
639 armv7m_info.core_mode = ARM_MODE_THREAD;
640
641 ret = target_run_flash_async_algorithm(target, buf, count, 4,
642 0, NULL,
643 5, reg_params,
644 source->address, source->size,
645 write_algorithm->address, 0,
646 &armv7m_info);
647
648 if (ret == ERROR_FLASH_OPERATION_FAILED) {
649 LOG_ERROR("flash write failed at address 0x%"PRIx32,
650 buf_get_u32(reg_params[4].value, 0, 32));
651
652 if (buf_get_u32(reg_params[0].value, 0, 32) &
653 EFM32_MSC_STATUS_LOCKED_MASK) {
654 LOG_ERROR("flash memory write protected");
655 }
656
657 if (buf_get_u32(reg_params[0].value, 0, 32) &
658 EFM32_MSC_STATUS_INVADDR_MASK) {
659 LOG_ERROR("invalid flash memory write address");
660 }
661 }
662
663 target_free_working_area(target, source);
664 target_free_working_area(target, write_algorithm);
665
666 destroy_reg_param(&reg_params[0]);
667 destroy_reg_param(&reg_params[1]);
668 destroy_reg_param(&reg_params[2]);
669 destroy_reg_param(&reg_params[3]);
670 destroy_reg_param(&reg_params[4]);
671
672 return ret;
673 }
674
675 static int efm32x_write_word(struct flash_bank *bank, uint32_t addr,
676 uint32_t val)
677 {
678 /* this function DOES NOT set WREN; must be set already */
679 /* 1. write address to ADDRB
680 2. write LADDRIM
681 3. check status (INVADDR, LOCKED)
682 4. wait for WDATAREADY
683 5. write data to WDATA
684 6. write WRITECMD_WRITEONCE to WRITECMD
685 7. wait until !STATUS_BUSY
686 */
687
688 /* FIXME: EFM32G ref states (7.3.2) that writes should be
689 * performed twice per dword */
690
691 int ret = 0;
692 uint32_t status = 0;
693
694 /* if not called, GDB errors will be reported during large writes */
695 keep_alive();
696
697 ret = target_write_u32(bank->target, EFM32_MSC_ADDRB, addr);
698 if (ERROR_OK != ret)
699 return ret;
700
701 ret = efm32x_set_reg_bits(bank, EFM32_MSC_WRITECMD,
702 EFM32_MSC_WRITECMD_LADDRIM_MASK, 1);
703 if (ERROR_OK != ret)
704 return ret;
705
706 ret = target_read_u32(bank->target, EFM32_MSC_STATUS, &status);
707 if (ERROR_OK != ret)
708 return ret;
709
710 LOG_DEBUG("status 0x%" PRIx32, status);
711
712 if (status & EFM32_MSC_STATUS_LOCKED_MASK) {
713 LOG_ERROR("Page is locked");
714 return ERROR_FAIL;
715 } else if (status & EFM32_MSC_STATUS_INVADDR_MASK) {
716 LOG_ERROR("Invalid address 0x%" PRIx32, addr);
717 return ERROR_FAIL;
718 }
719
720 ret = efm32x_wait_status(bank, EFM32_FLASH_WDATAREADY_TMO,
721 EFM32_MSC_STATUS_WDATAREADY_MASK, 1);
722 if (ERROR_OK != ret) {
723 LOG_ERROR("Wait for WDATAREADY failed");
724 return ret;
725 }
726
727 ret = target_write_u32(bank->target, EFM32_MSC_WDATA, val);
728 if (ERROR_OK != ret) {
729 LOG_ERROR("WDATA write failed");
730 return ret;
731 }
732
733 ret = target_write_u32(bank->target, EFM32_MSC_WRITECMD,
734 EFM32_MSC_WRITECMD_WRITEONCE_MASK);
735 if (ERROR_OK != ret) {
736 LOG_ERROR("WRITECMD write failed");
737 return ret;
738 }
739
740 ret = efm32x_wait_status(bank, EFM32_FLASH_WRITE_TMO,
741 EFM32_MSC_STATUS_BUSY_MASK, 0);
742 if (ERROR_OK != ret) {
743 LOG_ERROR("Wait for BUSY failed");
744 return ret;
745 }
746
747 return ERROR_OK;
748 }
749
750 static int efm32x_write(struct flash_bank *bank, const uint8_t *buffer,
751 uint32_t offset, uint32_t count)
752 {
753 struct target *target = bank->target;
754 uint8_t *new_buffer = NULL;
755
756 if (target->state != TARGET_HALTED) {
757 LOG_ERROR("Target not halted");
758 return ERROR_TARGET_NOT_HALTED;
759 }
760
761 if (offset & 0x3) {
762 LOG_ERROR("offset 0x%" PRIx32 " breaks required 4-byte "
763 "alignment", offset);
764 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
765 }
766
767 if (count & 0x3) {
768 uint32_t old_count = count;
769 count = (old_count | 3) + 1;
770 new_buffer = malloc(count);
771 if (new_buffer == NULL) {
772 LOG_ERROR("odd number of bytes to write and no memory "
773 "for padding buffer");
774 return ERROR_FAIL;
775 }
776 LOG_INFO("odd number of bytes to write (%" PRIu32 "), extending to %" PRIu32 " "
777 "and padding with 0xff", old_count, count);
778 memset(new_buffer, 0xff, count);
779 buffer = memcpy(new_buffer, buffer, old_count);
780 }
781
782 uint32_t words_remaining = count / 4;
783 int retval, retval2;
784
785 /* unlock flash registers */
786 efm32x_msc_lock(bank, 0);
787 retval = efm32x_set_wren(bank, 1);
788 if (retval != ERROR_OK)
789 goto cleanup;
790
791 /* try using a block write */
792 retval = efm32x_write_block(bank, buffer, offset, words_remaining);
793
794 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
795 /* if block write failed (no sufficient working area),
796 * we use normal (slow) single word accesses */
797 LOG_WARNING("couldn't use block writes, falling back to single "
798 "memory accesses");
799
800 while (words_remaining > 0) {
801 uint32_t value;
802 memcpy(&value, buffer, sizeof(uint32_t));
803
804 retval = efm32x_write_word(bank, offset, value);
805 if (retval != ERROR_OK)
806 goto reset_pg_and_lock;
807
808 words_remaining--;
809 buffer += 4;
810 offset += 4;
811 }
812 }
813
814 reset_pg_and_lock:
815 retval2 = efm32x_set_wren(bank, 0);
816 efm32x_msc_lock(bank, 1);
817 if (retval == ERROR_OK)
818 retval = retval2;
819
820 cleanup:
821 if (new_buffer)
822 free(new_buffer);
823
824 return retval;
825 }
826
827 static int efm32x_probe(struct flash_bank *bank)
828 {
829 struct efm32x_flash_bank *efm32x_info = bank->driver_priv;
830 struct efm32_info efm32_mcu_info;
831 int ret;
832 int i;
833 uint32_t base_address = 0x00000000;
834
835 efm32x_info->probed = 0;
836 memset(efm32x_info->lb_page, 0xff, LOCKBITS_PAGE_SZ);
837
838 ret = efm32x_read_info(bank, &efm32_mcu_info);
839 if (ERROR_OK != ret)
840 return ret;
841
842 switch (efm32_mcu_info.part_family) {
843 case EFM_FAMILY_ID_GECKO:
844 LOG_INFO("Gecko MCU detected");
845 break;
846 case EFM_FAMILY_ID_GIANT_GECKO:
847 LOG_INFO("Giant Gecko MCU detected");
848 break;
849 case EFM_FAMILY_ID_TINY_GECKO:
850 LOG_INFO("Tiny Gecko MCU detected");
851 break;
852 case EFM_FAMILY_ID_LEOPARD_GECKO:
853 case EZR_FAMILY_ID_LEOPARD_GECKO:
854 LOG_INFO("Leopard Gecko MCU detected");
855 break;
856 case EFM_FAMILY_ID_WONDER_GECKO:
857 case EZR_FAMILY_ID_WONDER_GECKO:
858 LOG_INFO("Wonder Gecko MCU detected");
859 break;
860 case EFM_FAMILY_ID_ZERO_GECKO:
861 LOG_INFO("Zero Gecko MCU detected");
862 break;
863 default:
864 LOG_ERROR("Unsupported MCU family %d",
865 efm32_mcu_info.part_family);
866 return ERROR_FAIL;
867 }
868
869 LOG_INFO("flash size = %dkbytes", efm32_mcu_info.flash_sz_kib);
870 LOG_INFO("flash page size = %dbytes", efm32_mcu_info.page_size);
871
872 assert(0 != efm32_mcu_info.page_size);
873
874 int num_pages = efm32_mcu_info.flash_sz_kib * 1024 /
875 efm32_mcu_info.page_size;
876
877 assert(num_pages > 0);
878
879 if (bank->sectors) {
880 free(bank->sectors);
881 bank->sectors = NULL;
882 }
883
884 bank->base = base_address;
885 bank->size = (num_pages * efm32_mcu_info.page_size);
886 bank->num_sectors = num_pages;
887
888 ret = efm32x_read_lock_data(bank);
889 if (ERROR_OK != ret) {
890 LOG_ERROR("Failed to read LB data");
891 return ret;
892 }
893
894 bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
895
896 for (i = 0; i < num_pages; i++) {
897 bank->sectors[i].offset = i * efm32_mcu_info.page_size;
898 bank->sectors[i].size = efm32_mcu_info.page_size;
899 bank->sectors[i].is_erased = -1;
900 bank->sectors[i].is_protected = 1;
901 }
902
903 efm32x_info->probed = 1;
904
905 return ERROR_OK;
906 }
907
908 static int efm32x_auto_probe(struct flash_bank *bank)
909 {
910 struct efm32x_flash_bank *efm32x_info = bank->driver_priv;
911 if (efm32x_info->probed)
912 return ERROR_OK;
913 return efm32x_probe(bank);
914 }
915
916 static int efm32x_protect_check(struct flash_bank *bank)
917 {
918 struct target *target = bank->target;
919 int ret = 0;
920 int i = 0;
921
922 if (target->state != TARGET_HALTED) {
923 LOG_ERROR("Target not halted");
924 return ERROR_TARGET_NOT_HALTED;
925 }
926
927 ret = efm32x_read_lock_data(bank);
928 if (ERROR_OK != ret) {
929 LOG_ERROR("Failed to read LB data");
930 return ret;
931 }
932
933 assert(NULL != bank->sectors);
934
935 for (i = 0; i < bank->num_sectors; i++)
936 bank->sectors[i].is_protected = efm32x_get_page_lock(bank, i);
937
938 return ERROR_OK;
939 }
940
941 static int get_efm32x_info(struct flash_bank *bank, char *buf, int buf_size)
942 {
943 struct efm32_info info;
944 int ret = 0;
945 int printed = 0;
946
947 ret = efm32x_read_info(bank, &info);
948 if (ERROR_OK != ret) {
949 LOG_ERROR("Failed to read EFM32 info");
950 return ret;
951 }
952
953 switch (info.part_family) {
954 case EZR_FAMILY_ID_WONDER_GECKO:
955 case EZR_FAMILY_ID_LEOPARD_GECKO:
956 printed = snprintf(buf, buf_size, "EZR32 ");
957 break;
958 default:
959 printed = snprintf(buf, buf_size, "EFM32 ");
960 }
961
962 buf += printed;
963 buf_size -= printed;
964
965 if (0 >= buf_size)
966 return ERROR_BUF_TOO_SMALL;
967
968 switch (info.part_family) {
969 case EFM_FAMILY_ID_GECKO:
970 printed = snprintf(buf, buf_size, "Gecko");
971 break;
972 case EFM_FAMILY_ID_GIANT_GECKO:
973 printed = snprintf(buf, buf_size, "Giant Gecko");
974 break;
975 case EFM_FAMILY_ID_TINY_GECKO:
976 printed = snprintf(buf, buf_size, "Tiny Gecko");
977 break;
978 case EFM_FAMILY_ID_LEOPARD_GECKO:
979 case EZR_FAMILY_ID_LEOPARD_GECKO:
980 printed = snprintf(buf, buf_size, "Leopard Gecko");
981 break;
982 case EFM_FAMILY_ID_WONDER_GECKO:
983 case EZR_FAMILY_ID_WONDER_GECKO:
984 printed = snprintf(buf, buf_size, "Wonder Gecko");
985 break;
986 case EFM_FAMILY_ID_ZERO_GECKO:
987 printed = snprintf(buf, buf_size, "Zero Gecko");
988 break;
989 }
990
991 buf += printed;
992 buf_size -= printed;
993
994 if (0 >= buf_size)
995 return ERROR_BUF_TOO_SMALL;
996
997 printed = snprintf(buf, buf_size, " - Rev: %d", info.prod_rev);
998 buf += printed;
999 buf_size -= printed;
1000
1001 if (0 >= buf_size)
1002 return ERROR_BUF_TOO_SMALL;
1003
1004 return ERROR_OK;
1005 }
1006
1007 static const struct command_registration efm32x_exec_command_handlers[] = {
1008 COMMAND_REGISTRATION_DONE
1009 };
1010
1011 static const struct command_registration efm32x_command_handlers[] = {
1012 {
1013 .name = "efm32",
1014 .mode = COMMAND_ANY,
1015 .help = "efm32 flash command group",
1016 .usage = "",
1017 .chain = efm32x_exec_command_handlers,
1018 },
1019 COMMAND_REGISTRATION_DONE
1020 };
1021
1022 struct flash_driver efm32_flash = {
1023 .name = "efm32",
1024 .commands = efm32x_command_handlers,
1025 .flash_bank_command = efm32x_flash_bank_command,
1026 .erase = efm32x_erase,
1027 .protect = efm32x_protect,
1028 .write = efm32x_write,
1029 .read = default_flash_read,
1030 .probe = efm32x_probe,
1031 .auto_probe = efm32x_auto_probe,
1032 .erase_check = default_flash_blank_check,
1033 .protect_check = efm32x_protect_check,
1034 .info = get_efm32x_info,
1035 };

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)