openocd: fix SPDX tag format for files .c
[fw/openocd] / src / flash / nor / ath79.c
index 451e843658b127546723cc34407d04760d87bccd..1d1ec02b3352a81356b6a2b42bef2989f72403fc 100644 (file)
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
 /***************************************************************************
  *   Copyright (C) 2015 by Tobias Diedrich                                 *
  *   <ranma+openwrt@tdiedrich.de>                                          *
@@ -5,20 +7,6 @@
  *   based on the stmsmi code written by Antonio Borneo                    *
  *   <borneo.antonio@gmail.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, write to the                         *
- *   Free Software Foundation, Inc.                                        *
- *                                                                         *
  ***************************************************************************/
 /*
  * Driver for the Atheros AR7xxx/AR9xxx SPI flash interface.
@@ -89,7 +77,7 @@ struct ath79_spi_ctx {
 };
 
 struct ath79_flash_bank {
-       int probed;
+       bool probed;
        int chipselect;
        uint32_t io_base;
        const struct flash_device *dev;
@@ -275,7 +263,7 @@ static int ath79_spi_bitbang_chunk(struct flash_bank *bank,
        *transferred = 0;
        pracc_queue_init(&ctx);
 
-       LOG_DEBUG("ath79_spi_bitbang_bytes(%p, %08x, %p, %d)",
+       LOG_DEBUG("ath79_spi_bitbang_bytes(%p, %08" PRIx32 ", %p, %d)",
                  target, ath79_info->io_base, data, len);
 
        LOG_DEBUG("max code %d => max len %d. to_xfer %d",
@@ -498,21 +486,21 @@ static int ath79_erase_sector(struct flash_bank *bank, int sector)
        return wait_till_ready(bank, ATH79_MAX_TIMEOUT);
 }
 
-static int ath79_erase(struct flash_bank *bank, int first, int last)
+static int ath79_erase(struct flash_bank *bank, unsigned int first,
+               unsigned int last)
 {
        struct target *target = bank->target;
        struct ath79_flash_bank *ath79_info = bank->driver_priv;
        int retval = ERROR_OK;
-       int sector;
 
-       LOG_DEBUG("%s: from sector %d to sector %d", __func__, first, last);
+       LOG_DEBUG("%s: from sector %u to sector %u", __func__, first, last);
 
        if (target->state != TARGET_HALTED) {
                LOG_ERROR("Target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
-       if ((first < 0) || (last < first) || (last >= bank->num_sectors)) {
+       if ((last < first) || (last >= bank->num_sectors)) {
                LOG_ERROR("Flash sector invalid");
                return ERROR_FLASH_SECTOR_INVALID;
        }
@@ -522,14 +510,17 @@ static int ath79_erase(struct flash_bank *bank, int first, int last)
                return ERROR_FLASH_BANK_NOT_PROBED;
        }
 
-       for (sector = first; sector <= last; sector++) {
+       if (ath79_info->dev->erase_cmd == 0x00)
+               return ERROR_FLASH_OPER_UNSUPPORTED;
+
+       for (unsigned sector = first; sector <= last; sector++) {
                if (bank->sectors[sector].is_protected) {
-                       LOG_ERROR("Flash sector %d protected", sector);
+                       LOG_ERROR("Flash sector %u protected", sector);
                        return ERROR_FAIL;
                }
        }
 
-       for (sector = first; sector <= last; sector++) {
+       for (unsigned int sector = first; sector <= last; sector++) {
                retval = ath79_erase_sector(bank, sector);
                if (retval != ERROR_OK)
                        break;
@@ -539,12 +530,10 @@ static int ath79_erase(struct flash_bank *bank, int first, int last)
        return retval;
 }
 
-static int ath79_protect(struct flash_bank *bank, int set,
-                        int first, int last)
+static int ath79_protect(struct flash_bank *bank, int set, unsigned int first,
+               unsigned int last)
 {
-       int sector;
-
-       for (sector = first; sector <= last; sector++)
+       for (unsigned int sector = first; sector <= last; sector++)
                bank->sectors[sector].is_protected = set;
        return ERROR_OK;
 }
@@ -560,10 +549,14 @@ static int ath79_write_page(struct flash_bank *bank, const uint8_t *buffer,
                address,
        };
        int retval;
-       uint32_t i;
+       uint32_t i, pagesize;
+
+       /* if no write pagesize, use reasonable default */
+       pagesize = ath79_info->dev->pagesize ?
+               ath79_info->dev->pagesize : SPIFLASH_DEF_PAGESIZE;
 
        if (address & 0xff) {
-               LOG_ERROR("ath79_write_page: unaligned write address: %08x",
+               LOG_ERROR("ath79_write_page: unaligned write address: %08" PRIx32,
                          address);
                return ERROR_FAIL;
        }
@@ -572,8 +565,8 @@ static int ath79_write_page(struct flash_bank *bank, const uint8_t *buffer,
                return ERROR_FAIL;
        }
        if (len > ath79_info->dev->pagesize) {
-               LOG_ERROR("ath79_write_page: len bigger than page size %d: %d",
-                         ath79_info->dev->pagesize, len);
+               LOG_ERROR("ath79_write_page: len bigger than page size %" PRIu32 ": %" PRIu32,
+                       pagesize, len);
                return ERROR_FAIL;
        }
 
@@ -584,7 +577,7 @@ static int ath79_write_page(struct flash_bank *bank, const uint8_t *buffer,
        if (i == len)  /* all 0xff, no need to program. */
                return ERROR_OK;
 
-       LOG_INFO("writing %d bytes to flash page @0x%08x", len, address);
+       LOG_INFO("writing %" PRIu32 " bytes to flash page @0x%08" PRIx32, len, address);
 
        memcpy(ath79_info->spi.page_buf, buffer, len);
 
@@ -611,12 +604,16 @@ static int ath79_write_buffer(struct flash_bank *bank, const uint8_t *buffer,
                              uint32_t address, uint32_t len)
 {
        struct ath79_flash_bank *ath79_info = bank->driver_priv;
-       const uint32_t page_size = ath79_info->dev->pagesize;
+       uint32_t page_size;
        int retval;
 
        LOG_DEBUG("%s: address=0x%08" PRIx32 " len=0x%08" PRIx32,
                  __func__, address, len);
 
+       /* if no valid page_size, use reasonable default */
+       page_size = ath79_info->dev->pagesize ?
+               ath79_info->dev->pagesize : SPIFLASH_DEF_PAGESIZE;
+
        while (len > 0) {
                int page_len = len > page_size ? page_size : len;
 
@@ -637,18 +634,10 @@ static int ath79_write(struct flash_bank *bank, const uint8_t *buffer,
                       uint32_t offset, uint32_t count)
 {
        struct target *target = bank->target;
-       int sector;
 
        LOG_DEBUG("%s: offset=0x%08" PRIx32 " count=0x%08" PRIx32,
                  __func__, offset, count);
 
-       if (offset < bank->base || offset >= bank->base + bank->size) {
-               LOG_ERROR("Start address out of range");
-               return ERROR_FAIL;
-       }
-
-       offset -= bank->base;
-
        if (target->state != TARGET_HALTED) {
                LOG_ERROR("Target not halted");
                return ERROR_TARGET_NOT_HALTED;
@@ -660,7 +649,7 @@ static int ath79_write(struct flash_bank *bank, const uint8_t *buffer,
        }
 
        /* Check sector protection */
-       for (sector = 0; sector < bank->num_sectors; sector++) {
+       for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
                /* Start offset in or before this sector? */
                /* End offset in or behind this sector? */
                struct flash_sector *bs = &bank->sectors[sector];
@@ -668,7 +657,7 @@ static int ath79_write(struct flash_bank *bank, const uint8_t *buffer,
                if ((offset < (bs->offset + bs->size)) &&
                    ((offset + count - 1) >= bs->offset) &&
                    bs->is_protected) {
-                       LOG_ERROR("Flash sector %d protected", sector);
+                       LOG_ERROR("Flash sector %u protected", sector);
                        return ERROR_FAIL;
                }
        }
@@ -691,12 +680,12 @@ static int ath79_read_buffer(struct flash_bank *bank, uint8_t *buffer,
                  __func__, address, len);
 
        if (address & 0xff) {
-               LOG_ERROR("ath79_read_buffer: unaligned read address: %08x",
+               LOG_ERROR("ath79_read_buffer: unaligned read address: %08" PRIx32,
                          address);
                return ERROR_FAIL;
        }
 
-       LOG_INFO("reading %d bytes from flash @0x%08x", len, address);
+       LOG_INFO("reading %" PRIu32 " bytes from flash @0x%08" PRIx32, len, address);
 
        /* bitbang command */
        ath79_spi_bitbang_prepare(bank);
@@ -718,13 +707,6 @@ static int ath79_read(struct flash_bank *bank, uint8_t *buffer,
        LOG_DEBUG("%s: offset=0x%08" PRIx32 " count=0x%08" PRIx32,
                  __func__, offset, count);
 
-       if (offset < bank->base || offset >= bank->base + bank->size) {
-               LOG_ERROR("Start address out of range");
-               return ERROR_FAIL;
-       }
-
-       offset -= bank->base;
-
        if (target->state != TARGET_HALTED) {
                LOG_ERROR("Target not halted");
                return ERROR_TARGET_NOT_HALTED;
@@ -775,6 +757,7 @@ static int ath79_probe(struct flash_bank *bank)
        struct ath79_flash_bank *ath79_info = bank->driver_priv;
        struct flash_sector *sectors;
        uint32_t id = 0; /* silence uninitialized warning */
+       uint32_t pagesize, sectorsize;
        const struct ath79_target *target_device;
        int retval;
 
@@ -782,7 +765,7 @@ static int ath79_probe(struct flash_bank *bank)
                free(bank->sectors);
                free(ath79_info->spi.page_buf);
        }
-       ath79_info->probed = 0;
+       ath79_info->probed = false;
 
        for (target_device = target_devices; target_device->name;
                ++target_device)
@@ -796,7 +779,7 @@ static int ath79_probe(struct flash_bank *bank)
 
        ath79_info->io_base = target_device->io_base;
 
-       LOG_DEBUG("Found device %s at address 0x%" PRIx32,
+       LOG_DEBUG("Found device %s at address " TARGET_ADDR_FMT,
                  target_device->name, bank->base);
 
        retval = read_flash_id(bank, &id);
@@ -820,31 +803,42 @@ static int ath79_probe(struct flash_bank *bank)
 
        /* Set correct size value */
        bank->size = ath79_info->dev->size_in_bytes;
+       if (bank->size <= (1UL << 16))
+               LOG_WARNING("device needs 2-byte addresses - not implemented");
+       if (bank->size > (1UL << 24))
+               LOG_WARNING("device needs paging or 4-byte addresses - not implemented");
+
+       /* if no sectors, treat whole bank as single sector */
+       sectorsize = ath79_info->dev->sectorsize ?
+               ath79_info->dev->sectorsize : ath79_info->dev->size_in_bytes;
 
        /* create and fill sectors array */
-       bank->num_sectors =
-               ath79_info->dev->size_in_bytes / ath79_info->dev->sectorsize;
+       bank->num_sectors = ath79_info->dev->size_in_bytes / sectorsize;
        sectors = calloc(1, sizeof(struct flash_sector) * bank->num_sectors);
        if (!sectors) {
                LOG_ERROR("not enough memory");
                return ERROR_FAIL;
        }
-       ath79_info->spi.page_buf = malloc(ath79_info->dev->pagesize);
+
+       /* if no write pagesize, use reasonable default */
+       pagesize = ath79_info->dev->pagesize ? ath79_info->dev->pagesize : SPIFLASH_DEF_PAGESIZE;
+
+       ath79_info->spi.page_buf = malloc(pagesize);
        if (!ath79_info->spi.page_buf) {
                LOG_ERROR("not enough memory");
                free(sectors);
                return ERROR_FAIL;
        }
 
-       for (int sector = 0; sector < bank->num_sectors; sector++) {
-               sectors[sector].offset = sector * ath79_info->dev->sectorsize;
-               sectors[sector].size = ath79_info->dev->sectorsize;
+       for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
+               sectors[sector].offset = sector * sectorsize;
+               sectors[sector].size = sectorsize;
                sectors[sector].is_erased = 0;
                sectors[sector].is_protected = 1;
        }
 
        bank->sectors = sectors;
-       ath79_info->probed = 1;
+       ath79_info->probed = true;
        return ERROR_OK;
 }
 
@@ -869,24 +863,23 @@ static int ath79_protect_check(struct flash_bank *bank)
        return ERROR_OK;
 }
 
-static int get_ath79_info(struct flash_bank *bank, char *buf, int buf_size)
+static int get_ath79_info(struct flash_bank *bank, struct command_invocation *cmd)
 {
        struct ath79_flash_bank *ath79_info = bank->driver_priv;
 
        if (!ath79_info->probed) {
-               snprintf(buf, buf_size,
-                        "\nATH79 flash bank not probed yet\n");
+               command_print_sameline(cmd, "\nATH79 flash bank not probed yet\n");
                return ERROR_OK;
        }
 
-       snprintf(buf, buf_size, "\nATH79 flash information:\n"
+       command_print_sameline(cmd, "\nATH79 flash information:\n"
                "  Device \'%s\' (ID 0x%08" PRIx32 ")\n",
                ath79_info->dev->name, ath79_info->dev->device_id);
 
        return ERROR_OK;
 }
 
-struct flash_driver ath79_flash = {
+const struct flash_driver ath79_flash = {
        .name = "ath79",
        .flash_bank_command = ath79_flash_bank_command,
        .erase = ath79_erase,
@@ -898,4 +891,5 @@ struct flash_driver ath79_flash = {
        .erase_check = ath79_flash_blank_check,
        .protect_check = ath79_protect_check,
        .info = get_ath79_info,
+       .free_driver_priv = default_flash_free_driver_priv,
 };