X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fflash%2Fstm32x.c;h=e69fb564af82f279d2368a219f15a34c1be9d2e1;hb=056fcdb540f0ab9a404f3b5de72fd707eb146603;hp=e9f121fc8bb8359bde82ea0e308f86d3b23e79eb;hpb=dc575dc5bf8cb597a0e9a47794744ae6b1928087;p=openocd diff --git a/src/flash/stm32x.c b/src/flash/stm32x.c index e9f121fc..e69fb564 100644 --- a/src/flash/stm32x.c +++ b/src/flash/stm32x.c @@ -29,61 +29,13 @@ #include "binarybuffer.h" -static int stm32x_register_commands(struct command_context_s *cmd_ctx); -static int stm32x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank); -static int stm32x_erase(struct flash_bank_s *bank, int first, int last); -static int stm32x_protect(struct flash_bank_s *bank, int set, int first, int last); -static int stm32x_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count); -static int stm32x_probe(struct flash_bank_s *bank); -static int stm32x_auto_probe(struct flash_bank_s *bank); -//static int stm32x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); -static int stm32x_protect_check(struct flash_bank_s *bank); -static int stm32x_info(struct flash_bank_s *bank, char *buf, int buf_size); - -static int stm32x_handle_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); -static int stm32x_handle_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); -static int stm32x_handle_options_read_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); -static int stm32x_handle_options_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); -static int stm32x_handle_mass_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); static int stm32x_mass_erase(struct flash_bank_s *bank); -flash_driver_t stm32x_flash = -{ - .name = "stm32x", - .register_commands = stm32x_register_commands, - .flash_bank_command = stm32x_flash_bank_command, - .erase = stm32x_erase, - .protect = stm32x_protect, - .write = stm32x_write, - .probe = stm32x_probe, - .auto_probe = stm32x_auto_probe, - .erase_check = default_flash_mem_blank_check, - .protect_check = stm32x_protect_check, - .info = stm32x_info -}; - -static int stm32x_register_commands(struct command_context_s *cmd_ctx) -{ - command_t *stm32x_cmd = register_command(cmd_ctx, NULL, "stm32x", NULL, COMMAND_ANY, "stm32x flash specific commands"); - - register_command(cmd_ctx, stm32x_cmd, "lock", stm32x_handle_lock_command, COMMAND_EXEC, - "lock device"); - register_command(cmd_ctx, stm32x_cmd, "unlock", stm32x_handle_unlock_command, COMMAND_EXEC, - "unlock protected device"); - register_command(cmd_ctx, stm32x_cmd, "mass_erase", stm32x_handle_mass_erase_command, COMMAND_EXEC, - "mass erase device"); - register_command(cmd_ctx, stm32x_cmd, "options_read", stm32x_handle_options_read_command, COMMAND_EXEC, - "read device option bytes"); - register_command(cmd_ctx, stm32x_cmd, "options_write", stm32x_handle_options_write_command, COMMAND_EXEC, - "write device option bytes"); - return ERROR_OK; -} - /* flash bank stm32x 0 0 */ -static int stm32x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank) +FLASH_BANK_COMMAND_HANDLER(stm32x_flash_bank_command) { - stm32x_flash_bank_t *stm32x_info; + struct stm32x_flash_bank *stm32x_info; if (argc < 6) { @@ -91,7 +43,7 @@ static int stm32x_flash_bank_command(struct command_context_s *cmd_ctx, char *cm return ERROR_FLASH_BANK_INVALID; } - stm32x_info = malloc(sizeof(stm32x_flash_bank_t)); + stm32x_info = malloc(sizeof(struct stm32x_flash_bank)); bank->driver_priv = stm32x_info; stm32x_info->write_algorithm = NULL; @@ -132,7 +84,7 @@ static uint32_t stm32x_wait_status_busy(flash_bank_t *bank, int timeout) static int stm32x_read_options(struct flash_bank_s *bank) { uint32_t optiondata; - stm32x_flash_bank_t *stm32x_info = NULL; + struct stm32x_flash_bank *stm32x_info = NULL; target_t *target = bank->target; stm32x_info = bank->driver_priv; @@ -159,7 +111,7 @@ static int stm32x_read_options(struct flash_bank_s *bank) static int stm32x_erase_options(struct flash_bank_s *bank) { - stm32x_flash_bank_t *stm32x_info = NULL; + struct stm32x_flash_bank *stm32x_info = NULL; target_t *target = bank->target; uint32_t status; @@ -196,7 +148,7 @@ static int stm32x_erase_options(struct flash_bank_s *bank) static int stm32x_write_options(struct flash_bank_s *bank) { - stm32x_flash_bank_t *stm32x_info = NULL; + struct stm32x_flash_bank *stm32x_info = NULL; target_t *target = bank->target; uint32_t status; @@ -281,7 +233,7 @@ static int stm32x_write_options(struct flash_bank_s *bank) static int stm32x_protect_check(struct flash_bank_s *bank) { target_t *target = bank->target; - stm32x_flash_bank_t *stm32x_info = bank->driver_priv; + struct stm32x_flash_bank *stm32x_info = bank->driver_priv; uint32_t protection; int i, s; @@ -304,14 +256,15 @@ static int stm32x_protect_check(struct flash_bank_s *bank) if (stm32x_info->ppage_size == 2) { - /* high density flash */ + /* high density flash/connectivity line protection */ set = 1; if (protection & (1 << 31)) set = 0; - /* bit 31 controls sector 62 - 255 protection */ + /* bit 31 controls sector 62 - 255 protection for high density + * bit 31 controls sector 62 - 127 protection for connectivity line */ for (s = 62; s < bank->num_sectors; s++) { bank->sectors[s].is_protected = set; @@ -333,7 +286,7 @@ static int stm32x_protect_check(struct flash_bank_s *bank) } else { - /* medium density flash */ + /* low/medium density flash protection */ for (i = 0; i < num_bits; i++) { set = 1; @@ -392,7 +345,7 @@ static int stm32x_erase(struct flash_bank_s *bank, int first, int last) static int stm32x_protect(struct flash_bank_s *bank, int set, int first, int last) { - stm32x_flash_bank_t *stm32x_info = NULL; + struct stm32x_flash_bank *stm32x_info = NULL; target_t *target = bank->target; uint16_t prot_reg[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}; int i, reg, bit; @@ -409,7 +362,7 @@ static int stm32x_protect(struct flash_bank_s *bank, int set, int first, int las if ((first && (first % stm32x_info->ppage_size)) || ((last + 1) && (last + 1) % stm32x_info->ppage_size)) { - LOG_WARNING("sector start/end incorrect - stm32 has %dK sector protection", stm32x_info->ppage_size); + LOG_WARNING("Error: start and end sectors must be on a %d sector boundary", stm32x_info->ppage_size); return ERROR_FLASH_SECTOR_INVALID; } @@ -479,12 +432,12 @@ static int stm32x_protect(struct flash_bank_s *bank, int set, int first, int las static int stm32x_write_block(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count) { - stm32x_flash_bank_t *stm32x_info = bank->driver_priv; + struct stm32x_flash_bank *stm32x_info = bank->driver_priv; target_t *target = bank->target; uint32_t buffer_size = 16384; working_area_t *source; uint32_t address = bank->base + offset; - reg_param_t reg_params[4]; + struct reg_param reg_params[4]; armv7m_algorithm_t armv7m_info; int retval = ERROR_OK; @@ -704,7 +657,7 @@ static int stm32x_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t off static int stm32x_probe(struct flash_bank_s *bank) { target_t *target = bank->target; - stm32x_flash_bank_t *stm32x_info = bank->driver_priv; + struct stm32x_flash_bank *stm32x_info = bank->driver_priv; int i; uint16_t num_pages; uint32_t device_id; @@ -776,10 +729,10 @@ static int stm32x_probe(struct flash_bank_s *bank) } else if ((device_id & 0x7ff) == 0x418) { - /* connectivity line density - we have 1k pages - * 4 pages for a protection area */ - page_size = 1024; - stm32x_info->ppage_size = 4; + /* connectivity line density - we have 2k pages + * 2 pages for a protection area */ + page_size = 2048; + stm32x_info->ppage_size = 2; /* check for early silicon */ if (num_pages == 0xffff) @@ -803,7 +756,7 @@ static int stm32x_probe(struct flash_bank_s *bank) bank->base = 0x08000000; bank->size = (num_pages * page_size); bank->num_sectors = num_pages; - bank->sectors = malloc(sizeof(flash_sector_t) * num_pages); + bank->sectors = malloc(sizeof(struct flash_sector) * num_pages); for (i = 0; i < num_pages; i++) { @@ -820,14 +773,14 @@ static int stm32x_probe(struct flash_bank_s *bank) static int stm32x_auto_probe(struct flash_bank_s *bank) { - stm32x_flash_bank_t *stm32x_info = bank->driver_priv; + struct stm32x_flash_bank *stm32x_info = bank->driver_priv; if (stm32x_info->probed) return ERROR_OK; return stm32x_probe(bank); } #if 0 -static int stm32x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +COMMAND_HANDLER(stm32x_handle_part_id_command) { return ERROR_OK; } @@ -921,6 +874,10 @@ static int stm32x_info(struct flash_bank_s *bank, char *buf, int buf_size) snprintf(buf, buf_size, "A"); break; + case 0x1001: + snprintf(buf, buf_size, "Z"); + break; + default: snprintf(buf, buf_size, "unknown"); break; @@ -935,11 +892,10 @@ static int stm32x_info(struct flash_bank_s *bank, char *buf, int buf_size) return ERROR_OK; } -static int stm32x_handle_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +COMMAND_HANDLER(stm32x_handle_lock_command) { - flash_bank_t *bank; target_t *target = NULL; - stm32x_flash_bank_t *stm32x_info = NULL; + struct stm32x_flash_bank *stm32x_info = NULL; if (argc < 1) { @@ -947,12 +903,10 @@ static int stm32x_handle_lock_command(struct command_context_s *cmd_ctx, char *c return ERROR_OK; } - bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0)); - if (!bank) - { - command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]); - return ERROR_OK; - } + flash_bank_t *bank; + int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank); + if (ERROR_OK != retval) + return retval; stm32x_info = bank->driver_priv; @@ -984,11 +938,10 @@ static int stm32x_handle_lock_command(struct command_context_s *cmd_ctx, char *c return ERROR_OK; } -static int stm32x_handle_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +COMMAND_HANDLER(stm32x_handle_unlock_command) { - flash_bank_t *bank; target_t *target = NULL; - stm32x_flash_bank_t *stm32x_info = NULL; + struct stm32x_flash_bank *stm32x_info = NULL; if (argc < 1) { @@ -996,12 +949,10 @@ static int stm32x_handle_unlock_command(struct command_context_s *cmd_ctx, char return ERROR_OK; } - bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0)); - if (!bank) - { - command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]); - return ERROR_OK; - } + flash_bank_t *bank; + int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank); + if (ERROR_OK != retval) + return retval; stm32x_info = bank->driver_priv; @@ -1030,12 +981,11 @@ static int stm32x_handle_unlock_command(struct command_context_s *cmd_ctx, char return ERROR_OK; } -static int stm32x_handle_options_read_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +COMMAND_HANDLER(stm32x_handle_options_read_command) { - flash_bank_t *bank; uint32_t optionbyte; target_t *target = NULL; - stm32x_flash_bank_t *stm32x_info = NULL; + struct stm32x_flash_bank *stm32x_info = NULL; if (argc < 1) { @@ -1043,12 +993,10 @@ static int stm32x_handle_options_read_command(struct command_context_s *cmd_ctx, return ERROR_OK; } - bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0)); - if (!bank) - { - command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]); - return ERROR_OK; - } + flash_bank_t *bank; + int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank); + if (ERROR_OK != retval) + return retval; stm32x_info = bank->driver_priv; @@ -1089,11 +1037,10 @@ static int stm32x_handle_options_read_command(struct command_context_s *cmd_ctx, return ERROR_OK; } -static int stm32x_handle_options_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +COMMAND_HANDLER(stm32x_handle_options_write_command) { - flash_bank_t *bank; target_t *target = NULL; - stm32x_flash_bank_t *stm32x_info = NULL; + struct stm32x_flash_bank *stm32x_info = NULL; uint16_t optionbyte = 0xF8; if (argc < 4) @@ -1102,12 +1049,10 @@ static int stm32x_handle_options_write_command(struct command_context_s *cmd_ctx return ERROR_OK; } - bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0)); - if (!bank) - { - command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]); - return ERROR_OK; - } + flash_bank_t *bank; + int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank); + if (ERROR_OK != retval) + return retval; stm32x_info = bank->driver_priv; @@ -1203,9 +1148,8 @@ static int stm32x_mass_erase(struct flash_bank_s *bank) return ERROR_OK; } -static int stm32x_handle_mass_erase_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +COMMAND_HANDLER(stm32x_handle_mass_erase_command) { - flash_bank_t *bank; int i; if (argc < 1) @@ -1214,12 +1158,10 @@ static int stm32x_handle_mass_erase_command(struct command_context_s *cmd_ctx, c return ERROR_OK; } - bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0)); - if (!bank) - { - command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]); - return ERROR_OK; - } + flash_bank_t *bank; + int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank); + if (ERROR_OK != retval) + return retval; if (stm32x_mass_erase(bank) == ERROR_OK) { @@ -1238,3 +1180,41 @@ static int stm32x_handle_mass_erase_command(struct command_context_s *cmd_ctx, c return ERROR_OK; } + +static int stm32x_register_commands(struct command_context_s *cmd_ctx) +{ + command_t *stm32x_cmd = register_command(cmd_ctx, NULL, "stm32x", + NULL, COMMAND_ANY, "stm32x flash specific commands"); + + register_command(cmd_ctx, stm32x_cmd, "lock", + stm32x_handle_lock_command, COMMAND_EXEC, + "lock device"); + register_command(cmd_ctx, stm32x_cmd, "unlock", + stm32x_handle_unlock_command, COMMAND_EXEC, + "unlock protected device"); + register_command(cmd_ctx, stm32x_cmd, "mass_erase", + stm32x_handle_mass_erase_command, COMMAND_EXEC, + "mass erase device"); + register_command(cmd_ctx, stm32x_cmd, "options_read", + stm32x_handle_options_read_command, COMMAND_EXEC, + "read device option bytes"); + register_command(cmd_ctx, stm32x_cmd, "options_write", + stm32x_handle_options_write_command, COMMAND_EXEC, + "write device option bytes"); + + return ERROR_OK; +} + +struct flash_driver stm32x_flash = { + .name = "stm32x", + .register_commands = &stm32x_register_commands, + .flash_bank_command = &stm32x_flash_bank_command, + .erase = &stm32x_erase, + .protect = &stm32x_protect, + .write = &stm32x_write, + .probe = &stm32x_probe, + .auto_probe = &stm32x_auto_probe, + .erase_check = &default_flash_mem_blank_check, + .protect_check = &stm32x_protect_check, + .info = &stm32x_info, + };