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

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)