flash/nor/stm32xx: fix segfault accessing Cortex-M part number
[fw/openocd] / src / flash / nor / stm32h7x.c
index 4c503db381fefaac3ae8a21bad3af4c51635a6f5..6d3149f9464dd1c9a813db3c19dc27d61d208e6b 100644 (file)
@@ -21,7 +21,7 @@
 #include "imp.h"
 #include <helper/binarybuffer.h>
 #include <target/algorithm.h>
-#include <target/armv7m.h>
+#include <target/cortex_m.h>
 
 
 /* Erase time can be as high as 1000ms, 10x this and it's toast... */
 #define FLASH_REG_BASE_B0       0x52002000
 #define FLASH_REG_BASE_B1       0x52002100
 
+/* Supported device IDs */
+#define DEVID_STM32H74_H75XX    0x450
+#define DEVID_STM32H7A_H7BXX    0x480
+#define DEVID_STM32H72_H73XX    0x483
+
 struct stm32h7x_rev {
        uint16_t rev;
        const char *str;
@@ -139,24 +144,24 @@ enum stm32h7x_opt_rdp {
        OPT_RDP_L2 = 0xcc
 };
 
-static const struct stm32h7x_rev stm32_450_revs[] = {
+static const struct stm32h7x_rev stm32h74_h75xx_revs[] = {
        { 0x1000, "A" }, { 0x1001, "Z" }, { 0x1003, "Y" }, { 0x2001, "X"  }, { 0x2003, "V"  },
 };
 
-static const struct stm32h7x_rev stm32_480_revs[] = {
+static const struct stm32h7x_rev stm32h7a_h7bxx_revs[] = {
        { 0x1000, "A"},
 };
 
-static const struct stm32h7x_rev stm32_483_revs[] = {
+static const struct stm32h7x_rev stm32h72_h73xx_revs[] = {
        { 0x1000, "A" }, { 0x1001, "Z" },
 };
 
-static uint32_t stm32x_compute_flash_cr_450_483(uint32_t cmd, int snb)
+static uint32_t stm32h74_h75xx_compute_flash_cr(uint32_t cmd, int snb)
 {
        return cmd | (snb << 8);
 }
 
-static uint32_t stm32x_compute_flash_cr_480(uint32_t cmd, int snb)
+static uint32_t stm32h7a_h7bxx_compute_flash_cr(uint32_t cmd, int snb)
 {
        /* save FW and START bits, to be right shifted by 2 bits later */
        const uint32_t tmp = cmd & (FLASH_FW | FLASH_START);
@@ -169,9 +174,9 @@ static uint32_t stm32x_compute_flash_cr_480(uint32_t cmd, int snb)
 
 static const struct stm32h7x_part_info stm32h7x_parts[] = {
        {
-       .id                                     = 0x450,
-       .revs                           = stm32_450_revs,
-       .num_revs                       = ARRAY_SIZE(stm32_450_revs),
+       .id                                     = DEVID_STM32H74_H75XX,
+       .revs                           = stm32h74_h75xx_revs,
+       .num_revs                       = ARRAY_SIZE(stm32h74_h75xx_revs),
        .device_str                     = "STM32H74x/75x",
        .page_size_kb           = 128,
        .block_size                     = 32,
@@ -181,12 +186,12 @@ static const struct stm32h7x_part_info stm32h7x_parts[] = {
        .fsize_addr                     = 0x1FF1E880,
        .wps_group_size         = 1,
        .wps_mask                       = 0xFF,
-       .compute_flash_cr       = stm32x_compute_flash_cr_450_483,
+       .compute_flash_cr       = stm32h74_h75xx_compute_flash_cr,
        },
        {
-       .id                                     = 0x480,
-       .revs                           = stm32_480_revs,
-       .num_revs                       = ARRAY_SIZE(stm32_480_revs),
+       .id                                     = DEVID_STM32H7A_H7BXX,
+       .revs                           = stm32h7a_h7bxx_revs,
+       .num_revs                       = ARRAY_SIZE(stm32h7a_h7bxx_revs),
        .device_str                     = "STM32H7Ax/7Bx",
        .page_size_kb           = 8,
        .block_size                     = 16,
@@ -196,12 +201,12 @@ static const struct stm32h7x_part_info stm32h7x_parts[] = {
        .fsize_addr                     = 0x08FFF80C,
        .wps_group_size         = 4,
        .wps_mask                       = 0xFFFFFFFF,
-       .compute_flash_cr       = stm32x_compute_flash_cr_480,
+       .compute_flash_cr       = stm32h7a_h7bxx_compute_flash_cr,
        },
        {
-       .id                                     = 0x483,
-       .revs                           = stm32_483_revs,
-       .num_revs                       = ARRAY_SIZE(stm32_483_revs),
+       .id                                     = DEVID_STM32H72_H73XX,
+       .revs                           = stm32h72_h73xx_revs,
+       .num_revs                       = ARRAY_SIZE(stm32h72_h73xx_revs),
        .device_str                     = "STM32H72x/73x",
        .page_size_kb           = 128,
        .block_size                     = 32,
@@ -211,7 +216,7 @@ static const struct stm32h7x_part_info stm32h7x_parts[] = {
        .fsize_addr                     = 0x1FF1E880,
        .wps_group_size         = 1,
        .wps_mask                       = 0xFF,
-       .compute_flash_cr   = stm32x_compute_flash_cr_450_483,
+       .compute_flash_cr   = stm32h74_h75xx_compute_flash_cr,
        },
 };
 
@@ -512,7 +517,6 @@ static int stm32x_erase(struct flash_bank *bank, unsigned int first,
                        LOG_ERROR("erase time-out or operation error sector %u", i);
                        goto flash_lock;
                }
-               bank->sectors[i].is_erased = 1;
        }
 
 flash_lock:
@@ -762,6 +766,11 @@ static int stm32x_probe(struct flash_bank *bank)
        stm32x_info->probed = false;
        stm32x_info->part_info = NULL;
 
+       if (!target_was_examined(target)) {
+               LOG_ERROR("Target not examined yet");
+               return ERROR_TARGET_NOT_EXAMINED;
+       }
+
        int retval = stm32x_read_id_code(bank, &stm32x_info->idcode);
        if (retval != ERROR_OK)
                return retval;
@@ -793,15 +802,20 @@ static int stm32x_probe(struct flash_bank *bank)
        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);
+       /* STM32H74x/H75x, the second core (Cortex-M4) cannot read the flash size */
+       retval = ERROR_FAIL;
+       if (device_id == DEVID_STM32H74_H75XX
+                       && cortex_m_get_partno_safe(target) == CORTEX_M4_PARTNO)
+               LOG_WARNING("%s cannot read the flash size register", target_name(target));
+       else
+               retval = target_read_u16(target, stm32x_info->part_info->fsize_addr, &flash_size_in_kb);
+
        if (retval != ERROR_OK) {
                /* read error when device has invalid value, set max flash size */
                flash_size_in_kb = stm32x_info->part_info->max_flash_size_kb;
+               LOG_INFO("assuming %" PRIu16 "k flash", flash_size_in_kb);
        } else
-               LOG_INFO("flash size probed value %" PRIu16, flash_size_in_kb);
-
-
-
+               LOG_INFO("flash size probed value %" PRIu16 "k", flash_size_in_kb);
 
        /* setup bank size */
        const uint32_t bank1_base = FLASH_BANK0_ADDRESS;
@@ -809,8 +823,8 @@ static int stm32x_probe(struct flash_bank *bank)
        bool has_dual_bank = stm32x_info->part_info->has_dual_bank;
 
        switch (device_id) {
-       case 0x450:
-       case 0x480:
+       case DEVID_STM32H74_H75XX:
+       case DEVID_STM32H7A_H7BXX:
                /* For STM32H74x/75x and STM32H7Ax/Bx
                 *  - STM32H7xxxI devices contains dual bank, 1 Mbyte each
                 *  - STM32H7xxxG devices contains dual bank, 512 Kbyte each
@@ -823,7 +837,7 @@ static int stm32x_probe(struct flash_bank *bank)
                        /* flash size is 2M or 1M */
                        flash_size_in_kb /= 2;
                break;
-       case 0x483:
+       case DEVID_STM32H72_H73XX:
                break;
        default:
                LOG_ERROR("unsupported device");
@@ -879,7 +893,7 @@ static int stm32x_probe(struct flash_bank *bank)
        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;
        }
@@ -896,7 +910,7 @@ static int stm32x_probe(struct flash_bank *bank)
        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;
        }
@@ -937,7 +951,7 @@ static int stm32x_get_info(struct flash_bank *bank, struct command_invocation *c
                        if (rev_id == info->revs[i].rev)
                                rev_str = info->revs[i].str;
 
-               if (rev_str != NULL) {
+               if (rev_str) {
                        command_print_sameline(cmd, "%s - Rev: %s",
                                stm32x_info->part_info->device_str, rev_str);
                } else {
@@ -1003,7 +1017,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);
@@ -1023,7 +1037,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);
@@ -1083,19 +1097,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 (unsigned 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;
 }
@@ -1109,14 +1118,14 @@ 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,
@@ -1134,7 +1143,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;
@@ -1147,7 +1156,7 @@ COMMAND_HANDLER(stm32x_handle_option_write_command)
        return stm32x_modify_option(bank, reg_offset, value, mask);
 }
 
-static const struct command_registration stm32x_exec_command_handlers[] = {
+static const struct command_registration stm32h7x_exec_command_handlers[] = {
        {
                .name = "lock",
                .handler = stm32x_handle_lock_command,
@@ -1186,20 +1195,20 @@ static const struct command_registration stm32x_exec_command_handlers[] = {
        COMMAND_REGISTRATION_DONE
 };
 
-static const struct command_registration stm32x_command_handlers[] = {
+static const struct command_registration stm32h7x_command_handlers[] = {
        {
                .name = "stm32h7x",
                .mode = COMMAND_ANY,
                .help = "stm32h7x flash command group",
                .usage = "",
-               .chain = stm32x_exec_command_handlers,
+               .chain = stm32h7x_exec_command_handlers,
        },
        COMMAND_REGISTRATION_DONE
 };
 
 const struct flash_driver stm32h7x_flash = {
        .name = "stm32h7x",
-       .commands = stm32x_command_handlers,
+       .commands = stm32h7x_command_handlers,
        .flash_bank_command = stm32x_flash_bank_command,
        .erase = stm32x_erase,
        .protect = stm32x_protect,