AC_ARG_ENABLE([stlink],
AS_HELP_STRING([--enable-stlink], [Enable building support for the ST-Link JTAG Programmer]),
- [build_stlink=$enableval], [build_stlink=no])
+ [build_hladapter=$enableval], [build_hladapter=no])
AC_ARG_ENABLE([osbdm],
AS_HELP_STRING([--enable-osbdm], [Enable building support for the OSBDM (JTAG only) Programmer]),
AC_DEFINE([BUILD_BUSPIRATE], [0], [0 if you don't want the Buspirate JTAG driver.])
fi
-if test $build_stlink = yes; then
- AC_DEFINE([BUILD_STLINK], [1], [1 if you want the ST-Link JTAG driver.])
+if test $build_hladapter = yes; then
+ AC_DEFINE([BUILD_HLADAPTER], [1], [1 if you want the ST-Link JTAG driver.])
else
- AC_DEFINE([BUILD_STLINK], [0], [0 if you don't want the ST-Link JTAG driver.])
+ AC_DEFINE([BUILD_HLADAPTER], [0], [0 if you don't want the ST-Link JTAG driver.])
fi
if test $build_osbdm = yes; then
# Check for libusb1 ported drivers.
build_usb_ng=no
-if test $build_jlink = yes -o $build_stlink = yes -o $build_osbdm = yes -o \
+if test $build_jlink = yes -o $build_hladapter = yes -o $build_osbdm = yes -o \
$build_opendous = yes -o $build_ftdi = yes
then
build_usb_ng=yes
AM_CONDITIONAL([ARMJTAGEW], [test $build_armjtagew = yes])
AM_CONDITIONAL([REMOTE_BITBANG], [test $build_remote_bitbang = yes])
AM_CONDITIONAL([BUSPIRATE], [test $build_buspirate = yes])
-AM_CONDITIONAL([STLINK], [test $build_stlink = yes])
+AM_CONDITIONAL([HLADAPTER], [test $build_hladapter = yes])
AM_CONDITIONAL([OSBDM], [test $build_osbdm = yes])
AM_CONDITIONAL([OPENDOUS], [test $build_opendous = yes])
AM_CONDITIONAL([SYSFSGPIO], [test $build_sysfsgpio = yes])
src/helper/Makefile
src/jtag/Makefile
src/jtag/drivers/Makefile
- src/jtag/stlink/Makefile
+ src/jtag/hla/Makefile
src/transport/Makefile
src/xsvf/Makefile
src/svf/Makefile
MINIDRIVER_IMP_DIR = $(srcdir)/drivers
DRIVERFILES += commands.c
-if STLINK
-SUBDIRS += stlink
-libjtag_la_LIBADD += $(top_builddir)/src/jtag/stlink/libocdstlink.la
+if HLADAPTER
+SUBDIRS += hla
+libjtag_la_LIBADD += $(top_builddir)/src/jtag/hla/libocdhla.la
endif
SUBDIRS += drivers
if REMOTE_BITBANG
DRIVERFILES += remote_bitbang.c
endif
-if STLINK
+if HLADAPTER
DRIVERFILES += stlink_usb.c
endif
if OSBDM
/* project specific includes */
#include <helper/binarybuffer.h>
#include <jtag/interface.h>
-#include <jtag/stlink/stlink_layout.h>
-#include <jtag/stlink/stlink_transport.h>
-#include <jtag/stlink/stlink_interface.h>
+#include <jtag/hla/hla_layout.h>
+#include <jtag/hla/hla_transport.h>
+#include <jtag/hla/hla_interface.h>
#include <target/target.h>
#include <target/cortex_m.h>
/** */
uint8_t databuf[STLINK_DATA_SIZE];
/** */
- enum stlink_transports transport;
+ enum hl_transports transport;
/** */
struct stlink_usb_version version;
/** */
/* set selected mode */
switch (h->transport) {
- case STLINK_TRANSPORT_SWD:
+ case HL_TRANSPORT_SWD:
emode = STLINK_MODE_DEBUG_SWD;
break;
- case STLINK_TRANSPORT_JTAG:
+ case HL_TRANSPORT_JTAG:
emode = STLINK_MODE_DEBUG_JTAG;
break;
- case STLINK_TRANSPORT_SWIM:
+ case HL_TRANSPORT_SWIM:
emode = STLINK_MODE_DEBUG_SWIM;
break;
default:
}
/** */
-static int stlink_usb_open(struct stlink_interface_param_s *param, void **fd)
+static int stlink_usb_open(struct hl_interface_param_s *param, void **fd)
{
int err;
struct stlink_usb_handle_s *h;
err = ERROR_OK;
switch (h->transport) {
- case STLINK_TRANSPORT_SWD:
- case STLINK_TRANSPORT_JTAG:
+ case HL_TRANSPORT_SWD:
+ case HL_TRANSPORT_JTAG:
if (h->version.jtag == 0)
err = ERROR_FAIL;
break;
- case STLINK_TRANSPORT_SWIM:
+ case HL_TRANSPORT_SWIM:
if (h->version.swim == 0)
err = ERROR_FAIL;
break;
}
/** */
-struct stlink_layout_api_s stlink_usb_layout_api = {
+struct hl_layout_api_s stlink_usb_layout_api = {
/** */
.open = stlink_usb_open,
/** */
--- /dev/null
+include $(top_srcdir)/common.mk
+
+noinst_LTLIBRARIES = libocdhla.la
+
+libocdhla_la_SOURCES = \
+ $(HLFILES)
+
+HLFILES =
+
+if HLADAPTER
+HLFILES += hla_transport.c
+HLFILES += hla_tcl.c
+HLFILES += hla_interface.c
+HLFILES += hla_layout.c
+endif
+
+noinst_HEADERS = \
+ hla_interface.h \
+ hla_layout.h \
+ hla_tcl.h \
+ hla_transport.h
+
+MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2011 by Mathias Kuester *
+ * Mathias Kuester <kesmtp@freenet.de> *
+ * *
+ * Copyright (C) 2012 by Spencer Oliver *
+ * spen@spen-soft.co.uk *
+ * *
+ * 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., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* project specific includes */
+#include <jtag/interface.h>
+#include <transport/transport.h>
+#include <helper/time_support.h>
+
+#include <jtag/hla/hla_tcl.h>
+#include <jtag/hla/hla_layout.h>
+#include <jtag/hla/hla_transport.h>
+#include <jtag/hla/hla_interface.h>
+
+#include <target/target.h>
+
+static struct hl_interface_s hl_if = { {0, 0, 0, 0, 0, 0}, 0, 0 };
+
+int hl_interface_open(enum hl_transports tr)
+{
+ LOG_DEBUG("hl_interface_open");
+
+ /* set transport mode */
+ hl_if.param.transport = tr;
+
+ int result = hl_if.layout->open(&hl_if);
+ if (result != ERROR_OK)
+ return result;
+
+ return hl_interface_init_reset();
+}
+
+int hl_interface_init_target(struct target *t)
+{
+ int res;
+
+ LOG_DEBUG("hl_interface_init_target");
+
+ /* this is the interface for the current target and we
+ * can setup the private pointer in the tap structure
+ * if the interface match the tap idcode
+ */
+ res = hl_if.layout->api->idcode(hl_if.fd, &t->tap->idcode);
+
+ if (res != ERROR_OK)
+ return res;
+
+ unsigned ii, limit = t->tap->expected_ids_cnt;
+ int found = 0;
+
+ for (ii = 0; ii < limit; ii++) {
+ uint32_t expected = t->tap->expected_ids[ii];
+
+ /* treat "-expected-id 0" as a "don't-warn" wildcard */
+ if (!expected || (t->tap->idcode == expected)) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found == 0) {
+ LOG_ERROR("hl_interface_init_target: target not found: idcode: 0x%08x",
+ t->tap->idcode);
+ return ERROR_FAIL;
+ }
+
+ t->tap->priv = &hl_if;
+ t->tap->hasidcode = 1;
+
+ return ERROR_OK;
+}
+
+static int hl_interface_init(void)
+{
+ LOG_DEBUG("hl_interface_init");
+
+ /* here we can initialize the layout */
+ return hl_layout_init(&hl_if);
+}
+
+static int hl_interface_quit(void)
+{
+ LOG_DEBUG("hl_interface_quit");
+
+ return ERROR_OK;
+}
+
+static int hl_interface_speed(int speed)
+{
+ LOG_DEBUG("hl_interface_speed: ignore speed %d", speed);
+
+ return ERROR_OK;
+}
+
+static int hl_speed_div(int speed, int *khz)
+{
+ *khz = speed;
+ return ERROR_OK;
+}
+
+static int hl_khz(int khz, int *jtag_speed)
+{
+ *jtag_speed = khz;
+ return ERROR_OK;
+}
+
+static int hl_interface_execute_queue(void)
+{
+ LOG_DEBUG("hl_interface_execute_queue: ignored");
+
+ return ERROR_OK;
+}
+
+int hl_interface_init_reset(void)
+{
+ enum reset_types jtag_reset_config = jtag_get_reset_config();
+
+ if (jtag_reset_config & RESET_CNCT_UNDER_SRST) {
+ if (jtag_reset_config & RESET_SRST_NO_GATING) {
+ jtag_add_reset(0, 1);
+ hl_if.layout->api->assert_srst(hl_if.fd, 0);
+ } else
+ LOG_WARNING("\'srst_nogate\' reset_config option is required");
+ }
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(hl_interface_handle_device_desc_command)
+{
+ LOG_DEBUG("hl_interface_handle_device_desc_command");
+
+ if (CMD_ARGC == 1) {
+ hl_if.param.device_desc = strdup(CMD_ARGV[0]);
+ } else {
+ LOG_ERROR("expected exactly one argument to hl_device_desc <description>");
+ }
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(hl_interface_handle_serial_command)
+{
+ LOG_DEBUG("hl_interface_handle_serial_command");
+
+ if (CMD_ARGC == 1) {
+ hl_if.param.serial = strdup(CMD_ARGV[0]);
+ } else {
+ LOG_ERROR("expected exactly one argument to hl_serial <serial-number>");
+ }
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(hl_interface_handle_layout_command)
+{
+ LOG_DEBUG("hl_interface_handle_layout_command");
+
+ if (CMD_ARGC != 1) {
+ LOG_ERROR("Need exactly one argument to stlink_layout");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ if (hl_if.layout) {
+ LOG_ERROR("already specified hl_layout %s",
+ hl_if.layout->name);
+ return (strcmp(hl_if.layout->name, CMD_ARGV[0]) != 0)
+ ? ERROR_FAIL : ERROR_OK;
+ }
+
+ for (const struct hl_layout *l = hl_layout_get_list(); l->name;
+ l++) {
+ if (strcmp(l->name, CMD_ARGV[0]) == 0) {
+ hl_if.layout = l;
+ return ERROR_OK;
+ }
+ }
+
+ LOG_ERROR("No adapter layout '%s' found", CMD_ARGV[0]);
+ return ERROR_FAIL;
+}
+
+COMMAND_HANDLER(hl_interface_handle_vid_pid_command)
+{
+ LOG_DEBUG("hl_interface_handle_vid_pid_command");
+
+ if (CMD_ARGC != 2) {
+ LOG_WARNING("ignoring extra IDs in hl_vid_pid (maximum is 1 pair)");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], hl_if.param.vid);
+ COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], hl_if.param.pid);
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(hl_interface_handle_api_command)
+{
+ if (CMD_ARGC != 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ unsigned new_api;
+ COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], new_api);
+ if ((new_api == 0) || (new_api > 2))
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ hl_if.param.api = new_api;
+
+ return ERROR_OK;
+}
+
+static const struct command_registration hl_interface_command_handlers[] = {
+ {
+ .name = "stlink_device_desc",
+ .handler = &hl_interface_handle_device_desc_command,
+ .mode = COMMAND_CONFIG,
+ .help = "set the a device description of the adapter",
+ .usage = "description_string",
+ },
+ {
+ .name = "stlink_serial",
+ .handler = &hl_interface_handle_serial_command,
+ .mode = COMMAND_CONFIG,
+ .help = "set the serial number of the adapter",
+ .usage = "serial_string",
+ },
+ {
+ .name = "stlink_layout",
+ .handler = &hl_interface_handle_layout_command,
+ .mode = COMMAND_CONFIG,
+ .help = "set the layout of the adapter",
+ .usage = "layout_name",
+ },
+ {
+ .name = "stlink_vid_pid",
+ .handler = &hl_interface_handle_vid_pid_command,
+ .mode = COMMAND_CONFIG,
+ .help = "the vendor and product ID of the adapter",
+ .usage = "(vid pid)* ",
+ },
+ {
+ .name = "stlink_api",
+ .handler = &hl_interface_handle_api_command,
+ .mode = COMMAND_CONFIG,
+ .help = "set the desired stlink api level",
+ .usage = "api version 1 or 2",
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
+struct jtag_interface hl_interface = {
+ .name = "stlink",
+ .supported = 0,
+ .commands = hl_interface_command_handlers,
+ .transports = hl_transports,
+ .init = hl_interface_init,
+ .quit = hl_interface_quit,
+ .speed = hl_interface_speed,
+ .speed_div = hl_speed_div,
+ .khz = hl_khz,
+ .execute_queue = hl_interface_execute_queue,
+};
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2011 by Mathias Kuester *
+ * Mathias Kuester <kesmtp@freenet.de> *
+ * *
+ * Copyright (C) 2012 by Spencer Oliver *
+ * spen@spen-soft.co.uk *
+ * *
+ * 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., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#ifndef _HL_INTERFACE
+#define _HL_INTERFACE
+
+/** */
+struct target;
+/** */
+enum e_hl_transports;
+/** */
+extern const char *hl_transports[];
+
+struct hl_interface_param_s {
+ /** */
+ char *device_desc;
+ /** */
+ char *serial;
+ /** */
+ uint16_t vid;
+ /** */
+ uint16_t pid;
+ /** */
+ unsigned api;
+ /** */
+ enum hl_transports transport;
+};
+
+struct hl_interface_s {
+ /** */
+ struct hl_interface_param_s param;
+ /** */
+ const struct hl_layout *layout;
+ /** */
+ void *fd;
+};
+
+/** */
+int hl_interface_open(enum hl_transports tr);
+/** */
+
+int hl_interface_init_target(struct target *t);
+int hl_interface_init_reset(void);
+
+#endif /* _HL_INTERFACE */
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2011 by Mathias Kuester *
+ * Mathias Kuester <kesmtp@freenet.de> *
+ * *
+ * Copyright (C) 2012 by Spencer Oliver *
+ * spen@spen-soft.co.uk *
+ * *
+ * 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., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* project specific includes */
+#include <jtag/interface.h>
+#include <transport/transport.h>
+#include <helper/time_support.h>
+
+#include <jtag/hla/hla_layout.h>
+#include <jtag/hla/hla_tcl.h>
+#include <jtag/hla/hla_transport.h>
+#include <jtag/hla/hla_interface.h>
+
+static int hl_layout_open(struct hl_interface_s *adapter)
+{
+ int res;
+
+ LOG_DEBUG("hl_layout_open");
+
+ adapter->fd = NULL;
+
+ res = adapter->layout->api->open(&adapter->param, &adapter->fd);
+
+ if (res != ERROR_OK) {
+ LOG_DEBUG("failed");
+ return res;
+ }
+
+ return ERROR_OK;
+}
+
+static int hl_layout_close(struct hl_interface_s *adapter)
+{
+ return ERROR_OK;
+}
+
+static const struct hl_layout hl_layouts[] = {
+ {
+ .name = "stlink",
+ .open = hl_layout_open,
+ .close = hl_layout_close,
+ .api = &stlink_usb_layout_api,
+ },
+ {.name = NULL, /* END OF TABLE */ },
+};
+
+/** */
+const struct hl_layout *hl_layout_get_list(void)
+{
+ return hl_layouts;
+}
+
+int hl_layout_init(struct hl_interface_s *adapter)
+{
+ LOG_DEBUG("hl_layout_init");
+
+ if (adapter->layout == NULL) {
+ LOG_ERROR("no layout specified");
+ return ERROR_FAIL;
+ }
+ return ERROR_OK;
+}
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2011 by Mathias Kuester *
+ * Mathias Kuester <kesmtp@freenet.de> *
+ * *
+ * Copyright (C) 2012 by Spencer Oliver *
+ * spen@spen-soft.co.uk *
+ * *
+ * 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., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#ifndef _HL_LAYOUT_H
+#define _HL_LAYOUT_H
+
+/** */
+struct hl_interface_s;
+struct hl_interface_param_s;
+
+/** */
+extern struct hl_layout_api_s stlink_usb_layout_api;
+
+/** */
+struct hl_layout_api_s {
+ /** */
+ int (*open) (struct hl_interface_param_s *param, void **fd);
+ /** */
+ int (*close) (void *fd);
+ /** */
+ int (*reset) (void *fd);
+ /** */
+ int (*assert_srst) (void *fd, int srst);
+ /** */
+ int (*run) (void *fd);
+ /** */
+ int (*halt) (void *fd);
+ /** */
+ int (*step) (void *fd);
+ /** */
+ int (*read_regs) (void *fd);
+ /** */
+ int (*read_reg) (void *fd, int num, uint32_t *val);
+ /** */
+ int (*write_reg) (void *fd, int num, uint32_t val);
+ /** */
+ int (*read_mem8) (void *handle, uint32_t addr, uint16_t len,
+ uint8_t *buffer);
+ /** */
+ int (*write_mem8) (void *handle, uint32_t addr, uint16_t len,
+ const uint8_t *buffer);
+ /** */
+ int (*read_mem32) (void *handle, uint32_t addr, uint16_t len,
+ uint8_t *buffer);
+ /** */
+ int (*write_mem32) (void *handle, uint32_t addr, uint16_t len,
+ const uint8_t *buffer);
+ /** */
+ int (*write_debug_reg) (void *handle, uint32_t addr, uint32_t val);
+ /** */
+ int (*idcode) (void *fd, uint32_t *idcode);
+ /** */
+ enum target_state (*state) (void *fd);
+};
+
+/** */
+struct hl_layout {
+ /** */
+ char *name;
+ /** */
+ int (*open) (struct hl_interface_s *adapter);
+ /** */
+ int (*close) (struct hl_interface_s *adapter);
+ /** */
+ struct hl_layout_api_s *api;
+};
+
+/** */
+const struct hl_layout *hl_layout_get_list(void);
+/** */
+int hl_layout_init(struct hl_interface_s *adapter);
+
+#endif /* _HL_LAYOUT_H */
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2011 by Mathias Kuester *
+ * Mathias Kuester <kesmtp@freenet.de> *
+ * *
+ * Copyright (C) 2012 by Spencer Oliver *
+ * spen@spen-soft.co.uk *
+ * *
+ * 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., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* project specific includes */
+#include <jtag/interface.h>
+#include <transport/transport.h>
+#include <helper/time_support.h>
+
+static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi,
+ struct jtag_tap *pTap)
+{
+ jim_wide w;
+ int e = Jim_GetOpt_Wide(goi, &w);
+ if (e != JIM_OK) {
+ Jim_SetResultFormatted(goi->interp, "option: %s bad parameter",
+ n->name);
+ return e;
+ }
+
+ unsigned expected_len = sizeof(uint32_t) * pTap->expected_ids_cnt;
+ uint32_t *new_expected_ids = malloc(expected_len + sizeof(uint32_t));
+ if (new_expected_ids == NULL) {
+ Jim_SetResultFormatted(goi->interp, "no memory");
+ return JIM_ERR;
+ }
+
+ memcpy(new_expected_ids, pTap->expected_ids, expected_len);
+
+ new_expected_ids[pTap->expected_ids_cnt] = w;
+
+ free(pTap->expected_ids);
+ pTap->expected_ids = new_expected_ids;
+ pTap->expected_ids_cnt++;
+
+ return JIM_OK;
+}
+
+#define NTAP_OPT_EXPECTED_ID 0
+
+static int jim_hl_newtap_cmd(Jim_GetOptInfo *goi)
+{
+ struct jtag_tap *pTap;
+ int x;
+ int e;
+ Jim_Nvp *n;
+ char *cp;
+ const Jim_Nvp opts[] = {
+ {.name = "-expected-id", .value = NTAP_OPT_EXPECTED_ID},
+ {.name = NULL, .value = -1},
+ };
+
+ pTap = calloc(1, sizeof(struct jtag_tap));
+ if (!pTap) {
+ Jim_SetResultFormatted(goi->interp, "no memory");
+ return JIM_ERR;
+ }
+
+ /*
+ * we expect CHIP + TAP + OPTIONS
+ * */
+ if (goi->argc < 3) {
+ Jim_SetResultFormatted(goi->interp,
+ "Missing CHIP TAP OPTIONS ....");
+ free(pTap);
+ return JIM_ERR;
+ }
+ Jim_GetOpt_String(goi, &cp, NULL);
+ pTap->chip = strdup(cp);
+
+ Jim_GetOpt_String(goi, &cp, NULL);
+ pTap->tapname = strdup(cp);
+
+ /* name + dot + name + null */
+ x = strlen(pTap->chip) + 1 + strlen(pTap->tapname) + 1;
+ cp = malloc(x);
+ sprintf(cp, "%s.%s", pTap->chip, pTap->tapname);
+ pTap->dotted_name = cp;
+
+ LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
+ pTap->chip, pTap->tapname, pTap->dotted_name, goi->argc);
+
+ while (goi->argc) {
+ e = Jim_GetOpt_Nvp(goi, opts, &n);
+ if (e != JIM_OK) {
+ Jim_GetOpt_NvpUnknown(goi, opts, 0);
+ free((void *)pTap->dotted_name);
+ free(pTap);
+ return e;
+ }
+ LOG_DEBUG("Processing option: %s", n->name);
+ switch (n->value) {
+ case NTAP_OPT_EXPECTED_ID:
+ e = jim_newtap_expected_id(n, goi, pTap);
+ if (JIM_OK != e) {
+ free((void *)pTap->dotted_name);
+ free(pTap);
+ return e;
+ }
+ break;
+ } /* switch (n->value) */
+ } /* while (goi->argc) */
+
+ /* default is enabled-after-reset */
+ pTap->enabled = !pTap->disabled_after_reset;
+
+ jtag_tap_init(pTap);
+ return JIM_OK;
+}
+
+int jim_hl_newtap(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
+{
+ Jim_GetOptInfo goi;
+ Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
+ return jim_hl_newtap_cmd(&goi);
+}
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2011 by Mathias Kuester *
+ * Mathias Kuester <kesmtp@freenet.de> *
+ * *
+ * Copyright (C) 2012 by Spencer Oliver *
+ * spen@spen-soft.co.uk *
+ * *
+ * 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., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#ifndef _HL_TCL_
+#define _HL_TCL_
+
+/** */
+int jim_hl_newtap(Jim_Interp *interp, int argc, Jim_Obj * const *argv);
+
+#endif /* _HL_TCL_ */
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2011 by Mathias Kuester *
+ * Mathias Kuester <kesmtp@freenet.de> *
+ * *
+ * Copyright (C) 2012 by Spencer Oliver *
+ * spen@spen-soft.co.uk *
+ * *
+ * 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., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* project specific includes */
+#include <jtag/interface.h>
+#include <jtag/tcl.h>
+#include <transport/transport.h>
+#include <helper/time_support.h>
+#include <target/target.h>
+#include <jtag/hla/hla_tcl.h>
+#include <jtag/hla/hla_transport.h>
+#include <jtag/hla/hla_interface.h>
+
+COMMAND_HANDLER(hl_transport_jtag_command)
+{
+ LOG_DEBUG("hl_transport_jtag_command");
+
+ return ERROR_OK;
+}
+
+COMMAND_HANDLER(hl_transport_reset_command)
+{
+ return hl_interface_init_reset();
+}
+
+static const struct command_registration
+hl_transport_stlink_subcommand_handlers[] = {
+ {
+ .name = "newtap",
+ .mode = COMMAND_CONFIG,
+ .jim_handler = jim_hl_newtap,
+ .help = "Create a new TAP instance named basename.tap_type, "
+ "and appends it to the scan chain.",
+ .usage = "basename tap_type '-irlen' count "
+ "['-expected_id' number] ",
+ },
+
+ COMMAND_REGISTRATION_DONE
+};
+
+static const struct command_registration
+hl_transport_jtag_subcommand_handlers[] = {
+ {
+ .name = "init",
+ .mode = COMMAND_ANY,
+ .handler = hl_transport_jtag_command,
+ .usage = ""
+ },
+ {
+ .name = "arp_init",
+ .mode = COMMAND_ANY,
+ .handler = hl_transport_jtag_command,
+ .usage = ""
+ },
+ {
+ .name = "arp_init-reset",
+ .mode = COMMAND_ANY,
+ .handler = hl_transport_reset_command,
+ .usage = ""
+ },
+ {
+ .name = "tapisenabled",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_jtag_tap_enabler,
+ },
+ {
+ .name = "tapenable",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_jtag_tap_enabler,
+ },
+ {
+ .name = "tapdisable",
+ .mode = COMMAND_EXEC,
+ .handler = hl_transport_jtag_command,
+ .usage = "",
+ },
+ {
+ .name = "configure",
+ .mode = COMMAND_EXEC,
+ .handler = hl_transport_jtag_command,
+ .usage = "",
+ },
+ {
+ .name = "cget",
+ .mode = COMMAND_EXEC,
+ .jim_handler = jim_jtag_configure,
+ },
+ {
+ .name = "names",
+ .mode = COMMAND_ANY,
+ .handler = hl_transport_jtag_command,
+ .usage = "",
+ },
+
+ COMMAND_REGISTRATION_DONE
+};
+
+static const struct command_registration stlink_transport_command_handlers[] = {
+
+ {
+ .name = "stlink",
+ .mode = COMMAND_ANY,
+ .help = "perform stlink actions",
+ .usage = "",
+ .chain = hl_transport_stlink_subcommand_handlers,
+ },
+ {
+ .name = "jtag",
+ .mode = COMMAND_ANY,
+ .usage = "",
+ .chain = hl_transport_jtag_subcommand_handlers,
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
+static int hl_transport_register_commands(struct command_context *cmd_ctx)
+{
+ return register_commands(cmd_ctx, NULL,
+ stlink_transport_command_handlers);
+}
+
+static int hl_transport_init(struct command_context *cmd_ctx)
+{
+ LOG_DEBUG("hl_transport_init");
+ struct target *t = get_current_target(cmd_ctx);
+ struct transport *transport;
+ enum hl_transports tr;
+
+ if (!t) {
+ LOG_ERROR("no current target");
+ return ERROR_FAIL;
+ }
+
+ transport = get_current_transport();
+
+ if (!transport) {
+ LOG_ERROR("no transport selected");
+ return ERROR_FAIL;
+ }
+
+ LOG_DEBUG("current transport %s", transport->name);
+
+ /* get selected transport as enum */
+ tr = HL_TRANSPORT_UNKNOWN;
+
+ if (strcmp(transport->name, "stlink_swd") == 0)
+ tr = HL_TRANSPORT_SWD;
+ else if (strcmp(transport->name, "stlink_jtag") == 0)
+ tr = HL_TRANSPORT_JTAG;
+ else if (strcmp(transport->name, "stlink_swim") == 0)
+ tr = HL_TRANSPORT_SWIM;
+
+ int retval = hl_interface_open(tr);
+
+ if (retval != ERROR_OK)
+ return retval;
+
+ return hl_interface_init_target(t);
+}
+
+static int hl_transport_select(struct command_context *ctx)
+{
+ LOG_DEBUG("hl_transport_select");
+
+ int retval;
+
+ /* NOTE: interface init must already have been done.
+ * That works with only C code ... no Tcl glue required.
+ */
+
+ retval = hl_transport_register_commands(ctx);
+
+ if (retval != ERROR_OK)
+ return retval;
+
+ return ERROR_OK;
+}
+
+static struct transport hl_swd_transport = {
+ .name = "stlink_swd",
+ .select = hl_transport_select,
+ .init = hl_transport_init,
+};
+
+static struct transport hl_jtag_transport = {
+ .name = "stlink_jtag",
+ .select = hl_transport_select,
+ .init = hl_transport_init,
+};
+
+static struct transport hl_swim_transport = {
+ .name = "stlink_swim",
+ .select = hl_transport_select,
+ .init = hl_transport_init,
+};
+
+const char *hl_transports[] = { "stlink_swd", "stlink_jtag", "stlink_swim", NULL };
+
+static void hl_constructor(void) __attribute__ ((constructor));
+static void hl_constructor(void)
+{
+ transport_register(&hl_swd_transport);
+ transport_register(&hl_jtag_transport);
+ transport_register(&hl_swim_transport);
+}
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2011 by Mathias Kuester *
+ * Mathias Kuester <kesmtp@freenet.de> *
+ * *
+ * Copyright (C) 2012 by Spencer Oliver *
+ * spen@spen-soft.co.uk *
+ * *
+ * 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., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#ifndef _HL_TRANSPORT
+#define _HL_TRANSPORT
+
+enum hl_transports {
+ HL_TRANSPORT_UNKNOWN = 0,
+ HL_TRANSPORT_SWD,
+ HL_TRANSPORT_JTAG,
+ HL_TRANSPORT_SWIM
+};
+
+#endif /* _HL_TRANSPORT */
#if BUILD_REMOTE_BITBANG == 1
extern struct jtag_interface remote_bitbang_interface;
#endif
-#if BUILD_STLINK == 1
-extern struct jtag_interface stlink_interface;
+#if BUILD_HLADAPTER == 1
+extern struct jtag_interface hl_interface;
#endif
#if BUILD_OSBDM == 1
extern struct jtag_interface osbdm_interface;
#if BUILD_REMOTE_BITBANG == 1
&remote_bitbang_interface,
#endif
-#if BUILD_STLINK == 1
- &stlink_interface,
+#if BUILD_HLADAPTER == 1
+ &hl_interface,
#endif
#if BUILD_OSBDM == 1
&osbdm_interface,
+++ /dev/null
-include $(top_srcdir)/common.mk
-
-noinst_LTLIBRARIES = libocdstlink.la
-
-libocdstlink_la_SOURCES = \
- $(STLINKFILES)
-
-STLINKFILES =
-
-if STLINK
-STLINKFILES += stlink_transport.c
-STLINKFILES += stlink_tcl.c
-STLINKFILES += stlink_interface.c
-STLINKFILES += stlink_layout.c
-endif
-
-noinst_HEADERS = \
- stlink_interface.h \
- stlink_layout.h \
- stlink_tcl.h \
- stlink_transport.h
-
-MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+++ /dev/null
-/***************************************************************************
- * Copyright (C) 2011 by Mathias Kuester *
- * Mathias Kuester <kesmtp@freenet.de> *
- * *
- * 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-/* project specific includes */
-#include <jtag/interface.h>
-#include <transport/transport.h>
-#include <helper/time_support.h>
-
-#include <jtag/stlink/stlink_tcl.h>
-#include <jtag/stlink/stlink_layout.h>
-#include <jtag/stlink/stlink_transport.h>
-#include <jtag/stlink/stlink_interface.h>
-
-#include <target/target.h>
-
-static struct stlink_interface_s stlink_if = { {0, 0, 0, 0, 0, 0}, 0, 0 };
-
-int stlink_interface_open(enum stlink_transports tr)
-{
- LOG_DEBUG("stlink_interface_open");
-
- /* set transport mode */
- stlink_if.param.transport = tr;
-
- int result = stlink_if.layout->open(&stlink_if);
- if (result != ERROR_OK)
- return result;
-
- return stlink_interface_init_reset();
-}
-
-int stlink_interface_init_target(struct target *t)
-{
- int res;
-
- LOG_DEBUG("stlink_interface_init_target");
-
- /* this is the interface for the current target and we
- * can setup the private pointer in the tap structure
- * if the interface match the tap idcode
- */
- res = stlink_if.layout->api->idcode(stlink_if.fd, &t->tap->idcode);
-
- if (res != ERROR_OK)
- return res;
-
- unsigned ii, limit = t->tap->expected_ids_cnt;
- int found = 0;
-
- for (ii = 0; ii < limit; ii++) {
- uint32_t expected = t->tap->expected_ids[ii];
-
- /* treat "-expected-id 0" as a "don't-warn" wildcard */
- if (!expected || (t->tap->idcode == expected)) {
- found = 1;
- break;
- }
- }
-
- if (found == 0) {
- LOG_ERROR("stlink_interface_init_target: target not found: idcode: 0x%08x",
- t->tap->idcode);
- return ERROR_FAIL;
- }
-
- t->tap->priv = &stlink_if;
- t->tap->hasidcode = 1;
-
- return ERROR_OK;
-}
-
-static int stlink_interface_init(void)
-{
- LOG_DEBUG("stlink_interface_init");
-
- /* here we can initialize the layout */
- return stlink_layout_init(&stlink_if);
-}
-
-static int stlink_interface_quit(void)
-{
- LOG_DEBUG("stlink_interface_quit");
-
- return ERROR_OK;
-}
-
-static int stlink_interface_speed(int speed)
-{
- LOG_DEBUG("stlink_interface_speed: ignore speed %d", speed);
-
- return ERROR_OK;
-}
-
-static int stlink_speed_div(int speed, int *khz)
-{
- *khz = speed;
- return ERROR_OK;
-}
-
-static int stlink_khz(int khz, int *jtag_speed)
-{
- *jtag_speed = khz;
- return ERROR_OK;
-}
-
-static int stlink_interface_execute_queue(void)
-{
- LOG_DEBUG("stlink_interface_execute_queue: ignored");
-
- return ERROR_OK;
-}
-
-int stlink_interface_init_reset(void)
-{
- enum reset_types jtag_reset_config = jtag_get_reset_config();
-
- if (jtag_reset_config & RESET_CNCT_UNDER_SRST) {
- if (jtag_reset_config & RESET_SRST_NO_GATING) {
- jtag_add_reset(0, 1);
- stlink_if.layout->api->assert_srst(stlink_if.fd, 0);
- } else
- LOG_WARNING("\'srst_nogate\' reset_config option is required");
- }
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(stlink_interface_handle_device_desc_command)
-{
- LOG_DEBUG("stlink_interface_handle_device_desc_command");
-
- if (CMD_ARGC == 1) {
- stlink_if.param.device_desc = strdup(CMD_ARGV[0]);
- } else {
- LOG_ERROR
- ("expected exactly one argument to stlink_device_desc <description>");
- }
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(stlink_interface_handle_serial_command)
-{
- LOG_DEBUG("stlink_interface_handle_serial_command");
-
- if (CMD_ARGC == 1) {
- stlink_if.param.serial = strdup(CMD_ARGV[0]);
- } else {
- LOG_ERROR
- ("expected exactly one argument to stlink_serial <serial-number>");
- }
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(stlink_interface_handle_layout_command)
-{
- LOG_DEBUG("stlink_interface_handle_layout_command");
-
- if (CMD_ARGC != 1) {
- LOG_ERROR("Need exactly one argument to stlink_layout");
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-
- if (stlink_if.layout) {
- LOG_ERROR("already specified stlink_layout %s",
- stlink_if.layout->name);
- return (strcmp(stlink_if.layout->name, CMD_ARGV[0]) != 0)
- ? ERROR_FAIL : ERROR_OK;
- }
-
- for (const struct stlink_layout *l = stlink_layout_get_list(); l->name;
- l++) {
- if (strcmp(l->name, CMD_ARGV[0]) == 0) {
- stlink_if.layout = l;
- return ERROR_OK;
- }
- }
-
- LOG_ERROR("No STLINK layout '%s' found", CMD_ARGV[0]);
- return ERROR_FAIL;
-}
-
-COMMAND_HANDLER(stlink_interface_handle_vid_pid_command)
-{
- LOG_DEBUG("stlink_interface_handle_vid_pid_command");
-
- if (CMD_ARGC != 2) {
- LOG_WARNING
- ("ignoring extra IDs in stlink_vid_pid (maximum is 1 pair)");
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-
- COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], stlink_if.param.vid);
- COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], stlink_if.param.pid);
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(stlink_interface_handle_api_command)
-{
- if (CMD_ARGC != 1)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- unsigned new_api;
- COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], new_api);
- if ((new_api == 0) || (new_api > 2))
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- stlink_if.param.api = new_api;
-
- return ERROR_OK;
-}
-
-static const struct command_registration stlink_interface_command_handlers[] = {
- {
- .name = "stlink_device_desc",
- .handler = &stlink_interface_handle_device_desc_command,
- .mode = COMMAND_CONFIG,
- .help = "set the stlink device description of the STLINK device",
- .usage = "description_string",
- },
- {
- .name = "stlink_serial",
- .handler = &stlink_interface_handle_serial_command,
- .mode = COMMAND_CONFIG,
- .help = "set the serial number of the STLINK device",
- .usage = "serial_string",
- },
- {
- .name = "stlink_layout",
- .handler = &stlink_interface_handle_layout_command,
- .mode = COMMAND_CONFIG,
- .help = "set the layout of the STLINK to usb or sg",
- .usage = "layout_name",
- },
- {
- .name = "stlink_vid_pid",
- .handler = &stlink_interface_handle_vid_pid_command,
- .mode = COMMAND_CONFIG,
- .help = "the vendor and product ID of the STLINK device",
- .usage = "(vid pid)* ",
- },
- {
- .name = "stlink_api",
- .handler = &stlink_interface_handle_api_command,
- .mode = COMMAND_CONFIG,
- .help = "set the desired stlink api level",
- .usage = "api version 1 or 2",
- },
- COMMAND_REGISTRATION_DONE
-};
-
-struct jtag_interface stlink_interface = {
- .name = "stlink",
- .supported = 0,
- .commands = stlink_interface_command_handlers,
- .transports = stlink_transports,
- .init = stlink_interface_init,
- .quit = stlink_interface_quit,
- .speed = stlink_interface_speed,
- .speed_div = stlink_speed_div,
- .khz = stlink_khz,
- .execute_queue = stlink_interface_execute_queue,
-};
+++ /dev/null
-/***************************************************************************
- * Copyright (C) 2011 by Mathias Kuester *
- * Mathias Kuester <kesmtp@freenet.de> *
- * *
- * 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-#ifndef _STLINK_INTERFACE_
-#define _STLINK_INTERFACE_
-
-/** */
-struct target;
-/** */
-enum e_stlink_transports;
-/** */
-extern const char *stlink_transports[];
-
-struct stlink_interface_param_s {
- /** */
- char *device_desc;
- /** */
- char *serial;
- /** */
- uint16_t vid;
- /** */
- uint16_t pid;
- /** */
- unsigned api;
- /** */
- enum stlink_transports transport;
-};
-
-struct stlink_interface_s {
- /** */
- struct stlink_interface_param_s param;
- /** */
- const struct stlink_layout *layout;
- /** */
- void *fd;
-};
-
-/** */
-int stlink_interface_open(enum stlink_transports tr);
-/** */
-int stlink_interface_init_target(struct target *t);
-int stlink_interface_init_reset(void);
-
-#endif
+++ /dev/null
-/***************************************************************************
- * Copyright (C) 2011 by Mathias Kuester *
- * Mathias Kuester <kesmtp@freenet.de> *
- * *
- * 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-/* project specific includes */
-#include <jtag/interface.h>
-#include <transport/transport.h>
-#include <helper/time_support.h>
-
-#include <jtag/stlink/stlink_layout.h>
-#include <jtag/stlink/stlink_tcl.h>
-#include <jtag/stlink/stlink_transport.h>
-#include <jtag/stlink/stlink_interface.h>
-
-static int stlink_layout_open(struct stlink_interface_s *stlink_if)
-{
- int res;
-
- LOG_DEBUG("stlink_layout_open");
-
- stlink_if->fd = NULL;
-
- res = stlink_if->layout->api->open(&stlink_if->param, &stlink_if->fd);
-
- if (res != ERROR_OK) {
- LOG_DEBUG("failed");
- return res;
- }
-
- return ERROR_OK;
-}
-
-static int stlink_layout_close(struct stlink_interface_s *stlink_if)
-{
- return ERROR_OK;
-}
-
-static const struct stlink_layout stlink_layouts[] = {
- {
- .name = "stlink",
- .open = stlink_layout_open,
- .close = stlink_layout_close,
- .api = &stlink_usb_layout_api,
- },
- {.name = NULL, /* END OF TABLE */ },
-};
-
-/** */
-const struct stlink_layout *stlink_layout_get_list(void)
-{
- return stlink_layouts;
-}
-
-int stlink_layout_init(struct stlink_interface_s *stlink_if)
-{
- LOG_DEBUG("stlink_layout_init");
-
- if (stlink_if->layout == NULL) {
- LOG_ERROR("no layout specified");
- return ERROR_FAIL;
- }
- return ERROR_OK;
-}
+++ /dev/null
-/***************************************************************************
- * Copyright (C) 2011 by Mathias Kuester *
- * Mathias Kuester <kesmtp@freenet.de> *
- * *
- * 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-#ifndef _STLINK_LAYOUT_H_
-#define _STLINK_LAYOUT_H_
-
-/** */
-struct stlink_interface_s;
-struct stlink_interface_param_s;
-
-/** */
-extern struct stlink_layout_api_s stlink_usb_layout_api;
-
-/** */
-struct stlink_layout_api_s {
- /** */
- int (*open) (struct stlink_interface_param_s *param, void **fd);
- /** */
- int (*close) (void *fd);
- /** */
- int (*reset) (void *fd);
- /** */
- int (*assert_srst) (void *fd, int srst);
- /** */
- int (*run) (void *fd);
- /** */
- int (*halt) (void *fd);
- /** */
- int (*step) (void *fd);
- /** */
- int (*read_regs) (void *fd);
- /** */
- int (*read_reg) (void *fd, int num, uint32_t *val);
- /** */
- int (*write_reg) (void *fd, int num, uint32_t val);
- /** */
- int (*read_mem8) (void *handle, uint32_t addr, uint16_t len,
- uint8_t *buffer);
- /** */
- int (*write_mem8) (void *handle, uint32_t addr, uint16_t len,
- const uint8_t *buffer);
- /** */
- int (*read_mem32) (void *handle, uint32_t addr, uint16_t len,
- uint8_t *buffer);
- /** */
- int (*write_mem32) (void *handle, uint32_t addr, uint16_t len,
- const uint8_t *buffer);
- /** */
- int (*write_debug_reg) (void *handle, uint32_t addr, uint32_t val);
- /** */
- int (*idcode) (void *fd, uint32_t *idcode);
- /** */
- enum target_state (*state) (void *fd);
-};
-
-/** */
-struct stlink_layout {
- /** */
- char *name;
- /** */
- int (*open) (struct stlink_interface_s *stlink_if);
- /** */
- int (*close) (struct stlink_interface_s *stlink_if);
- /** */
- struct stlink_layout_api_s *api;
-};
-
-/** */
-const struct stlink_layout *stlink_layout_get_list(void);
-/** */
-int stlink_layout_init(struct stlink_interface_s *stlink_if);
-
-#endif
+++ /dev/null
-/***************************************************************************
- * Copyright (C) 2011 by Mathias Kuester *
- * Mathias Kuester <kesmtp@freenet.de> *
- * *
- * 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-/* project specific includes */
-#include <jtag/interface.h>
-#include <transport/transport.h>
-#include <helper/time_support.h>
-
-static int jim_newtap_expected_id(Jim_Nvp *n, Jim_GetOptInfo *goi,
- struct jtag_tap *pTap)
-{
- jim_wide w;
- int e = Jim_GetOpt_Wide(goi, &w);
- if (e != JIM_OK) {
- Jim_SetResultFormatted(goi->interp, "option: %s bad parameter",
- n->name);
- return e;
- }
-
- unsigned expected_len = sizeof(uint32_t) * pTap->expected_ids_cnt;
- uint32_t *new_expected_ids = malloc(expected_len + sizeof(uint32_t));
- if (new_expected_ids == NULL) {
- Jim_SetResultFormatted(goi->interp, "no memory");
- return JIM_ERR;
- }
-
- memcpy(new_expected_ids, pTap->expected_ids, expected_len);
-
- new_expected_ids[pTap->expected_ids_cnt] = w;
-
- free(pTap->expected_ids);
- pTap->expected_ids = new_expected_ids;
- pTap->expected_ids_cnt++;
-
- return JIM_OK;
-}
-
-#define NTAP_OPT_EXPECTED_ID 0
-
-static int jim_stlink_newtap_cmd(Jim_GetOptInfo *goi)
-{
- struct jtag_tap *pTap;
- int x;
- int e;
- Jim_Nvp *n;
- char *cp;
- const Jim_Nvp opts[] = {
- {.name = "-expected-id", .value = NTAP_OPT_EXPECTED_ID},
- {.name = NULL, .value = -1},
- };
-
- pTap = calloc(1, sizeof(struct jtag_tap));
- if (!pTap) {
- Jim_SetResultFormatted(goi->interp, "no memory");
- return JIM_ERR;
- }
-
- /*
- * we expect CHIP + TAP + OPTIONS
- * */
- if (goi->argc < 3) {
- Jim_SetResultFormatted(goi->interp,
- "Missing CHIP TAP OPTIONS ....");
- free(pTap);
- return JIM_ERR;
- }
- Jim_GetOpt_String(goi, &cp, NULL);
- pTap->chip = strdup(cp);
-
- Jim_GetOpt_String(goi, &cp, NULL);
- pTap->tapname = strdup(cp);
-
- /* name + dot + name + null */
- x = strlen(pTap->chip) + 1 + strlen(pTap->tapname) + 1;
- cp = malloc(x);
- sprintf(cp, "%s.%s", pTap->chip, pTap->tapname);
- pTap->dotted_name = cp;
-
- LOG_DEBUG("Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params",
- pTap->chip, pTap->tapname, pTap->dotted_name, goi->argc);
-
- while (goi->argc) {
- e = Jim_GetOpt_Nvp(goi, opts, &n);
- if (e != JIM_OK) {
- Jim_GetOpt_NvpUnknown(goi, opts, 0);
- free((void *)pTap->dotted_name);
- free(pTap);
- return e;
- }
- LOG_DEBUG("Processing option: %s", n->name);
- switch (n->value) {
- case NTAP_OPT_EXPECTED_ID:
- e = jim_newtap_expected_id(n, goi, pTap);
- if (JIM_OK != e) {
- free((void *)pTap->dotted_name);
- free(pTap);
- return e;
- }
- break;
- } /* switch (n->value) */
- } /* while (goi->argc) */
-
- /* default is enabled-after-reset */
- pTap->enabled = !pTap->disabled_after_reset;
-
- jtag_tap_init(pTap);
- return JIM_OK;
-}
-
-int jim_stlink_newtap(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
-{
- Jim_GetOptInfo goi;
- Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
- return jim_stlink_newtap_cmd(&goi);
-}
+++ /dev/null
-/***************************************************************************
- * Copyright (C) 2011 by Mathias Kuester *
- * Mathias Kuester <kesmtp@freenet.de> *
- * *
- * 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-#ifndef _STLINK_TCL_
-#define _STLINK_TCL_
-
-/** */
-int jim_stlink_newtap(Jim_Interp *interp, int argc, Jim_Obj * const *argv);
-
-#endif
+++ /dev/null
-/***************************************************************************
- * Copyright (C) 2011 by Mathias Kuester *
- * Mathias Kuester <kesmtp@freenet.de> *
- * *
- * 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-/* project specific includes */
-#include <jtag/interface.h>
-#include <jtag/tcl.h>
-#include <transport/transport.h>
-#include <helper/time_support.h>
-#include <target/target.h>
-#include <jtag/stlink/stlink_tcl.h>
-#include <jtag/stlink/stlink_transport.h>
-#include <jtag/stlink/stlink_interface.h>
-
-COMMAND_HANDLER(stlink_transport_jtag_command)
-{
- LOG_DEBUG("stlink_transport_jtag_command");
-
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(stlink_transport_reset_command)
-{
- return stlink_interface_init_reset();
-}
-
-static const struct command_registration
-stlink_transport_stlink_subcommand_handlers[] = {
- {
- .name = "newtap",
- .mode = COMMAND_CONFIG,
- .jim_handler = jim_stlink_newtap,
- .help = "Create a new TAP instance named basename.tap_type, "
- "and appends it to the scan chain.",
- .usage = "basename tap_type '-irlen' count "
- "['-expected_id' number] ",
- },
-
- COMMAND_REGISTRATION_DONE
-};
-
-static const struct command_registration
-stlink_transport_jtag_subcommand_handlers[] = {
- {
- .name = "init",
- .mode = COMMAND_ANY,
- .handler = stlink_transport_jtag_command,
- .usage = ""
- },
- {
- .name = "arp_init",
- .mode = COMMAND_ANY,
- .handler = stlink_transport_jtag_command,
- .usage = ""
- },
- {
- .name = "arp_init-reset",
- .mode = COMMAND_ANY,
- .handler = stlink_transport_reset_command,
- .usage = ""
- },
- {
- .name = "tapisenabled",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_jtag_tap_enabler,
- },
- {
- .name = "tapenable",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_jtag_tap_enabler,
- },
- {
- .name = "tapdisable",
- .mode = COMMAND_EXEC,
- .handler = stlink_transport_jtag_command,
- .usage = "",
- },
- {
- .name = "configure",
- .mode = COMMAND_EXEC,
- .handler = stlink_transport_jtag_command,
- .usage = "",
- },
- {
- .name = "cget",
- .mode = COMMAND_EXEC,
- .jim_handler = jim_jtag_configure,
- },
- {
- .name = "names",
- .mode = COMMAND_ANY,
- .handler = stlink_transport_jtag_command,
- .usage = "",
- },
-
- COMMAND_REGISTRATION_DONE
-};
-
-static const struct command_registration stlink_transport_command_handlers[] = {
-
- {
- .name = "stlink",
- .mode = COMMAND_ANY,
- .help = "perform stlink actions",
- .usage = "",
- .chain = stlink_transport_stlink_subcommand_handlers,
- },
- {
- .name = "jtag",
- .mode = COMMAND_ANY,
- .usage = "",
- .chain = stlink_transport_jtag_subcommand_handlers,
- },
- COMMAND_REGISTRATION_DONE
-};
-
-static int stlink_transport_register_commands(struct command_context *cmd_ctx)
-{
- return register_commands(cmd_ctx, NULL,
- stlink_transport_command_handlers);
-}
-
-static int stlink_transport_init(struct command_context *cmd_ctx)
-{
- LOG_DEBUG("stlink_transport_init");
- struct target *t = get_current_target(cmd_ctx);
- struct transport *transport;
- enum stlink_transports tr;
-
- if (!t) {
- LOG_ERROR("no current target");
- return ERROR_FAIL;
- }
-
- transport = get_current_transport();
-
- if (!transport) {
- LOG_ERROR("no transport selected");
- return ERROR_FAIL;
- }
-
- LOG_DEBUG("current transport %s", transport->name);
-
- /* get selected transport as enum */
- tr = STLINK_TRANSPORT_UNKNOWN;
-
- if (strcmp(transport->name, "stlink_swd") == 0)
- tr = STLINK_TRANSPORT_SWD;
- else if (strcmp(transport->name, "stlink_jtag") == 0)
- tr = STLINK_TRANSPORT_JTAG;
- else if (strcmp(transport->name, "stlink_swim") == 0)
- tr = STLINK_TRANSPORT_SWIM;
-
- int retval = stlink_interface_open(tr);
-
- if (retval != ERROR_OK)
- return retval;
-
- return stlink_interface_init_target(t);
-}
-
-static int stlink_transport_select(struct command_context *ctx)
-{
- LOG_DEBUG("stlink_transport_select");
-
- int retval;
-
- /* NOTE: interface init must already have been done.
- * That works with only C code ... no Tcl glue required.
- */
-
- retval = stlink_transport_register_commands(ctx);
-
- if (retval != ERROR_OK)
- return retval;
-
- return ERROR_OK;
-}
-
-static struct transport stlink_swd_transport = {
- .name = "stlink_swd",
- .select = stlink_transport_select,
- .init = stlink_transport_init,
-};
-
-static struct transport stlink_jtag_transport = {
- .name = "stlink_jtag",
- .select = stlink_transport_select,
- .init = stlink_transport_init,
-};
-
-static struct transport stlink_swim_transport = {
- .name = "stlink_swim",
- .select = stlink_transport_select,
- .init = stlink_transport_init,
-};
-
-const char *stlink_transports[] = { "stlink_swd", "stlink_jtag", "stlink_swim", NULL };
-
-static void stlink_constructor(void) __attribute__ ((constructor));
-static void stlink_constructor(void)
-{
- transport_register(&stlink_swd_transport);
- transport_register(&stlink_jtag_transport);
- transport_register(&stlink_swim_transport);
-}
-
-bool transport_is_stlink(void)
-{
- return get_current_transport() == &stlink_swd_transport;
-}
+++ /dev/null
-/***************************************************************************
- * Copyright (C) 2011 by Mathias Kuester *
- * Mathias Kuester <kesmtp@freenet.de> *
- * *
- * 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-#ifndef _STLINK_TRANSPORT_
-#define _STLINK_TRANSPORT_
-
-enum stlink_transports {
- STLINK_TRANSPORT_UNKNOWN = 0,
- STLINK_TRANSPORT_SWD,
- STLINK_TRANSPORT_JTAG,
- STLINK_TRANSPORT_SWIM
-};
-
-#endif
dsp563xx.c \
dsp563xx_once.c \
dsp5680xx.c \
- stm32_stlink.c
+ hla_target.c
TARGET_CORE_SRC = \
algorithm.c \
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2011 by Mathias Kuester *
+ * Mathias Kuester <kesmtp@freenet.de> *
+ * *
+ * Copyright (C) 2011 by Spencer Oliver *
+ * spen@spen-soft.co.uk *
+ * *
+ * 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., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "jtag/jtag.h"
+#include "jtag/hla/hla_transport.h"
+#include "jtag/hla/hla_interface.h"
+#include "jtag/hla/hla_layout.h"
+#include "register.h"
+#include "algorithm.h"
+#include "target.h"
+#include "breakpoints.h"
+#include "target_type.h"
+#include "armv7m.h"
+#include "cortex_m.h"
+#include "arm_semihosting.h"
+
+#define ARMV7M_SCS_DCRSR 0xe000edf4
+#define ARMV7M_SCS_DCRDR 0xe000edf8
+
+static inline struct hl_interface_s *target_to_adapter(struct target *target)
+{
+ return target->tap->priv;
+}
+
+static int adapter_load_core_reg_u32(struct target *target,
+ enum armv7m_regtype type,
+ uint32_t num, uint32_t *value)
+{
+ int retval;
+ struct hl_interface_s *adapter = target_to_adapter(target);
+
+ LOG_DEBUG("%s", __func__);
+
+ /* NOTE: we "know" here that the register identifiers used
+ * in the v7m header match the Cortex-M3 Debug Core Register
+ * Selector values for R0..R15, xPSR, MSP, and PSP.
+ */
+ switch (num) {
+ case 0 ... 18:
+ /* read a normal core register */
+ retval = adapter->layout->api->read_reg(adapter->fd, num, value);
+
+ if (retval != ERROR_OK) {
+ LOG_ERROR("JTAG failure %i", retval);
+ return ERROR_JTAG_DEVICE_ERROR;
+ }
+ LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value);
+ break;
+
+ case ARMV7M_FPSID:
+ case ARMV7M_FPEXC:
+ *value = 0;
+ break;
+
+ case ARMV7M_FPSCR:
+ /* Floating-point Status and Registers */
+ retval = target_write_u32(target, ARMV7M_SCS_DCRSR, 33);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = target_read_u32(target, ARMV7M_SCS_DCRDR, value);
+ if (retval != ERROR_OK)
+ return retval;
+ LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value);
+ break;
+
+ case ARMV7M_S0 ... ARMV7M_S31:
+ /* Floating-point Status and Registers */
+ retval = target_write_u32(target, ARMV7M_SCS_DCRSR, num-ARMV7M_S0+64);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = target_read_u32(target, ARMV7M_SCS_DCRDR, value);
+ if (retval != ERROR_OK)
+ return retval;
+ LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value);
+ break;
+
+ case ARMV7M_D0 ... ARMV7M_D15:
+ value = 0;
+ break;
+
+ case ARMV7M_PRIMASK:
+ case ARMV7M_BASEPRI:
+ case ARMV7M_FAULTMASK:
+ case ARMV7M_CONTROL:
+ /* Cortex-M3 packages these four registers as bitfields
+ * in one Debug Core register. So say r0 and r2 docs;
+ * it was removed from r1 docs, but still works.
+ */
+ retval = adapter->layout->api->read_reg(adapter->fd, 20, value);
+ if (retval != ERROR_OK)
+ return retval;
+
+ switch (num) {
+ case ARMV7M_PRIMASK:
+ *value = buf_get_u32((uint8_t *) value, 0, 1);
+ break;
+
+ case ARMV7M_BASEPRI:
+ *value = buf_get_u32((uint8_t *) value, 8, 8);
+ break;
+
+ case ARMV7M_FAULTMASK:
+ *value = buf_get_u32((uint8_t *) value, 16, 1);
+ break;
+
+ case ARMV7M_CONTROL:
+ *value = buf_get_u32((uint8_t *) value, 24, 2);
+ break;
+ }
+
+ LOG_DEBUG("load from special reg %i value 0x%" PRIx32 "",
+ (int)num, *value);
+ break;
+
+ default:
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ return ERROR_OK;
+}
+
+static int adapter_store_core_reg_u32(struct target *target,
+ enum armv7m_regtype type,
+ uint32_t num, uint32_t value)
+{
+ int retval;
+ uint32_t reg;
+ struct armv7m_common *armv7m = target_to_armv7m(target);
+ struct hl_interface_s *adapter = target_to_adapter(target);
+
+ LOG_DEBUG("%s", __func__);
+
+#ifdef ARMV7_GDB_HACKS
+ /* If the LR register is being modified, make sure it will put us
+ * in "thumb" mode, or an INVSTATE exception will occur. This is a
+ * hack to deal with the fact that gdb will sometimes "forge"
+ * return addresses, and doesn't set the LSB correctly (i.e., when
+ * printing expressions containing function calls, it sets LR = 0.)
+ * Valid exception return codes have bit 0 set too.
+ */
+ if (num == ARMV7M_R14)
+ value |= 0x01;
+#endif
+
+ /* NOTE: we "know" here that the register identifiers used
+ * in the v7m header match the Cortex-M3 Debug Core Register
+ * Selector values for R0..R15, xPSR, MSP, and PSP.
+ */
+ switch (num) {
+ case 0 ... 18:
+ retval = adapter->layout->api->write_reg(adapter->fd, num, value);
+
+ if (retval != ERROR_OK) {
+ struct reg *r;
+
+ LOG_ERROR("JTAG failure");
+ r = armv7m->core_cache->reg_list + num;
+ r->dirty = r->valid;
+ return ERROR_JTAG_DEVICE_ERROR;
+ }
+ LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
+ break;
+
+ case ARMV7M_FPSID:
+ case ARMV7M_FPEXC:
+ break;
+
+ case ARMV7M_FPSCR:
+ /* Floating-point Status and Registers */
+ retval = target_write_u32(target, ARMV7M_SCS_DCRDR, value);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = target_write_u32(target, ARMV7M_SCS_DCRSR, 33 | (1<<16));
+ if (retval != ERROR_OK)
+ return retval;
+ LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
+ break;
+
+ case ARMV7M_S0 ... ARMV7M_S31:
+ /* Floating-point Status and Registers */
+ retval = target_write_u32(target, ARMV7M_SCS_DCRDR, value);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = target_write_u32(target, ARMV7M_SCS_DCRSR, (num-ARMV7M_S0+64) | (1<<16));
+ if (retval != ERROR_OK)
+ return retval;
+ LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
+ break;
+
+ case ARMV7M_D0 ... ARMV7M_D15:
+ break;
+
+ case ARMV7M_PRIMASK:
+ case ARMV7M_BASEPRI:
+ case ARMV7M_FAULTMASK:
+ case ARMV7M_CONTROL:
+ /* Cortex-M3 packages these four registers as bitfields
+ * in one Debug Core register. So say r0 and r2 docs;
+ * it was removed from r1 docs, but still works.
+ */
+
+ adapter->layout->api->read_reg(adapter->fd, 20, ®);
+
+ switch (num) {
+ case ARMV7M_PRIMASK:
+ buf_set_u32((uint8_t *) ®, 0, 1, value);
+ break;
+
+ case ARMV7M_BASEPRI:
+ buf_set_u32((uint8_t *) ®, 8, 8, value);
+ break;
+
+ case ARMV7M_FAULTMASK:
+ buf_set_u32((uint8_t *) ®, 16, 1, value);
+ break;
+
+ case ARMV7M_CONTROL:
+ buf_set_u32((uint8_t *) ®, 24, 2, value);
+ break;
+ }
+
+ adapter->layout->api->write_reg(adapter->fd, 20, reg);
+
+ LOG_DEBUG("write special reg %i value 0x%" PRIx32 " ", (int)num, value);
+ break;
+
+ default:
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+
+ return ERROR_OK;
+}
+
+static int adapter_examine_debug_reason(struct target *target)
+{
+ if ((target->debug_reason != DBG_REASON_DBGRQ)
+ && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
+ target->debug_reason = DBG_REASON_BREAKPOINT;
+ }
+
+ return ERROR_OK;
+}
+
+static int adapter_init_arch_info(struct target *target,
+ struct cortex_m3_common *cortex_m3,
+ struct jtag_tap *tap)
+{
+ struct armv7m_common *armv7m;
+
+ LOG_DEBUG("%s", __func__);
+
+ armv7m = &cortex_m3->armv7m;
+ armv7m_init_arch_info(target, armv7m);
+
+ armv7m->load_core_reg_u32 = adapter_load_core_reg_u32;
+ armv7m->store_core_reg_u32 = adapter_store_core_reg_u32;
+
+ armv7m->examine_debug_reason = adapter_examine_debug_reason;
+ armv7m->stlink = true;
+
+ return ERROR_OK;
+}
+
+static int adapter_init_target(struct command_context *cmd_ctx,
+ struct target *target)
+{
+ LOG_DEBUG("%s", __func__);
+
+ armv7m_build_reg_cache(target);
+
+ return ERROR_OK;
+}
+
+static int adapter_target_create(struct target *target,
+ Jim_Interp *interp)
+{
+ LOG_DEBUG("%s", __func__);
+
+ struct cortex_m3_common *cortex_m3 = calloc(1, sizeof(struct cortex_m3_common));
+
+ if (!cortex_m3)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ adapter_init_arch_info(target, cortex_m3, target->tap);
+
+ return ERROR_OK;
+}
+
+static int adapter_load_context(struct target *target)
+{
+ struct armv7m_common *armv7m = target_to_armv7m(target);
+ int num_regs = armv7m->core_cache->num_regs;
+
+ for (int i = 0; i < num_regs; i++) {
+ if (!armv7m->core_cache->reg_list[i].valid)
+ armv7m->read_core_reg(target, i);
+ }
+
+ return ERROR_OK;
+}
+
+static int adapter_debug_entry(struct target *target)
+{
+ struct hl_interface_s *adapter = target_to_adapter(target);
+ struct armv7m_common *armv7m = target_to_armv7m(target);
+ struct arm *arm = &armv7m->arm;
+ struct reg *r;
+ uint32_t xPSR;
+ int retval;
+
+ retval = armv7m->examine_debug_reason(target);
+ if (retval != ERROR_OK)
+ return retval;
+
+ adapter_load_context(target);
+
+ /* make sure we clear the vector catch bit */
+ adapter->layout->api->write_debug_reg(adapter->fd, DCB_DEMCR, 0);
+
+ r = armv7m->core_cache->reg_list + ARMV7M_xPSR;
+ xPSR = buf_get_u32(r->value, 0, 32);
+
+ /* Are we in an exception handler */
+ if (xPSR & 0x1FF) {
+ armv7m->core_mode = ARMV7M_MODE_HANDLER;
+ armv7m->exception_number = (xPSR & 0x1FF);
+
+ arm->core_mode = ARM_MODE_HANDLER;
+ arm->map = armv7m_msp_reg_map;
+ } else {
+ unsigned control = buf_get_u32(armv7m->core_cache
+ ->reg_list[ARMV7M_CONTROL].value, 0, 2);
+
+ /* is this thread privileged? */
+ armv7m->core_mode = control & 1;
+ arm->core_mode = armv7m->core_mode
+ ? ARM_MODE_USER_THREAD
+ : ARM_MODE_THREAD;
+
+ /* which stack is it using? */
+ if (control & 2)
+ arm->map = armv7m_psp_reg_map;
+ else
+ arm->map = armv7m_msp_reg_map;
+
+ armv7m->exception_number = 0;
+ }
+
+ LOG_DEBUG("entered debug state in core mode: %s at PC 0x%08" PRIx32 ", target->state: %s",
+ armv7m_mode_strings[armv7m->core_mode],
+ *(uint32_t *)(arm->pc->value),
+ target_state_name(target));
+
+ return retval;
+}
+
+static int adapter_poll(struct target *target)
+{
+ enum target_state state;
+ struct hl_interface_s *adapter = target_to_adapter(target);
+ struct armv7m_common *armv7m = target_to_armv7m(target);
+
+ state = adapter->layout->api->state(adapter->fd);
+
+ if (state == TARGET_UNKNOWN) {
+ LOG_ERROR("jtag status contains invalid mode value - communication failure");
+ return ERROR_TARGET_FAILURE;
+ }
+
+ if (target->state == state)
+ return ERROR_OK;
+
+ if (state == TARGET_HALTED) {
+ target->state = state;
+
+ int retval = adapter_debug_entry(target);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if (arm_semihosting(target, &retval) != 0)
+ return retval;
+
+ target_call_event_callbacks(target, TARGET_EVENT_HALTED);
+ LOG_DEBUG("halted: PC: 0x%08x", buf_get_u32(armv7m->arm.pc->value, 0, 32));
+ }
+
+ return ERROR_OK;
+}
+
+static int adapter_assert_reset(struct target *target)
+{
+ int res = ERROR_OK;
+ struct hl_interface_s *adapter = target_to_adapter(target);
+ struct armv7m_common *armv7m = target_to_armv7m(target);
+ bool use_srst_fallback = true;
+
+ LOG_DEBUG("%s", __func__);
+
+ enum reset_types jtag_reset_config = jtag_get_reset_config();
+
+ bool srst_asserted = false;
+
+ if (jtag_reset_config & RESET_SRST_NO_GATING) {
+ jtag_add_reset(0, 1);
+ res = adapter->layout->api->assert_srst(adapter->fd, 0);
+ srst_asserted = true;
+ }
+
+ adapter->layout->api->write_debug_reg(adapter->fd, DCB_DHCSR, DBGKEY|C_DEBUGEN);
+
+ /* only set vector catch if halt is requested */
+ if (target->reset_halt)
+ adapter->layout->api->write_debug_reg(adapter->fd, DCB_DEMCR, VC_CORERESET);
+ else
+ adapter->layout->api->write_debug_reg(adapter->fd, DCB_DEMCR, 0);
+
+ if (jtag_reset_config & RESET_HAS_SRST) {
+ if (!srst_asserted) {
+ jtag_add_reset(0, 1);
+ res = adapter->layout->api->assert_srst(adapter->fd, 0);
+ }
+ if (res == ERROR_COMMAND_NOTFOUND)
+ LOG_ERROR("Hardware srst not supported, falling back to software reset");
+ else if (res == ERROR_OK) {
+ /* hardware srst supported */
+ use_srst_fallback = false;
+ }
+ }
+
+ if (use_srst_fallback) {
+ /* stlink v1 api does not support hardware srst, so we use a software reset fallback */
+ adapter->layout->api->write_debug_reg(adapter->fd, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_SYSRESETREQ);
+ }
+
+ res = adapter->layout->api->reset(adapter->fd);
+
+ if (res != ERROR_OK)
+ return res;
+
+ /* registers are now invalid */
+ register_cache_invalidate(armv7m->core_cache);
+
+ if (target->reset_halt) {
+ target->state = TARGET_RESET;
+ target->debug_reason = DBG_REASON_DBGRQ;
+ } else {
+ target->state = TARGET_HALTED;
+ }
+
+ return ERROR_OK;
+}
+
+static int adapter_deassert_reset(struct target *target)
+{
+ int res;
+ struct hl_interface_s *adapter = target_to_adapter(target);
+
+ enum reset_types jtag_reset_config = jtag_get_reset_config();
+
+ LOG_DEBUG("%s", __func__);
+
+ if (jtag_reset_config & RESET_HAS_SRST)
+ adapter->layout->api->assert_srst(adapter->fd, 1);
+
+ /* virtual deassert reset, we need it for the internal
+ * jtag state machine
+ */
+ jtag_add_reset(0, 0);
+
+ if (!target->reset_halt) {
+ res = target_resume(target, 1, 0, 0, 0);
+
+ if (res != ERROR_OK)
+ return res;
+ }
+
+ return ERROR_OK;
+}
+
+static int adapter_soft_reset_halt(struct target *target)
+{
+ LOG_DEBUG("%s", __func__);
+ return ERROR_OK;
+}
+
+static int adapter_halt(struct target *target)
+{
+ int res;
+ struct hl_interface_s *adapter = target_to_adapter(target);
+
+ LOG_DEBUG("%s", __func__);
+
+ if (target->state == TARGET_HALTED) {
+ LOG_DEBUG("target was already halted");
+ return ERROR_OK;
+ }
+
+ if (target->state == TARGET_UNKNOWN)
+ LOG_WARNING("target was in unknown state when halt was requested");
+
+ res = adapter->layout->api->halt(adapter->fd);
+
+ if (res != ERROR_OK)
+ return res;
+
+ target->debug_reason = DBG_REASON_DBGRQ;
+
+ return ERROR_OK;
+}
+
+static int adapter_resume(struct target *target, int current,
+ uint32_t address, int handle_breakpoints,
+ int debug_execution)
+{
+ int res;
+ struct hl_interface_s *adapter = target_to_adapter(target);
+ struct armv7m_common *armv7m = target_to_armv7m(target);
+ uint32_t resume_pc;
+ struct breakpoint *breakpoint = NULL;
+ struct reg *pc;
+
+ LOG_DEBUG("%s %d 0x%08x %d %d", __func__, current, address,
+ handle_breakpoints, debug_execution);
+
+ if (target->state != TARGET_HALTED) {
+ LOG_WARNING("target not halted");
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ pc = armv7m->arm.pc;
+ if (!current) {
+ buf_set_u32(pc->value, 0, 32, address);
+ pc->dirty = true;
+ pc->valid = true;
+ }
+
+ if (!breakpoint_find(target, buf_get_u32(pc->value, 0, 32))
+ && !debug_execution) {
+ armv7m_maybe_skip_bkpt_inst(target, NULL);
+ }
+
+ resume_pc = buf_get_u32(pc->value, 0, 32);
+
+ armv7m_restore_context(target);
+
+ /* registers are now invalid */
+ register_cache_invalidate(armv7m->core_cache);
+
+ /* the front-end may request us not to handle breakpoints */
+ if (handle_breakpoints) {
+ /* Single step past breakpoint at current address */
+ breakpoint = breakpoint_find(target, resume_pc);
+ if (breakpoint) {
+ LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (ID: %d)",
+ breakpoint->address,
+ breakpoint->unique_id);
+ cortex_m3_unset_breakpoint(target, breakpoint);
+
+ res = adapter->layout->api->step(adapter->fd);
+
+ if (res != ERROR_OK)
+ return res;
+
+ cortex_m3_set_breakpoint(target, breakpoint);
+ }
+ }
+
+ res = adapter->layout->api->run(adapter->fd);
+
+ if (res != ERROR_OK)
+ return res;
+
+ target->state = TARGET_RUNNING;
+ target->debug_reason = DBG_REASON_NOTHALTED;
+
+ target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
+
+ return ERROR_OK;
+}
+
+static int adapter_step(struct target *target, int current,
+ uint32_t address, int handle_breakpoints)
+{
+ int res;
+ struct hl_interface_s *adapter = target_to_adapter(target);
+ struct armv7m_common *armv7m = target_to_armv7m(target);
+ struct breakpoint *breakpoint = NULL;
+ struct reg *pc = armv7m->arm.pc;
+ bool bkpt_inst_found = false;
+
+ LOG_DEBUG("%s", __func__);
+
+ if (target->state != TARGET_HALTED) {
+ LOG_WARNING("target not halted");
+ return ERROR_TARGET_NOT_HALTED;
+ }
+
+ if (!current) {
+ buf_set_u32(pc->value, 0, 32, address);
+ pc->dirty = true;
+ pc->valid = true;
+ }
+
+ uint32_t pc_value = buf_get_u32(pc->value, 0, 32);
+
+ /* the front-end may request us not to handle breakpoints */
+ if (handle_breakpoints) {
+ breakpoint = breakpoint_find(target, pc_value);
+ if (breakpoint)
+ cortex_m3_unset_breakpoint(target, breakpoint);
+ }
+
+ armv7m_maybe_skip_bkpt_inst(target, &bkpt_inst_found);
+
+ target->debug_reason = DBG_REASON_SINGLESTEP;
+
+ armv7m_restore_context(target);
+
+ target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
+
+ res = adapter->layout->api->step(adapter->fd);
+
+ if (res != ERROR_OK)
+ return res;
+
+ /* registers are now invalid */
+ register_cache_invalidate(armv7m->core_cache);
+
+ if (breakpoint)
+ cortex_m3_set_breakpoint(target, breakpoint);
+
+ adapter_debug_entry(target);
+ target_call_event_callbacks(target, TARGET_EVENT_HALTED);
+
+ LOG_INFO("halted: PC: 0x%08x", buf_get_u32(armv7m->arm.pc->value, 0, 32));
+
+ return ERROR_OK;
+}
+
+static int adapter_read_memory(struct target *target, uint32_t address,
+ uint32_t size, uint32_t count,
+ uint8_t *buffer)
+{
+ int res;
+ uint32_t buffer_threshold = 128;
+ uint32_t addr_increment = 4;
+ uint32_t c;
+ struct hl_interface_s *adapter = target_to_adapter(target);
+
+ if (!count || !buffer)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ LOG_DEBUG("%s 0x%08x %d %d", __func__, address, size, count);
+
+ /* prepare byte count, buffer threshold
+ * and address increment for none 32bit access
+ */
+ if (size != 4) {
+ count *= size;
+ buffer_threshold = 64;
+ addr_increment = 1;
+ }
+
+ while (count) {
+ if (count > buffer_threshold)
+ c = buffer_threshold;
+ else
+ c = count;
+
+ if (size != 4)
+ res = adapter->layout->api->read_mem8(adapter->fd,
+ address, c, buffer);
+ else
+ res = adapter->layout->api->read_mem32(adapter->fd,
+ address, c, buffer);
+
+ if (res != ERROR_OK)
+ return res;
+
+ address += (c * addr_increment);
+ buffer += (c * addr_increment);
+ count -= c;
+ }
+
+ return ERROR_OK;
+}
+
+static int adapter_write_memory(struct target *target, uint32_t address,
+ uint32_t size, uint32_t count,
+ const uint8_t *buffer)
+{
+ int res;
+ uint32_t buffer_threshold = 128;
+ uint32_t addr_increment = 4;
+ uint32_t c;
+ struct hl_interface_s *adapter = target_to_adapter(target);
+
+ if (!count || !buffer)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ LOG_DEBUG("%s 0x%08x %d %d", __func__, address, size, count);
+
+ /* prepare byte count, buffer threshold
+ * and address increment for none 32bit access
+ */
+ if (size != 4) {
+ count *= size;
+ buffer_threshold = 64;
+ addr_increment = 1;
+ }
+
+ while (count) {
+ if (count > buffer_threshold)
+ c = buffer_threshold;
+ else
+ c = count;
+
+ if (size != 4)
+ res = adapter->layout->api->write_mem8(adapter->fd,
+ address, c, buffer);
+ else
+ res = adapter->layout->api->write_mem32(adapter->fd,
+ address, c, buffer);
+
+ if (res != ERROR_OK)
+ return res;
+
+ address += (c * addr_increment);
+ buffer += (c * addr_increment);
+ count -= c;
+ }
+
+ return ERROR_OK;
+}
+
+static int adapter_bulk_write_memory(struct target *target,
+ uint32_t address, uint32_t count,
+ const uint8_t *buffer)
+{
+ return adapter_write_memory(target, address, 4, count, buffer);
+}
+
+static const struct command_registration adapter_command_handlers[] = {
+ {
+ .chain = arm_command_handlers,
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
+struct target_type stm32_stlink_target = {
+ .name = "stm32_stlink",
+
+ .init_target = adapter_init_target,
+ .target_create = adapter_target_create,
+ .examine = cortex_m3_examine,
+ .commands = adapter_command_handlers,
+
+ .poll = adapter_poll,
+ .arch_state = armv7m_arch_state,
+
+ .assert_reset = adapter_assert_reset,
+ .deassert_reset = adapter_deassert_reset,
+ .soft_reset_halt = adapter_soft_reset_halt,
+
+ .halt = adapter_halt,
+ .resume = adapter_resume,
+ .step = adapter_step,
+
+ .get_gdb_reg_list = armv7m_get_gdb_reg_list,
+
+ .read_memory = adapter_read_memory,
+ .write_memory = adapter_write_memory,
+ .bulk_write_memory = adapter_bulk_write_memory,
+ .checksum_memory = armv7m_checksum_memory,
+ .blank_check_memory = armv7m_blank_check_memory,
+
+ .run_algorithm = armv7m_run_algorithm,
+ .start_algorithm = armv7m_start_algorithm,
+ .wait_algorithm = armv7m_wait_algorithm,
+
+ .add_breakpoint = cortex_m3_add_breakpoint,
+ .remove_breakpoint = cortex_m3_remove_breakpoint,
+ .add_watchpoint = cortex_m3_add_watchpoint,
+ .remove_watchpoint = cortex_m3_remove_watchpoint,
+};
+++ /dev/null
-/***************************************************************************
- * Copyright (C) 2011 by Mathias Kuester *
- * Mathias Kuester <kesmtp@freenet.de> *
- * *
- * Copyright (C) 2011 by Spencer Oliver *
- * spen@spen-soft.co.uk *
- * *
- * 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "jtag/jtag.h"
-#include "jtag/stlink/stlink_transport.h"
-#include "jtag/stlink/stlink_interface.h"
-#include "jtag/stlink/stlink_layout.h"
-#include "register.h"
-#include "algorithm.h"
-#include "target.h"
-#include "breakpoints.h"
-#include "target_type.h"
-#include "armv7m.h"
-#include "cortex_m.h"
-#include "arm_semihosting.h"
-
-#define ARMV7M_SCS_DCRSR 0xe000edf4
-#define ARMV7M_SCS_DCRDR 0xe000edf8
-
-static inline struct stlink_interface_s *target_to_stlink(struct target *target)
-{
- return target->tap->priv;
-}
-
-static int stm32_stlink_load_core_reg_u32(struct target *target,
- enum armv7m_regtype type,
- uint32_t num, uint32_t *value)
-{
- int retval;
- struct stlink_interface_s *stlink_if = target_to_stlink(target);
-
- LOG_DEBUG("%s", __func__);
-
- /* NOTE: we "know" here that the register identifiers used
- * in the v7m header match the Cortex-M3 Debug Core Register
- * Selector values for R0..R15, xPSR, MSP, and PSP.
- */
- switch (num) {
- case 0 ... 18:
- /* read a normal core register */
- retval = stlink_if->layout->api->read_reg(stlink_if->fd, num, value);
-
- if (retval != ERROR_OK) {
- LOG_ERROR("JTAG failure %i", retval);
- return ERROR_JTAG_DEVICE_ERROR;
- }
- LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value);
- break;
-
- case ARMV7M_FPSID:
- case ARMV7M_FPEXC:
- *value = 0;
- break;
-
- case ARMV7M_FPSCR:
- /* Floating-point Status and Registers */
- retval = target_write_u32(target, ARMV7M_SCS_DCRSR, 33);
- if (retval != ERROR_OK)
- return retval;
- retval = target_read_u32(target, ARMV7M_SCS_DCRDR, value);
- if (retval != ERROR_OK)
- return retval;
- LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value);
- break;
-
- case ARMV7M_S0 ... ARMV7M_S31:
- /* Floating-point Status and Registers */
- retval = target_write_u32(target, ARMV7M_SCS_DCRSR, num-ARMV7M_S0+64);
- if (retval != ERROR_OK)
- return retval;
- retval = target_read_u32(target, ARMV7M_SCS_DCRDR, value);
- if (retval != ERROR_OK)
- return retval;
- LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value);
- break;
-
- case ARMV7M_D0 ... ARMV7M_D15:
- value = 0;
- break;
-
- case ARMV7M_PRIMASK:
- case ARMV7M_BASEPRI:
- case ARMV7M_FAULTMASK:
- case ARMV7M_CONTROL:
- /* Cortex-M3 packages these four registers as bitfields
- * in one Debug Core register. So say r0 and r2 docs;
- * it was removed from r1 docs, but still works.
- */
- retval = stlink_if->layout->api->read_reg(stlink_if->fd, 20, value);
- if (retval != ERROR_OK)
- return retval;
-
- switch (num) {
- case ARMV7M_PRIMASK:
- *value = buf_get_u32((uint8_t *) value, 0, 1);
- break;
-
- case ARMV7M_BASEPRI:
- *value = buf_get_u32((uint8_t *) value, 8, 8);
- break;
-
- case ARMV7M_FAULTMASK:
- *value = buf_get_u32((uint8_t *) value, 16, 1);
- break;
-
- case ARMV7M_CONTROL:
- *value = buf_get_u32((uint8_t *) value, 24, 2);
- break;
- }
-
- LOG_DEBUG("load from special reg %i value 0x%" PRIx32 "",
- (int)num, *value);
- break;
-
- default:
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-
- return ERROR_OK;
-}
-
-static int stm32_stlink_store_core_reg_u32(struct target *target,
- enum armv7m_regtype type,
- uint32_t num, uint32_t value)
-{
- int retval;
- uint32_t reg;
- struct armv7m_common *armv7m = target_to_armv7m(target);
- struct stlink_interface_s *stlink_if = target_to_stlink(target);
-
- LOG_DEBUG("%s", __func__);
-
-#ifdef ARMV7_GDB_HACKS
- /* If the LR register is being modified, make sure it will put us
- * in "thumb" mode, or an INVSTATE exception will occur. This is a
- * hack to deal with the fact that gdb will sometimes "forge"
- * return addresses, and doesn't set the LSB correctly (i.e., when
- * printing expressions containing function calls, it sets LR = 0.)
- * Valid exception return codes have bit 0 set too.
- */
- if (num == ARMV7M_R14)
- value |= 0x01;
-#endif
-
- /* NOTE: we "know" here that the register identifiers used
- * in the v7m header match the Cortex-M3 Debug Core Register
- * Selector values for R0..R15, xPSR, MSP, and PSP.
- */
- switch (num) {
- case 0 ... 18:
- retval = stlink_if->layout->api->write_reg(stlink_if->fd, num, value);
-
- if (retval != ERROR_OK) {
- struct reg *r;
-
- LOG_ERROR("JTAG failure");
- r = armv7m->core_cache->reg_list + num;
- r->dirty = r->valid;
- return ERROR_JTAG_DEVICE_ERROR;
- }
- LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
- break;
-
- case ARMV7M_FPSID:
- case ARMV7M_FPEXC:
- break;
-
- case ARMV7M_FPSCR:
- /* Floating-point Status and Registers */
- retval = target_write_u32(target, ARMV7M_SCS_DCRDR, value);
- if (retval != ERROR_OK)
- return retval;
- retval = target_write_u32(target, ARMV7M_SCS_DCRSR, 33 | (1<<16));
- if (retval != ERROR_OK)
- return retval;
- LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
- break;
-
- case ARMV7M_S0 ... ARMV7M_S31:
- /* Floating-point Status and Registers */
- retval = target_write_u32(target, ARMV7M_SCS_DCRDR, value);
- if (retval != ERROR_OK)
- return retval;
- retval = target_write_u32(target, ARMV7M_SCS_DCRSR, (num-ARMV7M_S0+64) | (1<<16));
- if (retval != ERROR_OK)
- return retval;
- LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
- break;
-
- case ARMV7M_D0 ... ARMV7M_D15:
- break;
-
- case ARMV7M_PRIMASK:
- case ARMV7M_BASEPRI:
- case ARMV7M_FAULTMASK:
- case ARMV7M_CONTROL:
- /* Cortex-M3 packages these four registers as bitfields
- * in one Debug Core register. So say r0 and r2 docs;
- * it was removed from r1 docs, but still works.
- */
-
- stlink_if->layout->api->read_reg(stlink_if->fd, 20, ®);
-
- switch (num) {
- case ARMV7M_PRIMASK:
- buf_set_u32((uint8_t *) ®, 0, 1, value);
- break;
-
- case ARMV7M_BASEPRI:
- buf_set_u32((uint8_t *) ®, 8, 8, value);
- break;
-
- case ARMV7M_FAULTMASK:
- buf_set_u32((uint8_t *) ®, 16, 1, value);
- break;
-
- case ARMV7M_CONTROL:
- buf_set_u32((uint8_t *) ®, 24, 2, value);
- break;
- }
-
- stlink_if->layout->api->write_reg(stlink_if->fd, 20, reg);
-
- LOG_DEBUG("write special reg %i value 0x%" PRIx32 " ", (int)num, value);
- break;
-
- default:
- return ERROR_COMMAND_SYNTAX_ERROR;
- }
-
- return ERROR_OK;
-}
-
-static int stm32_stlink_examine_debug_reason(struct target *target)
-{
- if ((target->debug_reason != DBG_REASON_DBGRQ)
- && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
- target->debug_reason = DBG_REASON_BREAKPOINT;
- }
-
- return ERROR_OK;
-}
-
-static int stm32_stlink_init_arch_info(struct target *target,
- struct cortex_m3_common *cortex_m3,
- struct jtag_tap *tap)
-{
- struct armv7m_common *armv7m;
-
- LOG_DEBUG("%s", __func__);
-
- armv7m = &cortex_m3->armv7m;
- armv7m_init_arch_info(target, armv7m);
-
- armv7m->load_core_reg_u32 = stm32_stlink_load_core_reg_u32;
- armv7m->store_core_reg_u32 = stm32_stlink_store_core_reg_u32;
-
- armv7m->examine_debug_reason = stm32_stlink_examine_debug_reason;
- armv7m->stlink = true;
-
- return ERROR_OK;
-}
-
-static int stm32_stlink_init_target(struct command_context *cmd_ctx,
- struct target *target)
-{
- LOG_DEBUG("%s", __func__);
-
- armv7m_build_reg_cache(target);
-
- return ERROR_OK;
-}
-
-static int stm32_stlink_target_create(struct target *target,
- Jim_Interp *interp)
-{
- LOG_DEBUG("%s", __func__);
-
- struct cortex_m3_common *cortex_m3 = calloc(1, sizeof(struct cortex_m3_common));
-
- if (!cortex_m3)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- stm32_stlink_init_arch_info(target, cortex_m3, target->tap);
-
- return ERROR_OK;
-}
-
-static int stm32_stlink_load_context(struct target *target)
-{
- struct armv7m_common *armv7m = target_to_armv7m(target);
- int num_regs = armv7m->core_cache->num_regs;
-
- for (int i = 0; i < num_regs; i++) {
- if (!armv7m->core_cache->reg_list[i].valid)
- armv7m->read_core_reg(target, i);
- }
-
- return ERROR_OK;
-}
-
-static int stlink_debug_entry(struct target *target)
-{
- struct stlink_interface_s *stlink_if = target_to_stlink(target);
- struct armv7m_common *armv7m = target_to_armv7m(target);
- struct arm *arm = &armv7m->arm;
- struct reg *r;
- uint32_t xPSR;
- int retval;
-
- retval = armv7m->examine_debug_reason(target);
- if (retval != ERROR_OK)
- return retval;
-
- stm32_stlink_load_context(target);
-
- /* make sure we clear the vector catch bit */
- stlink_if->layout->api->write_debug_reg(stlink_if->fd, DCB_DEMCR, 0);
-
- r = armv7m->core_cache->reg_list + ARMV7M_xPSR;
- xPSR = buf_get_u32(r->value, 0, 32);
-
- /* Are we in an exception handler */
- if (xPSR & 0x1FF) {
- armv7m->core_mode = ARMV7M_MODE_HANDLER;
- armv7m->exception_number = (xPSR & 0x1FF);
-
- arm->core_mode = ARM_MODE_HANDLER;
- arm->map = armv7m_msp_reg_map;
- } else {
- unsigned control = buf_get_u32(armv7m->core_cache
- ->reg_list[ARMV7M_CONTROL].value, 0, 2);
-
- /* is this thread privileged? */
- armv7m->core_mode = control & 1;
- arm->core_mode = armv7m->core_mode
- ? ARM_MODE_USER_THREAD
- : ARM_MODE_THREAD;
-
- /* which stack is it using? */
- if (control & 2)
- arm->map = armv7m_psp_reg_map;
- else
- arm->map = armv7m_msp_reg_map;
-
- armv7m->exception_number = 0;
- }
-
- LOG_DEBUG("entered debug state in core mode: %s at PC 0x%08" PRIx32 ", target->state: %s",
- armv7m_mode_strings[armv7m->core_mode],
- *(uint32_t *)(arm->pc->value),
- target_state_name(target));
-
- return retval;
-}
-
-static int stm32_stlink_poll(struct target *target)
-{
- enum target_state state;
- struct stlink_interface_s *stlink_if = target_to_stlink(target);
- struct armv7m_common *armv7m = target_to_armv7m(target);
-
- state = stlink_if->layout->api->state(stlink_if->fd);
-
- if (state == TARGET_UNKNOWN) {
- LOG_ERROR("jtag status contains invalid mode value - communication failure");
- return ERROR_TARGET_FAILURE;
- }
-
- if (target->state == state)
- return ERROR_OK;
-
- if (state == TARGET_HALTED) {
- target->state = state;
-
- int retval = stlink_debug_entry(target);
- if (retval != ERROR_OK)
- return retval;
-
- if (arm_semihosting(target, &retval) != 0)
- return retval;
-
- target_call_event_callbacks(target, TARGET_EVENT_HALTED);
- LOG_DEBUG("halted: PC: 0x%08x", buf_get_u32(armv7m->arm.pc->value, 0, 32));
- }
-
- return ERROR_OK;
-}
-
-static int stm32_stlink_assert_reset(struct target *target)
-{
- int res = ERROR_OK;
- struct stlink_interface_s *stlink_if = target_to_stlink(target);
- struct armv7m_common *armv7m = target_to_armv7m(target);
- bool use_srst_fallback = true;
-
- LOG_DEBUG("%s", __func__);
-
- enum reset_types jtag_reset_config = jtag_get_reset_config();
-
- bool srst_asserted = false;
-
- if (jtag_reset_config & RESET_SRST_NO_GATING) {
- jtag_add_reset(0, 1);
- res = stlink_if->layout->api->assert_srst(stlink_if->fd, 0);
- srst_asserted = true;
- }
-
- stlink_if->layout->api->write_debug_reg(stlink_if->fd, DCB_DHCSR, DBGKEY|C_DEBUGEN);
-
- /* only set vector catch if halt is requested */
- if (target->reset_halt)
- stlink_if->layout->api->write_debug_reg(stlink_if->fd, DCB_DEMCR, VC_CORERESET);
- else
- stlink_if->layout->api->write_debug_reg(stlink_if->fd, DCB_DEMCR, 0);
-
- if (jtag_reset_config & RESET_HAS_SRST) {
- if (!srst_asserted) {
- jtag_add_reset(0, 1);
- res = stlink_if->layout->api->assert_srst(stlink_if->fd, 0);
- }
- if (res == ERROR_COMMAND_NOTFOUND)
- LOG_ERROR("Hardware srst not supported, falling back to software reset");
- else if (res == ERROR_OK) {
- /* hardware srst supported */
- use_srst_fallback = false;
- }
- }
-
- if (use_srst_fallback) {
- /* stlink v1 api does not support hardware srst, so we use a software reset fallback */
- stlink_if->layout->api->write_debug_reg(stlink_if->fd, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_SYSRESETREQ);
- }
-
- res = stlink_if->layout->api->reset(stlink_if->fd);
-
- if (res != ERROR_OK)
- return res;
-
- /* registers are now invalid */
- register_cache_invalidate(armv7m->core_cache);
-
- if (target->reset_halt) {
- target->state = TARGET_RESET;
- target->debug_reason = DBG_REASON_DBGRQ;
- } else {
- target->state = TARGET_HALTED;
- }
-
- return ERROR_OK;
-}
-
-static int stm32_stlink_deassert_reset(struct target *target)
-{
- int res;
- struct stlink_interface_s *stlink_if = target_to_stlink(target);
-
- enum reset_types jtag_reset_config = jtag_get_reset_config();
-
- LOG_DEBUG("%s", __func__);
-
- if (jtag_reset_config & RESET_HAS_SRST)
- stlink_if->layout->api->assert_srst(stlink_if->fd, 1);
-
- /* virtual deassert reset, we need it for the internal
- * jtag state machine
- */
- jtag_add_reset(0, 0);
-
- if (!target->reset_halt) {
- res = target_resume(target, 1, 0, 0, 0);
-
- if (res != ERROR_OK)
- return res;
- }
-
- return ERROR_OK;
-}
-
-static int stm32_stlink_soft_reset_halt(struct target *target)
-{
- LOG_DEBUG("%s", __func__);
- return ERROR_OK;
-}
-
-static int stm32_stlink_halt(struct target *target)
-{
- int res;
- struct stlink_interface_s *stlink_if = target_to_stlink(target);
-
- LOG_DEBUG("%s", __func__);
-
- if (target->state == TARGET_HALTED) {
- LOG_DEBUG("target was already halted");
- return ERROR_OK;
- }
-
- if (target->state == TARGET_UNKNOWN)
- LOG_WARNING("target was in unknown state when halt was requested");
-
- res = stlink_if->layout->api->halt(stlink_if->fd);
-
- if (res != ERROR_OK)
- return res;
-
- target->debug_reason = DBG_REASON_DBGRQ;
-
- return ERROR_OK;
-}
-
-static int stm32_stlink_resume(struct target *target, int current,
- uint32_t address, int handle_breakpoints,
- int debug_execution)
-{
- int res;
- struct stlink_interface_s *stlink_if = target_to_stlink(target);
- struct armv7m_common *armv7m = target_to_armv7m(target);
- uint32_t resume_pc;
- struct breakpoint *breakpoint = NULL;
- struct reg *pc;
-
- LOG_DEBUG("%s %d 0x%08x %d %d", __func__, current, address,
- handle_breakpoints, debug_execution);
-
- if (target->state != TARGET_HALTED) {
- LOG_WARNING("target not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
-
- pc = armv7m->arm.pc;
- if (!current) {
- buf_set_u32(pc->value, 0, 32, address);
- pc->dirty = true;
- pc->valid = true;
- }
-
- if (!breakpoint_find(target, buf_get_u32(pc->value, 0, 32))
- && !debug_execution) {
- armv7m_maybe_skip_bkpt_inst(target, NULL);
- }
-
- resume_pc = buf_get_u32(pc->value, 0, 32);
-
- armv7m_restore_context(target);
-
- /* registers are now invalid */
- register_cache_invalidate(armv7m->core_cache);
-
- /* the front-end may request us not to handle breakpoints */
- if (handle_breakpoints) {
- /* Single step past breakpoint at current address */
- breakpoint = breakpoint_find(target, resume_pc);
- if (breakpoint) {
- LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (ID: %d)",
- breakpoint->address,
- breakpoint->unique_id);
- cortex_m3_unset_breakpoint(target, breakpoint);
-
- res = stlink_if->layout->api->step(stlink_if->fd);
-
- if (res != ERROR_OK)
- return res;
-
- cortex_m3_set_breakpoint(target, breakpoint);
- }
- }
-
- res = stlink_if->layout->api->run(stlink_if->fd);
-
- if (res != ERROR_OK)
- return res;
-
- target->state = TARGET_RUNNING;
- target->debug_reason = DBG_REASON_NOTHALTED;
-
- target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
-
- return ERROR_OK;
-}
-
-static int stm32_stlink_step(struct target *target, int current,
- uint32_t address, int handle_breakpoints)
-{
- int res;
- struct stlink_interface_s *stlink_if = target_to_stlink(target);
- struct armv7m_common *armv7m = target_to_armv7m(target);
- struct breakpoint *breakpoint = NULL;
- struct reg *pc = armv7m->arm.pc;
- bool bkpt_inst_found = false;
-
- LOG_DEBUG("%s", __func__);
-
- if (target->state != TARGET_HALTED) {
- LOG_WARNING("target not halted");
- return ERROR_TARGET_NOT_HALTED;
- }
-
- if (!current) {
- buf_set_u32(pc->value, 0, 32, address);
- pc->dirty = true;
- pc->valid = true;
- }
-
- uint32_t pc_value = buf_get_u32(pc->value, 0, 32);
-
- /* the front-end may request us not to handle breakpoints */
- if (handle_breakpoints) {
- breakpoint = breakpoint_find(target, pc_value);
- if (breakpoint)
- cortex_m3_unset_breakpoint(target, breakpoint);
- }
-
- armv7m_maybe_skip_bkpt_inst(target, &bkpt_inst_found);
-
- target->debug_reason = DBG_REASON_SINGLESTEP;
-
- armv7m_restore_context(target);
-
- target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
-
- res = stlink_if->layout->api->step(stlink_if->fd);
-
- if (res != ERROR_OK)
- return res;
-
- /* registers are now invalid */
- register_cache_invalidate(armv7m->core_cache);
-
- if (breakpoint)
- cortex_m3_set_breakpoint(target, breakpoint);
-
- stlink_debug_entry(target);
- target_call_event_callbacks(target, TARGET_EVENT_HALTED);
-
- LOG_INFO("halted: PC: 0x%08x", buf_get_u32(armv7m->arm.pc->value, 0, 32));
-
- return ERROR_OK;
-}
-
-static int stm32_stlink_read_memory(struct target *target, uint32_t address,
- uint32_t size, uint32_t count,
- uint8_t *buffer)
-{
- int res;
- uint32_t buffer_threshold = 128;
- uint32_t addr_increment = 4;
- uint32_t c;
- struct stlink_interface_s *stlink_if = target_to_stlink(target);
-
- if (!count || !buffer)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- LOG_DEBUG("%s 0x%08x %d %d", __func__, address, size, count);
-
- /* prepare byte count, buffer threshold
- * and address increment for none 32bit access
- */
- if (size != 4) {
- count *= size;
- buffer_threshold = 64;
- addr_increment = 1;
- }
-
- while (count) {
- if (count > buffer_threshold)
- c = buffer_threshold;
- else
- c = count;
-
- if (size != 4)
- res = stlink_if->layout->api->read_mem8(stlink_if->fd,
- address, c, buffer);
- else
- res = stlink_if->layout->api->read_mem32(stlink_if->fd,
- address, c, buffer);
-
- if (res != ERROR_OK)
- return res;
-
- address += (c * addr_increment);
- buffer += (c * addr_increment);
- count -= c;
- }
-
- return ERROR_OK;
-}
-
-static int stm32_stlink_write_memory(struct target *target, uint32_t address,
- uint32_t size, uint32_t count,
- const uint8_t *buffer)
-{
- int res;
- uint32_t buffer_threshold = 128;
- uint32_t addr_increment = 4;
- uint32_t c;
- struct stlink_interface_s *stlink_if = target_to_stlink(target);
-
- if (!count || !buffer)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- LOG_DEBUG("%s 0x%08x %d %d", __func__, address, size, count);
-
- /* prepare byte count, buffer threshold
- * and address increment for none 32bit access
- */
- if (size != 4) {
- count *= size;
- buffer_threshold = 64;
- addr_increment = 1;
- }
-
- while (count) {
- if (count > buffer_threshold)
- c = buffer_threshold;
- else
- c = count;
-
- if (size != 4)
- res = stlink_if->layout->api->write_mem8(stlink_if->fd,
- address, c, buffer);
- else
- res = stlink_if->layout->api->write_mem32(stlink_if->fd,
- address, c, buffer);
-
- if (res != ERROR_OK)
- return res;
-
- address += (c * addr_increment);
- buffer += (c * addr_increment);
- count -= c;
- }
-
- return ERROR_OK;
-}
-
-static int stm32_stlink_bulk_write_memory(struct target *target,
- uint32_t address, uint32_t count,
- const uint8_t *buffer)
-{
- return stm32_stlink_write_memory(target, address, 4, count, buffer);
-}
-
-static const struct command_registration stm32_stlink_command_handlers[] = {
- {
- .chain = arm_command_handlers,
- },
- COMMAND_REGISTRATION_DONE
-};
-
-struct target_type stm32_stlink_target = {
- .name = "stm32_stlink",
-
- .init_target = stm32_stlink_init_target,
- .target_create = stm32_stlink_target_create,
- .examine = cortex_m3_examine,
- .commands = stm32_stlink_command_handlers,
-
- .poll = stm32_stlink_poll,
- .arch_state = armv7m_arch_state,
-
- .assert_reset = stm32_stlink_assert_reset,
- .deassert_reset = stm32_stlink_deassert_reset,
- .soft_reset_halt = stm32_stlink_soft_reset_halt,
-
- .halt = stm32_stlink_halt,
- .resume = stm32_stlink_resume,
- .step = stm32_stlink_step,
-
- .get_gdb_reg_list = armv7m_get_gdb_reg_list,
-
- .read_memory = stm32_stlink_read_memory,
- .write_memory = stm32_stlink_write_memory,
- .bulk_write_memory = stm32_stlink_bulk_write_memory,
- .checksum_memory = armv7m_checksum_memory,
- .blank_check_memory = armv7m_blank_check_memory,
-
- .run_algorithm = armv7m_run_algorithm,
- .start_algorithm = armv7m_start_algorithm,
- .wait_algorithm = armv7m_wait_algorithm,
-
- .add_breakpoint = cortex_m3_add_breakpoint,
- .remove_breakpoint = cortex_m3_remove_breakpoint,
- .add_watchpoint = cortex_m3_add_watchpoint,
- .remove_watchpoint = cortex_m3_remove_watchpoint,
-};
/* found */
break;
}
+
+ /* check for deprecated name */
+ if (target_types[x]->deprecated_name) {
+ if (0 == strcmp(cp, target_types[x]->deprecated_name)) {
+ /* found */
+ LOG_WARNING("target name is deprecated use: \'%s\'", target_types[x]->name);
+ break;
+ }
+ }
}
if (target_types[x] == NULL) {
Jim_SetResultFormatted(goi->interp, "Unknown target type %s, try one of ", cp);
* field directly, use target_type_name() instead.
*/
const char *name;
+ const char *deprecated_name;
/* poll current target status */
int (*poll)(struct target *target);