+COMMAND_HANDLER(stm32l4_handle_wrp_info_command)
+{
+ if (CMD_ARGC < 1 || CMD_ARGC > 2)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ struct flash_bank *bank;
+ int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
+ if (ERROR_OK != retval)
+ return retval;
+
+ if (stm32l4_is_otp(bank)) {
+ LOG_ERROR("OTP memory does not have write protection areas");
+ return ERROR_FLASH_OPER_UNSUPPORTED;
+ }
+
+ struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;
+ enum stm32_bank_id dev_bank_id = STM32_ALL_BANKS;
+ if (CMD_ARGC == 2) {
+ if (strcmp(CMD_ARGV[1], "bank1") == 0)
+ dev_bank_id = STM32_BANK1;
+ else if (strcmp(CMD_ARGV[1], "bank2") == 0)
+ dev_bank_id = STM32_BANK2;
+ else
+ return ERROR_COMMAND_ARGUMENT_INVALID;
+ }
+
+ if (dev_bank_id == STM32_BANK2) {
+ if (!stm32l4_info->part_info->has_dual_bank) {
+ LOG_ERROR("this device has no second bank");
+ return ERROR_FAIL;
+ } else if (!stm32l4_info->dual_bank_mode) {
+ LOG_ERROR("this device is configured in single bank mode");
+ return ERROR_FAIL;
+ }
+ }
+
+ int ret;
+ unsigned int n_wrp, i;
+ struct stm32l4_wrp wrpxy[4];
+
+ ret = stm32l4_get_all_wrpxy(bank, dev_bank_id, wrpxy, &n_wrp);
+ if (ret != ERROR_OK)
+ return ret;
+
+ /* use bitmap and range helpers to better describe protected areas */
+ DECLARE_BITMAP(pages, bank->num_sectors);
+ bitmap_zero(pages, bank->num_sectors);
+
+ for (i = 0; i < n_wrp; i++) {
+ if (wrpxy[i].used) {
+ for (int p = wrpxy[i].first; p <= wrpxy[i].last; p++)
+ set_bit(p, pages);
+ }
+ }
+
+ /* we have at most 'n_wrp' WRP areas */
+ struct range ranges[n_wrp];
+ unsigned int ranges_count = 0;
+
+ bitmap_to_ranges(pages, bank->num_sectors, ranges, &ranges_count);
+
+ if (ranges_count > 0) {
+ /* pretty-print the protected ranges */
+ char *ranges_str = range_print_alloc(ranges, ranges_count);
+ command_print(CMD, "protected areas: %s", ranges_str);
+ free(ranges_str);
+ } else
+ command_print(CMD, "no protected areas");
+
+ return ERROR_OK;
+}
+