openocd: fix SPDX tag format for files .c
[fw/openocd] / src / flash / nor / stm32lx.c
index 5ca424b873407933e215fc3544bc157993c8e6aa..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,6 +429,10 @@ 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 %" 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,8 +524,12 @@ 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,
@@ -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;
 }
@@ -842,7 +843,7 @@ static int stm32lx_probe(struct flash_bank *bank)
        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;
        }
@@ -889,7 +890,7 @@ static int stm32lx_get_info(struct flash_bank *bank, struct command_invocation *
                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", info->device_str, rev_str);
        } else {
                command_print_sameline(cmd, "%s - Rev: unknown (0x%04x)", info->device_str, rev_id);