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
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)
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
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 },
232 uint32_t base = efm32x_info->
reg_base;
241 uint32_t base = efm32x_info->
reg_base;
341 if (bank_index < 0) {
342 LOG_ERROR(
"Flash bank with base address %" PRIx32
" is not supported",
343 (uint32_t)
bank->base);
350 && bank_iter->target ==
bank->target
351 &&
bank->driver_priv) {
352 efm32x_info =
bank->driver_priv;
365 bank->driver_priv = efm32x_info;
392 uint32_t bitmask,
int set)
395 uint32_t reg_val = 0;
423 uint32_t wait_mask,
int wait_for_set)
435 if (((
status & wait_mask) == 0) && (wait_for_set == 0))
437 else if (((
status & wait_mask) != 0) && wait_for_set)
441 LOG_ERROR(
"timed out waiting for MSC status");
517 for (
unsigned int i = first; i <= last; i++) {
531 LOG_ERROR(
"Failed to restore lockbits after erase");
542 uint32_t *ptr =
NULL;
545 assert(
bank->num_sectors > 0);
548 data_size = (
bank->num_sectors + 31) / 32;
552 for (
int i = 0; i < data_size; i++, ptr++) {
563 ptr = efm32x_info->
lb_page + 126;
571 ptr = efm32x_info->
lb_page + 127;
579 ptr = efm32x_info->
lb_page + 125;
587 ptr = efm32x_info->
lb_page + 124;
595 ptr = efm32x_info->
lb_page + 123;
603 ptr = efm32x_info->
lb_page + 122;
627 uint8_t *extra_data =
NULL;
629 extra_data = malloc(extra_bytes);
632 LOG_ERROR(
"Failed to read extra contents of LB page");
650 LOG_ERROR(
"Failed to restore extra contents of LB page");
664 switch (
bank->base) {
666 dw = efm32x_info->
lb_page[page >> 5];
667 mask = 1 << (page & 0x1f);
670 dw = efm32x_info->
lb_page[126];
674 dw = efm32x_info->
lb_page[126];
679 return (dw &
mask) ? 0 : 1;
687 LOG_ERROR(
"Locking user and lockbits pages is not supported yet");
691 uint32_t *dw = &efm32x_info->
lb_page[page >> 5];
694 mask = 1 << (page & 0x1f);
715 for (
unsigned int i = first; i <= last; i++) {
718 LOG_ERROR(
"Failed to set lock on page %d", i);
733 uint32_t address, uint32_t
count)
736 uint32_t buffer_size = 16384;
745 static const uint8_t efm32x_flash_write_code[] = {
816 LOG_WARNING(
"no working area available, can't do block memory writes");
821 sizeof(efm32x_flash_write_code), efm32x_flash_write_code);
829 if (buffer_size <= 256) {
834 LOG_WARNING(
"no large enough working area available, can't do block memory writes");
862 LOG_ERROR(
"flash write failed at address 0x%"PRIx32,
867 LOG_ERROR(
"flash memory write protected");
872 LOG_ERROR(
"invalid flash memory write address");
967 uint8_t *new_buffer =
NULL;
975 LOG_ERROR(
"addr 0x%" PRIx32
" breaks required 4-byte "
981 uint32_t old_count =
count;
982 count = (old_count | 3) + 1;
983 new_buffer = malloc(
count);
985 LOG_ERROR(
"odd number of bytes to write and no memory "
986 "for padding buffer");
989 LOG_INFO(
"odd number of bytes to write (%" PRIu32
"), extending to %" PRIu32
" "
990 "and padding with 0xff", old_count,
count);
991 memset(new_buffer, 0xff,
count);
995 uint32_t words_remaining =
count / 4;
1010 LOG_WARNING(
"couldn't use block writes, falling back to single "
1013 while (words_remaining > 0) {
1015 memcpy(&value,
buffer,
sizeof(uint32_t));
1019 goto reset_pg_and_lock;
1042 LOG_ERROR(
"Cannot write to lock words");
1055 assert(bank_index >= 0);
1057 efm32x_info->
probed[bank_index] =
false;
1064 LOG_INFO(
"detected part: %s Gecko, rev %d",
1071 free(
bank->sectors);
1077 assert(
bank->num_sectors > 0);
1085 bank->num_sectors = 1;
1089 for (uint32_t i = 0; i <
bank->num_sectors; i++) {
1092 bank->sectors[i].is_erased = -1;
1093 bank->sectors[i].is_protected = 1;
1096 efm32x_info->
probed[bank_index] =
true;
1106 assert(bank_index >= 0);
1108 if (efm32x_info->
probed[bank_index])
1129 assert(
bank->sectors);
1131 for (
unsigned int i = 0; i <
bank->num_sectors; i++)
1175 ptr = efm32x_info->
lb_page + 127;
1184 command_print(
CMD,
"efm32x debug interface locked, reset the device to apply");
1191 .
name =
"debuglock",
1192 .handler = efm32x_handle_debuglock_command,
1195 .help =
"Lock the debug interface of the device.",
1204 .help =
"efm32 flash command group",
1214 .flash_bank_command = efm32x_flash_bank_command,
void init_reg_param(struct reg_param *param, char *reg_name, uint32_t size, enum param_direction direction)
void destroy_reg_param(struct reg_param *param)
#define ARMV7M_COMMON_MAGIC
Support functions to access arbitrary bits in a byte array.
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned int first, unsigned int num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 32-bit word.
static void buf_set_u32(uint8_t *_buffer, unsigned int first, unsigned int num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
void command_print_sameline(struct command_invocation *cmd, const char *format,...)
void command_print(struct command_invocation *cmd, const char *format,...)
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
#define CALL_COMMAND_HANDLER(name, extra ...)
Use this to macro to call a command helper (or a nested handler).
#define ERROR_COMMAND_SYNTAX_ERROR
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
static int efm32x_read_lock_data(struct flash_bank *bank)
static int efm32x_get_flash_size(struct flash_bank *bank, uint16_t *flash_sz)
static int efm32x_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
static int efm32x_protect(struct flash_bank *bank, int set, unsigned int first, unsigned int last)
static const struct efm32_family_data efm32_families[]
static int efm32x_get_bank_index(target_addr_t base)
static int efm32x_erase_page(struct flash_bank *bank, uint32_t addr)
#define EFM_FAMILY_ID_LEOPARD_GECKO
#define EFM32_MSC_STATUS_ERASEABORTED_MASK
#define EFM32_MSC_LOCK_BITS
static int efm32x_write_lock_data(struct flash_bank *bank)
#define EFM32_MSC_DI_FLASH_SZ
static int efm32x_auto_probe(struct flash_bank *bank)
static int efm32x_protect_check(struct flash_bank *bank)
#define EFM32_MSC_USER_DATA
#define EFM32_MSC_STATUS_WDATAREADY_MASK
#define EFM32_MSC_STATUS_BUSY_MASK
static int efm32x_write_block(struct flash_bank *bank, const uint8_t *buf, uint32_t address, uint32_t count)
#define EFM32_MSC_REG_WRITECMD
#define EFM32_MSC_REG_STATUS
static int efm32x_get_ram_size(struct flash_bank *bank, uint16_t *ram_sz)
static int efm32x_priv_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t addr, uint32_t count)
#define EFM32_MSC_LOCK_BITS_EXTRA
#define EFM32_MSC_DI_PART_FAMILY
#define EFM32_MSC_WRITECMD_LADDRIM_MASK
#define EFM32_MSC_REG_LOCK
#define EFM32_MSC_DI_PROD_REV
#define EFM32_MSC_LOCK_LOCKKEY
static const struct command_registration efm32x_exec_command_handlers[]
#define EFM_FAMILY_ID_GIANT_GECKO
static int efm32x_set_page_lock(struct flash_bank *bank, size_t page, int set)
#define EFM32_MSC_WRITECMD_WRITEONCE_MASK
static int efm32x_set_wren(struct flash_bank *bank, int write_enable)
static int efm32x_wait_status(struct flash_bank *bank, int timeout, uint32_t wait_mask, int wait_for_set)
FLASH_BANK_COMMAND_HANDLER(efm32x_flash_bank_command)
static int efm32x_read_reg_u32(struct flash_bank *bank, target_addr_t offset, uint32_t *value)
#define EFM32_MSC_REGBASE_SERIES1
static const struct command_registration efm32x_command_handlers[]
#define EFM32_MSC_REGBASE
#define EFM32_MSC_REG_WDATA
#define EFM32_MSC_WRITECTRL_WREN_MASK
static void efm32x_free_driver_priv(struct flash_bank *bank)
Remove flash structure corresponding to this bank, if and only if it's not used by any others.
const struct flash_driver efm32_flash
#define EFM32_FLASH_ERASE_TMO
static int efm32x_get_prod_rev(struct flash_bank *bank, uint8_t *prev)
static int efm32x_get_part_num(struct flash_bank *bank, uint16_t *pnum)
#define EFM32_FLASH_WDATAREADY_TMO
static int efm32x_get_part_family(struct flash_bank *bank, uint8_t *pfamily)
static int efm32x_set_reg_bits(struct flash_bank *bank, uint32_t reg, uint32_t bitmask, int set)
COMMAND_HANDLER(efm32x_handle_debuglock_command)
@ EFM32_BANK_INDEX_USER_DATA
@ EFM32_BANK_INDEX_LOCK_BITS
#define EFM32_MSC_DI_PAGE_SIZE
static int efm32x_probe(struct flash_bank *bank)
static int efm32x_write_reg_u32(struct flash_bank *bank, target_addr_t offset, uint32_t value)
static int efm32x_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
#define EFM32_MSC_REG_ADDRB
#define EFM32_MSC_STATUS_INVADDR_MASK
#define EFM32_MSC_STATUS_LOCKED_MASK
static int efm32x_write_word(struct flash_bank *bank, uint32_t addr, uint32_t val)
static int efm32x_write_only_lockbits(struct flash_bank *bank)
#define EFM32_MSC_REG_WRITECTRL
#define EFM32_MSC_DI_PART_NUM
static int efm32x_get_page_lock(struct flash_bank *bank, size_t page)
#define EFM32_MSC_DI_RAM_SZ
#define EFM32_MSC_REG_LOCK_SERIES1
static int get_efm32x_info(struct flash_bank *bank, struct command_invocation *cmd)
#define EFM32_MSC_WRITECMD_ERASEPAGE_MASK
#define EFM32_FLASH_WRITE_TMO
static int efm32x_read_info(struct flash_bank *bank)
static int efm32x_msc_lock(struct flash_bank *bank, int lock)
#define ERROR_FLASH_OPERATION_FAILED
#define ERROR_FLASH_DST_BREAKS_ALIGNMENT
int default_flash_blank_check(struct flash_bank *bank)
Provides default erased-bank check handling.
int default_flash_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
Provides default read implementation for flash memory.
struct flash_bank * flash_bank_list(void)
void alive_sleep(uint64_t ms)
#define LOG_WARNING(expr ...)
#define LOG_ERROR(expr ...)
#define LOG_INFO(expr ...)
#define LOG_DEBUG(expr ...)
target_addr_t addr
Start address to search for the control block.
unsigned int common_magic
When run_command is called, a new instance will be created on the stack, filled with the proper value...
const struct efm32_family_data * family_data
uint32_t lb_page[LOCKWORDS_SZ/4]
bool probed[EFM32_N_BANKS]
Provides details of a flash bank, available either on-chip or through a major interface.
struct flash_bank * next
The next flash bank on this chip.
Provides the implementation-independent structure that defines all of the callbacks required by OpenO...
const char * name
Gives a human-readable name of this flash driver, This field is used to select and initialize the dri...
Describes the geometry and status of a single flash sector within a flash bank.
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
int target_read_buffer(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)
int target_read_u8(struct target *target, target_addr_t address, uint8_t *value)
int target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
int target_free_working_area(struct target *target, struct working_area *area)
Free a working area.
int target_alloc_working_area_try(struct target *target, uint32_t size, struct working_area **area)
int target_read_u16(struct target *target, target_addr_t address, uint16_t *value)
int target_run_flash_async_algorithm(struct target *target, const uint8_t *buffer, uint32_t count, int block_size, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, uint32_t buffer_start, uint32_t buffer_size, uint32_t entry_point, uint32_t exit_point, void *arch_info)
Streams data to a circular buffer on target intended for consumption by code running asynchronously o...
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
#define ERROR_TARGET_NOT_HALTED
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.