flash Kinetis: handle all types of watchdog, disable in reset-init 01/3901/5
authorTomas Vanek <vanekt@fbl.cz>
Mon, 26 Dec 2016 18:59:10 +0000 (19:59 +0100)
committerFreddie Chopin <freddie.chopin@gmail.com>
Sat, 17 Jun 2017 11:01:55 +0000 (12:01 +0100)
Active watchdog forces reset during armv7m_checksum_memory()
in verify_image command if run just after reset init.

COP watchdog in KL series and WDOG32 in KE1 series
have longer timeout however they need to be disabled too.

The change extends 'kinetis disable_wdog' command to optionally
probe the chip and use appropriate algorithm to disable watchdog.

Setting of cache type is also split from flash_support flags.

Tcl command 'kinetis disable_wdog' is called in reset-init event.

Change-Id: I3191e230f38b679ed74f2a97fe323ef8fb3fe22e
Signed-off-by: Tomas Vanek <vanekt@fbl.cz>
Reviewed-on: http://openocd.zylin.com/3901
Tested-by: jenkins
Reviewed-by: Joakim NohlgÄrd <joakim.nohlgard@eistec.se>
Reviewed-by: Freddie Chopin <freddie.chopin@gmail.com>
contrib/loaders/watchdog/Makefile
contrib/loaders/watchdog/armv7m_kinetis_wdog.inc
contrib/loaders/watchdog/armv7m_kinetis_wdog.s
contrib/loaders/watchdog/armv7m_kinetis_wdog32.inc [new file with mode: 0644]
contrib/loaders/watchdog/armv7m_kinetis_wdog32.s [new file with mode: 0644]
src/flash/nor/kinetis.c
tcl/target/klx.cfg
tcl/target/kx.cfg

index 623e74407c09a7407defd799f3d64adfe0d013af..ed6d8f4e555c80f203e42f40c8941594b3578182 100644 (file)
@@ -6,7 +6,7 @@ ARM_OBJCOPY ?= $(ARM_CROSS_COMPILE)objcopy
 
 ARM_AFLAGS = -EL -mthumb
 
-arm: armv7m_kinetis_wdog.inc
+arm: armv7m_kinetis_wdog.inc armv7m_kinetis_wdog32.inc
 
 armv7m_%.elf: armv7m_%.s
        $(ARM_AS) $(ARM_AFLAGS) $< -o $@
index 4b6579e0ce4fcc1923cfadc20cf474cacd3a7b3c..317d084dddf5be62e57d9dd25dacd154816b301d 100644 (file)
@@ -1,4 +1,3 @@
 /* Autogenerated with ../../../src/helper/bin2char.sh */
-0x04,0x4b,0x05,0x4a,0xda,0x81,0x05,0x4a,0xda,0x81,0x01,0x24,0x1a,0x88,0xa2,0x43,
-0x1a,0x80,0x06,0xe0,0x00,0x20,0x05,0x40,0x20,0xc5,0x00,0x00,0x28,0xd9,0x00,0x00,
-0x00,0x00,0x00,0xbe,
+0x04,0x4a,0xc2,0x81,0x04,0x4a,0xc2,0x81,0x01,0x24,0x02,0x88,0xa2,0x43,0x02,0x80,
+0x05,0xe0,0x00,0x00,0x20,0xc5,0x00,0x00,0x28,0xd9,0x00,0x00,0x00,0x00,0x00,0xbe,
index bac924ab805dbac45f26fc8fae96577ae0dfea98..d7241927c96ff593a7def293e4b3db10bfad139d 100644 (file)
@@ -19,7 +19,9 @@
 
 /*
        Disable watchdog for Kinetis Kx and KVx
-       Parameters: none
+       Parameters:
+               r0 ... WDOG base (in)
+
        Used instruction set should work on both Cortex-M4 and M0+
 */
 
@@ -28,7 +30,6 @@
         .cpu cortex-m0
        .thumb
 
-WDOG_ADDR      = 0x40052000
 /* WDOG registers offsets */
 WDOG_STCTRLH   = 0
 WDOG_UNLOCK    = 0x0e
@@ -39,17 +40,16 @@ WDOG_KEY2   = 0xd928
        .thumb_func
 start:
 /* WDOG_UNLOCK = 0xC520 */
-       ldr     r3, =WDOG_ADDR
        ldr     r2, =WDOG_KEY1
-       strh    r2, [r3, WDOG_UNLOCK]
+       strh    r2, [r0, WDOG_UNLOCK]
 /* WDOG_UNLOCK = 0xD928 */
        ldr     r2, =WDOG_KEY2
-       strh    r2, [r3, WDOG_UNLOCK]
+       strh    r2, [r0, WDOG_UNLOCK]
 /* WDOG_STCTRLH clear bit 0 */
        movs    r4, #1
-       ldrh    r2, [r3, WDOG_STCTRLH]
+       ldrh    r2, [r0, WDOG_STCTRLH]
        bics    r2, r4
-       strh    r2, [r3, WDOG_STCTRLH]
+       strh    r2, [r0, WDOG_STCTRLH]
 /* OpenOCD checks exit point address. Jump to the very end. */
        b       done
 
diff --git a/contrib/loaders/watchdog/armv7m_kinetis_wdog32.inc b/contrib/loaders/watchdog/armv7m_kinetis_wdog32.inc
new file mode 100644 (file)
index 0000000..4ee06ed
--- /dev/null
@@ -0,0 +1,5 @@
+/* Autogenerated with ../../../src/helper/bin2char.sh */
+0x02,0x68,0x08,0x4b,0x1a,0x42,0x08,0x4b,0x01,0xd0,0x43,0x60,0x02,0xe0,0x83,0x80,
+0x1b,0x0c,0x83,0x80,0x80,0x24,0xa2,0x43,0x20,0x24,0x22,0x43,0x02,0x60,0x03,0x4b,
+0x83,0x60,0x06,0xe0,0x00,0x20,0x00,0x00,0x20,0xc5,0x28,0xd9,0x00,0x04,0x00,0x00,
+0x00,0x00,0x00,0xbe,
diff --git a/contrib/loaders/watchdog/armv7m_kinetis_wdog32.s b/contrib/loaders/watchdog/armv7m_kinetis_wdog32.s
new file mode 100644 (file)
index 0000000..bf58327
--- /dev/null
@@ -0,0 +1,81 @@
+/***************************************************************************
+ *   Copyright (C) 2017 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     *
+ *   (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.                                        *
+ ***************************************************************************/
+
+/*
+       Disable watchdog, 32-bit version for newer Kinetis
+       Parameters:
+               r0 ... WDOG32 base (in)
+
+       Used instruction set should work on both Cortex-M4 and M0+
+*/
+
+       .text
+       .syntax unified
+        .cpu cortex-m0
+       .thumb
+
+/* WDOG registers offsets */
+WDOG_CS                = 0
+WDOG_CNT       = 4
+WDOG_TOVAL     = 8
+
+WDOG_KEY       = 0xd928c520
+
+       .thumb_func
+start:
+/* test WDOG_CS bit CMD32EN */
+       ldr     r2, [r0, WDOG_CS]
+       ldr     r3, =0x2000
+       tst     r2, r3
+       ldr     r3, =WDOG_KEY
+       beq     cmd16
+
+/* WDOG_CNT = key */
+       str     r3, [r0, WDOG_CNT]
+       b       unlocked
+
+cmd16:
+/* WDOG_CNT = key, halfword by halfword */
+       strh    r3, [r0, WDOG_CNT]
+       lsrs    r3, r3, #16
+       strh    r3, [r0, WDOG_CNT]
+
+/* WDOG_CS: clear EN bit 7, set UPDATE bit 5 */
+unlocked:
+       movs    r4, #0x80
+       bics    r2, r4
+       movs    r4, #0x20
+       orrs    r2, r4
+       str     r2, [r0, WDOG_CS]
+/* All active WDOG registers have to be updated, set dummy timeout */
+/* WDOG_TOVAL = 0x400 */
+       ldr     r3, =0x400
+       str     r3, [r0, WDOG_TOVAL]
+/* OpenOCD checks exit point address. Jump to the very end. */
+       b       done
+
+       .pool
+
+/* Avoid padding at .text segment end. Otherwise exit point check fails. */
+       .skip   ( . - start + 2) & 2, 0
+done:
+       bkpt    #0
+
+       .end
+
index dc3dc45976b0f9066a01c95a96e5bdc65d58aac9..1f2383d00d4bce963ea3fd57a134e5704de35922 100644 (file)
 #define SIM_SOPT1      0x40047000
 #define SIM_FCFG1      0x4004804c
 #define SIM_FCFG2      0x40048050
-#define WDOG_STCTRH    0x40052000
+#define SIM_COPC       0x40048100
+#define WDOG_BASE      0x40052000
+#define WDOG32_KE1X    0x40052000
+#define WDOG32_KL28    0x40076000
 #define SMC_PMCTRL     0x4007E001
 #define SMC_PMSTAT     0x4007E003
 #define MCM_PLACR      0xF000300C
 
+/* Offsets */
+#define WDOG_STCTRLH_OFFSET      0
+#define WDOG32_CS_OFFSET         0
+
 /* Values */
 #define PM_STAT_RUN            0x01
 #define PM_STAT_VLPR           0x04
@@ -270,13 +277,26 @@ struct kinetis_chip {
                FS_PROGRAM_SECTOR = 1,
                FS_PROGRAM_LONGWORD = 2,
                FS_PROGRAM_PHRASE = 4,          /* Unsupported */
-               FS_INVALIDATE_CACHE_K = 8,      /* using FMC->PFB0CR/PFB01CR */
-               FS_INVALIDATE_CACHE_L = 0x10,   /* using MCM->PLACR */
-               FS_INVALIDATE_CACHE_MSCM = 0x20,
+
                FS_NO_CMD_BLOCKSTAT = 0x40,
                FS_WIDTH_256BIT = 0x80,
        } flash_support;
 
+       enum {
+               KINETIS_CACHE_NONE,
+               KINETIS_CACHE_K,        /* invalidate using FMC->PFB0CR/PFB01CR */
+               KINETIS_CACHE_L,        /* invalidate using MCM->PLACR */
+               KINETIS_CACHE_MSCM,     /* devices like KE1xF, invalidate MSCM->OCMDR0 */
+       } cache_type;
+
+       enum {
+               KINETIS_WDOG_NONE,
+               KINETIS_WDOG_K,
+               KINETIS_WDOG_COP,
+               KINETIS_WDOG32_KE1X,
+               KINETIS_WDOG32_KL28,
+       } watchdog_type;
+
        char name[40];
 
        unsigned num_banks;
@@ -362,6 +382,7 @@ static bool create_banks;
 struct flash_driver kinetis_flash;
 static int kinetis_write_inner(struct flash_bank *bank, const uint8_t *buffer,
                        uint32_t offset, uint32_t count);
+static int kinetis_probe_chip(struct kinetis_chip *k_chip);
 static int kinetis_auto_probe(struct flash_bank *bank);
 
 
@@ -941,11 +962,53 @@ static int kinetis_create_missing_banks(struct kinetis_chip *k_chip)
 }
 
 
-/* Disable the watchdog on Kinetis devices */
-int kinetis_disable_wdog(struct target *target, uint32_t sim_sdid)
+static int kinetis_disable_wdog_algo(struct target *target, size_t code_size, const uint8_t *code, uint32_t wdog_base)
 {
        struct working_area *wdog_algorithm;
        struct armv7m_algorithm armv7m_info;
+       struct reg_param reg_params[1];
+       int retval;
+
+       if (target->state != TARGET_HALTED) {
+               LOG_ERROR("Target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       retval = target_alloc_working_area(target, code_size, &wdog_algorithm);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = target_write_buffer(target, wdog_algorithm->address,
+                       code_size, code);
+       if (retval == ERROR_OK) {
+               armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
+               armv7m_info.core_mode = ARM_MODE_THREAD;
+
+               init_reg_param(&reg_params[0], "r0", 32, PARAM_IN);
+               buf_set_u32(reg_params[0].value, 0, 32, wdog_base);
+
+               retval = target_run_algorithm(target, 0, NULL, 1, reg_params,
+                       wdog_algorithm->address,
+                       wdog_algorithm->address + code_size - 2,
+                       500, &armv7m_info);
+
+               destroy_reg_param(&reg_params[0]);
+
+               if (retval != ERROR_OK)
+                       LOG_ERROR("Error executing Kinetis WDOG unlock algorithm");
+       }
+
+       target_free_working_area(target, wdog_algorithm);
+
+       return retval;
+}
+
+/* Disable the watchdog on Kinetis devices
+ * Standard Kx WDOG peripheral checks timing and therefore requires to run algo.
+ */
+static int kinetis_disable_wdog_kx(struct target *target)
+{
+       const uint32_t wdog_base = WDOG_BASE;
        uint16_t wdog;
        int retval;
 
@@ -953,14 +1016,7 @@ int kinetis_disable_wdog(struct target *target, uint32_t sim_sdid)
 #include "../../../contrib/loaders/watchdog/armv7m_kinetis_wdog.inc"
        };
 
-       /* Decide whether the connected device needs watchdog disabling.
-        * Disable for all Kx and KVx devices, return if it is a KLx */
-
-       if ((sim_sdid & KINETIS_SDID_SERIESID_MASK) == KINETIS_SDID_SERIESID_KL)
-               return ERROR_OK;
-
-       /* The connected device requires watchdog disabling. */
-       retval = target_read_u16(target, WDOG_STCTRH, &wdog);
+       retval = target_read_u16(target, wdog_base + WDOG_STCTRLH_OFFSET, &wdog);
        if (retval != ERROR_OK)
                return retval;
 
@@ -968,60 +1024,116 @@ int kinetis_disable_wdog(struct target *target, uint32_t sim_sdid)
                /* watchdog already disabled */
                return ERROR_OK;
        }
-       LOG_INFO("Disabling Kinetis watchdog (initial WDOG_STCTRLH = 0x%x)", wdog);
+       LOG_INFO("Disabling Kinetis watchdog (initial WDOG_STCTRLH = 0x%04" PRIx16 ")", wdog);
 
-       if (target->state != TARGET_HALTED) {
-               LOG_ERROR("Target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
+       retval = kinetis_disable_wdog_algo(target, sizeof(kinetis_unlock_wdog_code), kinetis_unlock_wdog_code, wdog_base);
+       if (retval != ERROR_OK)
+               return retval;
 
-       retval = target_alloc_working_area(target, sizeof(kinetis_unlock_wdog_code), &wdog_algorithm);
+       retval = target_read_u16(target, wdog_base + WDOG_STCTRLH_OFFSET, &wdog);
        if (retval != ERROR_OK)
                return retval;
 
-       retval = target_write_buffer(target, wdog_algorithm->address,
-                       sizeof(kinetis_unlock_wdog_code), (uint8_t *)kinetis_unlock_wdog_code);
-       if (retval != ERROR_OK) {
-               target_free_working_area(target, wdog_algorithm);
+       LOG_INFO("WDOG_STCTRLH = 0x%04" PRIx16, wdog);
+       return (wdog & 0x1) ? ERROR_FAIL : ERROR_OK;
+}
+
+static int kinetis_disable_wdog32(struct target *target, uint32_t wdog_base)
+{
+       uint32_t wdog_cs;
+       int retval;
+
+       static const uint8_t kinetis_unlock_wdog_code[] = {
+#include "../../../contrib/loaders/watchdog/armv7m_kinetis_wdog32.inc"
+       };
+
+       retval = target_read_u32(target, wdog_base + WDOG32_CS_OFFSET, &wdog_cs);
+       if (retval != ERROR_OK)
                return retval;
-       }
 
-       armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
-       armv7m_info.core_mode = ARM_MODE_THREAD;
+       if ((wdog_cs & 0x80) == 0)
+               return ERROR_OK; /* watchdog already disabled */
 
-       retval = target_run_algorithm(target, 0, NULL, 0, NULL, wdog_algorithm->address,
-                       wdog_algorithm->address + (sizeof(kinetis_unlock_wdog_code) - 2),
-                       10000, &armv7m_info);
+       LOG_INFO("Disabling Kinetis watchdog (initial WDOG_CS 0x%08" PRIx32 ")", wdog_cs);
 
+       retval = kinetis_disable_wdog_algo(target, sizeof(kinetis_unlock_wdog_code), kinetis_unlock_wdog_code, wdog_base);
        if (retval != ERROR_OK)
-               LOG_ERROR("error executing kinetis wdog unlock algorithm");
+               return retval;
 
-       retval = target_read_u16(target, WDOG_STCTRH, &wdog);
+       retval = target_read_u32(target, wdog_base + WDOG32_CS_OFFSET, &wdog_cs);
        if (retval != ERROR_OK)
                return retval;
-       LOG_INFO("WDOG_STCTRLH = 0x%x", wdog);
 
-       target_free_working_area(target, wdog_algorithm);
+       if ((wdog_cs & 0x80) == 0)
+               return ERROR_OK; /* watchdog disabled successfully */
 
-       return retval;
+       LOG_ERROR("Cannot disable Kinetis watchdog (WDOG_CS 0x%08" PRIx32 "), issue 'reset init'", wdog_cs);
+       return ERROR_FAIL;
+}
+
+static int kinetis_disable_wdog(struct kinetis_chip *k_chip)
+{
+       struct target *target = k_chip->target;
+       uint8_t sim_copc;
+       int retval;
+
+       if (!k_chip->probed) {
+               retval = kinetis_probe_chip(k_chip);
+               if (retval != ERROR_OK)
+                       return retval;
+       }
+
+       switch (k_chip->watchdog_type) {
+       case KINETIS_WDOG_K:
+               return kinetis_disable_wdog_kx(target);
+
+       case KINETIS_WDOG_COP:
+               retval = target_read_u8(target, SIM_COPC, &sim_copc);
+               if (retval != ERROR_OK)
+                       return retval;
+
+               if ((sim_copc & 0xc) == 0)
+                       return ERROR_OK; /* watchdog already disabled */
+
+               LOG_INFO("Disabling Kinetis watchdog (initial SIM_COPC 0x%02" PRIx8 ")", sim_copc);
+               retval = target_write_u8(target, SIM_COPC, sim_copc & ~0xc);
+               if (retval != ERROR_OK)
+                       return retval;
+
+               retval = target_read_u8(target, SIM_COPC, &sim_copc);
+               if (retval != ERROR_OK)
+                       return retval;
+
+               if ((sim_copc & 0xc) == 0)
+                       return ERROR_OK; /* watchdog disabled successfully */
+
+               LOG_ERROR("Cannot disable Kinetis watchdog (SIM_COPC 0x%02" PRIx8 "), issue 'reset init'", sim_copc);
+               return ERROR_FAIL;
+
+       case KINETIS_WDOG32_KE1X:
+               return kinetis_disable_wdog32(target, WDOG32_KE1X);
+
+       case KINETIS_WDOG32_KL28:
+               return kinetis_disable_wdog32(target, WDOG32_KL28);
+
+       default:
+               return ERROR_OK;
+       }
 }
 
 COMMAND_HANDLER(kinetis_disable_wdog_handler)
 {
        int result;
-       uint32_t sim_sdid;
        struct target *target = get_current_target(CMD_CTX);
+       struct kinetis_chip *k_chip = kinetis_get_chip(target);
+
+       if (k_chip == NULL)
+               return ERROR_FAIL;
 
        if (CMD_ARGC > 0)
                return ERROR_COMMAND_SYNTAX_ERROR;
 
-       result = target_read_u32(target, SIM_SDID, &sim_sdid);
-       if (result != ERROR_OK) {
-               LOG_ERROR("Failed to read SIMSDID");
-               return result;
-       }
-
-       result = kinetis_disable_wdog(target, sim_sdid);
+       result = kinetis_disable_wdog(k_chip);
        return result;
 }
 
@@ -1400,20 +1512,26 @@ static void kinetis_invalidate_flash_cache(struct kinetis_chip *k_chip)
 {
        struct target *target = k_chip->target;
 
-       if (k_chip->flash_support & FS_INVALIDATE_CACHE_K)
+       switch (k_chip->cache_type) {
+       case KINETIS_CACHE_K:
                target_write_u8(target, FMC_PFB01CR + 2, 0xf0);
                /* Set CINV_WAY bits - request invalidate of all cache ways */
                /* FMC_PFB0CR has same address and CINV_WAY bits as FMC_PFB01CR */
+               break;
 
-       else if (k_chip->flash_support & FS_INVALIDATE_CACHE_L)
+       case KINETIS_CACHE_L:
                target_write_u8(target, MCM_PLACR + 1, 0x04);
                /* set bit CFCC - Clear Flash Controller Cache */
+               break;
 
-       else if (k_chip->flash_support & FS_INVALIDATE_CACHE_MSCM)
+       case KINETIS_CACHE_MSCM:
                target_write_u32(target, MSCM_OCMDR0, 0x30);
                /* disable data prefetch and flash speculate */
+               break;
 
-       return;
+       default:
+               break;
+       }
 }
 
 
@@ -1647,7 +1765,7 @@ static int kinetis_write_inner(struct flash_bank *bank, const uint8_t *buffer,
 
                uint32_t words_remaining = count / 4;
 
-               kinetis_disable_wdog(bank->target, k_chip->sim_sdid);
+               kinetis_disable_wdog(k_chip);
 
                /* try using a block write */
                result = kinetis_write_block(bank, buffer, offset, words_remaining);
@@ -1791,6 +1909,8 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
        if ((k_chip->sim_sdid & (~KINETIS_SDID_K_SERIES_MASK)) == 0) {
                /* older K-series MCU */
                uint32_t mcu_type = k_chip->sim_sdid & KINETIS_K_SDID_TYPE_MASK;
+               k_chip->cache_type = KINETIS_CACHE_K;
+               k_chip->watchdog_type = KINETIS_WDOG_K;
 
                switch (mcu_type) {
                case KINETIS_K_SDID_K10_M50:
@@ -1799,7 +1919,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
                        k_chip->pflash_sector_size = 1<<10;
                        k_chip->nvm_sector_size = 1<<10;
                        num_blocks = 2;
-                       k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+                       k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR;
                        break;
                case KINETIS_K_SDID_K10_M72:
                case KINETIS_K_SDID_K20_M72:
@@ -1812,7 +1932,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
                        k_chip->pflash_sector_size = 2<<10;
                        k_chip->nvm_sector_size = 1<<10;
                        num_blocks = 2;
-                       k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+                       k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR;
                        k_chip->max_flash_prog_size = 1<<10;
                        break;
                case KINETIS_K_SDID_K10_M100:
@@ -1828,7 +1948,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
                        k_chip->pflash_sector_size = 2<<10;
                        k_chip->nvm_sector_size = 2<<10;
                        num_blocks = 2;
-                       k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+                       k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR;
                        break;
                case KINETIS_K_SDID_K21_M120:
                case KINETIS_K_SDID_K22_M120:
@@ -1837,7 +1957,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
                        k_chip->max_flash_prog_size = 1<<10;
                        k_chip->nvm_sector_size = 4<<10;
                        num_blocks = 2;
-                       k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+                       k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
                        break;
                case KINETIS_K_SDID_K10_M120:
                case KINETIS_K_SDID_K20_M120:
@@ -1847,7 +1967,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
                        k_chip->pflash_sector_size = 4<<10;
                        k_chip->nvm_sector_size = 4<<10;
                        num_blocks = 4;
-                       k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+                       k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
                        break;
                default:
                        LOG_ERROR("Unsupported K-family FAMID");
@@ -1869,12 +1989,15 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
                switch (k_chip->sim_sdid & KINETIS_SDID_SERIESID_MASK) {
                case KINETIS_SDID_SERIESID_K:
                        use_nvm_marking = true;
+                       k_chip->cache_type = KINETIS_CACHE_K;
+                       k_chip->watchdog_type = KINETIS_WDOG_K;
+
                        switch (k_chip->sim_sdid & (KINETIS_SDID_FAMILYID_MASK | KINETIS_SDID_SUBFAMID_MASK)) {
                        case KINETIS_SDID_FAMILYID_K0X | KINETIS_SDID_SUBFAMID_KX2:
                                /* K02FN64, K02FN128: FTFA, 2kB sectors */
                                k_chip->pflash_sector_size = 2<<10;
                                num_blocks = 1;
-                               k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
+                               k_chip->flash_support = FS_PROGRAM_LONGWORD;
                                cpu_mhz = 100;
                                break;
 
@@ -1890,7 +2013,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
                                        /* MK24FN1M */
                                        k_chip->pflash_sector_size = 4<<10;
                                        num_blocks = 2;
-                                       k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+                                       k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
                                        k_chip->max_flash_prog_size = 1<<10;
                                        subfamid = 4; /* errata 1N83J fix */
                                        break;
@@ -1901,7 +2024,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
                                        /* K22 with new-style SDID - smaller pflash with FTFA, 2kB sectors */
                                        k_chip->pflash_sector_size = 2<<10;
                                        /* autodetect 1 or 2 blocks */
-                                       k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
+                                       k_chip->flash_support = FS_PROGRAM_LONGWORD;
                                        break;
                                }
                                LOG_ERROR("Unsupported Kinetis K22 DIEID");
@@ -1912,12 +2035,12 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
                                if ((k_chip->sim_sdid & (KINETIS_SDID_DIEID_MASK)) == KINETIS_SDID_DIEID_K24FN256) {
                                        /* K24FN256 - smaller pflash with FTFA */
                                        num_blocks = 1;
-                                       k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
+                                       k_chip->flash_support = FS_PROGRAM_LONGWORD;
                                        break;
                                }
                                /* K24FN1M without errata 7534 */
                                num_blocks = 2;
-                               k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+                               k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
                                k_chip->max_flash_prog_size = 1<<10;
                                break;
 
@@ -1932,7 +2055,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
                                k_chip->nvm_sector_size = 4<<10;
                                k_chip->max_flash_prog_size = 1<<10;
                                num_blocks = 2;
-                               k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+                               k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
                                break;
 
                        case KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX6:
@@ -1943,7 +2066,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
                                k_chip->nvm_sector_size = 4<<10;
                                k_chip->max_flash_prog_size = 1<<10;
                                num_blocks = 4;
-                               k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+                               k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
                                cpu_mhz = 180;
                                break;
 
@@ -1953,7 +2076,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
                                /* K80FN256, K81FN256, K82FN256 */
                                k_chip->pflash_sector_size = 4<<10;
                                num_blocks = 1;
-                               k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K | FS_NO_CMD_BLOCKSTAT;
+                               k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_NO_CMD_BLOCKSTAT;
                                cpu_mhz = 150;
                                break;
 
@@ -1962,7 +2085,9 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
                                /* KL81Z128, KL82Z128 */
                                k_chip->pflash_sector_size = 2<<10;
                                num_blocks = 1;
-                               k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_L | FS_NO_CMD_BLOCKSTAT;
+                               k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_NO_CMD_BLOCKSTAT;
+                               k_chip->cache_type = KINETIS_CACHE_L;
+
                                use_nvm_marking = false;
                                snprintf(name, sizeof(name), "MKL8%uZ%%s7",
                                         subfamid);
@@ -1982,7 +2107,9 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
                        k_chip->pflash_sector_size = 1<<10;
                        k_chip->nvm_sector_size = 1<<10;
                        /* autodetect 1 or 2 blocks */
-                       k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_L;
+                       k_chip->flash_support = FS_PROGRAM_LONGWORD;
+                       k_chip->cache_type = KINETIS_CACHE_L;
+                       k_chip->watchdog_type = KINETIS_WDOG_COP;
 
                        cpu_mhz = 48;
                        if (subfamid == 3 && (familyid == 1 || familyid == 2))
@@ -1993,12 +2120,14 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
 
                case KINETIS_SDID_SERIESID_KV:
                        /* KV-series */
+                       k_chip->watchdog_type = KINETIS_WDOG_K;
                        switch (k_chip->sim_sdid & (KINETIS_SDID_FAMILYID_MASK | KINETIS_SDID_SUBFAMID_MASK)) {
                        case KINETIS_SDID_FAMILYID_K1X | KINETIS_SDID_SUBFAMID_KX0:
                                /* KV10: FTFA, 1kB sectors */
                                k_chip->pflash_sector_size = 1<<10;
                                num_blocks = 1;
-                               k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_L;
+                               k_chip->flash_support = FS_PROGRAM_LONGWORD;
+                               k_chip->cache_type = KINETIS_CACHE_L;
                                strcpy(name, "MKV10Z%s7");
                                break;
 
@@ -2006,7 +2135,8 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
                                /* KV11: FTFA, 2kB sectors */
                                k_chip->pflash_sector_size = 2<<10;
                                num_blocks = 1;
-                               k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_L;
+                               k_chip->flash_support = FS_PROGRAM_LONGWORD;
+                               k_chip->cache_type = KINETIS_CACHE_L;
                                strcpy(name, "MKV11Z%s7");
                                break;
 
@@ -2016,7 +2146,8 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
                                /* KV31: FTFA, 2kB sectors, 2 blocks */
                                k_chip->pflash_sector_size = 2<<10;
                                /* autodetect 1 or 2 blocks */
-                               k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
+                               k_chip->flash_support = FS_PROGRAM_LONGWORD;
+                               k_chip->cache_type = KINETIS_CACHE_K;
                                break;
 
                        case KINETIS_SDID_FAMILYID_K4X | KINETIS_SDID_SUBFAMID_KX2:
@@ -2025,7 +2156,8 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
                                /* KV4x: FTFA, 4kB sectors */
                                k_chip->pflash_sector_size = 4<<10;
                                num_blocks = 1;
-                               k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
+                               k_chip->flash_support = FS_PROGRAM_LONGWORD;
+                               k_chip->cache_type = KINETIS_CACHE_K;
                                cpu_mhz = 168;
                                break;
 
@@ -2053,6 +2185,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
 
                case KINETIS_SDID_SERIESID_KE:
                        /* KE1x-series */
+                       k_chip->watchdog_type = KINETIS_WDOG32_KE1X;
                        switch (k_chip->sim_sdid &
                                (KINETIS_SDID_FAMILYID_MASK | KINETIS_SDID_SUBFAMID_MASK | KINETIS_SDID_PROJECTID_MASK)) {
                        case KINETIS_SDID_FAMILYID_K1X | KINETIS_SDID_SUBFAMID_KX4 | KINETIS_SDID_PROJECTID_KE1xZ:
@@ -2062,7 +2195,8 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
                                k_chip->nvm_sector_size = 2<<10;
                                k_chip->max_flash_prog_size = 1<<9;
                                num_blocks = 2;
-                               k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_L;
+                               k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
+                               k_chip->cache_type = KINETIS_CACHE_L;
 
                                cpu_mhz = 72;
                                snprintf(name, sizeof(name), "MKE%u%uZ%%s%u",
@@ -2077,7 +2211,8 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
                                k_chip->nvm_sector_size = 2<<10;
                                k_chip->max_flash_prog_size = 1<<10;
                                num_blocks = 2;
-                               k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_MSCM;
+                               k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
+                               k_chip->cache_type = KINETIS_CACHE_MSCM;
 
                                cpu_mhz = 168;
                                snprintf(name, sizeof(name), "MKE%u%uF%%s%u",
index c2de9f7d50b2a6270172dabfe1c67aba74d04718..7dd0404f96bd3cc633fac71c456298c4e2fd8aed 100644 (file)
@@ -37,7 +37,8 @@ flash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME
 kinetis create_banks
 
 # Table 5-1. Clock Summary of KL25 Sub-Family Reference Manual
-# specifies up to 1MHz for VLPR mode.
+# specifies up to 1MHz for VLPR mode and up to 24MHz for run mode;
+# Table 17 of Sub-Family Data Sheet rev4 lists 25MHz as the maximum frequency.
 adapter_khz 1000
 
 reset_config srst_nogate
@@ -53,10 +54,9 @@ if {![using_hla]} {
    cortex_m reset_config sysresetreq
 }
 
-# Table 5-1. Clock Summary of KL25 Sub-Family Reference Manual
-# specifies up to 24MHz for run mode; Table 17 of Sub-Family Data
-# Sheet rev4 lists 25MHz as the maximum frequency.
-# Uncoment only if VLPR mode is not used
-#$_TARGETNAME configure -event reset-init {
-#   adapter_khz 24000
-#}
+# Disable watchdog not to disturb OpenOCD algorithms running on MCU
+# (e.g. armv7m_checksum_memory() in verify_image)
+# Flash driver also disables watchdog before FTFA flash programming.
+$_TARGETNAME configure -event reset-init {
+   kinetis disable_wdog
+}
index cf777135c6614454b452ddc2de971f99f63ff153..7b0351706a9420d3cbf63f5eed40719aeed6e5ed 100644 (file)
@@ -54,3 +54,11 @@ if {![using_hla]} {
    # perform a soft reset
    cortex_m reset_config sysresetreq
 }
+
+# Disable watchdog not to disturb OpenOCD algorithms running on MCU
+# (e.g. armv7m_checksum_memory() in verify_image)
+# Flash driver also disables watchdog before FTFA flash programming.
+$_TARGETNAME configure -event reset-init {
+   kinetis disable_wdog
+}
+

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)