flash/nor/stm32h7x: fix option bytes handling to work with both banks 91/5291/4
authorTarek BOCHKATI <tarek.bouchkati@gmail.com>
Thu, 29 Aug 2019 13:58:39 +0000 (15:58 +0200)
committerTomas Vanek <vanekt@fbl.cz>
Wed, 27 Nov 2019 06:16:40 +0000 (06:16 +0000)
To achieve that we need to avoid using FLASH_REG_BASE_B0, and use
bank registers instead:
   For dual bank devices, each option register is mapped in 2 addresses
   at the same offset from flash_bank_reg_base.
   This is true for OPTCR, OPTKEYR, OPTSR_CUR/PRG, OPTCCR according to
   RM0433 Rev6 (refer to section 3.9: FLASH registers)

In stm32x_write_options, according to RM0433 Rev6, after OBL launch we
should wait for OPTSR_CUR.BSY bit instead of FLASH_SR.QW

Change-Id: Ie24a91f069d03c9233797390fc2e925c737dad90
Signed-off-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com>
Reviewed-on: http://openocd.zylin.com/5291
Tested-by: jenkins
Reviewed-by: Christopher Head <chead@zaber.com>
Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
src/flash/nor/stm32h7x.c

index 1d128f3be1841b0511eb7b5ba6992d6501e7d25b..feb7acafdae25052137f258fa7795df50c00c3ac 100644 (file)
@@ -79,6 +79,9 @@
 #define OPT_LOCK       (1 << 0)
 #define OPT_START      (1 << 1)
 
+/* FLASH_OPTSR register bits */
+#define OPT_BSY        (1 << 0)
+
 /* register unlock keys */
 #define KEY1           0x45670123
 #define KEY2           0xCDEF89AB
@@ -263,7 +266,7 @@ static int stm32x_unlock_option_reg(struct flash_bank *bank)
        uint32_t ctrl;
        struct target *target = bank->target;
 
-       int retval = target_read_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTCR, &ctrl);
+       int retval = target_read_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTCR), &ctrl);
        if (retval != ERROR_OK)
                return retval;
 
@@ -271,15 +274,15 @@ static int stm32x_unlock_option_reg(struct flash_bank *bank)
                return ERROR_OK;
 
        /* unlock option registers */
-       retval = target_write_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTKEYR, OPTKEY1);
+       retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTKEYR), OPTKEY1);
        if (retval != ERROR_OK)
                return retval;
 
-       retval = target_write_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTKEYR, OPTKEY2);
+       retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTKEYR), OPTKEY2);
        if (retval != ERROR_OK)
                return retval;
 
-       retval = target_read_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTCR, &ctrl);
+       retval = target_read_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTCR), &ctrl);
        if (retval != ERROR_OK)
                return retval;
 
@@ -310,7 +313,7 @@ static int stm32x_read_options(struct flash_bank *bank)
        struct target *target = bank->target;
 
        /* read current option bytes */
-       int retval = target_read_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTSR_CUR, &optiondata);
+       int retval = target_read_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTSR_CUR), &optiondata);
        if (retval != ERROR_OK)
                return retval;
 
@@ -349,7 +352,7 @@ static int stm32x_write_options(struct flash_bank *bank)
        optiondata |= (stm32x_info->option_bytes.user3_options & 0xa3) << 24;
 
        /* program options */
-       retval = target_write_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTSR_PRG, optiondata);
+       retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTSR_PRG), optiondata);
        if (retval != ERROR_OK)
                return retval;
 
@@ -361,12 +364,12 @@ static int stm32x_write_options(struct flash_bank *bank)
 
        optiondata = 0x40000000;
        /* Remove OPT error flag before programming */
-       retval = target_write_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTCCR, optiondata);
+       retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTCCR), optiondata);
        if (retval != ERROR_OK)
                return retval;
 
        /* start programming cycle */
-       retval = target_write_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTCR, OPT_START);
+       retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTCR), OPT_START);
        if (retval != ERROR_OK)
                return retval;
 
@@ -374,23 +377,23 @@ static int stm32x_write_options(struct flash_bank *bank)
        int timeout = FLASH_ERASE_TIMEOUT;
        for (;;) {
                uint32_t status;
-               retval = target_read_u32(target, FLASH_REG_BASE_B0 + FLASH_SR, &status);
+               retval = target_read_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTSR_CUR), &status);
                if (retval != ERROR_OK) {
-                       LOG_INFO("stm32x_write_options: wait_flash_op_queue : error");
+                       LOG_INFO("stm32x_write_options: failed to read FLASH_OPTSR_CUR");
                        return retval;
                }
-               if ((status & FLASH_QW) == 0)
+               if ((status & OPT_BSY) == 0)
                        break;
 
                if (timeout-- <= 0) {
-                       LOG_INFO("wait_flash_op_queue, time out expired, status: 0x%" PRIx32 "", status);
+                       LOG_INFO("waiting for OBL launch, time out expired, OPTSR: 0x%" PRIx32 "", status);
                        return ERROR_FAIL;
                }
                alive_sleep(1);
        }
 
        /* relock option registers */
-       retval = target_write_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTCR, OPT_LOCK);
+       retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_OPTCR), OPT_LOCK);
        if (retval != ERROR_OK)
                return retval;
 
@@ -904,13 +907,6 @@ COMMAND_HANDLER(stm32x_handle_lock_command)
        stm32x_info = bank->driver_priv;
        target = bank->target;
 
-       /* if we have a dual flash bank device then
-        * we need to perform option byte lock on bank0 only */
-       if (stm32x_info->flash_base != FLASH_REG_BASE_B0) {
-               LOG_ERROR("Option Byte Lock Operation must use bank0");
-               return ERROR_FLASH_OPERATION_FAILED;
-       }
-
        if (target->state != TARGET_HALTED) {
                LOG_ERROR("Target not halted");
                return ERROR_TARGET_NOT_HALTED;
@@ -921,6 +917,9 @@ COMMAND_HANDLER(stm32x_handle_lock_command)
                              bank->driver->name);
                return ERROR_OK;
        }
+
+       LOG_WARNING("locking the entire flash device");
+
        /* set readout protection */
        stm32x_info->option_bytes.RDP = 0;
 
@@ -950,13 +949,6 @@ COMMAND_HANDLER(stm32x_handle_unlock_command)
        stm32x_info = bank->driver_priv;
        target = bank->target;
 
-       /* if we have a dual flash bank device then
-        * we need to perform option byte unlock on bank0 only */
-       if (stm32x_info->flash_base != FLASH_REG_BASE_B0) {
-               LOG_ERROR("Option Byte Unlock Operation must use bank0");
-               return ERROR_FLASH_OPERATION_FAILED;
-       }
-
        if (target->state != TARGET_HALTED) {
                LOG_ERROR("Target not halted");
                return ERROR_TARGET_NOT_HALTED;
@@ -967,6 +959,8 @@ COMMAND_HANDLER(stm32x_handle_unlock_command)
                return ERROR_OK;
        }
 
+       LOG_WARNING("unlocking the entire flash device");
+
        /* clear readout protection option byte
         * this will also force a device unlock if set */
        stm32x_info->option_bytes.RDP = 0xAA;

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)