18 #define FLSH_ADDR 0x000
19 #define FLSH_CLKDIV 0x004
21 #define PR1E_ADDR 0x00C
22 #define PR2S_ADDR 0x010
23 #define PR2E_ADDR 0x014
24 #define PR3S_ADDR 0x018
25 #define PR3E_ADDR 0x01C
27 #define FLSH_INT 0x024
28 #define FLSH_DATA0 0x030
29 #define FLSH_DATA1 0x034
30 #define FLSH_DATA2 0x038
31 #define FLSH_DATA3 0x03C
32 #define FLSH_BL_CTRL 0x170
33 #define FLSH_PROT 0x300
35 #define ARM_PID_REG 0xE00FFFE0
36 #define MAX326XX_ID_REG 0x40000838
39 #define FLSH_INT_AF 0x00000002
41 #define FLSH_CN_UNLOCK_MASK 0xF0000000
42 #define FLSH_CN_UNLOCK_VALUE 0x20000000
44 #define FLSH_CN_PEND 0x01000000
46 #define FLSH_CN_ERASE_CODE_MASK 0x0000FF00
47 #define FLSH_CN_ERASE_CODE_PGE 0x00005500
48 #define FLSH_CN_ERASE_CODE_ME 0x0000AA00
50 #define FLSH_CN_PGE 0x00000004
51 #define FLSH_CN_ME 0x00000002
52 #define FLSH_CN_WR 0x00000001
53 #define FLASH_BL_CTRL_23 0x00020000
54 #define FLASH_BL_CTRL_IFREN 0x00000001
56 #define ARM_PID_DEFAULT_CM3 0xB4C3
57 #define ARM_PID_DEFAULT_CM4 0xB4C4
58 #define MAX326XX_ID 0x4D
75 #include "../../../contrib/loaders/flash/max32xxx/max32xxx.inc"
86 LOG_WARNING(
"incomplete flash bank max32xxx configuration: <base> <size> 0 0 <target> <FLC base> <sector size> <clkdiv> [burst_bits]");
99 info->burst_size_bits = 32;
143 LOG_ERROR(
"Read failure on FLSH_BL_CTRL");
147 LOG_WARNING(
"FLSH_BL_CTRL indicates BL mode 2 or mode 3.");
149 LOG_WARNING(
"Flash page 0 swapped out, attempting to swap back in for programming");
152 LOG_ERROR(
"Write failure on FLSH_BL_CTRL");
156 LOG_ERROR(
"Read failure on FLSH_BL_CTRL");
161 LOG_ERROR(
"Unable to swap flash page 0 back in. Writes to page 0 will fail.");
204 if (!
info->max326xx) {
205 for (
unsigned i = 0; i <
bank->num_sectors; i++)
206 bank->sectors[i].is_protected = -1;
212 for (
unsigned i = 0; i <
bank->num_sectors; i++) {
216 if (temp_reg & (0x1 << i%32))
217 bank->sectors[i].is_protected = 1;
219 bank->sectors[i].is_protected = 0;
227 uint32_t flsh_cn, flsh_int;
241 if ((last < first) || (last >=
bank->num_sectors))
244 if ((first == 0) && (last == (
bank->num_sectors - 1)))
254 for (
unsigned int banknr = first; banknr <= last; banknr++) {
257 if (
bank->sectors[banknr].is_protected == 1) {
258 LOG_WARNING(
"Flash sector %u is protected", banknr);
282 LOG_ERROR(
"Timed out waiting for flash page erase @ 0x%08x",
283 banknr *
info->sector_size);
290 LOG_ERROR(
"Error erasing flash page %i", banknr);
298 LOG_ERROR(
"All pages protected %u to %u", first, last);
310 unsigned int first,
unsigned int last)
327 if ((last < first) || (last >=
bank->num_sectors))
331 for (
unsigned int page = first; page <= last; page++) {
335 temp_reg |= (0x1 << page%32);
337 bank->sectors[page].is_protected = 1;
341 temp_reg &= ~(0x1 << page%32);
343 bank->sectors[page].is_protected = 0;
351 uint32_t
offset, uint32_t wcount)
355 uint32_t buffer_size = 16384;
363 static const unsigned buf_min = 128;
366 if (wcount * 4 < buf_min)
369 LOG_DEBUG(
"(bank=%p buffer=%p offset=%08" PRIx32
" wcount=%08" PRIx32
"",
374 LOG_DEBUG(
"no working area for block memory writes");
379 if (wcount * 4 < buffer_size)
380 buffer_size = wcount * 4;
386 if (buffer_size <= buf_min) {
391 LOG_DEBUG(
"retry target_alloc_working_area(%s, size=%u)",
415 LOG_ERROR(
"error %d executing max32xxx flash write algorithm", retval);
432 uint32_t flsh_cn, flsh_int;
433 uint32_t address =
offset;
434 uint32_t remaining =
count;
435 uint32_t words_remaining;
444 LOG_DEBUG(
"bank=%p buffer=%p offset=%08" PRIx32
" count=%08" PRIx32
"",
464 if (remaining >= 4) {
467 flsh_cn &= 0xF7FFFFFF;
468 flsh_cn |= 0x00000010;
472 words_remaining = remaining / 4;
477 LOG_DEBUG(
"writing flash word-at-a-time");
484 buffer += words_remaining * 4;
485 address += words_remaining * 4;
486 remaining -= words_remaining * 4;
490 if ((remaining >= 4) && ((address & 0x1F) != 0)) {
493 flsh_cn &= 0xF7FFFFFF;
494 flsh_cn |= 0x00000010;
497 while ((remaining >= 4) && ((address & 0x1F) != 0)) {
500 flsh_cn |= 0x00000001;
510 LOG_ERROR(
"Timed out waiting for flash write @ 0x%08" PRIx32, address);
520 if ((
info->burst_size_bits == 128) && (remaining >= 16)) {
524 flsh_cn &= 0xFFFFFFEF;
525 flsh_cn |= 0x08000000;
529 while (remaining >= 16) {
530 if ((address & 0xFFF) == 0)
531 LOG_DEBUG(
"Writing @ 0x%08" PRIx32, address);
534 flsh_cn |= 0x00000001;
544 LOG_ERROR(
"Timed out waiting for flash write @ 0x%08" PRIx32, address);
554 if (remaining >= 4) {
558 flsh_cn &= 0xF7FFFFFF;
559 flsh_cn |= 0x00000010;
562 while (remaining >= 4) {
565 flsh_cn |= 0x00000001;
575 LOG_ERROR(
"Timed out waiting for flash write @ 0x%08" PRIx32, address);
588 flsh_cn &= 0xF7FFFFFF;
589 flsh_cn |= 0x00000010;
592 uint8_t last_word[4] = {0xff, 0xff, 0xff, 0xff};
595 while (remaining > 0) {
603 flsh_cn |= 0x00000001;
613 LOG_ERROR(
"Timed out waiting for flash write @ 0x%08" PRIx32, address);
643 bank->num_sectors =
info->flash_size /
info->sector_size;
646 for (
unsigned int i = 0; i <
bank->num_sectors; i++) {
647 bank->sectors[i].offset = i *
info->sector_size;
648 bank->sectors[i].size =
info->sector_size;
649 bank->sectors[i].is_erased = -1;
650 bank->sectors[i].is_protected = -1;
657 arm_pid = (arm_id[1] << 8) + arm_id[0];
661 uint32_t max326xx_id;
663 LOG_DEBUG(
"max326xx_id = 0x%" PRIx32, max326xx_id);
664 max326xx_id = ((max326xx_id & 0xFF000000) >> 24);
672 LOG_WARNING(
"Flash protection not supported on this device");
682 uint32_t flsh_cn, flsh_int;
696 int not_protected = 0;
697 for (
unsigned int i = 0; i <
bank->num_sectors; i++) {
698 if (
bank->sectors[i].is_protected == 1)
704 if (!not_protected) {
731 LOG_ERROR(
"Timed out waiting for flash mass erase");
796 if (sscanf(
CMD_ARGV[2],
"0x%"SCNx32, &len) != 1) {
811 if (len %
info->sector_size)
812 len = len +
info->sector_size - (len %
info->sector_size);
816 len =
addr + (len /
info->sector_size) - 1;
852 if (sscanf(
CMD_ARGV[2],
"0x%"SCNx32, &len) != 1) {
867 if (len %
info->sector_size)
868 len = len +
info->sector_size - (len %
info->sector_size);
872 len =
addr + (len /
info->sector_size) - 1;
901 LOG_WARNING(
"Error updating the protection array");
905 LOG_WARNING(
"s:<sector number> a:<address> p:<protection bit>");
906 for (
unsigned i = 0; i <
bank->num_sectors; i += 4) {
907 LOG_WARNING(
"s:%03d a:0x%06x p:%d | s:%03d a:0x%06x p:%d | s:%03d a:0x%06x p:%d | s:%03d a:0x%06x p:%d",
908 (i+0), (i+0)*
info->sector_size,
bank->sectors[(i+0)].is_protected,
909 (i+1), (i+1)*
info->sector_size,
bank->sectors[(i+1)].is_protected,
910 (i+2), (i+2)*
info->sector_size,
bank->sectors[(i+2)].is_protected,
911 (i+3), (i+3)*
info->sector_size,
bank->sectors[(i+3)].is_protected);
919 .
name =
"mass_erase",
920 .handler = max32xxx_handle_mass_erase_command,
923 .help =
"mass erase flash",
926 .name =
"protection_set",
927 .handler = max32xxx_handle_protection_set_command,
929 .usage =
"bank_id addr size",
930 .help =
"set flash protection for address range",
933 .name =
"protection_clr",
934 .handler = max32xxx_handle_protection_clr_command,
936 .usage =
"bank_id addr size",
937 .help =
"clear flash protection for address range",
940 .name =
"protection_check",
941 .handler = max32xxx_handle_protection_check_command,
944 .help =
"check flash protection",
953 .help =
"max32xxx flash command group",
963 .flash_bank_command = max32xxx_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 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 CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
#define COMMAND_PARSE_NUMBER(type, in, out)
parses the string in into out as a type, or prints a command error and passes the error code to the c...
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
#define ERROR_FLASH_OPER_UNSUPPORTED
#define ERROR_FLASH_BANK_INVALID
#define ERROR_FLASH_SECTOR_INVALID
#define ERROR_FLASH_BANK_NOT_PROBED
#define ERROR_FLASH_OPERATION_FAILED
#define ERROR_FLASH_DST_BREAKS_ALIGNMENT
#define ERROR_FLASH_DST_OUT_OF_BANK
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.
#define LOG_WARNING(expr ...)
#define LOG_ERROR(expr ...)
#define LOG_DEBUG(expr ...)
static int max32xxx_flash_op_post(struct flash_bank *bank)
static int max32xxx_probe(struct flash_bank *bank)
static int max32xxx_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
static const struct command_registration max32xxx_exec_command_handlers[]
static const uint8_t write_code[]
static const struct command_registration max32xxx_command_handlers[]
#define FLSH_CN_ERASE_CODE_MASK
#define FLSH_CN_ERASE_CODE_PGE
static int max32xxx_protect(struct flash_bank *bank, int set, unsigned int first, unsigned int last)
static int max32xxx_mass_erase(struct flash_bank *bank)
#define FLSH_CN_UNLOCK_VALUE
static int max32xxx_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
COMMAND_HANDLER(max32xxx_handle_mass_erase_command)
#define FLSH_CN_UNLOCK_MASK
#define FLSH_CN_ERASE_CODE_ME
#define ARM_PID_DEFAULT_CM3
#define ARM_PID_DEFAULT_CM4
const struct flash_driver max32xxx_flash
static int max32xxx_write_block(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t wcount)
static int get_info(struct flash_bank *bank, struct command_invocation *cmd)
static int max32xxx_flash_op_pre(struct flash_bank *bank)
static int max32xxx_protect_check(struct flash_bank *bank)
#define FLASH_BL_CTRL_IFREN
FLASH_BANK_COMMAND_HANDLER(max32xxx_flash_bank_command)
unsigned int common_magic
When run_command is called, a new instance will be created on the stack, filled with the proper value...
const char * usage
a string listing the options and arguments, required or optional
Provides details of a flash bank, available either on-chip or through a major interface.
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.
unsigned int burst_size_bits
unsigned int clkdiv_value
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
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_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
static const char * target_name(struct target *target)
Returns the instance-specific name of the specified target.
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
static struct ublast_lowlevel_priv info