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

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)