unsigned pflash_sector_size_bytes;
unsigned nvm_sector_size_bytes;
unsigned num_blocks;
-} kinetis_flash_params[4] = {
+} kinetis_flash_params[7] = {
{ 1<<10, 1<<10, 2 },
{ 2<<10, 1<<10, 2 },
{ 2<<10, 2<<10, 2 },
- { 4<<10, 4<<10, 4 }
+ { 4<<10, 4<<10, 4 },
+ { 4<<10, 4<<10, 2 },
+ { 2<<10, 2<<10, 2 },
+ { 4<<10, 0, 1 }
};
/* Addressess */
#define SIM_SDID 0x40048024
#define SIM_FCFG1 0x4004804c
#define SIM_FCFG2 0x40048050
+#define SMC_PMCTRL 0x4007E001
+#define SMC_PMSTAT 0x4007E003
+#define WDOG_STCTRLH 0x40052000
+
+/* Values */
+#define PM_STAT_RUN 0x01
+#define PM_STAT_VLPR 0x04
+#define PM_STAT_HSR 0x80
+#define PM_CTRL_RUNM_RUN 0x00
/* Commands */
#define FTFx_CMD_BLOCKSTAT 0x00
#define FTFx_CMD_MASSERASE 0x44
/* The Kinetis K series uses the following SDID layout :
- * Bit 31-16 : 0
+ * Bit 31-28 : FAMILYID (or 0 on older devices)
+ * Bit 27-24 : SUBFAMID (or 0 on older devices)
+ * Bit 23-20 : SERIESID (or 0 on older devices)
+ * Bit 19-16 : Reserved (0)
* Bit 15-12 : REVID
* Bit 11-7 : DIEID
* Bit 6-4 : FAMID
* Bit 15-12 : REVID
* Bit 6-4 : Reserved (0)
* Bit 3-0 : PINID
- *
- * SERIESID should be 1 for the KL-series so we assume that if
- * bits 31-16 are 0 then it's a K-series MCU.
*/
-#define KINETIS_SDID_K_SERIES_MASK 0x0000FFFF
-
#define KINETIS_SDID_DIEID_MASK 0x00000F80
#define KINETIS_SDID_DIEID_K_A 0x00000100
#define KINETIS_SDID_DIEID_K_B 0x00000200
#define KINETIS_K_SDID_K20 0x00000290
#define KINETIS_K_SDID_K21 0x00000230
#define KINETIS_K_SDID_K22 0x00000210
+#define KINETIS_K_SDID_K22_M120 0x00000E90
+#define KINETIS_K_SDID_K24 0x00000710
#define KINETIS_K_SDID_K30 0x00000120
#define KINETIS_K_SDID_K40 0x00000130
#define KINETIS_K_SDID_K50 0x000000E0
#define KINETIS_K_SDID_K51 0x000000F0
#define KINETIS_K_SDID_K53 0x00000170
#define KINETIS_K_SDID_K60 0x000001C0
+#define KINETIS_K_SDID_K64 0x00000340
#define KINETIS_K_SDID_K70 0x000001D0
+#define KINETIS_K_SDID_SERIESID_MASK 0x00F00000
+#define KINETIS_K_SDID_SERIESID_KL 0x00000000
+
#define KINETIS_KL_SDID_SERIESID_MASK 0x00F00000
#define KINETIS_KL_SDID_SERIESID_KL 0x00100000
} flash_class;
};
+static int allow_fcf_writes = 0;
+
+COMMAND_HANDLER(fcf_write_enable_command)
+{
+ allow_fcf_writes = 1;
+ command_print(CMD_CTX, "Arbitrary flash configuration field writes disabled");
+ LOG_WARNING("BEWARE: incorrect flash configuration may permanently lock device");
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(fcf_write_disable_command)
+{
+ allow_fcf_writes = 0;
+ command_print(CMD_CTX, "Arbitrary flash configuration field writes disabled.");
+ return ERROR_OK;
+}
+
+static const struct command_registration fcf_command_handlers[] = {
+ {
+ .name = "fcf_write_enable",
+ .handler = fcf_write_enable_command,
+ .mode = COMMAND_CONFIG,
+ .help = "Allow writing arbitrary values to the Kinetis flash configuration field (use with caution).",
+ .usage = "",
+ },
+ {
+ .name = "fcf_write_disable",
+ .handler = fcf_write_disable_command,
+ .mode = COMMAND_CONFIG,
+ .help = "Disable writing arbitrary values to the Kinetis flash configuration field."
+ "Any writes will be adjusted to use the value "
+ "0xffffffff 0xffffffff 0xffffffff 0xfffffffe."
+ "Adjustments will trigger a warning.",
+ .usage = "",
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
FLASH_BANK_COMMAND_HANDLER(kinetis_flash_bank_command)
{
struct kinetis_flash_bank *bank_info;
bank->driver_priv = bank_info;
+ register_commands(CMD_CTX, NULL, fcf_command_handlers);
+
return ERROR_OK;
}
return ERROR_OK;
}
+static uint8_t kinetis_get_mode(struct flash_bank *bank)
+{
+ int result;
+ uint8_t pmstat;
+ result = target_read_u8(bank->target, SMC_PMSTAT, &pmstat);
+ if (result != ERROR_OK)
+ return result;
+ LOG_DEBUG("SMC_PMSTAT: 0x%x", pmstat);
+ return pmstat;
+}
+
static int kinetis_erase(struct flash_bank *bank, int first, int last)
{
int result, i;
if ((first > bank->num_sectors) || (last > bank->num_sectors))
return ERROR_FLASH_OPERATION_FAILED;
+ if ((kinfo->sim_sdid & KINETIS_K_SDID_TYPE_MASK) == KINETIS_K_SDID_K22_M120) {
+ uint8_t pmstat = kinetis_get_mode (bank);
+ if (pmstat == PM_STAT_VLPR || pmstat == PM_STAT_HSR) {
+ LOG_DEBUG("Switching to run mode to perform flash operation");
+ uint8_t pmctrl = PM_CTRL_RUNM_RUN;
+ result = target_write_u8(bank->target, SMC_PMCTRL, pmctrl);
+ if (result != ERROR_OK)
+ return result;
+ while (kinetis_get_mode(bank) != PM_STAT_RUN);
+ }
+ }
+
if ((first == 0) && (last == (bank->num_sectors - 1)) && (kinfo->klxx))
return kinetis_mass_erase(bank);
if (first == 0) {
LOG_WARNING
- ("flash configuration field erased, please reset the device");
+ ("Any changes to flash configuration field will not take effect until next reset");
}
return ERROR_OK;
return ERROR_TARGET_NOT_HALTED;
}
+ if (!allow_fcf_writes) {
+ if (offset <= 0x400 && offset + count > 0x400) {
+ int fcf_match = 1;
+ uint32_t requested_fcf[4] = {
+ *((uint32_t *) (buffer + (0x400 - offset))),
+ *((uint32_t *) (buffer + (0x404 - offset))),
+ *((uint32_t *) (buffer + (0x408 - offset))),
+ *((uint32_t *) (buffer + (0x40c - offset)))
+ };
+ uint32_t required_fcf[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffffe };
+ for (i = 0; i < 4; i++) {
+ if (requested_fcf[i] != required_fcf[i]) {
+ fcf_match = 0;
+ *((uint32_t *) (buffer + (0x400 + (i * 4) - offset))) = required_fcf[i];
+ }
+ }
+ if (!fcf_match) {
+ LOG_WARNING ("Requested write to flash configuration "
+ "field 0x%08x 0x%08x 0x%08x 0x%08x "
+ "transformed to 0x%08x 0x%08x 0x%08x 0x%08x",
+ requested_fcf[0], requested_fcf[1], requested_fcf[2], requested_fcf[3],
+ required_fcf[0], required_fcf[1], required_fcf[2], required_fcf[3]);
+ }
+ }
+ }
+
if (kinfo->klxx) {
/* fallback to longword write */
fallback = 1;
LOG_WARNING("Kinetis L Series supports Program Longword execution only.");
LOG_DEBUG("flash write into PFLASH @08%" PRIX32, offset);
+ } else if (kinfo->granularity == 5 || kinfo->granularity == 6) {
+ fallback = 1;
+ LOG_DEBUG("flash write into PFLASH @08%" PRIX32, offset);
} else if (kinfo->flash_class == FC_FLEX_NVM) {
uint8_t ftfx_fstat;
unsigned prog_section_chunk_bytes = kinfo->sector_size >> 8;
/* assume the NVM sector size is half the FlexRAM size */
unsigned prog_size_bytes = MIN(kinfo->sector_size,
- kinetis_flash_params[kinfo->granularity].nvm_sector_size_bytes);
+ kinetis_flash_params[kinfo->granularity].nvm_sector_size_bytes / ((kinfo->granularity == 4) ? 4 : 1));
for (i = 0; i < count; i += prog_size_bytes) {
uint8_t residual_buffer[16];
uint8_t ftfx_fstat;
}
}
/* program longword command, not supported in "SF3" devices */
- else if ((kinfo->granularity != 3) || (kinfo->klxx)) {
+ else if ((kinfo->granularity != 3 && kinfo->granularity != 4)
+ || (kinfo->klxx)) {
if (count & 0x3) {
uint32_t old_count = count;
result = target_read_u32(target, SIM_SDID, &kinfo->sim_sdid);
if (result != ERROR_OK)
return result;
+ LOG_DEBUG("SIM_SDID: 0x%x\n", kinfo->sim_sdid);
kinfo->klxx = 0;
/* K-series MCU? */
- if ((kinfo->sim_sdid & (~KINETIS_SDID_K_SERIES_MASK)) == 0) {
+ if ((kinfo->sim_sdid & KINETIS_K_SDID_SERIESID_MASK) == KINETIS_K_SDID_SERIESID_KL) {
uint32_t mcu_type = kinfo->sim_sdid & KINETIS_K_SDID_TYPE_MASK;
switch (mcu_type) {
/* 2kB sectors */
granularity = 2;
break;
+ case KINETIS_K_SDID_K22_M120:
+ /* 2kB sectors, no program section command */
+ granularity = 5;
+ break;
+ case KINETIS_K_SDID_K24:
+ /* 4kB sectors, no program section command */
+ granularity = 6;
+ break;
+ case KINETIS_K_SDID_K64:
+ /* 2kB sectors, 2 banks */
+ granularity = 4;
+ break;
case KINETIS_K_SDID_K10:
case KINETIS_K_SDID_K70:
- /* 4kB sectors */
+ /* 4kB sectors, 4 banks */
granularity = 3;
break;
default:
nvm_size = 1 << (14 + (fcfg1_nvmsize >> 1));
break;
case 0x0f:
- if (granularity == 3)
+ if (granularity == 3 || granularity == 4)
nvm_size = 512<<10;
+ else if (granularity == 5)
+ nvm_size = 128<<10;
else
nvm_size = 256<<10;
break;
pf_size = 1 << (14 + (fcfg1_pfsize >> 1));
break;
case 0x0f:
- if (granularity == 3)
+ if (granularity == 3 || granularity == 4)
pf_size = 1024<<10;
+ else if (granularity == 5)
+ pf_size = 512<<10;
else if (fcfg2_pflsh)
pf_size = 512<<10;
else
return ERROR_OK;
}
+/* Set SP - With the ff02
+ version of the CMSIS-DAP firmare on TWR-K24F boards, this is required to
+ ensure SP is initialized correctly. This may be related to the that version of
+ the firmware deviating from the norm by calling set_target_state(RESET_PROGRAM)
+ when OpenOCD connects. */
+int kinetis_k24f_fix (struct target *target)
+{
+ int retval;
+ uint32_t sim_sdid;
+ retval = target_read_u32(target, SIM_SDID, &sim_sdid);
+ if (retval != ERROR_OK)
+ return retval;
+ if (((sim_sdid & KINETIS_K_SDID_SERIESID_MASK) == KINETIS_K_SDID_SERIESID_KL)
+ && ((sim_sdid & KINETIS_K_SDID_TYPE_MASK) == KINETIS_K_SDID_K24)) {
+ uint32_t sp;
+ uint32_t pc;
+ struct armv7m_common *armv7m = target_to_armv7m(target);
+ target_step (target, 1, 0, 0);
+ retval = target_read_u32(target, 0x0, &sp);
+ if (retval != ERROR_OK) {
+ return retval;
+ }
+ retval = armv7m->store_core_reg_u32(target, 13, sp);
+ if (retval != ERROR_OK) {
+ return retval;
+ }
+ retval = target_read_u32 (target, 0x4, &pc);
+ if (retval != ERROR_OK) {
+ return retval;
+ }
+ retval = armv7m->store_core_reg_u32 (target, 15, pc & ~1);
+ if (retval != ERROR_OK) {
+ return retval;
+ }
+ }
+ return ERROR_OK;
+}
+
+/* Disable the watchdog on Kinetis devices */
+int kinetis_disable_wdog (struct target *target)
+{
+ struct working_area *wdog_algorithm;
+ struct armv7m_algorithm armv7m_info;
+ uint32_t sim_sdid;
+ uint16_t wdog;
+ int retval;
+
+ static const uint8_t kinetis_unlock_wdog_code[] = {
+ /* WDOG_UNLOCK = 0xC520 */
+ 0x4f, 0xf4, 0x00, 0x53, /* mov.w r3, #8192 ; 0x2000 */
+ 0xc4, 0xf2, 0x05, 0x03, /* movt r3, #16389 ; 0x4005 */
+ 0x4c, 0xf2, 0x20, 0x52, /* movw r2, #50464 ; 0xc520 */
+ 0xda, 0x81, /* strh r2, [r3, #14] */
+
+ /* WDOG_UNLOCK = 0xD928 */
+ 0x4f, 0xf4, 0x00, 0x53, /* mov.w r3, #8192 ; 0x2000 */
+ 0xc4, 0xf2, 0x05, 0x03, /* movt r3, #16389 ; 0x4005 */
+ 0x4d, 0xf6, 0x28, 0x12, /* movw r2, #55592 ; 0xd928 */
+ 0xda, 0x81, /* strh r2, [r3, #14] */
+
+ /* WDOG_SCR = 0x1d2 */
+ 0x4f, 0xf4, 0x00, 0x53, /* mov.w r3, #8192 ; 0x2000 */
+ 0xc4, 0xf2, 0x05, 0x03, /* movt r3, #16389 ; 0x4005 */
+ 0x4f, 0xf4, 0xe9, 0x72, /* mov.w r2, #466 ; 0x1d2 */
+ 0x1a, 0x80, /* strh r2, [r3, #0] */
+
+ /* END */
+ 0x00, 0xBE, /* bkpt #0 */
+ };
+
+ /* Decide whether the connected device should needs its watchdog disabling. */
+ retval = target_read_u32(target, SIM_SDID, &sim_sdid);
+ if (retval != ERROR_OK)
+ return retval;
+ if ((sim_sdid & KINETIS_K_SDID_SERIESID_MASK) == KINETIS_K_SDID_SERIESID_KL) {
+ uint32_t mcu_type = sim_sdid & KINETIS_K_SDID_TYPE_MASK;
+
+ switch (mcu_type) {
+ case KINETIS_K_SDID_K22_M120:
+ case KINETIS_K_SDID_K24:
+ break;
+ default:
+ return ERROR_OK;
+ }
+ }
+ else {
+ return ERROR_OK;
+ }
+
+ /* The connected device requires its watchdog disabling. */
+ retval = target_read_u16(target, WDOG_STCTRLH, &wdog);
+ if (retval != ERROR_OK)
+ return retval;
+ LOG_INFO("Disabling Kinetis watchdog (initial WDOG_STCTRLH = 0x%x)", wdog);
+
+ retval = target_halt(target);
+ if (retval != ERROR_OK)
+ return retval;
+ target->state = TARGET_HALTED;
+
+ retval = target_alloc_working_area(target, sizeof(kinetis_unlock_wdog_code), &wdog_algorithm);
+ 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);
+ return retval;
+ }
+
+ armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
+ armv7m_info.core_mode = ARM_MODE_THREAD;
+
+ retval = target_run_algorithm(target, 0, NULL, 0, NULL, wdog_algorithm->address,
+ wdog_algorithm->address + (sizeof(kinetis_unlock_wdog_code) - 2),
+ 10000, &armv7m_info);
+
+ if (retval != ERROR_OK)
+ LOG_ERROR("error executing kinetis wdog unlock algorithm");
+
+ retval = target_read_u16(target, WDOG_STCTRLH, &wdog);
+ if (retval != ERROR_OK)
+ return retval;
+ LOG_INFO("WDOG_STCTRLH = 0x%x", wdog);
+
+ target_free_working_area(target, wdog_algorithm);
+ retval = kinetis_k24f_fix (target);
+ if (retval != ERROR_OK)
+ return retval;
+
+ return retval;
+}
+
struct flash_driver kinetis_flash = {
.name = "kinetis",
.flash_bank_command = kinetis_flash_bank_command,
char **cfg;
if (!config_file_names) {
- command_run_line(cmd_ctx, "script openocd.cfg");
+ int rc;
+ rc = command_run_line(cmd_ctx, "script openocd.cfg");
+ if (rc != ERROR_OK) {
+ LOG_INFO("No configuration files specified defaulting to kinetis.cfg");
+ rc = command_run_line(cmd_ctx, "script kinetis.cfg");
+ if (rc != ERROR_OK) {
+ return rc;
+ }
+ }
+ else {
+ LOG_INFO("Found openocd.cfg; kinetis.cfg not read automatically");
+ }
return ERROR_OK;
}
static long long start;
-static char *log_strings[5] = {
+static char *log_strings[6] = {
"User : ",
"Error: ",
"Warn : ", /* want a space after each colon, all same width, colons aligned */
"Info : ",
- "Debug: "
+ "Debug: ",
+ "DAP: "
};
static int count;
if (CMD_ARGC == 1) {
int new_level;
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], new_level);
- if ((new_level > LOG_LVL_DEBUG) || (new_level < LOG_LVL_SILENT)) {
+ if ((new_level > LOG_LVL_DAP) || (new_level < LOG_LVL_SILENT)) {
LOG_ERROR("level must be between %d and %d", LOG_LVL_SILENT, LOG_LVL_DEBUG);
return ERROR_COMMAND_SYNTAX_ERROR;
}
LOG_LVL_ERROR = 0,
LOG_LVL_WARNING = 1,
LOG_LVL_INFO = 2,
- LOG_LVL_DEBUG = 3
+ LOG_LVL_DEBUG = 3,
+ LOG_LVL_DAP = 4
};
void log_printf(enum log_levels level, const char *file, unsigned line,
#define LOG_LEVEL_IS(FOO) ((debug_level) >= (FOO))
+#define LOG_DAP(expr ...) \
+ do { \
+ if (debug_level >= LOG_LVL_DAP) \
+ log_printf_lf(LOG_LVL_DAP, \
+ __FILE__, __LINE__, __func__, \
+ expr); \
+ } while (0)
+
#define LOG_DEBUG(expr ...) \
do { \
if (debug_level >= LOG_LVL_DEBUG) \
#include "config.h"
#endif
+#include "openocd.h"
+
#include "configuration.h"
/* @todo the inclusion of server.h here is a layering violation */
#include <server/server.h>
#include <getopt.h>
+#include <libgen.h>
+#include <string.h>
+
static int help_flag, version_flag;
static const struct option long_options[] = {
}
#endif
+#ifdef _WIN32
+#define PATH_DELIM ";"
+#else
+#define PATH_DELIM ":"
+
+static char *find_in_path(const char *bin)
+{
+ char *path = strdup (getenv ("PATH"));
+ char *elem;
+ while ((elem = strtok (path, PATH_DELIM))) {
+ char *t = alloc_printf ("%s/%s", elem, bin);
+ if (!access (t, X_OK))
+ return strdup (elem);
+ path = NULL;
+ }
+ return "";
+}
+#endif
+
+static inline int contains_slash (const char *str) {
+ int i;
+ for (i = 0; str[i]; i++) {
+ if (str[i] == '/')
+ return 1;
+ }
+ return 0;
+}
+
+#undef PKGDATADIR
+#define PKGDATADIR "/../"
static void add_default_dirs(void)
{
const char *run_prefix;
run_prefix = strExePath;
#else
- run_prefix = "";
+ if (!contains_slash (argv0)) {
+ run_prefix = find_in_path (argv0);
+ }
+ else {
+ run_prefix = dirname (strdup (argv0));
+ }
#endif
- LOG_DEBUG("bindir=%s", BINDIR);
LOG_DEBUG("pkgdatadir=%s", PKGDATADIR);
LOG_DEBUG("run_prefix=%s", run_prefix);
LOG_OUTPUT("--version | -v\tdisplay OpenOCD version\n");
LOG_OUTPUT("--file | -f\tuse configuration file <name>\n");
LOG_OUTPUT("--search | -s\tdir to search for config files and scripts\n");
- LOG_OUTPUT("--debug | -d\tset debug level <0-3>\n");
+ LOG_OUTPUT("--debug | -d\tset debug level <0-4>\n");
LOG_OUTPUT("--log_output | -l\tredirect log output to file <name>\n");
LOG_OUTPUT("--command | -c\trun <command>\n");
exit(-1);
return ret;
}
+char *argv0;
+
/* normally this is the main() function entry, but if OpenOCD is linked
* into application, then this fn will not be invoked, but rather that
* application will have it's own implementation of main(). */
int openocd_main(int argc, char *argv[])
{
int ret;
+ argv0 = argv[0];
/* initialize commandline interface */
struct command_context *cmd_ctx;
#ifndef OPENOCD_H
#define OPENOCD_H
+extern char *argv0;
+
/**
* Different applications can define this entry point to override
* the default openocd main function. On most systems, this will be
static int (cmsis_dap_queue_ap_abort)(struct adiv5_dap *dap, uint8_t *ack)
{
- LOG_DEBUG("CMSIS-ADI: cmsis_dap_queue_ap_abort");
+ LOG_DAP("CMSIS-ADI: cmsis_dap_queue_ap_abort");
/* FIXME: implement this properly cmsis-dap has DAP_WriteABORT()
* for now just hack @ everything */
static int cmsis_dap_queue_dp_read(struct adiv5_dap *dap, unsigned reg, uint32_t *data)
{
- LOG_DEBUG("CMSIS-ADI: cmsis_dap_queue_dp_read %d", reg);
+ LOG_DAP("CMSIS-ADI: cmsis_dap_queue_dp_read %d", reg);
int retval = jtag_interface->swd->read_reg(
(CMSIS_CMD_DP | CMSIS_CMD_READ | CMSIS_CMD_A32(reg)), data);
static int cmsis_dap_queue_idcode_read(struct adiv5_dap *dap, uint8_t *ack, uint32_t *data)
{
- LOG_DEBUG("CMSIS-ADI: cmsis_dap_queue_idcode_read");
+ LOG_DAP("CMSIS-ADI: cmsis_dap_queue_idcode_read");
int retval = cmsis_dap_queue_dp_read(dap, DP_IDCODE, data);
if (retval != ERROR_OK)
static int (cmsis_dap_queue_dp_write)(struct adiv5_dap *dap, unsigned reg, uint32_t data)
{
- LOG_DEBUG("CMSIS-ADI: cmsis_dap_queue_dp_write %d 0x%08" PRIx32, reg, data);
+ LOG_DAP("CMSIS-ADI: cmsis_dap_queue_dp_write %d 0x%08" PRIx32, reg, data);
/* setting the ORUNDETECT bit causes issues for some targets,
* disable until we find out why */
static int (cmsis_dap_queue_ap_read)(struct adiv5_dap *dap, unsigned reg, uint32_t *data)
{
- LOG_DEBUG("CMSIS-ADI: cmsis_dap_queue_ap_read %d", reg);
+ LOG_DAP("CMSIS-ADI: cmsis_dap_queue_ap_read %d", reg);
int retval = cmsis_dap_ap_q_bankselect(dap, reg);
if (retval != ERROR_OK)
static int (cmsis_dap_queue_ap_write)(struct adiv5_dap *dap, unsigned reg, uint32_t data)
{
- LOG_DEBUG("CMSIS-ADI: cmsis_dap_queue_ap_write %d 0x%08" PRIx32, reg, data);
+ LOG_DAP("CMSIS-ADI: cmsis_dap_queue_ap_write %d 0x%08" PRIx32, reg, data);
/* TODO: CSW_DBGSWENABLE (bit31) causes issues for some targets
* disable until we find out why */
static int (cmsis_dap_queue_ap_read_block)(struct adiv5_dap *dap, unsigned reg,
uint32_t blocksize, uint8_t *buffer)
{
- LOG_DEBUG("CMSIS-ADI: cmsis_dap_queue_ap_read_block 0x%08" PRIx32, blocksize);
+ LOG_DAP("CMSIS-ADI: cmsis_dap_queue_ap_read_block 0x%08" PRIx32, blocksize);
int retval = jtag_interface->swd->read_block(
(CMSIS_CMD_AP | CMSIS_CMD_READ | CMSIS_CMD_A32(AP_REG_DRW)),
/** Executes all queued DAP operations. */
static int cmsis_dap_run(struct adiv5_dap *dap)
{
- LOG_DEBUG("CMSIS-ADI: cmsis_dap_run");
+ LOG_DAP("CMSIS-ADI: cmsis_dap_run");
/* FIXME: for now the CMSIS-DAP interface hard-wires a zero-size queue. */
return ERROR_OK;
static int cmsis_dap_select(struct command_context *ctx)
{
- LOG_DEBUG("CMSIS-ADI: cmsis_dap_select");
+ LOG_DAP("CMSIS-ADI: cmsis_dap_select");
int retval = register_commands(ctx, NULL, cmsis_dap_handlers);
uint32_t idcode;
int status;
- LOG_DEBUG("CMSIS-ADI: cmsis_dap_init");
+ LOG_DAP("CMSIS-ADI: cmsis_dap_init");
/* Force the DAP's ops vector for CMSIS-DAP mode.
* messy - is there a better way? */
cortex_m_endreset_event(target);
target->state = TARGET_RUNNING;
prev_target_state = TARGET_RUNNING;
+
+ /* Disable Freescale Kinetis WDOG */
+ kinetis_disable_wdog(target);
}
if (cortex_m->dcb_dhcsr & S_HALT) {
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
if (watchpoint->address & ((1 << mask) - 1)) {
- LOG_DEBUG("watchpoint address is unaligned");
- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ LOG_WARNING("watchpoint address is unaligned");
}
/* Caller doesn't seem to be able to describe watching for data
{
int retval;
uint32_t cpuid, fpcr, mvfr0, mvfr1;
+ uint8_t fsec;
int i;
struct cortex_m_common *cortex_m = target_to_cm(target);
struct adiv5_dap *swjdp = cortex_m->armv7m.arm.dap;
if (!target_was_examined(target)) {
target_set_examined(target);
+ retval = target_read_u8(target, FSEC, &fsec);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("Cannot read FSEC. Device may be secured");
+ LOG_INFO("Mass erasing a device will unsecure it until the next reset. "
+ "To permanently unsecure, mass erase then flash a "
+ "program containing an appropriate flash configuration field.");
+ exit(-1);
+ }
+ else if ((fsec & 0x3) != 0x2) {
+ LOG_ERROR("Cannot access device, device is secured");
+ LOG_INFO("Mass erasing a device will unsecure it until the next reset. "
+ "To permanently unsecure, mass erase then flash a "
+ "program containing an appropriate flash configuration field.");
+ exit(-1);
+ }
+
/* Read from Device Identification Registers */
retval = target_read_u32(target, CPUID, &cpuid);
if (retval != ERROR_OK)
#define ITM_LAR 0xE0000FB0
#define CPUID 0xE000ED00
+#define FSEC 0x0000040C
/* Debug Control Block */
#define DCB_DHCSR 0xE000EDF0
#define DCB_DCRSR 0xE000EDF4
void cortex_m_enable_watchpoints(struct target *target);
void cortex_m_dwt_setup(struct cortex_m_common *cm, struct target *target);
+int kinetis_disable_wdog (struct target *target);
+
#endif /* CORTEX_M_H */
--- /dev/null
+#!/bin/bash
+
+gen_cfg () {
+ local name=$1
+ local tapid=$2
+ cp kinetis_template.cfg $name.cfg
+ sed -i "s/SOMNNAME/$name/g" $name.cfg
+ sed -i "s/SOMNTAPID/$tapid/g" $name.cfg
+}
+
+gen_cfg kl25 0x0BC11477
+gen_cfg kl26 0x0BC11477
+gen_cfg k64 0x4BA00477
+gen_cfg k21 0x4BA00477
+gen_cfg k22 0x4BA00477
+gen_cfg kl46 0x0BC11477
+gen_cfg k40 0x4ba00477
+gen_cfg k60 0x4ba00477
--- /dev/null
+#
+# Freescale Kinetis k21 devices
+#
+
+#
+# k21 devices support both JTAG and SWD transports.
+#
+source [find target/swj-dp.tcl]
+
+if { [info exists CHIPNAME] } {
+ set _CHIPNAME $CHIPNAME
+} else {
+ set _CHIPNAME k21
+}
+
+if { [info exists ENDIAN] } {
+ set _ENDIAN $ENDIAN
+} else {
+ set _ENDIAN little
+}
+
+# Work-area is a space in RAM used for flash programming
+# By default use 4kB
+if { [info exists WORKAREASIZE] } {
+ set _WORKAREASIZE $WORKAREASIZE
+} else {
+ set _WORKAREASIZE 0x1000
+}
+
+if { [info exists CPUTAPID] } {
+ set _CPUTAPID $CPUTAPID
+} else {
+ set _CPUTAPID 0x4BA00477
+}
+
+swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID
+
+set _TARGETNAME $_CHIPNAME.cpu
+target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_CHIPNAME.cpu
+
+$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
+
+set _FLASHNAME $_CHIPNAME.flash
+flash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME
+
+# if srst is not fitted use SYSRESETREQ to
+# perform a soft reset
+cortex_m reset_config sysresetreq
+
+adapter_khz 50
+
+$_TARGETNAME configure -event gdb-attach {
+ halt
+}
+
+echo "Warning - This configuration file is deprecated and will be removed in future versions, use kinetis.cfg instead."
--- /dev/null
+#
+# Freescale Kinetis k22 devices
+#
+
+#
+# k22 devices support both JTAG and SWD transports.
+#
+source [find target/swj-dp.tcl]
+
+if { [info exists CHIPNAME] } {
+ set _CHIPNAME $CHIPNAME
+} else {
+ set _CHIPNAME k22
+}
+
+if { [info exists ENDIAN] } {
+ set _ENDIAN $ENDIAN
+} else {
+ set _ENDIAN little
+}
+
+# Work-area is a space in RAM used for flash programming
+# By default use 4kB
+if { [info exists WORKAREASIZE] } {
+ set _WORKAREASIZE $WORKAREASIZE
+} else {
+ set _WORKAREASIZE 0x1000
+}
+
+if { [info exists CPUTAPID] } {
+ set _CPUTAPID $CPUTAPID
+} else {
+ set _CPUTAPID 0x4BA00477
+}
+
+swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID
+
+set _TARGETNAME $_CHIPNAME.cpu
+target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_CHIPNAME.cpu
+
+$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
+
+set _FLASHNAME $_CHIPNAME.flash
+flash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME
+
+# if srst is not fitted use SYSRESETREQ to
+# perform a soft reset
+cortex_m reset_config sysresetreq
+
+adapter_khz 50
+
+$_TARGETNAME configure -event gdb-attach {
+ halt
+}
+
+echo "Warning - This configuration file is deprecated and will be removed in future versions, use kinetis.cfg instead."
#
-# Freescale Kinetis K40 devices
+# Freescale Kinetis k40 devices
#
#
-# K40 devices support both JTAG and SWD transports.
+# k40 devices support both JTAG and SWD transports.
#
source [find target/swj-dp.tcl]
set _ENDIAN little
}
+# Work-area is a space in RAM used for flash programming
+# By default use 4kB
+if { [info exists WORKAREASIZE] } {
+ set _WORKAREASIZE $WORKAREASIZE
+} else {
+ set _WORKAREASIZE 0x1000
+}
+
if { [info exists CPUTAPID] } {
set _CPUTAPID $CPUTAPID
} else {
set _CPUTAPID 0x4ba00477
}
-set _TARGETNAME $_CHIPNAME.cpu
+swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID
-swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
+set _TARGETNAME $_CHIPNAME.cpu
+target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_CHIPNAME.cpu
-target create $_TARGETNAME cortex_m -chain-position $_CHIPNAME.cpu
+$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
-$_CHIPNAME.cpu configure -event examine-start { puts "START..." ; }
-$_CHIPNAME.cpu configure -event examine-end { puts "END..." ; }
+set _FLASHNAME $_CHIPNAME.flash
+flash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME
# if srst is not fitted use SYSRESETREQ to
# perform a soft reset
cortex_m reset_config sysresetreq
+
+adapter_khz 50
+
+$_TARGETNAME configure -event gdb-attach {
+ halt
+}
+
+echo "Warning - This configuration file is deprecated and will be removed in future versions, use kinetis.cfg instead."
#
-# Freescale Kinetis K60 devices
+# Freescale Kinetis k60 devices
#
#
-# K60 devices support both JTAG and SWD transports.
+# k60 devices support both JTAG and SWD transports.
#
source [find target/swj-dp.tcl]
set _ENDIAN little
}
+# Work-area is a space in RAM used for flash programming
+# By default use 4kB
+if { [info exists WORKAREASIZE] } {
+ set _WORKAREASIZE $WORKAREASIZE
+} else {
+ set _WORKAREASIZE 0x1000
+}
+
if { [info exists CPUTAPID] } {
set _CPUTAPID $CPUTAPID
} else {
set _CPUTAPID 0x4ba00477
}
-set _TARGETNAME $_CHIPNAME.cpu
+swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID
-swj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
+set _TARGETNAME $_CHIPNAME.cpu
+target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_CHIPNAME.cpu
-target create $_TARGETNAME cortex_m -chain-position $_CHIPNAME.cpu
+$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
-$_CHIPNAME.cpu configure -event examine-start { puts "START..." ; }
-$_CHIPNAME.cpu configure -event examine-end { puts "END..." ; }
+set _FLASHNAME $_CHIPNAME.flash
+flash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME
# if srst is not fitted use SYSRESETREQ to
# perform a soft reset
cortex_m reset_config sysresetreq
+
+adapter_khz 50
+
+$_TARGETNAME configure -event gdb-attach {
+ halt
+}
+
+echo "Warning - This configuration file is deprecated and will be removed in future versions, use kinetis.cfg instead."
--- /dev/null
+#
+# Freescale Kinetis k64 devices
+#
+
+#
+# k64 devices support both JTAG and SWD transports.
+#
+source [find target/swj-dp.tcl]
+
+if { [info exists CHIPNAME] } {
+ set _CHIPNAME $CHIPNAME
+} else {
+ set _CHIPNAME k64
+}
+
+if { [info exists ENDIAN] } {
+ set _ENDIAN $ENDIAN
+} else {
+ set _ENDIAN little
+}
+
+# Work-area is a space in RAM used for flash programming
+# By default use 4kB
+if { [info exists WORKAREASIZE] } {
+ set _WORKAREASIZE $WORKAREASIZE
+} else {
+ set _WORKAREASIZE 0x1000
+}
+
+if { [info exists CPUTAPID] } {
+ set _CPUTAPID $CPUTAPID
+} else {
+ set _CPUTAPID 0x4BA00477
+}
+
+swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID
+
+set _TARGETNAME $_CHIPNAME.cpu
+target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_CHIPNAME.cpu
+
+$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
+
+set _FLASHNAME $_CHIPNAME.flash
+flash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME
+
+# if srst is not fitted use SYSRESETREQ to
+# perform a soft reset
+cortex_m reset_config sysresetreq
+
+adapter_khz 50
+
+$_TARGETNAME configure -event gdb-attach {
+ halt
+}
+
+echo "Warning - This configuration file is deprecated and will be removed in future versions, use kinetis.cfg instead."
--- /dev/null
+# Config Freescale Kinetis devices providing a CMSIS-DAP interface.
+
+interface cmsis-dap
+
+if { [info exists CHIPNAME] } {
+ set _CHIPNAME $CHIPNAME
+} else {
+ set _CHIPNAME kinetis
+}
+
+cmsis-dap newdap $_CHIPNAME cpu -irlen 4
+global using_jtag
+set using_jtag 0
+
+set _TARGETNAME $_CHIPNAME.cpu
+target create $_TARGETNAME cortex_m -chain-position $_CHIPNAME.cpu
+
+$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size 0x1000 -work-area-backup 0
+
+# Flash size is detected automatically.
+flash bank $_CHIPNAME.flash kinetis 0 0 0 0 $_TARGETNAME
+
+cortex_m reset_config sysresetreq
+
+adapter_khz 1000
+
+$_TARGETNAME configure -event gdb-attach {
+ halt
+}
--- /dev/null
+#
+# Freescale Kinetis SOMNNAME devices
+#
+
+#
+# SOMNNAME devices support both JTAG and SWD transports.
+#
+source [find target/swj-dp.tcl]
+
+if { [info exists CHIPNAME] } {
+ set _CHIPNAME $CHIPNAME
+} else {
+ set _CHIPNAME SOMNNAME
+}
+
+if { [info exists ENDIAN] } {
+ set _ENDIAN $ENDIAN
+} else {
+ set _ENDIAN little
+}
+
+# Work-area is a space in RAM used for flash programming
+# By default use 4kB
+if { [info exists WORKAREASIZE] } {
+ set _WORKAREASIZE $WORKAREASIZE
+} else {
+ set _WORKAREASIZE 0x1000
+}
+
+if { [info exists CPUTAPID] } {
+ set _CPUTAPID $CPUTAPID
+} else {
+ set _CPUTAPID SOMNTAPID
+}
+
+swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID
+
+set _TARGETNAME $_CHIPNAME.cpu
+target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_CHIPNAME.cpu
+
+$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
+
+set _FLASHNAME $_CHIPNAME.flash
+flash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME
+
+# if srst is not fitted use SYSRESETREQ to
+# perform a soft reset
+cortex_m reset_config sysresetreq
+
+adapter_khz 50
+
+$_TARGETNAME configure -event gdb-attach {
+ halt
+}
+
+echo "Warning - This configuration file is deprecated and will be removed in future versions, use kinetis.cfg instead."
#
-# Freescale Kinetis KL25 devices
+# Freescale Kinetis kl25 devices
#
#
-# KL25 devices support both JTAG and SWD transports.
+# kl25 devices support both JTAG and SWD transports.
#
source [find target/swj-dp.tcl]
if { [info exists CPUTAPID] } {
set _CPUTAPID $CPUTAPID
} else {
- set _CPUTAPID 0x0bc11477
+ set _CPUTAPID 0x0BC11477
}
swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID
# if srst is not fitted use SYSRESETREQ to
# perform a soft reset
cortex_m reset_config sysresetreq
+
+adapter_khz 50
+
+$_TARGETNAME configure -event gdb-attach {
+ halt
+}
+
+echo "Warning - This configuration file is deprecated and will be removed in future versions, use kinetis.cfg instead."
--- /dev/null
+#
+# Freescale Kinetis kl26 devices
+#
+
+#
+# kl26 devices support both JTAG and SWD transports.
+#
+source [find target/swj-dp.tcl]
+
+if { [info exists CHIPNAME] } {
+ set _CHIPNAME $CHIPNAME
+} else {
+ set _CHIPNAME kl26
+}
+
+if { [info exists ENDIAN] } {
+ set _ENDIAN $ENDIAN
+} else {
+ set _ENDIAN little
+}
+
+# Work-area is a space in RAM used for flash programming
+# By default use 4kB
+if { [info exists WORKAREASIZE] } {
+ set _WORKAREASIZE $WORKAREASIZE
+} else {
+ set _WORKAREASIZE 0x1000
+}
+
+if { [info exists CPUTAPID] } {
+ set _CPUTAPID $CPUTAPID
+} else {
+ set _CPUTAPID 0x0BC11477
+}
+
+swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID
+
+set _TARGETNAME $_CHIPNAME.cpu
+target create $_TARGETNAME cortex_m -endian $_ENDIAN -chain-position $_CHIPNAME.cpu
+
+$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0
+
+set _FLASHNAME $_CHIPNAME.flash
+flash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME
+
+# if srst is not fitted use SYSRESETREQ to
+# perform a soft reset
+cortex_m reset_config sysresetreq
+
+adapter_khz 50
+
+$_TARGETNAME configure -event gdb-attach {
+ halt
+}
+
+echo "Warning - This configuration file is deprecated and will be removed in future versions, use kinetis.cfg instead."
#
-# Freescale Kinetis KL46 devices
+# Freescale Kinetis kl46 devices
#
#
-# KL46 devices supports SWD transport only.
+# kl46 devices support both JTAG and SWD transports.
#
source [find target/swj-dp.tcl]
if { [info exists CPUTAPID] } {
set _CPUTAPID $CPUTAPID
} else {
- set _CPUTAPID 0x0bc11477
+ set _CPUTAPID 0x0BC11477
}
swj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID
# if srst is not fitted use SYSRESETREQ to
# perform a soft reset
cortex_m reset_config sysresetreq
+
+adapter_khz 50
+
+$_TARGETNAME configure -event gdb-attach {
+ halt
+}
+
+echo "Warning - This configuration file is deprecated and will be removed in future versions, use kinetis.cfg instead."