flash/nor/rp2040: make SPI flash ID detection optional
[openocd.git] / src / flash / nor / numicro.c
index 992baa5155b4a112dcaf346dc5b88933139243fb..1a73eb26d0f3a463e06d924a5a0409f33e8859c9 100644 (file)
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
 /***************************************************************************
  *   Copyright (C) 2011 by James K. Larson                                 *
  *   jlarson@pacifier.com                                                  *
  *                                                                         *
  *   Copyright (C) 2015 Nemui Trinomius                                    *
  *   nemuisan_kawausogasuki@live.jp                                        *
- *                                                                         *
- *   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
@@ -151,7 +140,7 @@ struct numicro_cpu_type {
        {NUMICRO_CONFIG_BASE, 1024} }
 
 
-static const struct numicro_cpu_type NuMicroParts[] = {
+static const struct numicro_cpu_type numicro_parts[] = {
        /*PART NO*/     /*PART ID*/ /*Banks*/
        /* NUC100 Version B */
        {"NUC100LD2BN", 0x10010004, NUMICRO_BANKS_NUC100(64*1024)},
@@ -1132,7 +1121,7 @@ static const struct numicro_cpu_type NuMicroParts[] = {
 /* Private bank information for NuMicro. */
 struct  numicro_flash_bank {
        struct working_area *write_algorithm;
-       int probed;
+       bool probed;
        const struct numicro_cpu_type *cpu;
 };
 
@@ -1216,7 +1205,7 @@ static int numicro_init_isp(struct target *target)
        return ERROR_OK;
 }
 
-static uint32_t numicro_fmc_cmd(struct target *target, uint32_t cmd, uint32_t addr, uint32_t wdata, uint32_trdata)
+static uint32_t numicro_fmc_cmd(struct target *target, uint32_t cmd, uint32_t addr, uint32_t wdata, uint32_t *rdata)
 {
        uint32_t timeout, status;
        int retval = ERROR_OK;
@@ -1243,7 +1232,7 @@ static uint32_t numicro_fmc_cmd(struct target *target, uint32_t cmd, uint32_t ad
                retval = target_read_u32(target, NUMICRO_FLASH_ISPTRG, &status);
                if (retval != ERROR_OK)
                        return retval;
-                       LOG_DEBUG("status: 0x%" PRIx32 "", status);
+               LOG_DEBUG("status: 0x%" PRIx32 "", status);
                if ((status & (ISPTRG_ISPGO)) == 0)
                        break;
                if (timeout-- <= 0) {
@@ -1385,13 +1374,6 @@ static int numicro_writeblock(struct flash_bank *bank, const uint8_t *buffer,
        init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);    /* faddr */
        init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);    /* number of words to program */
 
-       struct armv7m_common *armv7m = target_to_armv7m(target);
-       if (armv7m == NULL) {
-               /* something is very wrong if armv7m is NULL */
-               LOG_ERROR("unable to get armv7m target");
-               return retval;
-       }
-
        /* write code buffer and use Flash programming code within NuMicro     */
        /* Set breakpoint to 0 with time-out of 1000 ms                        */
        while (count > 0) {
@@ -1433,7 +1415,7 @@ static int numicro_protect_check(struct flash_bank *bank)
 {
        struct target *target = bank->target;
        uint32_t set, config[2];
-       int i, retval = ERROR_OK;
+       int retval = ERROR_OK;
 
        if (target->state != TARGET_HALTED) {
                LOG_ERROR("Target not halted");
@@ -1467,25 +1449,26 @@ static int numicro_protect_check(struct flash_bank *bank)
            set = 0;
        }
 
-       for (i = 0; i < bank->num_sectors; i++)
+       for (unsigned int i = 0; i < bank->num_sectors; i++)
                bank->sectors[i].is_protected = set;
 
        return ERROR_OK;
 }
 
 
-static int numicro_erase(struct flash_bank *bank, int first, int last)
+static int numicro_erase(struct flash_bank *bank, unsigned int first,
+               unsigned int last)
 {
        struct target *target = bank->target;
        uint32_t timeout, status;
-       int i, retval = ERROR_OK;
+       int retval = ERROR_OK;
 
        if (target->state != TARGET_HALTED) {
                LOG_ERROR("Target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
-       LOG_INFO("Nuvoton NuMicro: Sector Erase ... (%d to %d)", first, last);
+       LOG_INFO("Nuvoton NuMicro: Sector Erase ... (%u to %u)", first, last);
 
        retval = numicro_init_isp(target);
        if (retval != ERROR_OK)
@@ -1495,8 +1478,9 @@ static int numicro_erase(struct flash_bank *bank, int first, int last)
        if (retval != ERROR_OK)
                return retval;
 
-       for (i = first; i <= last; i++) {
-               LOG_DEBUG("erasing sector %d at address 0x%" PRIx32 "", i, bank->base + bank->sectors[i].offset);
+       for (unsigned int i = first; i <= last; i++) {
+               LOG_DEBUG("erasing sector %u at address " TARGET_ADDR_FMT, i,
+                               bank->base + bank->sectors[i].offset);
                retval = target_write_u32(target, NUMICRO_FLASH_ISPADR, bank->base + bank->sectors[i].offset);
                if (retval != ERROR_OK)
                        return retval;
@@ -1510,7 +1494,7 @@ static int numicro_erase(struct flash_bank *bank, int first, int last)
                        retval = target_read_u32(target, NUMICRO_FLASH_ISPTRG, &status);
                        if (retval != ERROR_OK)
                                return retval;
-                               LOG_DEBUG("status: 0x%" PRIx32 "", status);
+                       LOG_DEBUG("status: 0x%" PRIx32 "", status);
                        if (status == 0)
                                break;
                        if (timeout-- <= 0) {
@@ -1530,8 +1514,6 @@ static int numicro_erase(struct flash_bank *bank, int first, int last)
                        retval = target_write_u32(target, NUMICRO_FLASH_ISPCON, (status | ISPCON_ISPFF));
                        if (retval != ERROR_OK)
                                return retval;
-               } else {
-                       bank->sectors[i].is_erased = 1;
                }
        }
 
@@ -1547,7 +1529,6 @@ static int numicro_write(struct flash_bank *bank, const uint8_t *buffer,
 {
        struct target *target = bank->target;
        uint32_t timeout, status;
-       uint8_t *new_buffer = NULL;
        int retval = ERROR_OK;
 
        if (target->state != TARGET_HALTED) {
@@ -1565,20 +1546,8 @@ static int numicro_write(struct flash_bank *bank, const uint8_t *buffer,
        if (retval != ERROR_OK)
                return retval;
 
-       if (count & 0x3) {
-               uint32_t old_count = count;
-               count = (old_count | 3) + 1;
-               new_buffer = malloc(count);
-               if (new_buffer == NULL) {
-                       LOG_ERROR("odd number of bytes to write and no memory "
-                               "for padding buffer");
-                       return ERROR_FAIL;
-               }
-               LOG_INFO("odd number of bytes to write (%d), extending to %d "
-                       "and padding with 0xff", old_count, count);
-               memset(new_buffer, 0xff, count);
-               buffer = memcpy(new_buffer, buffer, old_count);
-       }
+       assert(offset % 4 == 0);
+       assert(count % 4 == 0);
 
        uint32_t words_remaining = count / 4;
 
@@ -1594,15 +1563,12 @@ static int numicro_write(struct flash_bank *bank, const uint8_t *buffer,
                /* program command */
                for (uint32_t i = 0; i < count; i += 4) {
 
-                       LOG_DEBUG("write longword @ %08X", offset + i);
-
-                       uint8_t padding[4] = {0xff, 0xff, 0xff, 0xff};
-                       memcpy(padding, buffer + i, MIN(4, count-i));
+                       LOG_DEBUG("write longword @ %08" PRIX32, offset + i);
 
                        retval = target_write_u32(target, NUMICRO_FLASH_ISPADR, bank->base + offset + i);
                        if (retval != ERROR_OK)
                                return retval;
-                       retval = target_write_memory(target, NUMICRO_FLASH_ISPDAT, 4, 1, padding);
+                       retval = target_write_memory(target, NUMICRO_FLASH_ISPDAT, 4, 1, buffer + i);
                        if (retval != ERROR_OK)
                                return retval;
                        retval = target_write_u32(target, NUMICRO_FLASH_ISPTRG, ISPTRG_ISPGO);
@@ -1615,7 +1581,7 @@ static int numicro_write(struct flash_bank *bank, const uint8_t *buffer,
                                retval = target_read_u32(target, NUMICRO_FLASH_ISPTRG, &status);
                                if (retval != ERROR_OK)
                                        return retval;
-                                       LOG_DEBUG("status: 0x%" PRIx32 "", status);
+                               LOG_DEBUG("status: 0x%" PRIx32 "", status);
                                if (status == 0)
                                        break;
                                if (timeout-- <= 0) {
@@ -1648,7 +1614,7 @@ static int numicro_write(struct flash_bank *bank, const uint8_t *buffer,
        return ERROR_OK;
 }
 
-static int numicro_get_cpu_type(struct target *target, const struct numicro_cpu_type** cpu)
+static int numicro_get_cpu_type(struct target *target, const struct numicro_cpu_type **cpu)
 {
        uint32_t part_id;
        int retval = ERROR_OK;
@@ -1662,9 +1628,9 @@ static int numicro_get_cpu_type(struct target *target, const struct numicro_cpu_
 
        LOG_INFO("Device ID: 0x%08" PRIx32 "", part_id);
        /* search part numbers */
-       for (size_t i = 0; i < sizeof(NuMicroParts)/sizeof(NuMicroParts[0]); i++) {
-               if (part_id == NuMicroParts[i].partid) {
-                       *cpu = &NuMicroParts[i];
+       for (size_t i = 0; i < ARRAY_SIZE(numicro_parts); i++) {
+               if (part_id == numicro_parts[i].partid) {
+                       *cpu = &numicro_parts[i];
                        LOG_INFO("Device Name: %s", (*cpu)->partname);
                        return ERROR_OK;
                }
@@ -1678,7 +1644,8 @@ static int numicro_get_flash_size(struct flash_bank *bank, const struct numicro_
        for (size_t i = 0; i < cpu->n_banks; i++) {
                if (bank->base == cpu->bank[i].base) {
                        *flash_size = cpu->bank[i].size;
-                       LOG_INFO("bank base = 0x%08" PRIx32 ", size = 0x%08" PRIx32 "", bank->base, *flash_size);
+                       LOG_INFO("bank base = " TARGET_ADDR_FMT ", size = 0x%08"
+                                       PRIx32, bank->base, *flash_size);
                        return ERROR_OK;
                }
        }
@@ -1752,6 +1719,7 @@ FLASH_BANK_COMMAND_HANDLER(numicro_flash_bank_command)
        memset(bank_info, 0, sizeof(struct numicro_flash_bank));
 
        bank->driver_priv = bank_info;
+       bank->write_start_alignment = bank->write_end_alignment = 4;
 
        return ERROR_OK;
 
@@ -1825,11 +1793,11 @@ COMMAND_HANDLER(numicro_handle_chip_erase_command)
 
        retval = numicro_fmc_cmd(target, ISPCMD_CHIPERASE, 0, 0, &rdat);
        if (retval != ERROR_OK) {
-               command_print(CMD_CTX, "numicro chip_erase failed");
+               command_print(CMD, "numicro chip_erase failed");
                return retval;
        }
 
-       command_print(CMD_CTX, "numicro chip_erase complete");
+       command_print(CMD, "numicro chip_erase complete");
 
        return ERROR_OK;
 }
@@ -1854,6 +1822,7 @@ static const struct command_registration numicro_exec_command_handlers[] = {
                .handler = numicro_handle_chip_erase_command,
                .mode = COMMAND_EXEC,
                .help = "chip erase through ISP.",
+               .usage = "",
        },
        COMMAND_REGISTRATION_DONE
 };
@@ -1869,7 +1838,7 @@ static const struct command_registration numicro_command_handlers[] = {
        COMMAND_REGISTRATION_DONE
 };
 
-struct flash_driver numicro_flash = {
+const struct flash_driver numicro_flash = {
        .name = "numicro",
        .commands = numicro_command_handlers,
        .flash_bank_command = numicro_flash_bank_command,
@@ -1880,4 +1849,5 @@ struct flash_driver numicro_flash = {
        .auto_probe = numicro_auto_probe,
        .erase_check = default_flash_blank_check,
        .protect_check = numicro_protect_check,
+       .free_driver_priv = default_flash_free_driver_priv,
 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)