This is an automated email from Gerrit. "Tobias Schifferer <[email protected]>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9696
-- gerrit commit 621c12915917474fa66b6d506705a6e156ee990e Author: Tobias Schifferer <[email protected]> Date: Thu Jun 25 13:04:01 2026 +0200 flash/nor/stm32f1x: support software boot select for FLASH/SYSTEM/SRAM in option bytes feature verified on STM32F042G6U6 Change-Id: I923a210595a9595d47d129377f69e7f5465f7ca3 Signed-off-by: Tobias Schifferer <[email protected]> diff --git a/doc/openocd.texi b/doc/openocd.texi index 89900b06a7..993c5ffc58 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -8358,7 +8358,7 @@ or upon executing the @command{stm32f1x options_load} command. The @var{num} parameter is a value shown by @command{flash banks}. @end deffn -@deffn {Command} {stm32f1x options_write} num (@option{SWWDG}|@option{HWWDG}) (@option{RSTSTNDBY}|@option{NORSTSTNDBY}) (@option{RSTSTOP}|@option{NORSTSTOP}) (@option{USEROPT} user_data) +@deffn {Command} {stm32f1x options_write} num (@option{SWWDG}|@option{HWWDG}) (@option{RSTSTNDBY}|@option{NORSTSTNDBY}) (@option{RSTSTOP}|@option{NORSTSTOP}) (@option{USEROPT} user_data) (@option{HW_BOOT_SEL}|@option{SW_BOOT_SEL} (@option{FLASH}|@option{SYSTEM}|@option{SRAM})) Writes the stm32 option byte with the specified values. The @var{num} parameter is a value shown by @command{flash banks}. The @var{user_data} parameter is content of higher 16 bits of the option byte register (Data0 and Data1 as one 16bit number). diff --git a/src/flash/nor/stm32f1x.c b/src/flash/nor/stm32f1x.c index f512a26e9c..711f0e89f0 100644 --- a/src/flash/nor/stm32f1x.c +++ b/src/flash/nor/stm32f1x.c @@ -85,7 +85,20 @@ #define OPT_RDWDGSW 2 #define OPT_RDRSTSTOP 3 #define OPT_RDRSTSTDBY 4 -#define OPT_BFB2 5 /* dual flash bank only */ +#define OPT_RDBOOT0 5 /* dual flash bank only */ +#define OPT_RDBOOT1 6 +#define OPT_RDBOOT_SEL 9 + +/* STM32_OB_RDP bit definitions (writing) */ + +#define OB_RDP_WDG_SW 0 +#define OB_RDP_NRST_STOP 1 +#define OB_RDP_NRST_STDBY 2 +#define OB_RDP_NBOOT1 4 +#define OB_RDP_NBOOT0 3 /* Only STM32F04x and STM32F09x */ +#define OB_RDP_VDDA_MONITOR 5 +#define OB_RDP_RAM_PARITY_CHECK 6 +#define OB_RDP_BOOT_SEL 7 /* Only STM32F04x and STM32F09x */ /* register unlock keys */ @@ -112,6 +125,7 @@ struct stm32x_flash_bank { bool has_dual_banks; /* used to access dual flash bank stm32xl */ bool can_load_options; + bool has_boot_sel; uint32_t register_base; uint8_t default_rdp; int user_data_offset; @@ -137,6 +151,7 @@ FLASH_BANK_COMMAND_HANDLER(stm32x_flash_bank_command) bank->driver_priv = stm32x_info; stm32x_info->probed = false; stm32x_info->has_dual_banks = false; + stm32x_info->has_boot_sel = false; stm32x_info->can_load_options = false; stm32x_info->register_base = FLASH_REG_BASE_B0; stm32x_info->user_bank_size = bank->size; @@ -842,6 +857,14 @@ static int stm32x_probe(struct flash_bank *bank) stm32x_info->can_load_options = true; break; case 0x444: /* stm32f03x */ + page_size = 1024; + stm32x_info->ppage_size = 4; + max_flash_size_in_kb = 32; + stm32x_info->user_data_offset = 16; + stm32x_info->option_offset = 6; + stm32x_info->default_rdp = 0xAA; + stm32x_info->can_load_options = true; + break; case 0x445: /* stm32f04x */ page_size = 1024; stm32x_info->ppage_size = 4; @@ -850,6 +873,7 @@ static int stm32x_probe(struct flash_bank *bank) stm32x_info->option_offset = 6; stm32x_info->default_rdp = 0xAA; stm32x_info->can_load_options = true; + stm32x_info->has_boot_sel = true; break; case 0x448: /* stm32f07x */ page_size = 2048; @@ -868,6 +892,7 @@ static int stm32x_probe(struct flash_bank *bank) stm32x_info->option_offset = 6; stm32x_info->default_rdp = 0xAA; stm32x_info->can_load_options = true; + stm32x_info->has_boot_sel = true; break; case 0x410: /* stm32f1x medium-density */ page_size = 1024; @@ -1463,8 +1488,13 @@ COMMAND_HANDLER(stm32x_handle_options_read_command) (optionbyte & (1 << OPT_RDRSTSTDBY)) ? "no " : ""); if (stm32x_info->has_dual_banks) - command_print(CMD, "boot: bank %d", (optionbyte & (1 << OPT_BFB2)) ? 0 : 1); + command_print(CMD, "boot: bank %d", (optionbyte & (1 << OPT_RDBOOT0)) ? 0 : 1); + if (stm32x_info->has_boot_sel) { + command_print(CMD, "boot select: %sware", (optionbyte & (1 << OPT_RDBOOT_SEL)) ? "hard" : "soft"); + command_print(CMD, "boot memmory: %s", (optionbyte & (1 << OPT_RDBOOT0)) ? "flash" : + (optionbyte & (1 << OPT_RDBOOT1)) ? "system" : "sram"); + } command_print(CMD, "user data = 0x%02" PRIx16, user_data); return ERROR_OK; @@ -1512,28 +1542,48 @@ COMMAND_HANDLER(stm32x_handle_options_write_command) while (CMD_ARGC) { if (strcmp("SWWDG", CMD_ARGV[0]) == 0) - optionbyte |= (1 << 0); + optionbyte |= (1 << OB_RDP_WDG_SW); else if (strcmp("HWWDG", CMD_ARGV[0]) == 0) - optionbyte &= ~(1 << 0); + optionbyte &= ~(1 << OB_RDP_WDG_SW); else if (strcmp("NORSTSTOP", CMD_ARGV[0]) == 0) - optionbyte |= (1 << 1); + optionbyte |= (1 << OB_RDP_NRST_STOP); else if (strcmp("RSTSTOP", CMD_ARGV[0]) == 0) - optionbyte &= ~(1 << 1); + optionbyte &= ~(1 << OB_RDP_NRST_STOP); else if (strcmp("NORSTSTNDBY", CMD_ARGV[0]) == 0) - optionbyte |= (1 << 2); + optionbyte |= (1 << OB_RDP_NRST_STDBY); else if (strcmp("RSTSTNDBY", CMD_ARGV[0]) == 0) - optionbyte &= ~(1 << 2); + optionbyte &= ~(1 << OB_RDP_NRST_STDBY); else if (strcmp("USEROPT", CMD_ARGV[0]) == 0) { if (CMD_ARGC < 2) return ERROR_COMMAND_SYNTAX_ERROR; COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], useropt); CMD_ARGC--; CMD_ARGV++; + } else if (stm32x_info->has_boot_sel) { + if (strcmp("HW_BOOT_SEL", CMD_ARGV[0]) == 0) + optionbyte |= (1 << OB_RDP_BOOT_SEL); + else if (strcmp("SW_BOOT_SEL", CMD_ARGV[0]) == 0) { + optionbyte &= ~(1 << OB_RDP_BOOT_SEL); + if (CMD_ARGC < 2) + return ERROR_COMMAND_SYNTAX_ERROR; + if (strcmp("FLASH", CMD_ARGV[1]) == 0) { + optionbyte |= (1 << OB_RDP_NBOOT0); + } else if (strcmp("SYSTEM", CMD_ARGV[1]) == 0) { + optionbyte &= ~(1 << OB_RDP_NBOOT0); + optionbyte |= (1 << OB_RDP_NBOOT1); + } else if (strcmp("SRAM", CMD_ARGV[1]) == 0) { + optionbyte &= ~(1 << OB_RDP_NBOOT0); + optionbyte &= ~(1 << OB_RDP_NBOOT1); + } else + return ERROR_COMMAND_SYNTAX_ERROR; + CMD_ARGC--; + CMD_ARGV++; + } } else if (stm32x_info->has_dual_banks) { if (strcmp("BOOT0", CMD_ARGV[0]) == 0) - optionbyte |= (1 << 3); + optionbyte |= (1 << OB_RDP_NBOOT0); else if (strcmp("BOOT1", CMD_ARGV[0]) == 0) - optionbyte &= ~(1 << 3); + optionbyte &= ~(1 << OB_RDP_NBOOT0); else return ERROR_COMMAND_SYNTAX_ERROR; } else @@ -1702,7 +1752,8 @@ static const struct command_registration stm32f1x_exec_command_handlers[] = { .mode = COMMAND_EXEC, .usage = "bank_id ('SWWDG'|'HWWDG') " "('RSTSTNDBY'|'NORSTSTNDBY') " - "('RSTSTOP'|'NORSTSTOP') ('USEROPT' user_data)", + "('RSTSTOP'|'NORSTSTOP') ('USEROPT' user_data) " + "('HW_BOOT_SEL'|'SW_BOOT_SEL' ('FLASH'|'SYSTEM'|'SRAM'))", .help = "Replace bits in device option bytes.", }, { --
