flash/nor: Do not update 'is_erased'
[fw/openocd] / src / flash / nor / stm32h7x.c
index 1e2b35159053cdd40b503b8f208839583345b25f..89ba75dad8a34c2cd656cc9b430969c2cf9084e7 100644 (file)
@@ -118,7 +118,6 @@ struct stm32h7x_part_info {
        uint16_t max_flash_size_kb;
        bool has_dual_bank;
        uint16_t max_bank_size_kb;  /* Used when has_dual_bank is true */
-       uint32_t flash_regs_base;   /* Flash controller registers location */
        uint32_t fsize_addr;        /* Location of FSIZE register */
        uint32_t wps_group_size;    /* write protection group sectors' count */
        uint32_t wps_mask;
@@ -148,7 +147,11 @@ static const struct stm32h7x_rev stm32_480_revs[] = {
        { 0x1000, "A"},
 };
 
-static uint32_t stm32x_compute_flash_cr_450(uint32_t cmd, int snb)
+static const struct stm32h7x_rev stm32_483_revs[] = {
+       { 0x1000, "A" }, { 0x1001, "Z" },
+};
+
+static uint32_t stm32x_compute_flash_cr_450_483(uint32_t cmd, int snb)
 {
        return cmd | (snb << 8);
 }
@@ -175,11 +178,10 @@ static const struct stm32h7x_part_info stm32h7x_parts[] = {
        .max_flash_size_kb      = 2048,
        .max_bank_size_kb       = 1024,
        .has_dual_bank          = true,
-       .flash_regs_base        = FLASH_REG_BASE_B0,
        .fsize_addr                     = 0x1FF1E880,
        .wps_group_size         = 1,
        .wps_mask                       = 0xFF,
-       .compute_flash_cr       = stm32x_compute_flash_cr_450,
+       .compute_flash_cr       = stm32x_compute_flash_cr_450_483,
        },
        {
        .id                                     = 0x480,
@@ -191,12 +193,26 @@ static const struct stm32h7x_part_info stm32h7x_parts[] = {
        .max_flash_size_kb      = 2048,
        .max_bank_size_kb       = 1024,
        .has_dual_bank          = true,
-       .flash_regs_base        = FLASH_REG_BASE_B0,
        .fsize_addr                     = 0x08FFF80C,
        .wps_group_size         = 4,
        .wps_mask                       = 0xFFFFFFFF,
        .compute_flash_cr       = stm32x_compute_flash_cr_480,
        },
+       {
+       .id                                     = 0x483,
+       .revs                           = stm32_483_revs,
+       .num_revs                       = ARRAY_SIZE(stm32_483_revs),
+       .device_str                     = "STM32H72x/73x",
+       .page_size_kb           = 128,
+       .block_size                     = 32,
+       .max_flash_size_kb      = 1024,
+       .max_bank_size_kb       = 1024,
+       .has_dual_bank          = false,
+       .fsize_addr                     = 0x1FF1E880,
+       .wps_group_size         = 1,
+       .wps_mask                       = 0xFF,
+       .compute_flash_cr   = stm32x_compute_flash_cr_450_483,
+       },
 };
 
 /* flash bank stm32x <base> <size> 0 0 <target#> */
@@ -265,7 +281,7 @@ static int stm32x_wait_flash_op_queue(struct flash_bank *bank, int timeout)
                        break;
 
                if (timeout-- <= 0) {
-                       LOG_ERROR("wait_flash_op_queue, time out expired, status: 0x%" PRIx32 "", status);
+                       LOG_ERROR("wait_flash_op_queue, time out expired, status: 0x%" PRIx32, status);
                        return ERROR_FAIL;
                }
                alive_sleep(1);
@@ -314,7 +330,7 @@ static int stm32x_unlock_reg(struct flash_bank *bank)
                return retval;
 
        if (ctrl & FLASH_LOCK) {
-               LOG_ERROR("flash not unlocked STM32_FLASH_CRx: %" PRIx32, ctrl);
+               LOG_ERROR("flash not unlocked STM32_FLASH_CRx: 0x%" PRIx32, ctrl);
                return ERROR_TARGET_FAILURE;
        }
        return ERROR_OK;
@@ -345,7 +361,7 @@ static int stm32x_unlock_option_reg(struct flash_bank *bank)
                return retval;
 
        if (ctrl & OPT_LOCK) {
-               LOG_ERROR("options not unlocked STM32_FLASH_OPTCR: %" PRIx32, ctrl);
+               LOG_ERROR("options not unlocked STM32_FLASH_OPTCR: 0x%" PRIx32, ctrl);
                return ERROR_TARGET_FAILURE;
        }
 
@@ -399,7 +415,7 @@ static int stm32x_write_option(struct flash_bank *bank, uint32_t reg_offset, uin
                        break;
 
                if (timeout-- <= 0) {
-                       LOG_ERROR("waiting for OBL launch, time out expired, OPTSR: 0x%" PRIx32 "", status);
+                       LOG_ERROR("waiting for OBL launch, time out expired, OPTSR: 0x%" PRIx32, status);
                        retval = ERROR_FAIL;
                        goto flash_options_lock;
                }
@@ -444,13 +460,14 @@ static int stm32x_protect_check(struct flash_bank *bank)
                return retval;
        }
 
-       for (int i = 0; i < bank->num_prot_blocks; i++)
+       for (unsigned int i = 0; i < bank->num_prot_blocks; i++)
                bank->prot_blocks[i].is_protected = protection & (1 << i) ? 0 : 1;
 
        return ERROR_OK;
 }
 
-static int stm32x_erase(struct flash_bank *bank, int first, int last)
+static int stm32x_erase(struct flash_bank *bank, unsigned int first,
+               unsigned int last)
 {
        struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
        int retval, retval2;
@@ -475,27 +492,26 @@ static int stm32x_erase(struct flash_bank *bank, int first, int last)
        3. Set the STRT bit in the FLASH_CR register
        4. Wait for flash operations completion
         */
-       for (int i = first; i <= last; i++) {
-               LOG_DEBUG("erase sector %d", i);
+       for (unsigned int i = first; i <= last; i++) {
+               LOG_DEBUG("erase sector %u", i);
                retval = stm32x_write_flash_reg(bank, FLASH_CR,
                                stm32x_info->part_info->compute_flash_cr(FLASH_SER | FLASH_PSIZE_64, i));
                if (retval != ERROR_OK) {
-                       LOG_ERROR("Error erase sector %d", i);
+                       LOG_ERROR("Error erase sector %u", i);
                        goto flash_lock;
                }
                retval = stm32x_write_flash_reg(bank, FLASH_CR,
                                stm32x_info->part_info->compute_flash_cr(FLASH_SER | FLASH_PSIZE_64 | FLASH_START, i));
                if (retval != ERROR_OK) {
-                       LOG_ERROR("Error erase sector %d", i);
+                       LOG_ERROR("Error erase sector %u", i);
                        goto flash_lock;
                }
                retval = stm32x_wait_flash_op_queue(bank, FLASH_ERASE_TIMEOUT);
 
                if (retval != ERROR_OK) {
-                       LOG_ERROR("erase time-out or operation error sector %d", i);
+                       LOG_ERROR("erase time-out or operation error sector %u", i);
                        goto flash_lock;
                }
-               bank->sectors[i].is_erased = 1;
        }
 
 flash_lock:
@@ -506,7 +522,8 @@ flash_lock:
        return (retval == ERROR_OK) ? retval2 : retval;
 }
 
-static int stm32x_protect(struct flash_bank *bank, int set, int first, int last)
+static int stm32x_protect(struct flash_bank *bank, int set, unsigned int first,
+               unsigned int last)
 {
        struct target *target = bank->target;
        uint32_t protection;
@@ -523,7 +540,7 @@ static int stm32x_protect(struct flash_bank *bank, int set, int first, int last)
                return retval;
        }
 
-       for (int i = first; i <= last; i++) {
+       for (unsigned int i = first; i <= last; i++) {
                if (set)
                        protection &= ~(1 << i);
                else
@@ -627,7 +644,7 @@ static int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer,
                        LOG_ERROR("flash memory write protected");
 
                if ((flash_sr & FLASH_ERROR) != 0) {
-                       LOG_ERROR("flash write failed, FLASH_SR = %08" PRIx32, flash_sr);
+                       LOG_ERROR("flash write failed, FLASH_SR = 0x%08" PRIx32, flash_sr);
                        /* Clear error + EOP flags but report errors */
                        stm32x_write_flash_reg(bank, FLASH_CCR, flash_sr);
                        retval = ERROR_FAIL;
@@ -748,7 +765,7 @@ static int stm32x_probe(struct flash_bank *bank)
        if (retval != ERROR_OK)
                return retval;
 
-       LOG_DEBUG("device id = 0x%08" PRIx32 "", stm32x_info->idcode);
+       LOG_DEBUG("device id = 0x%08" PRIx32, stm32x_info->idcode);
 
        device_id = stm32x_info->idcode & 0xfff;
 
@@ -763,8 +780,16 @@ static int stm32x_probe(struct flash_bank *bank)
                LOG_INFO("Device: %s", stm32x_info->part_info->device_str);
        }
 
-       /* update the address of controller from data base */
-       stm32x_info->flash_regs_base = stm32x_info->part_info->flash_regs_base;
+       /* update the address of controller */
+       if (bank->base == FLASH_BANK0_ADDRESS)
+               stm32x_info->flash_regs_base = FLASH_REG_BASE_B0;
+       else if (bank->base == FLASH_BANK1_ADDRESS)
+               stm32x_info->flash_regs_base = FLASH_REG_BASE_B1;
+       else {
+               LOG_WARNING("Flash register base not defined for bank %u", bank->bank_number);
+               return ERROR_FAIL;
+       }
+       LOG_DEBUG("flash_regs_base: 0x%" PRIx32, stm32x_info->flash_regs_base);
 
        /* get flash size from target */
        retval = target_read_u16(target, stm32x_info->part_info->fsize_addr, &flash_size_in_kb);
@@ -772,7 +797,7 @@ static int stm32x_probe(struct flash_bank *bank)
                /* read error when device has invalid value, set max flash size */
                flash_size_in_kb = stm32x_info->part_info->max_flash_size_kb;
        } else
-               LOG_INFO("flash size probed value %d", flash_size_in_kb);
+               LOG_INFO("flash size probed value %" PRIu16, flash_size_in_kb);
 
 
 
@@ -797,6 +822,8 @@ static int stm32x_probe(struct flash_bank *bank)
                        /* flash size is 2M or 1M */
                        flash_size_in_kb /= 2;
                break;
+       case 0x483:
+               break;
        default:
                LOG_ERROR("unsupported device");
                return ERROR_FAIL;
@@ -823,8 +850,8 @@ static int stm32x_probe(struct flash_bank *bank)
                }
        }
 
-       LOG_INFO("Bank (%d) size is %d kb, base address is 0x%" PRIx32,
-               bank->bank_number, flash_size_in_kb, (uint32_t) bank->base);
+       LOG_INFO("Bank (%u) size is %" PRIu16 " kb, base address is " TARGET_ADDR_FMT,
+               bank->bank_number, flash_size_in_kb, bank->base);
 
        /* if the user sets the size manually then ignore the probed value
         * this allows us to work around devices that have an invalid flash size register value */
@@ -846,13 +873,12 @@ static int stm32x_probe(struct flash_bank *bank)
        bank->num_sectors = flash_size_in_kb / stm32x_info->part_info->page_size_kb;
        assert(bank->num_sectors > 0);
 
-       if (bank->sectors)
-               free(bank->sectors);
+       free(bank->sectors);
 
        bank->sectors = alloc_block_array(0, stm32x_info->part_info->page_size_kb * 1024,
                        bank->num_sectors);
 
-       if (bank->sectors == NULL) {
+       if (!bank->sectors) {
                LOG_ERROR("failed to allocate bank sectors");
                return ERROR_FAIL;
        }
@@ -864,18 +890,17 @@ static int stm32x_probe(struct flash_bank *bank)
        bank->num_prot_blocks = bank->num_sectors / wpsn;
        assert(bank->num_prot_blocks > 0);
 
-       if (bank->prot_blocks)
-               free(bank->prot_blocks);
+       free(bank->prot_blocks);
 
        bank->prot_blocks = alloc_block_array(0, stm32x_info->part_info->page_size_kb * wpsn * 1024,
                        bank->num_prot_blocks);
 
-       if (bank->prot_blocks == NULL) {
+       if (!bank->prot_blocks) {
                LOG_ERROR("failed to allocate bank prot_block");
                return ERROR_FAIL;
        }
 
-       stm32x_info->probed = 1;
+       stm32x_info->probed = true;
        return ERROR_OK;
 }
 
@@ -890,7 +915,7 @@ static int stm32x_auto_probe(struct flash_bank *bank)
 }
 
 /* This method must return a string displaying information about the bank */
-static int stm32x_get_info(struct flash_bank *bank, char *buf, int buf_size)
+static int stm32x_get_info(struct flash_bank *bank, struct command_invocation *cmd)
 {
        struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;
        const struct stm32h7x_part_info *info = stm32x_info->part_info;
@@ -898,7 +923,7 @@ static int stm32x_get_info(struct flash_bank *bank, char *buf, int buf_size)
        if (!stm32x_info->probed) {
                int retval = stm32x_probe(bank);
                if (retval != ERROR_OK) {
-                       snprintf(buf, buf_size, "Unable to find bank information.");
+                       command_print_sameline(cmd, "Unable to find bank information.");
                        return retval;
                }
        }
@@ -911,17 +936,17 @@ static int stm32x_get_info(struct flash_bank *bank, char *buf, int buf_size)
                        if (rev_id == info->revs[i].rev)
                                rev_str = info->revs[i].str;
 
-               if (rev_str != NULL) {
-                       snprintf(buf, buf_size, "%s - Rev: %s",
+               if (rev_str) {
+                       command_print_sameline(cmd, "%s - Rev: %s",
                                stm32x_info->part_info->device_str, rev_str);
                } else {
-                       snprintf(buf, buf_size,
-                                "%s - Rev: unknown (0x%04x)",
+                       command_print_sameline(cmd,
+                                "%s - Rev: unknown (0x%04" PRIx16 ")",
                                stm32x_info->part_info->device_str, rev_id);
                }
        } else {
-         snprintf(buf, buf_size, "Cannot identify target as a STM32H7x");
-         return ERROR_FAIL;
+               command_print_sameline(cmd, "Cannot identify target as a STM32H7x");
+               return ERROR_FAIL;
        }
        return ERROR_OK;
 }
@@ -977,7 +1002,7 @@ COMMAND_HANDLER(stm32x_handle_lock_command)
 
        struct flash_bank *bank;
        int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
-       if (ERROR_OK != retval)
+       if (retval != ERROR_OK)
                return retval;
 
        retval = stm32x_set_rdp(bank, OPT_RDP_L1);
@@ -997,7 +1022,7 @@ COMMAND_HANDLER(stm32x_handle_unlock_command)
 
        struct flash_bank *bank;
        int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
-       if (ERROR_OK != retval)
+       if (retval != ERROR_OK)
                return retval;
 
        retval = stm32x_set_rdp(bank, OPT_RDP_L0);
@@ -1057,19 +1082,14 @@ COMMAND_HANDLER(stm32x_handle_mass_erase_command)
 
        struct flash_bank *bank;
        int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
-       if (ERROR_OK != retval)
+       if (retval != ERROR_OK)
                return retval;
 
        retval = stm32x_mass_erase(bank);
-       if (retval == ERROR_OK) {
-               /* set all sectors as erased */
-               for (int i = 0; i < bank->num_sectors; i++)
-                       bank->sectors[i].is_erased = 1;
-
+       if (retval == ERROR_OK)
                command_print(CMD, "stm32h7x mass erase complete");
-       } else {
+       else
                command_print(CMD, "stm32h7x mass erase failed");
-       }
 
        return retval;
 }
@@ -1083,17 +1103,17 @@ COMMAND_HANDLER(stm32x_handle_option_read_command)
 
        struct flash_bank *bank;
        int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
-       if (ERROR_OK != retval)
+       if (retval != ERROR_OK)
                return retval;
 
        uint32_t reg_offset, value;
 
        COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], reg_offset);
        retval = stm32x_read_flash_reg(bank, reg_offset, &value);
-       if (ERROR_OK != retval)
+       if (retval != ERROR_OK)
                return retval;
 
-       command_print(CMD, "Option Register: <0x%" PRIx32 "> = 0x%" PRIx32 "",
+       command_print(CMD, "Option Register: <0x%" PRIx32 "> = 0x%" PRIx32,
                        stm32x_get_flash_reg(bank, reg_offset), value);
 
        return retval;
@@ -1108,7 +1128,7 @@ COMMAND_HANDLER(stm32x_handle_option_write_command)
 
        struct flash_bank *bank;
        int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
-       if (ERROR_OK != retval)
+       if (retval != ERROR_OK)
                return retval;
 
        uint32_t reg_offset, value, mask = 0xffffffff;