flash/nor: add support for Nuvoton NPCX series flash
[fw/openocd] / src / flash / nor / lpc2900.c
index 328232e662da94f0740e60ec90b58d16403bf763..4bf52974b6cf8fab5411af005e6d0a76797b81f7 100644 (file)
@@ -13,9 +13,7 @@
  *   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.,                                       *
- *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  ***************************************************************************/
 
 #ifdef HAVE_CONFIG_H
@@ -51,8 +49,8 @@
 #define FTCTR           0x2020000C     /* Flash test control */
 #define FBWST           0x20200010     /* Flash bridge wait-state */
 #define FCRA            0x2020001C     /* Flash clock divider */
-#define FMSSTART        0x20200020     /* Flash Built-In Selft Test start address */
-#define FMSSTOP         0x20200024     /* Flash Built-In Selft Test stop address */
+#define FMSSTART        0x20200020     /* Flash Built-In Self Test start address */
+#define FMSSTOP         0x20200024     /* Flash Built-In Self Test stop address */
 #define FMS16           0x20200028     /* Flash 16-bit signature */
 #define FMSW0           0x2020002C     /* Flash 128-bit signature Word 0 */
 #define FMSW1           0x20200030     /* Flash 128-bit signature Word 1 */
@@ -162,7 +160,7 @@ struct lpc2900_flash_bank {
 
        /**
         * Maximum contiguous block of internal SRAM (bytes).
-        * Autodetected by the driver. Not the total amount of SRAM, only the
+        * Autodetected by the driver. Not the total amount of SRAM, only
         * the largest \em contiguous block!
         */
        uint32_t max_ram_block;
@@ -176,7 +174,7 @@ static uint32_t lpc2900_read_security_status(struct flash_bank *bank);
 static uint32_t lpc2900_run_bist128(struct flash_bank *bank,
                uint32_t addr_from, uint32_t addr_to,
                uint32_t signature[4]);
-static uint32_t lpc2900_address2sector(struct flash_bank *bank, uint32_t offset);
+static unsigned int lpc2900_address2sector(struct flash_bank *bank, uint32_t offset);
 static uint32_t lpc2900_calc_tr(uint32_t clock_var, uint32_t time_var);
 
 /***********************  Helper functions  **************************/
@@ -285,9 +283,9 @@ static uint32_t lpc2900_read_security_status(struct flash_bank *bank)
         * Anything else is undefined (is_protected = -1). This is treated as
         * a protected sector!
         */
-       int sector;
-       int index_t;
-       for (sector = 0; sector < bank->num_sectors; sector++) {
+       for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
+               unsigned int index_t;
+
                /* Convert logical sector number to physical sector number */
                if (sector <= 4)
                        index_t = sector + 11;
@@ -358,14 +356,13 @@ static uint32_t lpc2900_run_bist128(struct flash_bank *bank,
  * @param bank Pointer to the flash bank descriptor
  * @param offset Offset address relative to bank start
  */
-static uint32_t lpc2900_address2sector(struct flash_bank *bank,
+static unsigned int lpc2900_address2sector(struct flash_bank *bank,
        uint32_t offset)
 {
        uint32_t address = bank->base + offset;
 
        /* Run through all sectors of this bank */
-       int sector;
-       for (sector = 0; sector < bank->num_sectors; sector++) {
+       for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
                /* Return immediately if address is within the current sector */
                if (address < (bank->sectors[sector].offset + bank->sectors[sector].size))
                        return sector;
@@ -456,8 +453,8 @@ static int lpc2900_write_index_page(struct flash_bank *bank,
 /**
  * Calculate FPTR.TR register value for desired program/erase time.
  *
- * @param clock System clock in Hz
- * @param time Program/erase time in µs
+ * @param clock_var System clock in Hz
+ * @param time_var Program/erase time in µs
  */
 static uint32_t lpc2900_calc_tr(uint32_t clock_var, uint32_t time_var)
 {
@@ -490,7 +487,7 @@ COMMAND_HANDLER(lpc2900_handle_signature_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;
 
        if (bank->target->state != TARGET_HALTED) {
@@ -503,7 +500,7 @@ COMMAND_HANDLER(lpc2900_handle_signature_command)
        if (status != ERROR_OK)
                return status;
 
-       command_print(CMD_CTX, "signature: 0x%8.8" PRIx32
+       command_print(CMD, "signature: 0x%8.8" PRIx32
                ":0x%8.8" PRIx32
                ":0x%8.8" PRIx32
                ":0x%8.8" PRIx32,
@@ -525,7 +522,7 @@ COMMAND_HANDLER(lpc2900_handle_read_custom_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;
 
        struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
@@ -587,7 +584,7 @@ COMMAND_HANDLER(lpc2900_handle_password_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;
 
        struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
@@ -597,11 +594,11 @@ COMMAND_HANDLER(lpc2900_handle_password_command)
        lpc2900_info->risky = !strcmp(CMD_ARGV[1], ISS_PASSWORD);
 
        if (!lpc2900_info->risky) {
-               command_print(CMD_CTX, "Wrong password (use '%s')", ISS_PASSWORD);
+               command_print(CMD, "Wrong password (use '%s')", ISS_PASSWORD);
                return ERROR_COMMAND_ARGUMENT_INVALID;
        }
 
-       command_print(CMD_CTX,
+       command_print(CMD,
                "Potentially dangerous operation allowed in next command!");
 
        return ERROR_OK;
@@ -617,14 +614,14 @@ COMMAND_HANDLER(lpc2900_handle_write_custom_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;
 
        struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
 
        /* Check if command execution is allowed. */
        if (!lpc2900_info->risky) {
-               command_print(CMD_CTX, "Command execution not allowed!");
+               command_print(CMD, "Command execution not allowed!");
                return ERROR_COMMAND_ARGUMENT_INVALID;
        }
        lpc2900_info->risky = 0;
@@ -638,9 +635,9 @@ COMMAND_HANDLER(lpc2900_handle_write_custom_command)
 
        /* The image will always start at offset 0 */
        struct image image;
-       image.base_address_set = 1;
+       image.base_address_set = true;
        image.base_address = 0;
-       image.start_address_set = 0;
+       image.start_address_set = false;
 
        const char *filename = CMD_ARGV[1];
        const char *type = (CMD_ARGC >= 3) ? CMD_ARGV[2] : NULL;
@@ -716,37 +713,36 @@ COMMAND_HANDLER(lpc2900_handle_secure_sector_command)
        /* Get the bank descriptor */
        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;
 
        struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
 
        /* Check if command execution is allowed. */
        if (!lpc2900_info->risky) {
-               command_print(CMD_CTX, "Command execution not allowed! "
+               command_print(CMD, "Command execution not allowed! "
                        "(use 'password' command first)");
                return ERROR_COMMAND_ARGUMENT_INVALID;
        }
        lpc2900_info->risky = 0;
 
        /* Read sector range, and do a sanity check. */
-       int first, last;
-       COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], first);
-       COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], last);
+       unsigned int first, last;
+       COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], first);
+       COMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], last);
        if ((first >= bank->num_sectors) ||
                        (last >= bank->num_sectors) ||
                        (first > last)) {
-               command_print(CMD_CTX, "Illegal sector range");
+               command_print(CMD, "Illegal sector range");
                return ERROR_COMMAND_ARGUMENT_INVALID;
        }
 
        uint8_t page[FLASH_PAGE_SIZE];
-       int sector;
 
        /* Sectors in page 6 */
        if ((first <= 4) || (last >= 8)) {
                memset(&page, 0xff, FLASH_PAGE_SIZE);
-               for (sector = first; sector <= last; sector++) {
+               for (unsigned int sector = first; sector <= last; sector++) {
                        if (sector <= 4)
                                memset(&page[0xB0 + 16*sector], 0, 16);
                        else if (sector >= 8)
@@ -763,7 +759,7 @@ COMMAND_HANDLER(lpc2900_handle_secure_sector_command)
        /* Sectors in page 7 */
        if ((first <= 7) && (last >= 5)) {
                memset(&page, 0xff, FLASH_PAGE_SIZE);
-               for (sector = first; sector <= last; sector++) {
+               for (unsigned int sector = first; sector <= last; sector++) {
                        if ((sector >= 5) && (sector <= 7))
                                memset(&page[0x00 + 16*(sector - 5)], 0, 16);
                }
@@ -775,7 +771,7 @@ COMMAND_HANDLER(lpc2900_handle_secure_sector_command)
                }
        }
 
-       command_print(CMD_CTX,
+       command_print(CMD,
                "Sectors security will become effective after next power cycle");
 
        /* Update the sector security status */
@@ -798,14 +794,14 @@ COMMAND_HANDLER(lpc2900_handle_secure_jtag_command)
        /* Get the bank descriptor */
        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;
 
        struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
 
        /* Check if command execution is allowed. */
        if (!lpc2900_info->risky) {
-               command_print(CMD_CTX, "Command execution not allowed! "
+               command_print(CMD, "Command execution not allowed! "
                        "(use 'password' command first)");
                return ERROR_COMMAND_ARGUMENT_INVALID;
        }
@@ -947,11 +943,12 @@ FLASH_BANK_COMMAND_HANDLER(lpc2900_flash_bank_command)
  * @param first First sector to be erased
  * @param last Last sector (including) to be erased
  */
-static int lpc2900_erase(struct flash_bank *bank, int first, int last)
+static int lpc2900_erase(struct flash_bank *bank, unsigned int first,
+               unsigned int last)
 {
        uint32_t status;
-       int sector;
-       int last_unsecured_sector;
+       unsigned int last_unsecured_sector;
+       bool has_unsecured_sector;
        struct target *target = bank->target;
        struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
 
@@ -961,7 +958,7 @@ static int lpc2900_erase(struct flash_bank *bank, int first, int last)
                return status;
 
        /* Sanity check on sector range */
-       if ((first < 0) || (last < first) || (last >= bank->num_sectors)) {
+       if ((last < first) || (last >= bank->num_sectors)) {
                LOG_INFO("Bad sector range");
                return ERROR_FLASH_SECTOR_INVALID;
        }
@@ -976,16 +973,19 @@ static int lpc2900_erase(struct flash_bank *bank, int first, int last)
         * a special way.
         */
        last_unsecured_sector = -1;
-       for (sector = first; sector <= last; sector++) {
-               if (!bank->sectors[sector].is_protected)
+       has_unsecured_sector = false;
+       for (unsigned int sector = first; sector <= last; sector++) {
+               if (!bank->sectors[sector].is_protected) {
                        last_unsecured_sector = sector;
+                       has_unsecured_sector = true;
+               }
        }
 
        /* Exit now, in case of the rare constellation where all sectors in range
         * are secured. This is regarded a success, since erasing/programming of
         * secured sectors shall be handled transparently.
         */
-       if (last_unsecured_sector == -1)
+       if (!has_unsecured_sector)
                return ERROR_OK;
 
        /* Enable flash block and set the correct CRA clock of 66 kHz */
@@ -1000,7 +1000,7 @@ static int lpc2900_erase(struct flash_bank *bank, int first, int last)
                        FLASH_ERASE_TIME));
 
        /* Sectors are marked for erasure, then erased all together */
-       for (sector = first; sector <= last_unsecured_sector; sector++) {
+       for (unsigned int sector = first; sector <= last_unsecured_sector; sector++) {
                /* Only mark sectors that aren't secured. Any attempt to erase a group
                 * of sectors will fail if any single one of them is secured!
                 */
@@ -1037,18 +1037,13 @@ static int lpc2900_erase(struct flash_bank *bank, int first, int last)
        return ERROR_OK;
 }
 
-static int lpc2900_protect(struct flash_bank *bank, int set, int first, int last)
-{
-       /* This command is not supported.
-       * "Protection" in LPC2900 terms is handled transparently. Sectors will
-       * automatically be unprotected as needed.
-       * Instead we use the concept of sector security. A secured sector is shown
-       * as "protected" in OpenOCD. Sector security is a permanent feature, and
-       * cannot be disabled once activated.
-       */
-
-       return ERROR_OK;
-}
+/* lpc2900_protect command is not supported.
+* "Protection" in LPC2900 terms is handled transparently. Sectors will
+* automatically be unprotected as needed.
+* Instead we use the concept of sector security. A secured sector is shown
+* as "protected" in OpenOCD. Sector security is a permanent feature, and
+* cannot be disabled once activated.
+*/
 
 /**
  * Write data to flash.
@@ -1066,7 +1061,6 @@ static int lpc2900_write(struct flash_bank *bank, const uint8_t *buffer,
        uint32_t num_bytes;
        struct target *target = bank->target;
        struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
-       int sector;
        int retval;
 
        static const uint32_t write_target_code[] = {
@@ -1118,7 +1112,7 @@ static int lpc2900_write(struct flash_bank *bank, const uint8_t *buffer,
        lpc2900_read_security_status(bank);
 
        /* Unprotect all involved sectors */
-       for (sector = 0; sector < bank->num_sectors; sector++) {
+       for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
                /* Start address in or before this sector?
                 * End address in or behind this sector? */
                if (((bank->base + offset) <
@@ -1186,7 +1180,7 @@ static int lpc2900_write(struct flash_bank *bank, const uint8_t *buffer,
                while (count != 0) {
                        uint32_t this_npages;
                        const uint8_t *this_buffer;
-                       int start_sector = lpc2900_address2sector(bank, offset);
+                       unsigned int start_sector = lpc2900_address2sector(bank, offset);
 
                        /* First page / last page / rest */
                        if (offset % FLASH_PAGE_SIZE) {
@@ -1215,7 +1209,7 @@ static int lpc2900_write(struct flash_bank *bank, const uint8_t *buffer,
                                this_buffer = buffer;
 
                                /* Make sure we stop at the next secured sector */
-                               sector = start_sector + 1;
+                               unsigned int sector = start_sector + 1;
                                while (sector < bank->num_sectors) {
                                        /* Secured? */
                                        if (bank->sectors[sector].is_protected) {
@@ -1237,7 +1231,7 @@ static int lpc2900_write(struct flash_bank *bank, const uint8_t *buffer,
 
                        /* Skip the current sector if it is secured */
                        if (bank->sectors[start_sector].is_protected) {
-                               LOG_DEBUG("Skip secured sector %d",
+                               LOG_DEBUG("Skip secured sector %u",
                                        start_sector);
 
                                /* Stop if this is the last sector */
@@ -1378,7 +1372,6 @@ static int lpc2900_probe(struct flash_bank *bank)
 {
        struct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;
        struct target *target = bank->target;
-       int i = 0;
        uint32_t offset;
 
 
@@ -1474,8 +1467,8 @@ static int lpc2900_probe(struct flash_bank *bank)
        }
 
        /* Show detected device */
-       LOG_INFO("Flash bank %d: Device %s, %" PRIu32
-               " KiB in %d sectors",
+       LOG_INFO("Flash bank %u: Device %s, %" PRIu32
+               " KiB in %u sectors",
                bank->bank_number,
                lpc2900_info->target_name, bank->size / KiB,
                bank->num_sectors);
@@ -1494,7 +1487,7 @@ static int lpc2900_probe(struct flash_bank *bank)
        bank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);
 
        offset = 0;
-       for (i = 0; i < bank->num_sectors; i++) {
+       for (unsigned int i = 0; i < bank->num_sectors; i++) {
                bank->sectors[i].offset = offset;
                bank->sectors[i].is_erased = -1;
                bank->sectors[i].is_protected = -1;
@@ -1508,7 +1501,7 @@ static int lpc2900_probe(struct flash_bank *bank)
                         * that has more than 19 sectors. Politely ask for a fix then.
                         */
                        bank->sectors[i].size = 0;
-                       LOG_ERROR("Never heard about sector %d", i);
+                       LOG_ERROR("Never heard about sector %u", i);
                }
 
                offset += bank->sectors[i].size;
@@ -1542,11 +1535,10 @@ static int lpc2900_erase_check(struct flash_bank *bank)
                return status;
        }
 
-       /* Use the BIST (Built-In Selft Test) to generate a signature of each flash
+       /* Use the BIST (Built-In Self Test) to generate a signature of each flash
         * sector. Compare against the expected signature of an empty sector.
         */
-       int sector;
-       for (sector = 0; sector < bank->num_sectors; sector++) {
+       for (unsigned int sector = 0; sector < bank->num_sectors; sector++) {
                uint32_t signature[4];
                status = lpc2900_run_bist128(bank, bank->sectors[sector].offset,
                                bank->sectors[sector].offset + (bank->sectors[sector].size - 1), signature);
@@ -1588,16 +1580,16 @@ static int lpc2900_protect_check(struct flash_bank *bank)
        return lpc2900_read_security_status(bank);
 }
 
-struct flash_driver lpc2900_flash = {
+const struct flash_driver lpc2900_flash = {
        .name = "lpc2900",
        .commands = lpc2900_command_handlers,
        .flash_bank_command = lpc2900_flash_bank_command,
        .erase = lpc2900_erase,
-       .protect = lpc2900_protect,
        .write = lpc2900_write,
        .read = default_flash_read,
        .probe = lpc2900_probe,
        .auto_probe = lpc2900_probe,
        .erase_check = lpc2900_erase_check,
        .protect_check = lpc2900_protect_check,
+       .free_driver_priv = default_flash_free_driver_priv,
 };