+static int stm32x_read_options(struct flash_bank *bank)
+{
+ uint32_t optiondata;
+ struct stm32x_flash_bank *stm32x_info = NULL;
+ struct target *target = bank->target;
+
+ stm32x_info = bank->driver_priv;
+
+ /* read current option bytes */
+ int retval = target_read_u32(target, STM32_FLASH_OPTCR, &optiondata);
+ if (retval != ERROR_OK)
+ return retval;
+
+ stm32x_info->option_bytes.user_options = optiondata & 0xec;
+ stm32x_info->option_bytes.RDP = (optiondata >> 8) & 0xff;
+ stm32x_info->option_bytes.protection = (optiondata >> 16) & 0xfff;
+
+ if (stm32x_info->has_large_mem) {
+
+ retval = target_read_u32(target, STM32_FLASH_OPTCR1, &optiondata);
+ if (retval != ERROR_OK)
+ return retval;
+
+ /* append protection bits */
+ stm32x_info->option_bytes.protection |= (optiondata >> 4) & 0x00fff000;
+ }
+
+ if (stm32x_info->option_bytes.RDP != 0xAA)
+ LOG_INFO("Device Security Bit Set");
+
+ return ERROR_OK;
+}
+
+static int stm32x_write_options(struct flash_bank *bank)
+{
+ struct stm32x_flash_bank *stm32x_info = NULL;
+ struct target *target = bank->target;
+ uint32_t optiondata;
+
+ stm32x_info = bank->driver_priv;
+
+ int retval = stm32x_unlock_option_reg(target);
+ if (retval != ERROR_OK)
+ return retval;
+
+ /* rebuild option data */
+ optiondata = stm32x_info->option_bytes.user_options;
+ buf_set_u32(&optiondata, 8, 8, stm32x_info->option_bytes.RDP);
+ buf_set_u32(&optiondata, 16, 12, stm32x_info->option_bytes.protection);
+
+ /* program options */
+ retval = target_write_u32(target, STM32_FLASH_OPTCR, optiondata);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if (stm32x_info->has_large_mem) {
+
+ uint32_t optiondata2 = 0;
+ buf_set_u32(&optiondata2, 16, 12, stm32x_info->option_bytes.protection >> 12);
+ retval = target_write_u32(target, STM32_FLASH_OPTCR1, optiondata2);
+ if (retval != ERROR_OK)
+ return retval;
+ }
+
+ /* start programming cycle */
+ retval = target_write_u32(target, STM32_FLASH_OPTCR, optiondata | OPT_START);
+ if (retval != ERROR_OK)
+ return retval;
+
+ /* wait for completion */
+ retval = stm32x_wait_status_busy(bank, FLASH_ERASE_TIMEOUT);
+ if (retval != ERROR_OK)
+ return retval;
+
+ /* relock registers */
+ retval = target_write_u32(target, STM32_FLASH_OPTCR, OPT_LOCK);
+ if (retval != ERROR_OK)
+ return retval;
+
+ return ERROR_OK;
+}
+