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

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)