1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2005 by Dominic Rath *
5 * Dominic.Rath@gmx.de *
7 * Copyright (C) 2008 by Spencer Oliver *
8 * spen@spen-soft.co.uk *
10 * Copyright (C) 2011 by Andreas Fritiofson *
11 * andreas.fritiofson@gmail.com *
13 * Copyright (C) 2013 by Roman Dmitrienko *
16 * Copyright (C) 2014 Nemui Trinomius *
17 * nemuisan_kawausogasuki@live.jp *
19 * Copyright (C) 2021 Doug Brunner *
20 * doug.a.brunner@gmail.com *
21 ***************************************************************************/
28 #include <helper/binarybuffer.h>
29 #include <target/algorithm.h>
30 #include <target/armv7m.h>
31 #include <target/cortex_m.h>
33 #define EFM_FAMILY_ID_GIANT_GECKO 72
34 #define EFM_FAMILY_ID_LEOPARD_GECKO 74
36 #define EFM32_FLASH_ERASE_TMO 100
37 #define EFM32_FLASH_WDATAREADY_TMO 100
38 #define EFM32_FLASH_WRITE_TMO 100
40 #define EFM32_FLASH_BASE 0
42 /* size in bytes, not words; must fit all Gecko devices */
43 #define LOCKWORDS_SZ 512
45 #define EFM32_MSC_INFO_BASE 0x0fe00000
47 #define EFM32_MSC_USER_DATA EFM32_MSC_INFO_BASE
48 #define EFM32_MSC_LOCK_BITS (EFM32_MSC_INFO_BASE+0x4000)
49 #define EFM32_MSC_LOCK_BITS_EXTRA (EFM32_MSC_LOCK_BITS+LOCKWORDS_SZ)
50 #define EFM32_MSC_DEV_INFO (EFM32_MSC_INFO_BASE+0x8000)
52 /* PAGE_SIZE is not present in Zero, Happy and the original Gecko MCU */
53 #define EFM32_MSC_DI_PAGE_SIZE (EFM32_MSC_DEV_INFO+0x1e7)
54 #define EFM32_MSC_DI_FLASH_SZ (EFM32_MSC_DEV_INFO+0x1f8)
55 #define EFM32_MSC_DI_RAM_SZ (EFM32_MSC_DEV_INFO+0x1fa)
56 #define EFM32_MSC_DI_PART_NUM (EFM32_MSC_DEV_INFO+0x1fc)
57 #define EFM32_MSC_DI_PART_FAMILY (EFM32_MSC_DEV_INFO+0x1fe)
58 #define EFM32_MSC_DI_PROD_REV (EFM32_MSC_DEV_INFO+0x1ff)
60 #define EFM32_MSC_REGBASE 0x400c0000
61 #define EFM32_MSC_REGBASE_SERIES1 0x400e0000
62 #define EFM32_MSC_REG_WRITECTRL 0x008
63 #define EFM32_MSC_WRITECTRL_WREN_MASK 0x1
64 #define EFM32_MSC_REG_WRITECMD 0x00c
65 #define EFM32_MSC_WRITECMD_LADDRIM_MASK 0x1
66 #define EFM32_MSC_WRITECMD_ERASEPAGE_MASK 0x2
67 #define EFM32_MSC_WRITECMD_WRITEONCE_MASK 0x8
68 #define EFM32_MSC_REG_ADDRB 0x010
69 #define EFM32_MSC_REG_WDATA 0x018
70 #define EFM32_MSC_REG_STATUS 0x01c
71 #define EFM32_MSC_STATUS_BUSY_MASK 0x1
72 #define EFM32_MSC_STATUS_LOCKED_MASK 0x2
73 #define EFM32_MSC_STATUS_INVADDR_MASK 0x4
74 #define EFM32_MSC_STATUS_WDATAREADY_MASK 0x8
75 #define EFM32_MSC_STATUS_WORDTIMEOUT_MASK 0x10
76 #define EFM32_MSC_STATUS_ERASEABORTED_MASK 0x20
77 #define EFM32_MSC_REG_LOCK 0x03c
78 #define EFM32_MSC_REG_LOCK_SERIES1 0x040
79 #define EFM32_MSC_LOCK_LOCKKEY 0x1b71
81 enum efm32_bank_index
{
82 EFM32_BANK_INDEX_MAIN
,
83 EFM32_BANK_INDEX_USER_DATA
,
84 EFM32_BANK_INDEX_LOCK_BITS
,
88 static int efm32x_get_bank_index(target_addr_t base
)
91 case EFM32_FLASH_BASE
:
92 return EFM32_BANK_INDEX_MAIN
;
93 case EFM32_MSC_USER_DATA
:
94 return EFM32_BANK_INDEX_USER_DATA
;
95 case EFM32_MSC_LOCK_BITS
:
96 return EFM32_BANK_INDEX_LOCK_BITS
;
102 struct efm32_family_data
{
106 /* EFM32 series (EFM32LG995F is the "old" series 0, while EFR32MG12P132
107 is the "new" series 1). Determines location of MSC registers. */
110 /* Page size in bytes, or 0 to read from EFM32_MSC_DI_PAGE_SIZE */
113 /* MSC register base address, or 0 to use default */
114 uint32_t msc_regbase
;
118 const struct efm32_family_data
*family_data
;
119 uint16_t flash_sz_kib
;
127 struct efm32x_flash_chip
{
128 struct efm32_info info
;
129 bool probed
[EFM32_N_BANKS
];
130 uint32_t lb_page
[LOCKWORDS_SZ
/4];
136 static const struct efm32_family_data efm32_families
[] = {
137 { 16, "EFR32MG1P Mighty", .series
= 1 },
138 { 17, "EFR32MG1B Mighty", .series
= 1 },
139 { 18, "EFR32MG1V Mighty", .series
= 1 },
140 { 19, "EFR32BG1P Blue", .series
= 1 },
141 { 20, "EFR32BG1B Blue", .series
= 1 },
142 { 21, "EFR32BG1V Blue", .series
= 1 },
143 { 25, "EFR32FG1P Flex", .series
= 1 },
144 { 26, "EFR32FG1B Flex", .series
= 1 },
145 { 27, "EFR32FG1V Flex", .series
= 1 },
146 { 28, "EFR32MG2P Mighty", .series
= 1 },
147 { 29, "EFR32MG2B Mighty", .series
= 1 },
148 { 30, "EFR32MG2V Mighty", .series
= 1 },
149 { 31, "EFR32BG12P Blue", .series
= 1 },
150 { 32, "EFR32BG12B Blue", .series
= 1 },
151 { 33, "EFR32BG12V Blue", .series
= 1 },
152 { 37, "EFR32FG12P Flex", .series
= 1 },
153 { 38, "EFR32FG12B Flex", .series
= 1 },
154 { 39, "EFR32FG12V Flex", .series
= 1 },
155 { 40, "EFR32MG13P Mighty", .series
= 1 },
156 { 41, "EFR32MG13B Mighty", .series
= 1 },
157 { 42, "EFR32MG13V Mighty", .series
= 1 },
158 { 43, "EFR32BG13P Blue", .series
= 1 },
159 { 44, "EFR32BG13B Blue", .series
= 1 },
160 { 45, "EFR32BG13V Blue", .series
= 1 },
161 { 46, "EFR32ZG13P Zen", .series
= 1 },
162 { 49, "EFR32FG13P Flex", .series
= 1 },
163 { 50, "EFR32FG13B Flex", .series
= 1 },
164 { 51, "EFR32FG13V Flex", .series
= 1 },
165 { 52, "EFR32MG14P Mighty", .series
= 1 },
166 { 53, "EFR32MG14B Mighty", .series
= 1 },
167 { 54, "EFR32MG14V Mighty", .series
= 1 },
168 { 55, "EFR32BG14P Blue", .series
= 1 },
169 { 56, "EFR32BG14B Blue", .series
= 1 },
170 { 57, "EFR32BG14V Blue", .series
= 1 },
171 { 58, "EFR32ZG14P Zen", .series
= 1 },
172 { 61, "EFR32FG14P Flex", .series
= 1 },
173 { 62, "EFR32FG14B Flex", .series
= 1 },
174 { 63, "EFR32FG14V Flex", .series
= 1 },
175 { 71, "EFM32G", .series
= 0, .page_size
= 512 },
176 { 72, "EFM32GG Giant", .series
= 0 },
177 { 73, "EFM32TG Tiny", .series
= 0, .page_size
= 512 },
178 { 74, "EFM32LG Leopard", .series
= 0 },
179 { 75, "EFM32WG Wonder", .series
= 0 },
180 { 76, "EFM32ZG Zero", .series
= 0, .page_size
= 1024 },
181 { 77, "EFM32HG Happy", .series
= 0, .page_size
= 1024 },
182 { 81, "EFM32PG1B Pearl", .series
= 1 },
183 { 83, "EFM32JG1B Jade", .series
= 1 },
184 { 85, "EFM32PG12B Pearl", .series
= 1 },
185 { 87, "EFM32JG12B Jade", .series
= 1 },
186 { 89, "EFM32PG13B Pearl", .series
= 1 },
187 { 91, "EFM32JG13B Jade", .series
= 1 },
188 { 100, "EFM32GG11B Giant", .series
= 1, .msc_regbase
= 0x40000000 },
189 { 103, "EFM32TG11B Tiny", .series
= 1, .msc_regbase
= 0x40000000 },
190 { 106, "EFM32GG12B Giant", .series
= 1, .msc_regbase
= 0x40000000 },
191 { 120, "EZR32WG Wonder", .series
= 0 },
192 { 121, "EZR32LG Leopard", .series
= 0 },
193 { 122, "EZR32HG Happy", .series
= 0, .page_size
= 1024 },
196 const struct flash_driver efm32_flash
;
198 static int efm32x_priv_write(struct flash_bank
*bank
, const uint8_t *buffer
,
199 uint32_t addr
, uint32_t count
);
201 static int efm32x_write_only_lockbits(struct flash_bank
*bank
);
203 static int efm32x_get_flash_size(struct flash_bank
*bank
, uint16_t *flash_sz
)
205 return target_read_u16(bank
->target
, EFM32_MSC_DI_FLASH_SZ
, flash_sz
);
208 static int efm32x_get_ram_size(struct flash_bank
*bank
, uint16_t *ram_sz
)
210 return target_read_u16(bank
->target
, EFM32_MSC_DI_RAM_SZ
, ram_sz
);
213 static int efm32x_get_part_num(struct flash_bank
*bank
, uint16_t *pnum
)
215 return target_read_u16(bank
->target
, EFM32_MSC_DI_PART_NUM
, pnum
);
218 static int efm32x_get_part_family(struct flash_bank
*bank
, uint8_t *pfamily
)
220 return target_read_u8(bank
->target
, EFM32_MSC_DI_PART_FAMILY
, pfamily
);
223 static int efm32x_get_prod_rev(struct flash_bank
*bank
, uint8_t *prev
)
225 return target_read_u8(bank
->target
, EFM32_MSC_DI_PROD_REV
, prev
);
228 static int efm32x_read_reg_u32(struct flash_bank
*bank
, target_addr_t offset
,
231 struct efm32x_flash_chip
*efm32x_info
= bank
->driver_priv
;
232 uint32_t base
= efm32x_info
->reg_base
;
234 return target_read_u32(bank
->target
, base
+ offset
, value
);
237 static int efm32x_write_reg_u32(struct flash_bank
*bank
, target_addr_t offset
,
240 struct efm32x_flash_chip
*efm32x_info
= bank
->driver_priv
;
241 uint32_t base
= efm32x_info
->reg_base
;
243 return target_write_u32(bank
->target
, base
+ offset
, value
);
246 static int efm32x_read_info(struct flash_bank
*bank
)
249 struct efm32x_flash_chip
*efm32x_info
= bank
->driver_priv
;
250 struct efm32_info
*efm32_info
= &(efm32x_info
->info
);
252 memset(efm32_info
, 0, sizeof(struct efm32_info
));
254 const struct cortex_m_common
*cortex_m
= target_to_cm(bank
->target
);
256 switch (cortex_m
->core_info
->partno
) {
257 case CORTEX_M3_PARTNO
:
258 case CORTEX_M4_PARTNO
:
259 case CORTEX_M0P_PARTNO
:
262 LOG_ERROR("Target is not Cortex-Mx Device");
266 ret
= efm32x_get_flash_size(bank
, &(efm32_info
->flash_sz_kib
));
270 ret
= efm32x_get_ram_size(bank
, &(efm32_info
->ram_sz_kib
));
274 ret
= efm32x_get_part_num(bank
, &(efm32_info
->part_num
));
278 ret
= efm32x_get_part_family(bank
, &(efm32_info
->part_family
));
282 ret
= efm32x_get_prod_rev(bank
, &(efm32_info
->prod_rev
));
286 for (size_t i
= 0; i
< ARRAY_SIZE(efm32_families
); i
++) {
287 if (efm32_families
[i
].family_id
== efm32_info
->part_family
)
288 efm32_info
->family_data
= &efm32_families
[i
];
291 if (!efm32_info
->family_data
) {
292 LOG_ERROR("Unknown MCU family %d", efm32_info
->part_family
);
296 switch (efm32_info
->family_data
->series
) {
298 efm32x_info
->reg_base
= EFM32_MSC_REGBASE
;
299 efm32x_info
->reg_lock
= EFM32_MSC_REG_LOCK
;
302 efm32x_info
->reg_base
= EFM32_MSC_REGBASE_SERIES1
;
303 efm32x_info
->reg_lock
= EFM32_MSC_REG_LOCK_SERIES1
;
307 if (efm32_info
->family_data
->msc_regbase
!= 0)
308 efm32x_info
->reg_base
= efm32_info
->family_data
->msc_regbase
;
310 if (efm32_info
->family_data
->page_size
!= 0) {
311 efm32_info
->page_size
= efm32_info
->family_data
->page_size
;
314 ret
= target_read_u8(bank
->target
, EFM32_MSC_DI_PAGE_SIZE
,
319 efm32_info
->page_size
= (1 << ((pg_size
+10) & 0xff));
321 if (efm32_info
->part_family
== EFM_FAMILY_ID_GIANT_GECKO
||
322 efm32_info
->part_family
== EFM_FAMILY_ID_LEOPARD_GECKO
) {
323 /* Giant or Leopard Gecko */
324 if (efm32_info
->prod_rev
< 18) {
325 /* EFM32 GG/LG errata: MEM_INFO_PAGE_SIZE is invalid
326 for MCUs with PROD_REV < 18 */
327 if (efm32_info
->flash_sz_kib
< 512)
328 efm32_info
->page_size
= 2048;
330 efm32_info
->page_size
= 4096;
334 if ((efm32_info
->page_size
!= 2048) &&
335 (efm32_info
->page_size
!= 4096)) {
336 LOG_ERROR("Invalid page size %u", efm32_info
->page_size
);
344 /* flash bank efm32 <base> <size> 0 0 <target#> */
345 FLASH_BANK_COMMAND_HANDLER(efm32x_flash_bank_command
)
347 struct efm32x_flash_chip
*efm32x_info
= NULL
;
350 return ERROR_COMMAND_SYNTAX_ERROR
;
352 int bank_index
= efm32x_get_bank_index(bank
->base
);
353 if (bank_index
< 0) {
354 LOG_ERROR("Flash bank with base address %" PRIx32
" is not supported",
355 (uint32_t) bank
->base
);
359 /* look for an existing flash structure matching target */
360 for (struct flash_bank
*bank_iter
= flash_bank_list(); bank_iter
; bank_iter
= bank_iter
->next
) {
361 if (bank_iter
->driver
== &efm32_flash
362 && bank_iter
->target
== bank
->target
363 && bank
->driver_priv
) {
364 efm32x_info
= bank
->driver_priv
;
370 /* target not matched, make a new one */
371 efm32x_info
= calloc(1, sizeof(struct efm32x_flash_chip
));
373 memset(efm32x_info
->lb_page
, 0xff, LOCKWORDS_SZ
);
376 ++efm32x_info
->refcount
;
377 bank
->driver_priv
= efm32x_info
;
383 * Remove flash structure corresponding to this bank,
384 * if and only if it's not used by any others
386 static void efm32x_free_driver_priv(struct flash_bank
*bank
)
388 struct efm32x_flash_chip
*efm32x_info
= bank
->driver_priv
;
391 /* Use ref count to determine if it can be freed; scanning bank list doesn't work,
392 * because this function can be called after some banks in the list have been
393 * already destroyed */
394 --efm32x_info
->refcount
;
395 if (efm32x_info
->refcount
== 0) {
397 bank
->driver_priv
= NULL
;
402 /* set or reset given bits in a register */
403 static int efm32x_set_reg_bits(struct flash_bank
*bank
, uint32_t reg
,
404 uint32_t bitmask
, int set
)
407 uint32_t reg_val
= 0;
409 ret
= efm32x_read_reg_u32(bank
, reg
, ®_val
);
418 return efm32x_write_reg_u32(bank
, reg
, reg_val
);
421 static int efm32x_set_wren(struct flash_bank
*bank
, int write_enable
)
423 return efm32x_set_reg_bits(bank
, EFM32_MSC_REG_WRITECTRL
,
424 EFM32_MSC_WRITECTRL_WREN_MASK
, write_enable
);
427 static int efm32x_msc_lock(struct flash_bank
*bank
, int lock
)
429 struct efm32x_flash_chip
*efm32x_info
= bank
->driver_priv
;
430 return efm32x_write_reg_u32(bank
, efm32x_info
->reg_lock
,
431 (lock
? 0 : EFM32_MSC_LOCK_LOCKKEY
));
434 static int efm32x_wait_status(struct flash_bank
*bank
, int timeout
,
435 uint32_t wait_mask
, int wait_for_set
)
441 ret
= efm32x_read_reg_u32(bank
, EFM32_MSC_REG_STATUS
, &status
);
445 LOG_DEBUG("status: 0x%" PRIx32
"", status
);
447 if (((status
& wait_mask
) == 0) && (wait_for_set
== 0))
449 else if (((status
& wait_mask
) != 0) && wait_for_set
)
452 if (timeout
-- <= 0) {
453 LOG_ERROR("timed out waiting for MSC status");
460 if (status
& EFM32_MSC_STATUS_ERASEABORTED_MASK
)
461 LOG_WARNING("page erase was aborted");
466 static int efm32x_erase_page(struct flash_bank
*bank
, uint32_t addr
)
468 /* this function DOES NOT set WREN; must be set already */
469 /* 1. write address to ADDRB
471 3. check status (INVADDR, LOCKED)
473 5. wait until !STATUS_BUSY
477 LOG_DEBUG("erasing flash page at 0x%08" PRIx32
, addr
);
479 ret
= efm32x_write_reg_u32(bank
, EFM32_MSC_REG_ADDRB
, addr
);
483 ret
= efm32x_set_reg_bits(bank
, EFM32_MSC_REG_WRITECMD
,
484 EFM32_MSC_WRITECMD_LADDRIM_MASK
, 1);
488 ret
= efm32x_read_reg_u32(bank
, EFM32_MSC_REG_STATUS
, &status
);
492 LOG_DEBUG("status 0x%" PRIx32
, status
);
494 if (status
& EFM32_MSC_STATUS_LOCKED_MASK
) {
495 LOG_ERROR("Page is locked");
497 } else if (status
& EFM32_MSC_STATUS_INVADDR_MASK
) {
498 LOG_ERROR("Invalid address 0x%" PRIx32
, addr
);
502 ret
= efm32x_set_reg_bits(bank
, EFM32_MSC_REG_WRITECMD
,
503 EFM32_MSC_WRITECMD_ERASEPAGE_MASK
, 1);
507 return efm32x_wait_status(bank
, EFM32_FLASH_ERASE_TMO
,
508 EFM32_MSC_STATUS_BUSY_MASK
, 0);
511 static int efm32x_erase(struct flash_bank
*bank
, unsigned int first
,
514 struct target
*target
= bank
->target
;
517 if (target
->state
!= TARGET_HALTED
) {
518 LOG_ERROR("Target not halted");
519 return ERROR_TARGET_NOT_HALTED
;
522 efm32x_msc_lock(bank
, 0);
523 ret
= efm32x_set_wren(bank
, 1);
524 if (ret
!= ERROR_OK
) {
525 LOG_ERROR("Failed to enable MSC write");
529 for (unsigned int i
= first
; i
<= last
; i
++) {
530 ret
= efm32x_erase_page(bank
, bank
->base
+ bank
->sectors
[i
].offset
);
532 LOG_ERROR("Failed to erase page %d", i
);
535 ret
= efm32x_set_wren(bank
, 0);
536 efm32x_msc_lock(bank
, 1);
540 if (bank
->base
== EFM32_MSC_LOCK_BITS
) {
541 ret
= efm32x_write_only_lockbits(bank
);
543 LOG_ERROR("Failed to restore lockbits after erase");
549 static int efm32x_read_lock_data(struct flash_bank
*bank
)
551 struct efm32x_flash_chip
*efm32x_info
= bank
->driver_priv
;
552 struct target
*target
= bank
->target
;
554 uint32_t *ptr
= NULL
;
557 assert(bank
->num_sectors
> 0);
559 /* calculate the number of 32-bit words to read (one lock bit per sector) */
560 data_size
= (bank
->num_sectors
+ 31) / 32;
562 ptr
= efm32x_info
->lb_page
;
564 for (int i
= 0; i
< data_size
; i
++, ptr
++) {
565 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+i
*4, ptr
);
566 if (ret
!= ERROR_OK
) {
567 LOG_ERROR("Failed to read PLW %d", i
);
572 /* also, read ULW, DLW, MLW, ALW and CLW words */
575 ptr
= efm32x_info
->lb_page
+ 126;
576 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+126*4, ptr
);
577 if (ret
!= ERROR_OK
) {
578 LOG_ERROR("Failed to read ULW");
583 ptr
= efm32x_info
->lb_page
+ 127;
584 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+127*4, ptr
);
585 if (ret
!= ERROR_OK
) {
586 LOG_ERROR("Failed to read DLW");
590 /* MLW, word 125, present in GG, LG, PG, JG, EFR32 */
591 ptr
= efm32x_info
->lb_page
+ 125;
592 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+125*4, ptr
);
593 if (ret
!= ERROR_OK
) {
594 LOG_ERROR("Failed to read MLW");
598 /* ALW, word 124, present in GG, LG, PG, JG, EFR32 */
599 ptr
= efm32x_info
->lb_page
+ 124;
600 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+124*4, ptr
);
601 if (ret
!= ERROR_OK
) {
602 LOG_ERROR("Failed to read ALW");
606 /* CLW1, word 123, present in EFR32 */
607 ptr
= efm32x_info
->lb_page
+ 123;
608 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+123*4, ptr
);
609 if (ret
!= ERROR_OK
) {
610 LOG_ERROR("Failed to read CLW1");
614 /* CLW0, word 122, present in GG, LG, PG, JG, EFR32 */
615 ptr
= efm32x_info
->lb_page
+ 122;
616 ret
= target_read_u32(target
, EFM32_MSC_LOCK_BITS
+122*4, ptr
);
617 if (ret
!= ERROR_OK
) {
618 LOG_ERROR("Failed to read CLW0");
625 static int efm32x_write_only_lockbits(struct flash_bank
*bank
)
627 struct efm32x_flash_chip
*efm32x_info
= bank
->driver_priv
;
628 return efm32x_priv_write(bank
, (uint8_t *)efm32x_info
->lb_page
, EFM32_MSC_LOCK_BITS
, LOCKWORDS_SZ
);
631 static int efm32x_write_lock_data(struct flash_bank
*bank
)
633 struct efm32x_flash_chip
*efm32x_info
= bank
->driver_priv
;
636 /* Preserve any data written to the high portion of the lockbits page */
637 assert(efm32x_info
->info
.page_size
>= LOCKWORDS_SZ
);
638 uint32_t extra_bytes
= efm32x_info
->info
.page_size
- LOCKWORDS_SZ
;
639 uint8_t *extra_data
= NULL
;
641 extra_data
= malloc(extra_bytes
);
642 ret
= target_read_buffer(bank
->target
, EFM32_MSC_LOCK_BITS_EXTRA
, extra_bytes
, extra_data
);
643 if (ret
!= ERROR_OK
) {
644 LOG_ERROR("Failed to read extra contents of LB page");
650 ret
= efm32x_erase_page(bank
, EFM32_MSC_LOCK_BITS
);
651 if (ret
!= ERROR_OK
) {
652 LOG_ERROR("Failed to erase LB page");
659 ret
= efm32x_priv_write(bank
, extra_data
, EFM32_MSC_LOCK_BITS_EXTRA
, extra_bytes
);
661 if (ret
!= ERROR_OK
) {
662 LOG_ERROR("Failed to restore extra contents of LB page");
667 return efm32x_write_only_lockbits(bank
);
670 static int efm32x_get_page_lock(struct flash_bank
*bank
, size_t page
)
672 struct efm32x_flash_chip
*efm32x_info
= bank
->driver_priv
;
676 switch (bank
->base
) {
677 case EFM32_FLASH_BASE
:
678 dw
= efm32x_info
->lb_page
[page
>> 5];
679 mask
= 1 << (page
& 0x1f);
681 case EFM32_MSC_USER_DATA
:
682 dw
= efm32x_info
->lb_page
[126];
685 case EFM32_MSC_LOCK_BITS
:
686 dw
= efm32x_info
->lb_page
[126];
691 return (dw
& mask
) ? 0 : 1;
694 static int efm32x_set_page_lock(struct flash_bank
*bank
, size_t page
, int set
)
696 struct efm32x_flash_chip
*efm32x_info
= bank
->driver_priv
;
698 if (bank
->base
!= EFM32_FLASH_BASE
) {
699 LOG_ERROR("Locking user and lockbits pages is not supported yet");
703 uint32_t *dw
= &efm32x_info
->lb_page
[page
>> 5];
706 mask
= 1 << (page
& 0x1f);
716 static int efm32x_protect(struct flash_bank
*bank
, int set
, unsigned int first
,
719 struct target
*target
= bank
->target
;
722 if (target
->state
!= TARGET_HALTED
) {
723 LOG_ERROR("Target not halted");
724 return ERROR_TARGET_NOT_HALTED
;
727 for (unsigned int i
= first
; i
<= last
; i
++) {
728 ret
= efm32x_set_page_lock(bank
, i
, set
);
729 if (ret
!= ERROR_OK
) {
730 LOG_ERROR("Failed to set lock on page %d", i
);
735 ret
= efm32x_write_lock_data(bank
);
736 if (ret
!= ERROR_OK
) {
737 LOG_ERROR("Failed to write LB page");
744 static int efm32x_write_block(struct flash_bank
*bank
, const uint8_t *buf
,
745 uint32_t address
, uint32_t count
)
747 struct target
*target
= bank
->target
;
748 uint32_t buffer_size
= 16384;
749 struct working_area
*write_algorithm
;
750 struct working_area
*source
;
751 struct reg_param reg_params
[5];
752 struct armv7m_algorithm armv7m_info
;
753 struct efm32x_flash_chip
*efm32x_info
= bank
->driver_priv
;
756 /* see contrib/loaders/flash/efm32.S for src */
757 static const uint8_t efm32x_flash_write_code
[] = {
758 /* #define EFM32_MSC_WRITECTRL_OFFSET 0x008 */
759 /* #define EFM32_MSC_WRITECMD_OFFSET 0x00c */
760 /* #define EFM32_MSC_ADDRB_OFFSET 0x010 */
761 /* #define EFM32_MSC_WDATA_OFFSET 0x018 */
762 /* #define EFM32_MSC_STATUS_OFFSET 0x01c */
764 0x01, 0x26, /* movs r6, #1 */
765 0x86, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECTRL_OFFSET] */
768 0x16, 0x68, /* ldr r6, [r2, #0] */
769 0x00, 0x2e, /* cmp r6, #0 */
770 0x22, 0xd0, /* beq exit */
771 0x55, 0x68, /* ldr r5, [r2, #4] */
772 0xb5, 0x42, /* cmp r5, r6 */
773 0xf9, 0xd0, /* beq wait_fifo */
775 0x04, 0x61, /* str r4, [r0, #EFM32_MSC_ADDRB_OFFSET] */
776 0x01, 0x26, /* movs r6, #1 */
777 0xc6, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] */
778 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
779 0x06, 0x27, /* movs r7, #6 */
780 0x3e, 0x42, /* tst r6, r7 */
781 0x16, 0xd1, /* bne error */
783 /* wait_wdataready: */
784 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
785 0x08, 0x27, /* movs r7, #8 */
786 0x3e, 0x42, /* tst r6, r7 */
787 0xfb, 0xd0, /* beq wait_wdataready */
789 0x2e, 0x68, /* ldr r6, [r5] */
790 0x86, 0x61, /* str r6, [r0, #EFM32_MSC_WDATA_OFFSET] */
791 0x08, 0x26, /* movs r6, #8 */
792 0xc6, 0x60, /* str r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] */
794 0x04, 0x35, /* adds r5, #4 */
795 0x04, 0x34, /* adds r4, #4 */
798 0xc6, 0x69, /* ldr r6, [r0, #EFM32_MSC_STATUS_OFFSET] */
799 0x01, 0x27, /* movs r7, #1 */
800 0x3e, 0x42, /* tst r6, r7 */
801 0xfb, 0xd1, /* bne busy */
803 0x9d, 0x42, /* cmp r5, r3 */
804 0x01, 0xd3, /* bcc no_wrap */
805 0x15, 0x46, /* mov r5, r2 */
806 0x08, 0x35, /* adds r5, #8 */
809 0x55, 0x60, /* str r5, [r2, #4] */
810 0x01, 0x39, /* subs r1, r1, #1 */
811 0x00, 0x29, /* cmp r1, #0 */
812 0x02, 0xd0, /* beq exit */
813 0xdb, 0xe7, /* b wait_fifo */
816 0x00, 0x20, /* movs r0, #0 */
817 0x50, 0x60, /* str r0, [r2, #4] */
820 0x30, 0x46, /* mov r0, r6 */
821 0x00, 0xbe, /* bkpt #0 */
825 /* flash write code */
826 if (target_alloc_working_area(target
, sizeof(efm32x_flash_write_code
),
827 &write_algorithm
) != ERROR_OK
) {
828 LOG_WARNING("no working area available, can't do block memory writes");
829 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
832 ret
= target_write_buffer(target
, write_algorithm
->address
,
833 sizeof(efm32x_flash_write_code
), efm32x_flash_write_code
);
838 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
) {
840 buffer_size
&= ~3UL; /* Make sure it's 4 byte aligned */
841 if (buffer_size
<= 256) {
842 /* we already allocated the writing code, but failed to get a
843 * buffer, free the algorithm */
844 target_free_working_area(target
, write_algorithm
);
846 LOG_WARNING("no large enough working area available, can't do block memory writes");
847 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
851 init_reg_param(®_params
[0], "r0", 32, PARAM_IN_OUT
); /* flash base (in), status (out) */
852 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* count (word-32bit) */
853 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* buffer start */
854 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
); /* buffer end */
855 init_reg_param(®_params
[4], "r4", 32, PARAM_IN_OUT
); /* target address */
857 buf_set_u32(reg_params
[0].value
, 0, 32, efm32x_info
->reg_base
);
858 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
859 buf_set_u32(reg_params
[2].value
, 0, 32, source
->address
);
860 buf_set_u32(reg_params
[3].value
, 0, 32, source
->address
+ source
->size
);
861 buf_set_u32(reg_params
[4].value
, 0, 32, address
);
863 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
864 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
866 ret
= target_run_flash_async_algorithm(target
, buf
, count
, 4,
869 source
->address
, source
->size
,
870 write_algorithm
->address
, 0,
873 if (ret
== ERROR_FLASH_OPERATION_FAILED
) {
874 LOG_ERROR("flash write failed at address 0x%"PRIx32
,
875 buf_get_u32(reg_params
[4].value
, 0, 32));
877 if (buf_get_u32(reg_params
[0].value
, 0, 32) &
878 EFM32_MSC_STATUS_LOCKED_MASK
) {
879 LOG_ERROR("flash memory write protected");
882 if (buf_get_u32(reg_params
[0].value
, 0, 32) &
883 EFM32_MSC_STATUS_INVADDR_MASK
) {
884 LOG_ERROR("invalid flash memory write address");
888 target_free_working_area(target
, source
);
889 target_free_working_area(target
, write_algorithm
);
891 destroy_reg_param(®_params
[0]);
892 destroy_reg_param(®_params
[1]);
893 destroy_reg_param(®_params
[2]);
894 destroy_reg_param(®_params
[3]);
895 destroy_reg_param(®_params
[4]);
900 static int efm32x_write_word(struct flash_bank
*bank
, uint32_t addr
,
903 /* this function DOES NOT set WREN; must be set already */
904 /* 1. write address to ADDRB
906 3. check status (INVADDR, LOCKED)
907 4. wait for WDATAREADY
908 5. write data to WDATA
909 6. write WRITECMD_WRITEONCE to WRITECMD
910 7. wait until !STATUS_BUSY
913 /* FIXME: EFM32G ref states (7.3.2) that writes should be
914 * performed twice per dword */
919 /* if not called, GDB errors will be reported during large writes */
922 ret
= efm32x_write_reg_u32(bank
, EFM32_MSC_REG_ADDRB
, addr
);
926 ret
= efm32x_set_reg_bits(bank
, EFM32_MSC_REG_WRITECMD
,
927 EFM32_MSC_WRITECMD_LADDRIM_MASK
, 1);
931 ret
= efm32x_read_reg_u32(bank
, EFM32_MSC_REG_STATUS
, &status
);
935 LOG_DEBUG("status 0x%" PRIx32
, status
);
937 if (status
& EFM32_MSC_STATUS_LOCKED_MASK
) {
938 LOG_ERROR("Page is locked");
940 } else if (status
& EFM32_MSC_STATUS_INVADDR_MASK
) {
941 LOG_ERROR("Invalid address 0x%" PRIx32
, addr
);
945 ret
= efm32x_wait_status(bank
, EFM32_FLASH_WDATAREADY_TMO
,
946 EFM32_MSC_STATUS_WDATAREADY_MASK
, 1);
947 if (ret
!= ERROR_OK
) {
948 LOG_ERROR("Wait for WDATAREADY failed");
952 ret
= efm32x_write_reg_u32(bank
, EFM32_MSC_REG_WDATA
, val
);
953 if (ret
!= ERROR_OK
) {
954 LOG_ERROR("WDATA write failed");
958 ret
= efm32x_write_reg_u32(bank
, EFM32_MSC_REG_WRITECMD
,
959 EFM32_MSC_WRITECMD_WRITEONCE_MASK
);
960 if (ret
!= ERROR_OK
) {
961 LOG_ERROR("WRITECMD write failed");
965 ret
= efm32x_wait_status(bank
, EFM32_FLASH_WRITE_TMO
,
966 EFM32_MSC_STATUS_BUSY_MASK
, 0);
967 if (ret
!= ERROR_OK
) {
968 LOG_ERROR("Wait for BUSY failed");
975 static int efm32x_priv_write(struct flash_bank
*bank
, const uint8_t *buffer
,
976 uint32_t addr
, uint32_t count
)
978 struct target
*target
= bank
->target
;
979 uint8_t *new_buffer
= NULL
;
981 if (target
->state
!= TARGET_HALTED
) {
982 LOG_ERROR("Target not halted");
983 return ERROR_TARGET_NOT_HALTED
;
987 LOG_ERROR("addr 0x%" PRIx32
" breaks required 4-byte "
989 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
993 uint32_t old_count
= count
;
994 count
= (old_count
| 3) + 1;
995 new_buffer
= malloc(count
);
997 LOG_ERROR("odd number of bytes to write and no memory "
998 "for padding buffer");
1001 LOG_INFO("odd number of bytes to write (%" PRIu32
"), extending to %" PRIu32
" "
1002 "and padding with 0xff", old_count
, count
);
1003 memset(new_buffer
, 0xff, count
);
1004 buffer
= memcpy(new_buffer
, buffer
, old_count
);
1007 uint32_t words_remaining
= count
/ 4;
1008 int retval
, retval2
;
1010 /* unlock flash registers */
1011 efm32x_msc_lock(bank
, 0);
1012 retval
= efm32x_set_wren(bank
, 1);
1013 if (retval
!= ERROR_OK
)
1016 /* try using a block write */
1017 retval
= efm32x_write_block(bank
, buffer
, addr
, words_remaining
);
1019 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
) {
1020 /* if block write failed (no sufficient working area),
1021 * we use normal (slow) single word accesses */
1022 LOG_WARNING("couldn't use block writes, falling back to single "
1025 while (words_remaining
> 0) {
1027 memcpy(&value
, buffer
, sizeof(uint32_t));
1029 retval
= efm32x_write_word(bank
, addr
, value
);
1030 if (retval
!= ERROR_OK
)
1031 goto reset_pg_and_lock
;
1040 retval2
= efm32x_set_wren(bank
, 0);
1041 efm32x_msc_lock(bank
, 1);
1042 if (retval
== ERROR_OK
)
1050 static int efm32x_write(struct flash_bank
*bank
, const uint8_t *buffer
,
1051 uint32_t offset
, uint32_t count
)
1053 if (bank
->base
== EFM32_MSC_LOCK_BITS
&& offset
< LOCKWORDS_SZ
) {
1054 LOG_ERROR("Cannot write to lock words");
1057 return efm32x_priv_write(bank
, buffer
, bank
->base
+ offset
, count
);
1060 static int efm32x_probe(struct flash_bank
*bank
)
1062 struct efm32x_flash_chip
*efm32x_info
= bank
->driver_priv
;
1063 struct efm32_info
*efm32_mcu_info
= &(efm32x_info
->info
);
1066 int bank_index
= efm32x_get_bank_index(bank
->base
);
1067 assert(bank_index
>= 0);
1069 efm32x_info
->probed
[bank_index
] = false;
1070 memset(efm32x_info
->lb_page
, 0xff, LOCKWORDS_SZ
);
1072 ret
= efm32x_read_info(bank
);
1073 if (ret
!= ERROR_OK
)
1076 LOG_INFO("detected part: %s Gecko, rev %d",
1077 efm32_mcu_info
->family_data
->name
, efm32_mcu_info
->prod_rev
);
1078 LOG_INFO("flash size = %d KiB", efm32_mcu_info
->flash_sz_kib
);
1079 LOG_INFO("flash page size = %d B", efm32_mcu_info
->page_size
);
1081 assert(efm32_mcu_info
->page_size
!= 0);
1083 free(bank
->sectors
);
1084 bank
->sectors
= NULL
;
1086 if (bank
->base
== EFM32_FLASH_BASE
) {
1087 bank
->num_sectors
= efm32_mcu_info
->flash_sz_kib
* 1024 /
1088 efm32_mcu_info
->page_size
;
1089 assert(bank
->num_sectors
> 0);
1091 ret
= efm32x_read_lock_data(bank
);
1092 if (ret
!= ERROR_OK
) {
1093 LOG_ERROR("Failed to read LB data");
1097 bank
->num_sectors
= 1;
1098 bank
->size
= bank
->num_sectors
* efm32_mcu_info
->page_size
;
1099 bank
->sectors
= malloc(sizeof(struct flash_sector
) * bank
->num_sectors
);
1101 for (uint32_t i
= 0; i
< bank
->num_sectors
; i
++) {
1102 bank
->sectors
[i
].offset
= i
* efm32_mcu_info
->page_size
;
1103 bank
->sectors
[i
].size
= efm32_mcu_info
->page_size
;
1104 bank
->sectors
[i
].is_erased
= -1;
1105 bank
->sectors
[i
].is_protected
= 1;
1108 efm32x_info
->probed
[bank_index
] = true;
1113 static int efm32x_auto_probe(struct flash_bank
*bank
)
1115 struct efm32x_flash_chip
*efm32x_info
= bank
->driver_priv
;
1117 int bank_index
= efm32x_get_bank_index(bank
->base
);
1118 assert(bank_index
>= 0);
1120 if (efm32x_info
->probed
[bank_index
])
1122 return efm32x_probe(bank
);
1125 static int efm32x_protect_check(struct flash_bank
*bank
)
1127 struct target
*target
= bank
->target
;
1130 if (target
->state
!= TARGET_HALTED
) {
1131 LOG_ERROR("Target not halted");
1132 return ERROR_TARGET_NOT_HALTED
;
1135 ret
= efm32x_read_lock_data(bank
);
1136 if (ret
!= ERROR_OK
) {
1137 LOG_ERROR("Failed to read LB data");
1141 assert(bank
->sectors
);
1143 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++)
1144 bank
->sectors
[i
].is_protected
= efm32x_get_page_lock(bank
, i
);
1149 static int get_efm32x_info(struct flash_bank
*bank
, struct command_invocation
*cmd
)
1151 struct efm32x_flash_chip
*efm32x_info
= bank
->driver_priv
;
1154 ret
= efm32x_read_info(bank
);
1155 if (ret
!= ERROR_OK
) {
1156 LOG_ERROR("Failed to read EFM32 info");
1160 command_print_sameline(cmd
, "%s Gecko, rev %d", efm32x_info
->info
.family_data
->name
,
1161 efm32x_info
->info
.prod_rev
);
1165 COMMAND_HANDLER(efm32x_handle_debuglock_command
)
1167 struct target
*target
= NULL
;
1170 return ERROR_COMMAND_SYNTAX_ERROR
;
1172 struct flash_bank
*bank
;
1173 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1174 if (retval
!= ERROR_OK
)
1177 struct efm32x_flash_chip
*efm32x_info
= bank
->driver_priv
;
1179 target
= bank
->target
;
1181 if (target
->state
!= TARGET_HALTED
) {
1182 LOG_ERROR("Target not halted");
1183 return ERROR_TARGET_NOT_HALTED
;
1187 ptr
= efm32x_info
->lb_page
+ 127;
1190 retval
= efm32x_write_lock_data(bank
);
1191 if (retval
!= ERROR_OK
) {
1192 LOG_ERROR("Failed to write LB page");
1196 command_print(CMD
, "efm32x debug interface locked, reset the device to apply");
1201 static const struct command_registration efm32x_exec_command_handlers
[] = {
1203 .name
= "debuglock",
1204 .handler
= efm32x_handle_debuglock_command
,
1205 .mode
= COMMAND_EXEC
,
1207 .help
= "Lock the debug interface of the device.",
1209 COMMAND_REGISTRATION_DONE
1212 static const struct command_registration efm32x_command_handlers
[] = {
1215 .mode
= COMMAND_ANY
,
1216 .help
= "efm32 flash command group",
1218 .chain
= efm32x_exec_command_handlers
,
1220 COMMAND_REGISTRATION_DONE
1223 const struct flash_driver efm32_flash
= {
1225 .commands
= efm32x_command_handlers
,
1226 .flash_bank_command
= efm32x_flash_bank_command
,
1227 .erase
= efm32x_erase
,
1228 .protect
= efm32x_protect
,
1229 .write
= efm32x_write
,
1230 .read
= default_flash_read
,
1231 .probe
= efm32x_probe
,
1232 .auto_probe
= efm32x_auto_probe
,
1233 .erase_check
= default_flash_blank_check
,
1234 .protect_check
= efm32x_protect_check
,
1235 .info
= get_efm32x_info
,
1236 .free_driver_priv
= efm32x_free_driver_priv
,
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)