Remove unnecessary casts
[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%08" PRIx32, 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%" PRIx32, 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%" PRIx32, 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), efm32x_flash_write_code);
582 if (ret != ERROR_OK)
583 return ret;
584
585 /* memory buffer */
586 while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {
587 buffer_size /= 2;
588 buffer_size &= ~3UL; /* Make sure it's 4 byte aligned */
589 if (buffer_size <= 256) {
590 /* we already allocated the writing code, but failed to get a
591 * buffer, free the algorithm */
592 target_free_working_area(target, write_algorithm);
593
594 LOG_WARNING("no large enough working area available, can't do block memory writes");
595 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
596 }
597 };
598
599 init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* flash base (in), status (out) */
600 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* count (word-32bit) */
601 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* buffer start */
602 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT); /* buffer end */
603 init_reg_param(&reg_params[4], "r4", 32, PARAM_IN_OUT); /* target address */
604
605 buf_set_u32(reg_params[0].value, 0, 32, EFM32_MSC_REGBASE);
606 buf_set_u32(reg_params[1].value, 0, 32, count);
607 buf_set_u32(reg_params[2].value, 0, 32, source->address);
608 buf_set_u32(reg_params[3].value, 0, 32, source->address + source->size);
609 buf_set_u32(reg_params[4].value, 0, 32, address);
610
611 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
612 armv7m_info.core_mode = ARM_MODE_THREAD;
613
614 ret = target_run_flash_async_algorithm(target, buf, count, 4,
615 0, NULL,
616 5, reg_params,
617 source->address, source->size,
618 write_algorithm->address, 0,
619 &armv7m_info);
620
621 if (ret == ERROR_FLASH_OPERATION_FAILED) {
622 LOG_ERROR("flash write failed at address 0x%"PRIx32,
623 buf_get_u32(reg_params[4].value, 0, 32));
624
625 if (buf_get_u32(reg_params[0].value, 0, 32) &
626 EFM32_MSC_STATUS_LOCKED_MASK) {
627 LOG_ERROR("flash memory write protected");
628 }
629
630 if (buf_get_u32(reg_params[0].value, 0, 32) &
631 EFM32_MSC_STATUS_INVADDR_MASK) {
632 LOG_ERROR("invalid flash memory write address");
633 }
634 }
635
636 target_free_working_area(target, source);
637 target_free_working_area(target, write_algorithm);
638
639 destroy_reg_param(&reg_params[0]);
640 destroy_reg_param(&reg_params[1]);
641 destroy_reg_param(&reg_params[2]);
642 destroy_reg_param(&reg_params[3]);
643 destroy_reg_param(&reg_params[4]);
644
645 return ret;
646 }
647
648 static int efm32x_write_word(struct flash_bank *bank, uint32_t addr,
649 uint32_t val)
650 {
651 /* this function DOES NOT set WREN; must be set already */
652 /* 1. write address to ADDRB
653 2. write LADDRIM
654 3. check status (INVADDR, LOCKED)
655 4. wait for WDATAREADY
656 5. write data to WDATA
657 6. write WRITECMD_WRITEONCE to WRITECMD
658 7. wait until !STATUS_BUSY
659 */
660
661 /* FIXME: EFM32G ref states (7.3.2) that writes should be
662 * performed twice per dword */
663
664 int ret = 0;
665 uint32_t status = 0;
666
667 /* if not called, GDB errors will be reported during large writes */
668 keep_alive();
669
670 ret = target_write_u32(bank->target, EFM32_MSC_ADDRB, addr);
671 if (ERROR_OK != ret)
672 return ret;
673
674 ret = efm32x_set_reg_bits(bank, EFM32_MSC_WRITECMD,
675 EFM32_MSC_WRITECMD_LADDRIM_MASK, 1);
676 if (ERROR_OK != ret)
677 return ret;
678
679 ret = target_read_u32(bank->target, EFM32_MSC_STATUS, &status);
680 if (ERROR_OK != ret)
681 return ret;
682
683 LOG_DEBUG("status 0x%" PRIx32, status);
684
685 if (status & EFM32_MSC_STATUS_LOCKED_MASK) {
686 LOG_ERROR("Page is locked");
687 return ERROR_FAIL;
688 } else if (status & EFM32_MSC_STATUS_INVADDR_MASK) {
689 LOG_ERROR("Invalid address 0x%" PRIx32, addr);
690 return ERROR_FAIL;
691 }
692
693 ret = efm32x_wait_status(bank, EFM32_FLASH_WDATAREADY_TMO,
694 EFM32_MSC_STATUS_WDATAREADY_MASK, 1);
695 if (ERROR_OK != ret) {
696 LOG_ERROR("Wait for WDATAREADY failed");
697 return ret;
698 }
699
700 ret = target_write_u32(bank->target, EFM32_MSC_WDATA, val);
701 if (ERROR_OK != ret) {
702 LOG_ERROR("WDATA write failed");
703 return ret;
704 }
705
706 ret = target_write_u32(bank->target, EFM32_MSC_WRITECMD,
707 EFM32_MSC_WRITECMD_WRITEONCE_MASK);
708 if (ERROR_OK != ret) {
709 LOG_ERROR("WRITECMD write failed");
710 return ret;
711 }
712
713 ret = efm32x_wait_status(bank, EFM32_FLASH_WRITE_TMO,
714 EFM32_MSC_STATUS_BUSY_MASK, 0);
715 if (ERROR_OK != ret) {
716 LOG_ERROR("Wait for BUSY failed");
717 return ret;
718 }
719
720 return ERROR_OK;
721 }
722
723 static int efm32x_write(struct flash_bank *bank, uint8_t *buffer,
724 uint32_t offset, uint32_t count)
725 {
726 struct target *target = bank->target;
727 uint8_t *new_buffer = NULL;
728
729 if (target->state != TARGET_HALTED) {
730 LOG_ERROR("Target not halted");
731 return ERROR_TARGET_NOT_HALTED;
732 }
733
734 if (offset & 0x3) {
735 LOG_ERROR("offset 0x%" PRIx32 " breaks required 4-byte "
736 "alignment", offset);
737 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
738 }
739
740 if (count & 0x3) {
741 uint32_t old_count = count;
742 count = (old_count | 3) + 1;
743 new_buffer = malloc(count);
744 if (new_buffer == NULL) {
745 LOG_ERROR("odd number of bytes to write and no memory "
746 "for padding buffer");
747 return ERROR_FAIL;
748 }
749 LOG_INFO("odd number of bytes to write (%" PRIu32 "), extending to %" PRIu32 " "
750 "and padding with 0xff", old_count, count);
751 memset(buffer, 0xff, count);
752 buffer = memcpy(new_buffer, buffer, old_count);
753 }
754
755 uint32_t words_remaining = count / 4;
756 int retval, retval2;
757
758 /* unlock flash registers */
759 efm32x_msc_lock(bank, 0);
760 retval = efm32x_set_wren(bank, 1);
761 if (retval != ERROR_OK)
762 goto cleanup;
763
764 /* try using a block write */
765 retval = efm32x_write_block(bank, buffer, offset, words_remaining);
766
767 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
768 /* if block write failed (no sufficient working area),
769 * we use normal (slow) single word accesses */
770 LOG_WARNING("couldn't use block writes, falling back to single "
771 "memory accesses");
772
773 while (words_remaining > 0) {
774 uint32_t value;
775 memcpy(&value, buffer, sizeof(uint32_t));
776
777 retval = efm32x_write_word(bank, offset, value);
778 if (retval != ERROR_OK)
779 goto reset_pg_and_lock;
780
781 words_remaining--;
782 buffer += 4;
783 offset += 4;
784 }
785 }
786
787 reset_pg_and_lock:
788 retval2 = efm32x_set_wren(bank, 0);
789 efm32x_msc_lock(bank, 1);
790 if (retval == ERROR_OK)
791 retval = retval2;
792
793 cleanup:
794 if (new_buffer)
795 free(new_buffer);
796
797 return retval;
798 }
799
800 static int efm32x_probe(struct flash_bank *bank)
801 {
802 struct efm32x_flash_bank *efm32x_info = bank->driver_priv;
803 struct efm32_info efm32_mcu_info;
804 int ret;
805 int i;
806 uint32_t base_address = 0x00000000;
807
808 efm32x_info->probed = 0;
809 memset(efm32x_info->lb_page, 0xff, LOCKBITS_PAGE_SZ);
810
811 ret = efm32x_read_info(bank, &efm32_mcu_info);
812 if (ERROR_OK != ret)
813 return ret;
814
815 switch (efm32_mcu_info.part_family) {
816 case EFM_FAMILY_ID_GECKO:
817 LOG_INFO("Gecko MCU detected");
818 break;
819 case EFM_FAMILY_ID_GIANT_GECKO:
820 LOG_INFO("Giant Gecko MCU detected");
821 break;
822 case EFM_FAMILY_ID_TINY_GECKO:
823 LOG_INFO("Tiny Gecko MCU detected");
824 break;
825 case EFM_FAMILY_ID_LEOPARD_GECKO:
826 LOG_INFO("Leopard Gecko MCU detected");
827 break;
828 default:
829 LOG_ERROR("Unsupported MCU family %d",
830 efm32_mcu_info.part_family);
831 return ERROR_FAIL;
832 }
833
834 LOG_INFO("flash size = %dkbytes", efm32_mcu_info.flash_sz_kib);
835 LOG_INFO("flash page size = %dbytes", efm32_mcu_info.page_size);
836
837 assert(0 != efm32_mcu_info.page_size);
838
839 int num_pages = efm32_mcu_info.flash_sz_kib * 1024 /
840 efm32_mcu_info.page_size;
841
842 assert(num_pages > 0);
843
844 if (bank->sectors) {
845 free(bank->sectors);
846 bank->sectors = NULL;
847 }
848
849 bank->base = base_address;
850 bank->size = (num_pages * efm32_mcu_info.page_size);
851 bank->num_sectors = num_pages;
852
853 ret = efm32x_read_lock_data(bank);
854 if (ERROR_OK != ret) {
855 LOG_ERROR("Failed to read LB data");
856 return ret;
857 }
858
859 bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
860
861 for (i = 0; i < num_pages; i++) {
862 bank->sectors[i].offset = i * efm32_mcu_info.page_size;
863 bank->sectors[i].size = efm32_mcu_info.page_size;
864 bank->sectors[i].is_erased = -1;
865 bank->sectors[i].is_protected = 1;
866 }
867
868 efm32x_info->probed = 1;
869
870 return ERROR_OK;
871 }
872
873 static int efm32x_auto_probe(struct flash_bank *bank)
874 {
875 struct efm32x_flash_bank *efm32x_info = bank->driver_priv;
876 if (efm32x_info->probed)
877 return ERROR_OK;
878 return efm32x_probe(bank);
879 }
880
881 static int efm32x_protect_check(struct flash_bank *bank)
882 {
883 struct target *target = bank->target;
884 int ret = 0;
885 int i = 0;
886
887 if (target->state != TARGET_HALTED) {
888 LOG_ERROR("Target not halted");
889 return ERROR_TARGET_NOT_HALTED;
890 }
891
892 ret = efm32x_read_lock_data(bank);
893 if (ERROR_OK != ret) {
894 LOG_ERROR("Failed to read LB data");
895 return ret;
896 }
897
898 assert(NULL != bank->sectors);
899
900 for (i = 0; i < bank->num_sectors; i++)
901 bank->sectors[i].is_protected = efm32x_get_page_lock(bank, i);
902
903 return ERROR_OK;
904 }
905
906 static int get_efm32x_info(struct flash_bank *bank, char *buf, int buf_size)
907 {
908 struct efm32_info info;
909 int ret = 0;
910 int printed = 0;
911
912 ret = efm32x_read_info(bank, &info);
913 if (ERROR_OK != ret) {
914 LOG_ERROR("Failed to read EFM32 info");
915 return ret;
916 }
917
918 printed = snprintf(buf, buf_size, "EFM32 ");
919 buf += printed;
920 buf_size -= printed;
921
922 if (0 >= buf_size)
923 return ERROR_BUF_TOO_SMALL;
924
925 switch (info.part_family) {
926 case EFM_FAMILY_ID_GECKO:
927 printed = snprintf(buf, buf_size, "Gecko");
928 break;
929 case EFM_FAMILY_ID_GIANT_GECKO:
930 printed = snprintf(buf, buf_size, "Giant Gecko");
931 break;
932 case EFM_FAMILY_ID_TINY_GECKO:
933 printed = snprintf(buf, buf_size, "Tiny Gecko");
934 break;
935 case EFM_FAMILY_ID_LEOPARD_GECKO:
936 printed = snprintf(buf, buf_size, "Leopard Gecko");
937 break;
938 }
939
940 buf += printed;
941 buf_size -= printed;
942
943 if (0 >= buf_size)
944 return ERROR_BUF_TOO_SMALL;
945
946 printed = snprintf(buf, buf_size, " - Rev: %d", info.prod_rev);
947 buf += printed;
948 buf_size -= printed;
949
950 if (0 >= buf_size)
951 return ERROR_BUF_TOO_SMALL;
952
953 return ERROR_OK;
954 }
955
956 static const struct command_registration efm32x_exec_command_handlers[] = {
957 COMMAND_REGISTRATION_DONE
958 };
959
960 static const struct command_registration efm32x_command_handlers[] = {
961 {
962 .name = "efm32",
963 .mode = COMMAND_ANY,
964 .help = "efm32 flash command group",
965 .usage = "",
966 .chain = efm32x_exec_command_handlers,
967 },
968 COMMAND_REGISTRATION_DONE
969 };
970
971 struct flash_driver efm32_flash = {
972 .name = "efm32",
973 .commands = efm32x_command_handlers,
974 .flash_bank_command = efm32x_flash_bank_command,
975 .erase = efm32x_erase,
976 .protect = efm32x_protect,
977 .write = efm32x_write,
978 .read = default_flash_read,
979 .probe = efm32x_probe,
980 .auto_probe = efm32x_auto_probe,
981 .erase_check = default_flash_blank_check,
982 .protect_check = efm32x_protect_check,
983 .info = get_efm32x_info,
984 };

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)