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;
262 LOG_ERROR(
"Target is not Cortex-Mx Device");
353 if (bank_index < 0) {
354 LOG_ERROR(
"Flash bank with base address %" PRIx32
" is not supported",
355 (uint32_t)
bank->base);
362 && bank_iter->target ==
bank->target
363 &&
bank->driver_priv) {
364 efm32x_info =
bank->driver_priv;
377 bank->driver_priv = efm32x_info;
404 uint32_t bitmask,
int set)
407 uint32_t reg_val = 0;
435 uint32_t wait_mask,
int wait_for_set)
447 if (((
status & wait_mask) == 0) && (wait_for_set == 0))
449 else if (((
status & wait_mask) != 0) && wait_for_set)
453 LOG_ERROR(
"timed out waiting for MSC status");
529 for (
unsigned int i = first; i <= last; i++) {
543 LOG_ERROR(
"Failed to restore lockbits after erase");
554 uint32_t *ptr =
NULL;
557 assert(
bank->num_sectors > 0);
560 data_size = (
bank->num_sectors + 31) / 32;
564 for (
int i = 0; i < data_size; i++, ptr++) {
575 ptr = efm32x_info->
lb_page + 126;
583 ptr = efm32x_info->
lb_page + 127;
591 ptr = efm32x_info->
lb_page + 125;
599 ptr = efm32x_info->
lb_page + 124;
607 ptr = efm32x_info->
lb_page + 123;
615 ptr = efm32x_info->
lb_page + 122;
639 uint8_t *extra_data =
NULL;
641 extra_data = malloc(extra_bytes);
644 LOG_ERROR(
"Failed to read extra contents of LB page");
662 LOG_ERROR(
"Failed to restore extra contents of LB page");
676 switch (
bank->base) {
678 dw = efm32x_info->
lb_page[page >> 5];
679 mask = 1 << (page & 0x1f);
682 dw = efm32x_info->
lb_page[126];
686 dw = efm32x_info->
lb_page[126];
691 return (dw &
mask) ? 0 : 1;
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);
727 for (
unsigned int i = first; i <= last; i++) {
730 LOG_ERROR(
"Failed to set lock on page %d", i);
745 uint32_t address, uint32_t
count)
748 uint32_t buffer_size = 16384;
757 static const uint8_t efm32x_flash_write_code[] = {
828 LOG_WARNING(
"no working area available, can't do block memory writes");
833 sizeof(efm32x_flash_write_code), efm32x_flash_write_code);
841 if (buffer_size <= 256) {
846 LOG_WARNING(
"no large enough working area available, can't do block memory writes");
874 LOG_ERROR(
"flash write failed at address 0x%"PRIx32,
879 LOG_ERROR(
"flash memory write protected");
884 LOG_ERROR(
"invalid flash memory write address");
979 uint8_t *new_buffer =
NULL;
987 LOG_ERROR(
"addr 0x%" PRIx32
" breaks required 4-byte "
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);
1007 uint32_t words_remaining =
count / 4;
1008 int retval, retval2;
1022 LOG_WARNING(
"couldn't use block writes, falling back to single "
1025 while (words_remaining > 0) {
1027 memcpy(&value,
buffer,
sizeof(uint32_t));
1031 goto reset_pg_and_lock;
1054 LOG_ERROR(
"Cannot write to lock words");
1067 assert(bank_index >= 0);
1069 efm32x_info->
probed[bank_index] =
false;
1076 LOG_INFO(
"detected part: %s Gecko, rev %d",
1083 free(
bank->sectors);
1089 assert(
bank->num_sectors > 0);
1097 bank->num_sectors = 1;
1101 for (uint32_t i = 0; i <
bank->num_sectors; i++) {
1104 bank->sectors[i].is_erased = -1;
1105 bank->sectors[i].is_protected = 1;
1108 efm32x_info->
probed[bank_index] =
true;
1118 assert(bank_index >= 0);
1120 if (efm32x_info->
probed[bank_index])
1141 assert(
bank->sectors);
1143 for (
unsigned int i = 0; i <
bank->num_sectors; i++)
1187 ptr = efm32x_info->
lb_page + 127;
1196 command_print(
CMD,
"efm32x debug interface locked, reset the device to apply");
1203 .
name =
"debuglock",
1204 .handler = efm32x_handle_debuglock_command,
1207 .help =
"Lock the debug interface of the device.",
1216 .help =
"efm32 flash command group",
1226 .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 first, unsigned 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 first, unsigned 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 struct cortex_m_common * target_to_cm(struct target *target)
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 ...)
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 cortex_m_part_info * core_info
enum cortex_m_partno partno
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.