openocd: fix SPDX tag format for files .c
[fw/openocd] / src / flash / nor / stm32lx.c
index cf5b360409d149eec40a78db65a2669630258a10..42b52c5c2b09a3d9cd2d419c2d2df9dd8493a95e 100644 (file)
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
 /***************************************************************************
  *   Copyright (C) 2005 by Dominic Rath                                    *
  *   Dominic.Rath@gmx.de                                                   *
@@ -7,19 +9,6 @@
  *                                                                         *
  *   Copyright (C) 2011 by Clement Burin des Roziers                       *
  *   clement.burin-des-roziers@hikob.com                                   *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  ***************************************************************************/
 
 #ifdef HAVE_CONFIG_H
@@ -152,7 +141,7 @@ static const struct stm32lx_rev stm32_429_revs[] = {
        { 0x1000, "A" }, { 0x1018, "Z" },
 };
 static const struct stm32lx_rev stm32_436_revs[] = {
-       { 0x1000, "A" }, { 0x1008, "Z" }, { 0x1018, "Y" },
+       { 0x1000, "A" }, { 0x1008, "Z" }, { 0x1018, "Y" }, { 0x1038, "X" },
 };
 static const struct stm32lx_rev stm32_437_revs[] = {
        { 0x1000, "A" },
@@ -290,7 +279,7 @@ FLASH_BANK_COMMAND_HANDLER(stm32lx_flash_bank_command)
        stm32lx_info = calloc(1, sizeof(*stm32lx_info));
 
        /* Check allocation */
-       if (stm32lx_info == NULL) {
+       if (!stm32lx_info) {
                LOG_ERROR("failed to allocate bank structure");
                return ERROR_FAIL;
        }
@@ -313,19 +302,14 @@ COMMAND_HANDLER(stm32lx_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 = stm32lx_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, "stm32lx mass erase complete");
-       } else {
+       else
                command_print(CMD, "stm32lx mass erase failed");
-       }
 
        return retval;
 }
@@ -337,7 +321,7 @@ COMMAND_HANDLER(stm32lx_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 = stm32lx_lock(bank);
@@ -357,7 +341,7 @@ COMMAND_HANDLER(stm32lx_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 = stm32lx_unlock(bank);
@@ -430,12 +414,12 @@ static int stm32lx_write_half_pages(struct flash_bank *bank, const uint8_t *buff
        struct stm32lx_flash_bank *stm32lx_info = bank->driver_priv;
 
        uint32_t hp_nb = stm32lx_info->part_info.page_size / 2;
-       uint32_t buffer_size = 16384;
+       uint32_t buffer_size = (16384 / hp_nb) * hp_nb; /* must be multiple of hp_nb */
        struct working_area *write_algorithm;
        struct working_area *source;
        uint32_t address = bank->base + offset;
 
-       struct reg_param reg_params[3];
+       struct reg_param reg_params[5];
        struct armv7m_algorithm armv7m_info;
 
        int retval = ERROR_OK;
@@ -445,8 +429,12 @@ static int stm32lx_write_half_pages(struct flash_bank *bank, const uint8_t *buff
        };
 
        /* Make sure we're performing a half-page aligned write. */
+       if (offset % hp_nb) {
+               LOG_ERROR("The offset must be %" PRIu32 "B-aligned but it is %" PRIi32 "B)", hp_nb, offset);
+               return ERROR_FAIL;
+       }
        if (count % hp_nb) {
-               LOG_ERROR("The byte count must be %" PRIu32 "B-aligned but count is %" PRIi32 "B)", hp_nb, count);
+               LOG_ERROR("The byte count must be %" PRIu32 "B-aligned but count is %" PRIu32 "B)", hp_nb, count);
                return ERROR_FAIL;
        }
 
@@ -481,6 +469,9 @@ static int stm32lx_write_half_pages(struct flash_bank *bank, const uint8_t *buff
 
                        LOG_WARNING("no large enough working area available, can't do block memory writes");
                        return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+               } else {
+                       /* Make sure we're still asking for an integral number of half-pages */
+                       buffer_size -= buffer_size % hp_nb;
                }
        }
 
@@ -489,6 +480,8 @@ static int stm32lx_write_half_pages(struct flash_bank *bank, const uint8_t *buff
        init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
        init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
        init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
+       init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
+       init_reg_param(&reg_params[4], "r4", 32, PARAM_OUT);
 
        /* Enable half-page write */
        retval = stm32lx_enable_write_half_page(bank);
@@ -499,11 +492,13 @@ static int stm32lx_write_half_pages(struct flash_bank *bank, const uint8_t *buff
                destroy_reg_param(&reg_params[0]);
                destroy_reg_param(&reg_params[1]);
                destroy_reg_param(&reg_params[2]);
+               destroy_reg_param(&reg_params[3]);
+               destroy_reg_param(&reg_params[4]);
                return retval;
        }
 
        struct armv7m_common *armv7m = target_to_armv7m(target);
-       if (armv7m == NULL) {
+       if (!armv7m) {
 
                /* something is very wrong if armv7m is NULL */
                LOG_ERROR("unable to get armv7m target");
@@ -529,12 +524,16 @@ static int stm32lx_write_half_pages(struct flash_bank *bank, const uint8_t *buff
                buf_set_u32(reg_params[0].value, 0, 32, address);
                /* The source address of the copy (R1) */
                buf_set_u32(reg_params[1].value, 0, 32, source->address);
-               /* The length of the copy (R2) */
-               buf_set_u32(reg_params[2].value, 0, 32, this_count / 4);
+               /* The number of half pages to copy (R2) */
+               buf_set_u32(reg_params[2].value, 0, 32, this_count / hp_nb);
+               /* The size in byes of a half page (R3) */
+               buf_set_u32(reg_params[3].value, 0, 32, hp_nb);
+               /* The flash base address (R4) */
+               buf_set_u32(reg_params[4].value, 0, 32, stm32lx_info->flash_base);
 
                /* 5: Execute the bunch of code */
-               retval = target_run_algorithm(target, 0, NULL, sizeof(reg_params)
-                               / sizeof(*reg_params), reg_params,
+               retval = target_run_algorithm(target, 0, NULL,
+                               ARRAY_SIZE(reg_params), reg_params,
                                write_algorithm->address, 0, 10000, &armv7m_info);
                if (retval != ERROR_OK)
                        break;
@@ -598,6 +597,8 @@ static int stm32lx_write_half_pages(struct flash_bank *bank, const uint8_t *buff
        destroy_reg_param(&reg_params[0]);
        destroy_reg_param(&reg_params[1]);
        destroy_reg_param(&reg_params[2]);
+       destroy_reg_param(&reg_params[3]);
+       destroy_reg_param(&reg_params[4]);
 
        return retval;
 }
@@ -718,7 +719,7 @@ static int stm32lx_read_id_code(struct target *target, uint32_t *id)
 {
        struct armv7m_common *armv7m = target_to_armv7m(target);
        int retval;
-       if (armv7m->arm.is_armv6m == true)
+       if (armv7m->arm.arch == ARM_ARCH_V6M)
                retval = target_read_u32(target, DBGMCU_IDCODE_L0, id);
        else
        /* read stm32 device id register */
@@ -836,16 +837,13 @@ static int stm32lx_probe(struct flash_bank *bank)
        /* calculate numbers of sectors (4kB per sector) */
        unsigned int num_sectors = (flash_size_in_kb * 1024) / FLASH_SECTOR_SIZE;
 
-       if (bank->sectors) {
-               free(bank->sectors);
-               bank->sectors = NULL;
-       }
+       free(bank->sectors);
 
        bank->size = flash_size_in_kb * 1024;
        bank->base = base_address;
        bank->num_sectors = num_sectors;
        bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
-       if (bank->sectors == NULL) {
+       if (!bank->sectors) {
                LOG_ERROR("failed to allocate bank sectors");
                return ERROR_FAIL;
        }
@@ -873,7 +871,7 @@ static int stm32lx_auto_probe(struct flash_bank *bank)
 }
 
 /* This method must return a string displaying information about the bank */
-static int stm32lx_get_info(struct flash_bank *bank, char *buf, int buf_size)
+static int stm32lx_get_info(struct flash_bank *bank, struct command_invocation *cmd)
 {
        struct stm32lx_flash_bank *stm32lx_info = bank->driver_priv;
        const struct stm32lx_part_info *info = &stm32lx_info->part_info;
@@ -883,8 +881,7 @@ static int stm32lx_get_info(struct flash_bank *bank, char *buf, int buf_size)
        if (!stm32lx_info->probed) {
                int retval = stm32lx_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;
                }
        }
@@ -893,14 +890,10 @@ static int stm32lx_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",
-                       info->device_str, rev_str);
+       if (rev_str) {
+               command_print_sameline(cmd, "%s - Rev: %s", info->device_str, rev_str);
        } else {
-               snprintf(buf, buf_size,
-                       "%s - Rev: unknown (0x%04x)",
-                       info->device_str, rev_id);
+               command_print_sameline(cmd, "%s - Rev: unknown (0x%04x)", info->device_str, rev_id);
        }
 
        return ERROR_OK;