Kinetis: check/switch run mode before flash operation
[openocd.git] / src / flash / nor / kinetis.c
index a1625ffee64bef805d74904a4eeca452f0f5e6ed..7907b8c386ad2f81d8f6a3ce946046d038fde36a 100644 (file)
@@ -11,6 +11,9 @@
  *   Copyright (C) 2013 Nemui Trinomius                                    *
  *   nemuisan_kawausogasuki@live.jp                                        *
  *                                                                         *
+ *   Copyright (C) 2015 Tomas Vanek                                        *
+ *   vanekt@fbl.cz                                                         *
+ *                                                                         *
  *   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     *
@@ -79,6 +82,8 @@
 
 /* Addressess */
 #define FLEXRAM                0x14000000
+
+#define FMC_PFB01CR    0x4001f004
 #define FTFx_FSTAT     0x40020000
 #define FTFx_FCNFG     0x40020001
 #define FTFx_FCCOB3    0x40020004
 #define SIM_FCFG1      0x4004804c
 #define SIM_FCFG2      0x40048050
 #define WDOG_STCTRH    0x40052000
+#define SMC_PMCTRL     0x4007E001
+#define SMC_PMSTAT     0x4007E003
+
+/* Values */
+#define PM_STAT_RUN            0x01
+#define PM_STAT_VLPR           0x04
+#define PM_CTRL_RUNM_RUN       0x00
 
 /* Commands */
 #define FTFx_CMD_BLOCKSTAT  0x00
 #define FTFx_CMD_LWORDPROG  0x06
 #define FTFx_CMD_SECTERASE  0x09
 #define FTFx_CMD_SECTWRITE  0x0b
-#define FTFx_CMD_SETFLEXRAM 0x81
 #define FTFx_CMD_MASSERASE  0x44
+#define FTFx_CMD_PGMPART    0x80
+#define FTFx_CMD_SETFLEXRAM 0x81
 
 /* The older Kinetis K series uses the following SDID layout :
  * Bit 31-16 : 0
@@ -212,6 +225,7 @@ struct kinetis_flash_bank {
                FS_PROGRAM_SECTOR = 1,
                FS_PROGRAM_LONGWORD = 2,
                FS_PROGRAM_PHRASE = 4, /* Unsupported */
+               FS_INVALIDATE_CACHE = 8,
        } flash_support;
 };
 
@@ -944,16 +958,69 @@ static int kinetis_ftfx_command(struct target *target, uint8_t fcmd, uint32_t fa
 }
 
 
-static int kinetis_erase(struct flash_bank *bank, int first, int last)
+static int kinetis_check_run_mode(struct target *target)
 {
        int result, i;
-       struct kinetis_flash_bank *kinfo = bank->driver_priv;
+       uint8_t pmctrl, pmstat;
 
-       if (bank->target->state != TARGET_HALTED) {
+       if (target->state != TARGET_HALTED) {
                LOG_ERROR("Target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
+       result = target_read_u8(target, SMC_PMSTAT, &pmstat);
+       if (result != ERROR_OK)
+               return result;
+
+       if (pmstat == PM_STAT_RUN)
+               return ERROR_OK;
+
+       if (pmstat == PM_STAT_VLPR) {
+               /* It is safe to switch from VLPR to RUN mode without changing clock */
+               LOG_INFO("Switching from VLPR to RUN mode.");
+               pmctrl = PM_CTRL_RUNM_RUN;
+               result = target_write_u8(target, SMC_PMCTRL, pmctrl);
+               if (result != ERROR_OK)
+                       return result;
+
+               for (i = 100; i; i--) {
+                       result = target_read_u8(target, SMC_PMSTAT, &pmstat);
+                       if (result != ERROR_OK)
+                               return result;
+
+                       if (pmstat == PM_STAT_RUN)
+                               return ERROR_OK;
+               }
+       }
+
+       LOG_ERROR("Flash operation not possible in current run mode: SMC_PMSTAT: 0x%x", pmstat);
+       LOG_ERROR("Issue a 'reset init' command.");
+       return ERROR_TARGET_NOT_HALTED;
+}
+
+
+static void kinetis_invalidate_flash_cache(struct flash_bank *bank)
+{
+       struct kinetis_flash_bank *kinfo = bank->driver_priv;
+       uint8_t pfb01cr_byte2 = 0xf0;
+
+       if (!(kinfo->flash_support & FS_INVALIDATE_CACHE))
+               return;
+
+       target_write_memory(bank->target, FMC_PFB01CR + 2, 1, 1, &pfb01cr_byte2);
+       return;
+}
+
+
+static int kinetis_erase(struct flash_bank *bank, int first, int last)
+{
+       int result, i;
+       struct kinetis_flash_bank *kinfo = bank->driver_priv;
+
+       result = kinetis_check_run_mode(bank->target);
+       if (result != ERROR_OK)
+               return result;
+
        if ((first > bank->num_sectors) || (last > bank->num_sectors))
                return ERROR_FLASH_OPERATION_FAILED;
 
@@ -976,6 +1043,8 @@ static int kinetis_erase(struct flash_bank *bank, int first, int last)
                bank->sectors[i].is_erased = 1;
        }
 
+       kinetis_invalidate_flash_cache(bank);
+
        if (first == 0) {
                LOG_WARNING
                        ("flash configuration field erased, please reset the device");
@@ -1023,10 +1092,9 @@ static int kinetis_write(struct flash_bank *bank, const uint8_t *buffer,
        struct kinetis_flash_bank *kinfo = bank->driver_priv;
        uint8_t *new_buffer = NULL;
 
-       if (bank->target->state != TARGET_HALTED) {
-               LOG_ERROR("Target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
+       result = kinetis_check_run_mode(bank->target);
+       if (result != ERROR_OK)
+               return result;
 
        if (!(kinfo->flash_support & FS_PROGRAM_SECTOR)) {
                /* fallback to longword write */
@@ -1175,6 +1243,7 @@ static int kinetis_write(struct flash_bank *bank, const uint8_t *buffer,
                return ERROR_FLASH_OPERATION_FAILED;
        }
 
+       kinetis_invalidate_flash_cache(bank);
        return ERROR_OK;
 }
 
@@ -1183,7 +1252,7 @@ static int kinetis_read_part_info(struct flash_bank *bank)
        int result, i;
        uint32_t offset = 0;
        uint8_t fcfg1_nvmsize, fcfg1_pfsize, fcfg1_eesize, fcfg1_depart;
-       uint8_t fcfg2_pflsh;
+       uint8_t fcfg2_maxaddr0, fcfg2_pflsh, fcfg2_maxaddr1;
        uint32_t nvm_size = 0, pf_size = 0, df_size = 0, ee_size = 0;
        unsigned num_blocks = 0, num_pflash_blocks = 0, num_nvm_blocks = 0, first_nvm_bank = 0,
                        pflash_sector_size_bytes = 0, nvm_sector_size_bytes = 0;
@@ -1207,7 +1276,7 @@ static int kinetis_read_part_info(struct flash_bank *bank)
                        pflash_sector_size_bytes = 1<<10;
                        nvm_sector_size_bytes = 1<<10;
                        num_blocks = 2;
-                       kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR;
+                       kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE;
                        break;
                case KINETIS_K_SDID_K10_M72:
                case KINETIS_K_SDID_K20_M72:
@@ -1220,7 +1289,7 @@ static int kinetis_read_part_info(struct flash_bank *bank)
                        pflash_sector_size_bytes = 2<<10;
                        nvm_sector_size_bytes = 1<<10;
                        num_blocks = 2;
-                       kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR;
+                       kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE;
                        kinfo->max_flash_prog_size = 1<<10;
                        break;
                case KINETIS_K_SDID_K10_M100:
@@ -1236,7 +1305,7 @@ static int kinetis_read_part_info(struct flash_bank *bank)
                        pflash_sector_size_bytes = 2<<10;
                        nvm_sector_size_bytes = 2<<10;
                        num_blocks = 2;
-                       kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR;
+                       kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE;
                        break;
                case KINETIS_K_SDID_K21_M120:
                case KINETIS_K_SDID_K22_M120:
@@ -1245,7 +1314,7 @@ static int kinetis_read_part_info(struct flash_bank *bank)
                        kinfo->max_flash_prog_size = 1<<10;
                        nvm_sector_size_bytes = 4<<10;
                        num_blocks = 2;
-                       kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
+                       kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE;
                        break;
                case KINETIS_K_SDID_K10_M120:
                case KINETIS_K_SDID_K20_M120:
@@ -1255,7 +1324,7 @@ static int kinetis_read_part_info(struct flash_bank *bank)
                        pflash_sector_size_bytes = 4<<10;
                        nvm_sector_size_bytes = 4<<10;
                        num_blocks = 4;
-                       kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
+                       kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE;
                        break;
                default:
                        LOG_ERROR("Unsupported K-family FAMID");
@@ -1269,7 +1338,7 @@ static int kinetis_read_part_info(struct flash_bank *bank)
                                /* K02FN64, K02FN128: FTFA, 2kB sectors */
                                pflash_sector_size_bytes = 2<<10;
                                num_blocks = 1;
-                               kinfo->flash_support = FS_PROGRAM_LONGWORD;
+                               kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE;
                                break;
 
                        case KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX2: {
@@ -1284,7 +1353,7 @@ static int kinetis_read_part_info(struct flash_bank *bank)
                                        /* MK24FN1M */
                                        pflash_sector_size_bytes = 4<<10;
                                        num_blocks = 2;
-                                       kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
+                                       kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE;
                                        kinfo->max_flash_prog_size = 1<<10;
                                        break;
                                }
@@ -1293,8 +1362,8 @@ static int kinetis_read_part_info(struct flash_bank *bank)
                                        || (kinfo->sim_sdid & (KINETIS_SDID_DIEID_MASK)) == KINETIS_SDID_DIEID_K22FN512) {
                                        /* K22 with new-style SDID - smaller pflash with FTFA, 2kB sectors */
                                        pflash_sector_size_bytes = 2<<10;
-                                       num_blocks = 2;         /* 1 or 2 blocks */
-                                       kinfo->flash_support = FS_PROGRAM_LONGWORD;
+                                       /* autodetect 1 or 2 blocks */
+                                       kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE;
                                        break;
                                }
                                LOG_ERROR("Unsupported Kinetis K22 DIEID");
@@ -1305,12 +1374,12 @@ static int kinetis_read_part_info(struct flash_bank *bank)
                                if ((kinfo->sim_sdid & (KINETIS_SDID_DIEID_MASK)) == KINETIS_SDID_DIEID_K24FN256) {
                                        /* K24FN256 - smaller pflash with FTFA */
                                        num_blocks = 1;
-                                       kinfo->flash_support = FS_PROGRAM_LONGWORD;
+                                       kinfo->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE;
                                        break;
                                }
                                /* K24FN1M without errata 7534 */
                                num_blocks = 2;
-                               kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
+                               kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE;
                                kinfo->max_flash_prog_size = 1<<10;
                                break;
 
@@ -1324,7 +1393,7 @@ static int kinetis_read_part_info(struct flash_bank *bank)
                                nvm_sector_size_bytes = 4<<10;
                                kinfo->max_flash_prog_size = 1<<10;
                                num_blocks = 2;
-                               kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
+                               kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE;
                                break;
 
                        case KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX6:
@@ -1335,7 +1404,7 @@ static int kinetis_read_part_info(struct flash_bank *bank)
                                nvm_sector_size_bytes = 4<<10;
                                kinfo->max_flash_prog_size = 1<<10;
                                num_blocks = 4;
-                               kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
+                               kinfo->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE;
                                break;
                        default:
                                LOG_ERROR("Unsupported Kinetis FAMILYID SUBFAMID");
@@ -1345,7 +1414,7 @@ static int kinetis_read_part_info(struct flash_bank *bank)
                        /* KL-series */
                        pflash_sector_size_bytes = 1<<10;
                        nvm_sector_size_bytes = 1<<10;
-                       num_blocks = 1;
+                       /* autodetect 1 or 2 blocks */
                        kinfo->flash_support = FS_PROGRAM_LONGWORD;
                        break;
                default:
@@ -1375,6 +1444,18 @@ static int kinetis_read_part_info(struct flash_bank *bank)
        fcfg1_depart = (uint8_t)((kinfo->sim_fcfg1 >> 8) & 0x0f);
 
        fcfg2_pflsh = (uint8_t)((kinfo->sim_fcfg2 >> 23) & 0x01);
+       fcfg2_maxaddr0 = (uint8_t)((kinfo->sim_fcfg2 >> 24) & 0x7f);
+       fcfg2_maxaddr1 = (uint8_t)((kinfo->sim_fcfg2 >> 16) & 0x7f);
+
+       if (num_blocks == 0)
+               num_blocks = fcfg2_maxaddr1 ? 2 : 1;
+       else if (fcfg2_maxaddr1 == 0 && num_blocks >= 2) {
+               num_blocks = 1;
+               LOG_WARNING("MAXADDR1 is zero, number of flash banks adjusted to 1");
+       } else if (fcfg2_maxaddr1 != 0 && num_blocks == 1) {
+               num_blocks = 2;
+               LOG_WARNING("MAXADDR1 is non zero, number of flash banks adjusted to 2");
+       }
 
        /* when the PFLSH bit is set, there is no FlexNVM/FlexRAM */
        if (!fcfg2_pflsh) {
@@ -1451,12 +1532,22 @@ static int kinetis_read_part_info(struct flash_bank *bank)
                pf_size = 1 << (14 + (fcfg1_pfsize >> 1));
                break;
        case 0x0f:
-               if (pflash_sector_size_bytes >= 4<<10)
-                       pf_size = 1024<<10;
-               else if (fcfg2_pflsh)
-                       pf_size = 512<<10;
+               /* a peculiar case: Freescale states different sizes for 0xf
+                * K02P64M100SFARM      128 KB ... duplicate of code 0x7
+                * K22P121M120SF8RM     256 KB ... duplicate of code 0x9
+                * K22P121M120SF7RM     512 KB ... duplicate of code 0xb
+                * K22P100M120SF5RM     1024 KB ... duplicate of code 0xd
+                * K26P169M180SF5RM     2048 KB ... the only unique value
+                * fcfg2_maxaddr0 seems to be the only clue to pf_size
+                * Checking fcfg2_maxaddr0 later in this routine is pointless then
+                */
+               if (fcfg2_pflsh)
+                       pf_size = ((uint32_t)fcfg2_maxaddr0 << 13) * num_blocks;
                else
-                       pf_size = 256<<10;
+                       pf_size = ((uint32_t)fcfg2_maxaddr0 << 13) * num_blocks / 2;
+               if (pf_size != 2048<<10)
+                       LOG_WARNING("SIM_FCFG1 PFSIZE = 0xf: please check if pflash is %u KB", pf_size>>10);
+
                break;
        default:
                pf_size = 0;
@@ -1528,6 +1619,20 @@ static int kinetis_read_part_info(struct flash_bank *bank)
                return ERROR_FLASH_BANK_INVALID;
        }
 
+       if (bank->bank_number == 0 && ((uint32_t)fcfg2_maxaddr0 << 13) != bank->size)
+               LOG_WARNING("MAXADDR0 0x%02" PRIx8 " check failed,"
+                               " please report to OpenOCD mailing list", fcfg2_maxaddr0);
+       if (fcfg2_pflsh) {
+               if (bank->bank_number == 1 && ((uint32_t)fcfg2_maxaddr1 << 13) != bank->size)
+                       LOG_WARNING("MAXADDR1 0x%02" PRIx8 " check failed,"
+                               " please report to OpenOCD mailing list", fcfg2_maxaddr1);
+       } else {
+               if ((unsigned)bank->bank_number == first_nvm_bank
+                               && ((uint32_t)fcfg2_maxaddr1 << 13) != df_size)
+                       LOG_WARNING("FlexNVM MAXADDR1 0x%02" PRIx8 " check failed,"
+                               " please report to OpenOCD mailing list", fcfg2_maxaddr1);
+       }
+
        if (bank->sectors) {
                free(bank->sectors);
                bank->sectors = NULL;
@@ -1603,14 +1708,14 @@ static int kinetis_info(struct flash_bank *bank, char *buf, int buf_size)
 static int kinetis_blank_check(struct flash_bank *bank)
 {
        struct kinetis_flash_bank *kinfo = bank->driver_priv;
+       int result;
 
-       if (bank->target->state != TARGET_HALTED) {
-               LOG_ERROR("Target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
+       /* suprisingly blank check does not work in VLPR and HSRUN modes */
+       result = kinetis_check_run_mode(bank->target);
+       if (result != ERROR_OK)
+               return result;
 
        if (kinfo->flash_class == FC_PFLASH || kinfo->flash_class == FC_FLEX_NVM) {
-               int result;
                bool block_dirty = false;
                uint8_t ftfx_fstat;
 
@@ -1660,6 +1765,145 @@ static int kinetis_blank_check(struct flash_bank *bank)
        return ERROR_OK;
 }
 
+
+COMMAND_HANDLER(kinetis_nvm_partition)
+{
+       int result, i;
+       unsigned long par, log2 = 0, ee1 = 0, ee2 = 0;
+       enum { SHOW_INFO, DF_SIZE, EEBKP_SIZE } sz_type = SHOW_INFO;
+       bool enable;
+       uint8_t ftfx_fstat;
+       uint8_t load_flex_ram = 1;
+       uint8_t ee_size_code = 0x3f;
+       uint8_t flex_nvm_partition_code = 0;
+       uint8_t ee_split = 3;
+       struct target *target = get_current_target(CMD_CTX);
+       struct flash_bank *bank;
+       struct kinetis_flash_bank *kinfo;
+       uint32_t sim_fcfg1;
+
+       if (CMD_ARGC >= 2) {
+               if (strcmp(CMD_ARGV[0], "dataflash") == 0)
+                       sz_type = DF_SIZE;
+               else if (strcmp(CMD_ARGV[0], "eebkp") == 0)
+                       sz_type = EEBKP_SIZE;
+
+               par = strtoul(CMD_ARGV[1], NULL, 10);
+               while (par >> (log2 + 3))
+                       log2++;
+       }
+       switch (sz_type) {
+       case SHOW_INFO:
+               result = target_read_u32(target, SIM_FCFG1, &sim_fcfg1);
+               if (result != ERROR_OK)
+                       return result;
+
+               flex_nvm_partition_code = (uint8_t)((sim_fcfg1 >> 8) & 0x0f);
+               switch (flex_nvm_partition_code) {
+               case 0:
+                       command_print(CMD_CTX, "No EEPROM backup, data flash only");
+                       break;
+               case 1:
+               case 2:
+               case 3:
+               case 4:
+               case 5:
+               case 6:
+                       command_print(CMD_CTX, "EEPROM backup %d KB", 4 << flex_nvm_partition_code);
+                       break;
+               case 8:
+                       command_print(CMD_CTX, "No data flash, EEPROM backup only");
+                       break;
+               case 0x9:
+               case 0xA:
+               case 0xB:
+               case 0xC:
+               case 0xD:
+               case 0xE:
+                       command_print(CMD_CTX, "data flash %d KB", 4 << (flex_nvm_partition_code & 7));
+                       break;
+               case 0xf:
+                       command_print(CMD_CTX, "No EEPROM backup, data flash only (DEPART not set)");
+                       break;
+               default:
+                       command_print(CMD_CTX, "Unsupported EEPROM backup size code 0x%02" PRIx8, flex_nvm_partition_code);
+               }
+               return ERROR_OK;
+
+       case DF_SIZE:
+               flex_nvm_partition_code = 0x8 | log2;
+               break;
+
+       case EEBKP_SIZE:
+               flex_nvm_partition_code = log2;
+               break;
+       }
+
+       if (CMD_ARGC == 3)
+               ee1 = ee2 = strtoul(CMD_ARGV[2], NULL, 10) / 2;
+       else if (CMD_ARGC >= 4) {
+               ee1 = strtoul(CMD_ARGV[2], NULL, 10);
+               ee2 = strtoul(CMD_ARGV[3], NULL, 10);
+       }
+
+       enable = ee1 + ee2 > 0;
+       if (enable) {
+               for (log2 = 2; ; log2++) {
+                       if (ee1 + ee2 == (16u << 10) >> log2)
+                               break;
+                       if (ee1 + ee2 > (16u << 10) >> log2 || log2 >= 9) {
+                               LOG_ERROR("Unsupported EEPROM size");
+                               return ERROR_FLASH_OPERATION_FAILED;
+                       }
+               }
+
+               if (ee1 * 3 == ee2)
+                       ee_split = 1;
+               else if (ee1 * 7 == ee2)
+                       ee_split = 0;
+               else if (ee1 != ee2) {
+                       LOG_ERROR("Unsupported EEPROM sizes ratio");
+                       return ERROR_FLASH_OPERATION_FAILED;
+               }
+
+               ee_size_code = log2 | ee_split << 4;
+       }
+
+       if (CMD_ARGC >= 5)
+               COMMAND_PARSE_ON_OFF(CMD_ARGV[4], enable);
+       if (enable)
+               load_flex_ram = 0;
+
+       LOG_INFO("DEPART 0x%" PRIx8 ", EEPROM size code 0x%" PRIx8,
+                flex_nvm_partition_code, ee_size_code);
+
+       result = kinetis_check_run_mode(target);
+       if (result != ERROR_OK)
+               return result;
+
+       result = kinetis_ftfx_command(target, FTFx_CMD_PGMPART, load_flex_ram,
+                                     ee_size_code, flex_nvm_partition_code, 0, 0,
+                                     0, 0, 0, 0,  &ftfx_fstat);
+       if (result != ERROR_OK)
+               return result;
+
+       command_print(CMD_CTX, "FlexNVM partition set. Please reset MCU.");
+
+       for (i = 1; i < 4; i++) {
+               bank = get_flash_bank_by_num_noprobe(i);
+               if (bank == NULL)
+                       break;
+
+               kinfo = bank->driver_priv;
+               if (kinfo && kinfo->flash_class == FC_FLEX_NVM)
+                       kinfo->probed = false;  /* re-probe before next use */
+       }
+
+       command_print(CMD_CTX, "FlexNVM banks will be re-probed to set new data flash size.");
+       return ERROR_OK;
+}
+
+
 static const struct command_registration kinetis_securtiy_command_handlers[] = {
        {
                .name = "check_security",
@@ -1693,6 +1937,14 @@ static const struct command_registration kinetis_exec_command_handlers[] = {
                .usage = "",
                .handler = kinetis_disable_wdog_handler,
        },
+       {
+               .name = "nvm_partition",
+               .mode = COMMAND_EXEC,
+               .help = "Show/set data flash or EEPROM backup size in kilobytes,"
+                       " set two EEPROM sizes in bytes and FlexRAM loading during reset",
+               .usage = "('info'|'dataflash' size|'eebkp' size) [eesize1 eesize2] ['on'|'off']",
+               .handler = kinetis_nvm_partition,
+       },
        COMMAND_REGISTRATION_DONE
 };
 

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)