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.",
        },
        {

-- 

Reply via email to