- added support for Asix Presto JTAG interface (thanks to Pavel Chromy and Asix for...
authordrath <drath@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Sun, 15 Jul 2007 11:19:33 +0000 (11:19 +0000)
committerdrath <drath@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Sun, 15 Jul 2007 11:19:33 +0000 (11:19 +0000)
- added support for usbprog (thanks to Benedikt Sauter)
- make OpenOCD listen for WM_QUIT messages on windows (thanks to Pavel Chromy)
- register at_exit handler to do necessary unregistering (thanks to Pavel Chromy)
- added dummy ETM capture driver to allow ETM to be registered without a capture driver

git-svn-id: svn://svn.berlios.de/openocd/trunk@180 b42882b7-edfa-0310-969c-e2dbd0fdcd60

17 files changed:
configure.in
src/Makefile.am
src/flash/str9x.c
src/jtag/Makefile.am
src/jtag/bitq.c [new file with mode: 0644]
src/jtag/bitq.h [new file with mode: 0644]
src/jtag/jtag.c
src/jtag/jtag.h
src/jtag/presto.c [new file with mode: 0644]
src/jtag/usbprog.c [new file with mode: 0644]
src/openocd.c
src/server/server.c
src/target/Makefile.am
src/target/etm.c
src/target/etm.h
src/target/etm_dummy.c [new file with mode: 0644]
src/target/etm_dummy.h [new file with mode: 0644]

index 7111b82adbda987e188400674064eded884a79e0..a9e1f90a16beb19b366d2a66a78ff3b0b6863291 100644 (file)
@@ -15,6 +15,7 @@ AC_CHECK_FUNCS(gettimeofday)
 AC_CHECK_FUNCS(usleep)
 
 build_bitbang=no
+build_bitq=no
 is_cygwin=no
 is_mingw=no
 is_win32=no
@@ -51,6 +52,14 @@ AC_ARG_ENABLE(gw16012,
   AS_HELP_STRING([--enable-gw16012], [Enable building support for the Gateworks GW16012 JTAG Programmer]),
   [build_gw16012=$enableval], [build_gw16012=no])
 
+AC_ARG_ENABLE(presto,
+  AS_HELP_STRING([--enable-presto], [Enable building support for ASIX Presto Programmer]),
+  [build_presto=$enableval], [build_presto=no])
+
+AC_ARG_ENABLE(usbprog,
+  AS_HELP_STRING([--enable-usbprog], [Enable building support for the usbprog JTAG Programmer]),
+  [build_usbprog=$enableval], [build_usbprog=no])
+
 AC_ARG_WITH(ftd2xx,
         [AS_HELP_STRING(--with-ftd2xx,
            [Where libftd2xx can be found <default=search>])],
@@ -156,6 +165,25 @@ else
   AC_DEFINE(BUILD_GW16012, 0, [0 if you don't want the Gateworks GW16012 driver.])
 fi
 
+if test $build_presto = yes; then
+  build_bitq=yes
+  AC_DEFINE(BUILD_PRESTO, 1, [1 if you want the ASIX PRESTO driver.])
+else
+  AC_DEFINE(BUILD_PRESTO, 0, [0 if you don't want the ASIX PRESTO driver.])
+fi
+
+if test $build_bitq = yes; then
+  AC_DEFINE(BUILD_BITQ, 1, [1 if you want a bitq interface.])
+else
+  AC_DEFINE(BUILD_BITQ, 0, [0 if you don't want a bitq interface.])
+fi
+
+if test $build_usbprog = yes; then
+  AC_DEFINE(BUILD_USBPROG, 1, [1 if you want the usbprog JTAG driver.])
+else
+  AC_DEFINE(BUILD_USBPROG, 0, [0 if you don't want the usbprog JTAG driver.])
+fi
+
 AM_CONFIG_HEADER(config.h)
 AM_INIT_AUTOMAKE(openocd, 0.1)
 
@@ -168,10 +196,13 @@ AM_CONDITIONAL(FT2232_LIBFTDI, test $build_ft2232_libftdi = yes)
 AM_CONDITIONAL(FT2232_FTD2XX, test $build_ft2232_ftd2xx = yes)
 AM_CONDITIONAL(AMTJTAGACCEL, test $build_amtjtagaccel = yes)
 AM_CONDITIONAL(GW16012, test $build_gw16012 = yes)
+AM_CONDITIONAL(PRESTO, test $build_presto = yes)
+AM_CONDITIONAL(USBPROG, test $build_usbprog = yes)
 AM_CONDITIONAL(IS_CYGWIN, test $is_cygwin = yes)
 AM_CONDITIONAL(IS_MINGW, test $is_mingw = yes)
 AM_CONDITIONAL(IS_WIN32, test $is_win32 = yes)
 AM_CONDITIONAL(FTD2XXDIR, test $with_ftd2xx != search)
+AM_CONDITIONAL(BITQ, test $build_bitq = yes)
 
 AC_LANG_C
 AC_PROG_CC
index 467149797fa0789738f1931896d3b28f44d46325..c8e7c81d3f02ae9257d4dbab3346b4e1372f3cd6 100644 (file)
@@ -22,6 +22,12 @@ else
 FTDI2232LIB =
 endif
 
+if USBPROG
+LIBUSB = -lusb
+else
+LIBUSB =
+endif
+
 if IS_WIN32
 if FTD2XXDIR
 FTD2XXLDADD = @WITH_FTD2XX@/FTD2XX.lib
@@ -35,8 +41,12 @@ endif
 if FT2232_FTD2XX
 FTD2XXLIB = $(FTD2XXLDADD)
 else
+if PRESTO
+FTD2XXLIB = $(FTD2XXLDADD)
+else
 FTD2XXLIB =
 endif
+endif
 
 openocd_LDADD = $(top_builddir)/src/xsvf/libxsvf.a \
        $(top_builddir)/src/target/libtarget.a $(top_builddir)/src/jtag/libjtag.a \
@@ -44,4 +54,4 @@ openocd_LDADD = $(top_builddir)/src/xsvf/libxsvf.a \
        $(top_builddir)/src/server/libserver.a $(top_builddir)/src/helper/libhelper.a \
        $(top_builddir)/src/flash/libflash.a $(top_builddir)/src/target/libtarget.a \
        $(top_builddir)/src/pld/libpld.a \
-       $(FTDI2232LIB) $(FTD2XXLIB) $(MINGWLDADD)
+       $(FTDI2232LIB) $(FTD2XXLIB) $(MINGWLDADD) $(LIBUSB)
index c07bc757f1814a131c00c66cad2cf36511c67593..b47758d27245dae907a117b4a9d509994d743bfd 100644 (file)
@@ -610,7 +610,7 @@ int str9x_handle_flash_config_command(struct command_context_s *cmd_ctx, char *c
        
        if (argc < 4)
        {
-               command_print(cmd_ctx, "usage: str9x flash_config b0size b1size b0start b1start");
+               command_print(cmd_ctx, "usage: str9x flash_config <b0size> <b1size> <b0start> <b1start>");
                return ERROR_OK;
        }
        
index 78230b629c97ebe430e9292e7ad09f53f080f630..64159e589ce841372bff726156af21b5a4d0055e 100644 (file)
@@ -59,6 +59,25 @@ else
 GW16012FILES =
 endif
 
-libjtag_a_SOURCES = jtag.c $(BITBANGFILES) $(PARPORTFILES) $(FT2232FILES) $(AMTJTAGACCELFILES) $(EP93XXFILES) $(AT91RM9200FILES) $(GW16012FILES)
+if BITQ
+BITQFILES = bitq.c
+else
+BITQFILES =
+endif
+
+if PRESTO
+PRESTOFILES = presto.c
+else
+PRESTOFILES =
+endif
+
+if USBPROG
+USBPROGFILES = usbprog.c
+else
+USBPROGFILES =
+endif
+
+libjtag_a_SOURCES = jtag.c $(BITBANGFILES) $(PARPORTFILES) $(FT2232FILES) $(AMTJTAGACCELFILES) $(EP93XXFILES) \
+       $(AT91RM9200FILES) $(GW16012FILES) $(BITQFILES) $(PRESTOFILES) $(USBPROGFILES)
 
 noinst_HEADERS = bitbang.h jtag.h
diff --git a/src/jtag/bitq.c b/src/jtag/bitq.c
new file mode 100644 (file)
index 0000000..03f9645
--- /dev/null
@@ -0,0 +1,388 @@
+/***************************************************************************
+ *   Copyright (C) 2007 by Pavel Chromy                                    *
+ *   chromy@asix.cz                                                        *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "bitq.h"
+
+/* project specific includes */
+#include "log.h"
+#include "types.h"
+#include "jtag.h"
+#include "configuration.h"
+
+/* system includes */
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <sys/time.h>
+#include <time.h>
+
+
+bitq_interface_t *bitq_interface; /* low level bit queue interface */
+
+bitq_state_t bitq_in_state; /* state of input queue */
+
+u8 *bitq_in_buffer; /* buffer dynamically reallocated as needed */
+unsigned long bitq_in_bufsize=32; /* min. buffer size */
+
+
+/*
+ * input queue processing does not use jtag_read_buffer() to avoid unnecessary overhead
+ * also the buffer for incomming data is reallocated only if necessary
+ * no parameters, makes use of stored state information
+ */ 
+void bitq_in_proc(void)
+{
+       /* static information preserved between calls to increase performance */
+       static u8 *in_buff; /* pointer to buffer for scanned data */
+  static int in_idx; /* index of byte being scanned */
+  static u8 in_mask; /* mask of next bit to be scanned */
+
+  scan_field_t *field;
+  int tdo;
+  
+  int result;
+
+  /* loop through the queue */
+  while (bitq_in_state.cmd) {
+    /* only JTAG_SCAN command may return data */
+    if (bitq_in_state.cmd->type==JTAG_SCAN) {
+      /* loop through the fields */
+      while (bitq_in_state.field_idx<bitq_in_state.cmd->cmd.scan->num_fields) {
+
+        field=&bitq_in_state.cmd->cmd.scan->fields[bitq_in_state.field_idx];
+        if (field->in_check_value || field->in_value || field->in_handler) {
+
+          if (bitq_in_state.bit_pos==0) {
+            /* initialize field scanning */
+            in_mask=0x01;
+            in_idx=0;
+            if (field->in_value) in_buff=field->in_value;
+            else {
+              /* buffer reallocation needed? */
+              if (field->num_bits>bitq_in_bufsize*8) {
+                /* buffer previously allocated? */
+                if (bitq_in_buffer!=NULL) {
+                  /* free it */
+                  free(bitq_in_buffer);
+                  bitq_in_buffer=NULL;
+                }
+                /* double the buffer size until it fits */
+                while (field->num_bits>bitq_in_bufsize*8) bitq_in_bufsize*=2;
+              }
+              /* if necessary, allocate buffer and check for malloc error */ 
+              if (bitq_in_buffer==NULL && (bitq_in_buffer=malloc(bitq_in_bufsize))==NULL) {
+                ERROR("malloc error");
+                exit(-1);                
+              }
+              in_buff=(void *)bitq_in_buffer;
+            }
+          }
+
+          /* field scanning */
+          while (bitq_in_state.bit_pos<field->num_bits) {
+            if ((tdo=bitq_interface->in())<0) {
+#ifdef _DEBUG_JTAG_IO_
+              DEBUG("bitq in EOF");
+#endif
+              return;
+            }
+            if (in_mask==0x01) in_buff[in_idx]=0;
+            if (tdo) in_buff[in_idx]|=in_mask;
+            if (in_mask==0x80) {
+              in_mask=0x01;
+              in_idx++;
+            }
+            else in_mask<<=1;
+            bitq_in_state.bit_pos++;
+          }
+          
+          if (field->in_check_value) {
+            /* match scanned in value */
+            for (in_idx=0; in_idx*8<field->num_bits; in_idx++) {
+              if (field->in_check_mask) in_mask=field->in_check_mask[in_idx];
+              else in_mask=0xff;
+              if (field->num_bits-in_idx*8<8) in_mask>>=8-(field->num_bits-in_idx*8);
+              if (field->in_check_value[in_idx]&in_mask!=in_buff[in_idx]&in_mask) {
+                                       char *captured_char = buf_to_str(in_buff, (field->num_bits > 64) ? 64 : field->num_bits, 16);
+                                       char *in_check_value_char = buf_to_str(field->in_check_value, (field->num_bits > 64) ? 64 : field->num_bits, 16);
+                                       char *in_check_mask_char = buf_to_str(field->in_check_mask, (field->num_bits > 64) ? 64 : field->num_bits, 16);
+                                       /* TODO: error reporting */
+                                       WARNING("value captured during scan didn't pass the requested check: captured: 0x%s check_value: 0x%s check_mask: 0x%s", captured_char, in_check_value_char, in_check_mask_char);
+                                       bitq_in_state.status=ERROR_JTAG_QUEUE_FAILED;
+                                       free(captured_char);
+                                       free(in_check_value_char);
+                                       free(in_check_mask_char);
+                break; /* leave the comparison loop upon first mismatch */                                             
+              }
+            }
+          }
+
+          if (field->in_handler && bitq_in_state.status==ERROR_OK) {
+            bitq_in_state.status=(*field->in_handler)(in_buff, field->in_handler_priv);
+          }
+
+        }
+        
+        bitq_in_state.field_idx++; /* advance to next field */
+        bitq_in_state.bit_pos=0; /* start next field from the first bit */
+      }
+
+    }
+    bitq_in_state.cmd=bitq_in_state.cmd->next; /* advance to next command */
+    bitq_in_state.field_idx=0; /* preselect first field */
+  }
+}
+
+
+
+void bitq_io(int tms, int tdi, int tdo_req)
+{
+  bitq_interface->out(tms, tdi, tdo_req);
+  /* check and process the input queue */ 
+  if (bitq_interface->in_rdy()) bitq_in_proc();
+}
+
+
+void bitq_end_state(enum tap_state state)
+{
+  if (state==-1) return;
+  if (tap_move_map[state]==-1) {
+               ERROR("BUG: %i is not a valid end state", state);
+               exit(-1);
+       }
+  end_state = state;
+}
+
+
+void bitq_state_move(enum tap_state new_state)
+{
+  int i=0;
+  u8 tms_scan;
+
+  if (tap_move_map[cur_state]==-1 || tap_move_map[new_state]==-1) {
+    ERROR("TAP move from or to unstable state");
+    exit(-1);
+  }
+  
+  tms_scan=TAP_MOVE(cur_state, new_state);
+
+  for (i=0; i<7; i++) {
+    bitq_io(tms_scan&1, 0, 0);
+    tms_scan>>=1;
+  }
+
+  cur_state = new_state;
+}
+
+
+void bitq_path_move(pathmove_command_t *cmd)
+{
+  int i;
+
+  for (i=0; i<=cmd->num_states; i++) {
+    if (tap_transitions[cur_state].low == cmd->path[i]) bitq_io(0, 0, 0);
+    else if (tap_transitions[cur_state].high == cmd->path[i]) bitq_io(1, 0, 0);
+    else {
+      ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[cmd->path[i]]);
+      exit(-1);
+    }
+
+    cur_state = cmd->path[i];
+  }
+
+  end_state = cur_state;
+}
+
+
+void bitq_runtest(int num_cycles)
+{
+  int i;
+
+  /* only do a state_move when we're not already in RTI */
+  if (cur_state != TAP_RTI) bitq_state_move(TAP_RTI);
+
+  /* execute num_cycles */
+  for (i = 0; i < num_cycles; i++)
+    bitq_io(0, 0, 0);
+
+  /* finish in end_state */
+  if (cur_state != end_state) bitq_state_move(end_state);
+}
+
+
+void bitq_scan_field(scan_field_t *field, int pause)
+{
+  int bit_cnt;
+  int tdo_req;
+
+  u8 *out_ptr;
+  u8 out_mask;
+  
+  if (field->in_check_value || field->in_value || field->in_handler) tdo_req=1;
+  else tdo_req=0;
+
+  if (field->out_value==NULL) {
+    /* just send zeros and request data from TDO */
+    for (bit_cnt=field->num_bits; bit_cnt>1; bit_cnt--)
+      bitq_io(0, 0, tdo_req);
+    bitq_io(pause, 0, tdo_req);
+  }
+  else {
+    /* send data, and optionally request TDO */
+    out_mask=0x01;
+    out_ptr=field->out_value;
+    for (bit_cnt=field->num_bits; bit_cnt>1; bit_cnt--) {
+      bitq_io(0, ((*out_ptr)&out_mask)!=0, tdo_req);
+      if (out_mask==0x80) {
+        out_mask=0x01;
+        out_ptr++;
+      }
+      else out_mask<<=1;
+    }
+    bitq_io(pause, ((*out_ptr)&out_mask)!=0, tdo_req);
+  }
+
+  if (pause) {
+    bitq_io(0,0,0);
+    if (cur_state==TAP_SI) cur_state=TAP_PI;
+    else if (cur_state==TAP_SD) cur_state=TAP_PD;
+  }
+}
+
+
+void bitq_scan(scan_command_t *cmd)
+{
+  int i;
+
+  if (cmd->ir_scan) bitq_state_move(TAP_SI);
+  else bitq_state_move(TAP_SD);
+
+  for (i=0; i < cmd->num_fields-1; i++)
+    bitq_scan_field(&cmd->fields[i], 0);
+  bitq_scan_field(&cmd->fields[i], 1);
+}
+
+
+int bitq_execute_queue(void)
+{
+  jtag_command_t *cmd = jtag_command_queue; /* currently processed command */
+  
+  bitq_in_state.cmd = jtag_command_queue;
+  bitq_in_state.field_idx = 0;
+  bitq_in_state.bit_pos = 0;
+  bitq_in_state.status = ERROR_OK;
+
+  while (cmd) {
+
+    switch (cmd->type) {
+
+      case JTAG_END_STATE:
+#ifdef _DEBUG_JTAG_IO_
+        DEBUG("end_state: %i", cmd->cmd.end_state->end_state);
+#endif
+        bitq_end_state(cmd->cmd.end_state->end_state);
+        break;
+
+      case JTAG_RESET:
+#ifdef _DEBUG_JTAG_IO_
+        DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
+#endif
+                               bitq_interface->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
+        if (bitq_interface->in_rdy()) bitq_in_proc();
+        break;
+
+      case JTAG_RUNTEST:
+#ifdef _DEBUG_JTAG_IO_
+        DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);
+#endif
+        bitq_end_state(cmd->cmd.runtest->end_state);
+        bitq_runtest(cmd->cmd.runtest->num_cycles);
+        break;
+
+      case JTAG_STATEMOVE:
+#ifdef _DEBUG_JTAG_IO_
+        DEBUG("statemove end in %i", cmd->cmd.statemove->end_state);
+#endif
+        bitq_end_state(cmd->cmd.statemove->end_state);
+        bitq_state_move(end_state); /* uncoditional TAP move */
+        break;
+
+      case JTAG_PATHMOVE:
+#ifdef _DEBUG_JTAG_IO_
+        DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
+#endif
+        bitq_path_move(cmd->cmd.pathmove);
+        break;
+
+      case JTAG_SCAN:
+#ifdef _DEBUG_JTAG_IO_
+        DEBUG("scan end in %i", cmd->cmd.scan->end_state);
+        if (cmd->cmd.scan->ir_scan) DEBUG("scan ir");
+        else DEBUG("scan dr");
+#endif
+        bitq_end_state(cmd->cmd.scan->end_state);
+        bitq_scan(cmd->cmd.scan);
+        if (cur_state != end_state) bitq_state_move(end_state);
+        break;
+
+      case JTAG_SLEEP:
+#ifdef _DEBUG_JTAG_IO_
+        DEBUG("sleep %i", cmd->cmd.sleep->us);
+#endif
+                               bitq_interface->sleep(cmd->cmd.sleep->us);
+        if (bitq_interface->in_rdy()) bitq_in_proc();
+        break;
+
+      default:
+        ERROR("BUG: unknown JTAG command type encountered");
+        exit(-1);
+    }
+
+    cmd = cmd->next;
+  }
+
+  bitq_interface->flush();
+  bitq_in_proc();
+
+  if (bitq_in_state.cmd) {
+    ERROR("missing data from bitq interface");
+    return ERROR_JTAG_QUEUE_FAILED;
+  }
+  if (bitq_interface->in()>=0) {
+    ERROR("extra data from bitq interface");
+    return ERROR_JTAG_QUEUE_FAILED;
+  }
+
+  return bitq_in_state.status;
+}
+
+
+void bitq_cleanup(void)
+{
+       if (bitq_in_buffer!=NULL)
+       {
+               free(bitq_in_buffer);
+               bitq_in_buffer=NULL;
+       }
+}
diff --git a/src/jtag/bitq.h b/src/jtag/bitq.h
new file mode 100644 (file)
index 0000000..2ee3f6b
--- /dev/null
@@ -0,0 +1,57 @@
+/***************************************************************************
+ *   Copyright (C) 2007 by Pavel Chromy                                    *
+ *   chromy@asix.cz                                                        *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+#ifndef BITQ_H
+#define BITQ_H
+
+#include "jtag.h"
+
+typedef struct bitq_interface_s
+{
+       /* functions enqueueing low level IO requests
+       */
+       int (*out)(int tms, int tdi, int tdo_req);
+       int (*flush)(void);
+
+       int (*sleep)(unsigned long us);
+       int (*reset)(int trst, int srst);
+
+       /* delayed read of requested TDO data,
+        * the input shall be checked after call to any enqueuing function
+        */
+       int (*in_rdy)(void);
+       int (*in)(void);
+} bitq_interface_t;
+
+typedef struct bitq_state_s
+{
+  jtag_command_t *cmd; /* command currently processed */
+  int field_idx; /* index of field currently being processed */
+  int bit_pos; /* position of bit curently being processed */
+
+  int status; /* processing status */
+} bitq_state_t;
+
+extern bitq_interface_t *bitq_interface;
+
+extern int bitq_execute_queue(void);
+
+extern void bitq_cleanup(void);
+
+#endif /* BITQ_H */
index 9891912347577ea8c5a753c117681ba70003eab6..1db8247eaab1a1bed23b8963f539876d2fa5ec6b 100644 (file)
@@ -162,6 +162,14 @@ jtag_event_callback_t *jtag_event_callbacks;
        extern jtag_interface_t gw16012_interface;
 #endif
 
+#if BUILD_PRESTO == 1
+       extern jtag_interface_t presto_interface;
+#endif
+
+#if BUILD_USBPROG == 1
+       extern jtag_interface_t usbprog_interface;
+#endif
+
 jtag_interface_t *jtag_interfaces[] = {
 #if BUILD_PARPORT == 1
        &parport_interface,
@@ -183,6 +191,12 @@ jtag_interface_t *jtag_interfaces[] = {
 #endif
 #if BUILD_GW16012 == 1
        &gw16012_interface,
+#endif
+#if BUILD_PRESTO == 1
+       &presto_interface,
+#endif
+#if BUILD_USBPROG == 1
+       &usbprog_interface,
 #endif
        NULL,
 };
index 1b03d615b9625d488e18a991e8177cd315977d18..470ba93eb68fea86e6c55cae8faf540866d1e86f 100644 (file)
@@ -25,7 +25,7 @@
 
 #include "command.h"
 
-#if 0
+#if 1
 #define _DEBUG_JTAG_IO_
 #endif
 
diff --git a/src/jtag/presto.c b/src/jtag/presto.c
new file mode 100644 (file)
index 0000000..a6c048a
--- /dev/null
@@ -0,0 +1,500 @@
+/***************************************************************************
+ *   Copyright (C) 2007 by Pavel Chromy                                    *
+ *   chromy@asix.cz                                                        *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if IS_CYGWIN == 1
+#include "windows.h"
+#undef ERROR
+#endif
+
+#include "replacements.h"
+
+/* project specific includes */
+#include "log.h"
+#include "types.h"
+#include "jtag.h"
+#include "configuration.h"
+#include "time_support.h"
+#include "bitq.h"
+
+/* system includes */
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <sys/time.h>
+#include <time.h>
+
+#include "ftd2xx.h"
+
+
+int presto_jtag_speed(int speed);
+int presto_jtag_register_commands(struct command_context_s *cmd_ctx);
+int presto_jtag_init(void);
+int presto_jtag_quit(void);
+
+jtag_interface_t presto_interface =
+{
+       .name = "presto",
+       .execute_queue = bitq_execute_queue,
+       .support_pathmove = 1,
+       .speed = presto_jtag_speed,
+       .register_commands = presto_jtag_register_commands,
+       .init = presto_jtag_init,
+       .quit = presto_jtag_quit,
+};
+
+
+int presto_bitq_out(int tms, int tdi, int tdo_req);
+int presto_bitq_flush(void);
+int presto_bitq_sleep(unsigned long us);
+int presto_bitq_reset(int rst, int en);
+int presto_bitq_in_rdy(void);
+int presto_bitq_in(void);
+
+bitq_interface_t presto_bitq =
+{
+       .out = presto_bitq_out,
+       .flush = presto_bitq_flush,
+       .sleep = presto_bitq_sleep,
+       .reset = presto_bitq_reset,
+       .in_rdy = presto_bitq_in_rdy,
+       .in = presto_bitq_in,
+};
+
+
+/* -------------------------------------------------------------------------- */
+
+
+#define FT_DEVICE_NAME_LEN 64
+#define FT_DEVICE_SERNUM_LEN 64
+
+#define PRESTO_VID_PID 0x0403f1a0
+
+#define PRST_OK 0
+#define PRST_ERR 1
+#define PRST_TIMEOUT 2
+
+#define BUFFER_SIZE (64*62)
+
+
+typedef struct presto_s
+{
+       FT_HANDLE handle;
+       FT_STATUS status;
+       
+       char serial[FT_DEVICE_SERNUM_LEN];
+
+       BYTE buff_out[BUFFER_SIZE];
+       int buff_out_pos;
+
+       BYTE buff_in[BUFFER_SIZE];
+       int buff_in_exp; /* expected in buffer length */
+       int buff_in_len; /* length of data received */
+       int buff_in_pos;
+
+       unsigned long total_out;
+       unsigned long total_in;
+
+       int jtag_tms; /* last tms state */
+       int jtag_tck; /* last tck state */
+
+       int jtag_tdi_data;
+       int jtag_tdi_count;
+
+} presto_t;
+
+presto_t presto_state;
+presto_t *presto=&presto_state;
+
+BYTE presto_init_seq[] =
+{
+       0x80,   0xA0,   0xA8,   0xB0,   0xC0,   0xE0
+};
+
+
+int presto_open(char *req_serial)
+{
+       int i;
+       int result;
+       DWORD numdevs;
+       DWORD vidpid;
+       char devname[FT_DEVICE_NAME_LEN];
+       FT_DEVICE device;
+
+       BYTE presto_data;
+       unsigned long ftbytes;
+
+       presto->handle=INVALID_HANDLE_VALUE;
+
+       presto->buff_out_pos=0;
+       presto->buff_in_pos=0;
+       presto->buff_in_len=0;
+       presto->buff_in_exp=0;
+
+       presto->total_out=0;
+       presto->total_in=0;
+
+       presto->jtag_tms=0;
+       presto->jtag_tck=0;
+       presto->jtag_tdi_data=0;
+       presto->jtag_tdi_count=0;
+
+       if (FT_ListDevices(&numdevs, NULL, FT_LIST_NUMBER_ONLY)!=FT_OK) return PRST_ERR;
+       for (i=0; i<numdevs; i++)
+       {
+               if (FT_Open(i, &(presto->handle))!=FT_OK) continue;
+               if (FT_GetDeviceInfo(presto->handle,&device,&vidpid,presto->serial,devname,NULL)==FT_OK)
+               {
+                       if (vidpid==PRESTO_VID_PID && (req_serial==NULL || !strcmp(presto->serial,req_serial)))
+                         break;
+               }
+               FT_Close(presto->handle);
+               presto->handle=INVALID_HANDLE_VALUE;
+       }
+
+       if (presto->handle==INVALID_HANDLE_VALUE) return PRST_ERR;
+
+       if ((presto->status=FT_SetLatencyTimer(presto->handle,1))!=FT_OK) return PRST_ERR;
+       if ((presto->status=FT_SetTimeouts(presto->handle,100,0))!=FT_OK) return PRST_ERR;
+       if ((presto->status=FT_Purge(presto->handle, FT_PURGE_TX|FT_PURGE_RX))!=FT_OK) return PRST_ERR;
+
+       presto_data=0xD0;
+       if ((presto->status=FT_Write(presto->handle,&presto_data,1,&ftbytes))!=FT_OK) return PRST_ERR;
+       if ((presto->status=FT_Read(presto->handle,&presto_data,1,&ftbytes))!=FT_OK) return PRST_ERR;
+
+       if (ftbytes!=1)
+       {
+               if ((presto->status=FT_SetBitMode(presto->handle,0x80,1))!=FT_OK) return PRST_ERR;
+               if ((presto->status=FT_Purge(presto->handle, FT_PURGE_TX|FT_PURGE_RX))!=FT_OK) return PRST_ERR ;
+               if ((presto->status=FT_SetBaudRate(presto->handle,9600))!=FT_OK) return PRST_ERR;
+
+               presto_data=0;
+               for (i=0; i<4*62; i++)
+                       if ((presto->status=FT_Write(presto->handle,&presto_data,1,&ftbytes))!=FT_OK) return PRST_ERR;
+
+               usleep(100000);
+
+               if ((presto->status=FT_SetBitMode(presto->handle,0x00,0))!=FT_OK) return PRST_ERR;
+               if ((presto->status=FT_Purge(presto->handle, FT_PURGE_TX|FT_PURGE_RX))!=FT_OK) return PRST_ERR;
+
+               presto_data=0xD0;
+               if ((presto->status=FT_Write(presto->handle,&presto_data,1,&ftbytes))!=FT_OK) return PRST_ERR;
+               if ((presto->status=FT_Read(presto->handle,&presto_data,1,&ftbytes))!=FT_OK) return PRST_ERR;
+               if (ftbytes!=1) return PRST_ERR;
+       }
+
+       if ((presto->status=FT_SetTimeouts(presto->handle,0,0))!=FT_OK) return PRST_ERR;
+
+       presto->status=FT_Write(presto->handle,&presto_init_seq,sizeof(presto_init_seq),&ftbytes);
+       if (presto->status!=FT_OK) return PRST_ERR;
+       if (ftbytes!=sizeof(presto_init_seq)) return PRST_TIMEOUT;
+
+       return PRST_OK;
+}
+
+
+int presto_close(void)
+{
+       unsigned long ftbytes;
+
+       int result=PRST_OK;
+
+       if (presto->handle==INVALID_HANDLE_VALUE) return result;
+
+       presto->status=FT_Write(presto->handle,&presto_init_seq,sizeof(presto_init_seq),&ftbytes);
+       if (presto->status!=FT_OK) result=PRST_ERR;
+       if (ftbytes!=sizeof(presto_init_seq)) result=PRST_TIMEOUT;
+
+       if ((presto->status=FT_SetLatencyTimer(presto->handle,16))!=FT_OK) result=PRST_ERR;
+
+       if ((presto->status=FT_Close(presto->handle))!=FT_OK) result=PRST_ERR;
+       else presto->handle=INVALID_HANDLE_VALUE;
+
+       return result;
+}
+
+
+int presto_flush(void)
+{
+       unsigned long ftbytes;
+
+       if (presto->buff_out_pos==0) return PRST_OK;
+       if (presto->status!=FT_OK) return PRST_ERR;
+
+       if ((presto->status=FT_Write(presto->handle, presto->buff_out, presto->buff_out_pos, &ftbytes))!=FT_OK)
+       {
+               presto->buff_out_pos=0;
+               return PRST_ERR;
+       }
+
+       presto->total_out+=ftbytes;
+
+       if (presto->buff_out_pos!=ftbytes)
+       {
+               presto->buff_out_pos=0;
+               return PRST_TIMEOUT;
+       }
+
+       presto->buff_out_pos=0;
+
+       if (presto->buff_in_exp==0) return PRST_OK;
+
+       presto->buff_in_pos=0;
+       presto->buff_in_len=0;
+
+       if ((presto->status=FT_Read(presto->handle, presto->buff_in, presto->buff_in_exp, &ftbytes))!=FT_OK)
+       {
+               presto->buff_in_exp=0;
+               return PRST_ERR;
+       }
+
+       presto->total_in+=ftbytes;
+
+       if (ftbytes!=presto->buff_in_exp)
+       {
+               presto->buff_in_exp=0;
+               return PRST_TIMEOUT;
+       }
+
+       presto->buff_in_len=presto->buff_in_exp;
+       presto->buff_in_exp=0;
+
+       return PRST_OK;
+}
+
+
+int presto_sendbyte(int data)
+{
+       if (data==EOF) return presto_flush();
+
+       if (presto->buff_out_pos < BUFFER_SIZE)
+       {
+               presto->buff_out[presto->buff_out_pos++]=(BYTE)data;
+               if (((data&0xC0)==0x40) || ((data&0xD0)==0xD0))
+                       presto->buff_in_exp++;
+       }
+       else return PRST_ERR;
+
+       if (presto->buff_out_pos >= BUFFER_SIZE) return presto_flush();
+       return PRST_OK;
+}
+
+
+int presto_getbyte(void)
+{
+       if (presto->buff_in_pos<presto->buff_in_len)
+               return presto->buff_in[presto->buff_in_pos++];
+
+       if (presto->buff_in_exp==0) return -1;
+       if (presto_flush()!=PRST_OK) return -1;
+
+       if (presto->buff_in_pos<presto->buff_in_len)
+               return presto->buff_in[presto->buff_in_pos++];
+
+       return -1;
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+int presto_bitq_out(int tms, int tdi, int tdo_req)
+{
+       unsigned char cmdparam;
+
+       if (presto->jtag_tck==0)
+       {
+               presto_sendbyte(0xA4);
+               presto->jtag_tck=1;
+       }
+
+       else if (!tdo_req && tms==presto->jtag_tms)
+       {
+               if (presto->jtag_tdi_count==0) presto->jtag_tdi_data=(tdi!=0);
+               else presto->jtag_tdi_data|=(tdi!=0)<<presto->jtag_tdi_count;
+               if (++presto->jtag_tdi_count==4)
+               {
+                       presto->jtag_tdi_data|=(presto->jtag_tdi_count-1)<<4;
+                       presto_sendbyte(presto->jtag_tdi_data);
+                       presto->jtag_tdi_count=0;
+               }
+               return 0;
+       }
+
+       if (presto->jtag_tdi_count)
+       {
+               presto->jtag_tdi_data|=(presto->jtag_tdi_count-1)<<4;
+               presto_sendbyte(presto->jtag_tdi_data);
+               presto->jtag_tdi_count=0;
+       }
+
+       if (tdi) cmdparam=0x0B;
+       else cmdparam=0x0A;
+
+       presto_sendbyte(0xC0|cmdparam);
+
+       if (tms!=presto->jtag_tms)
+       {
+               if (tms) presto_sendbyte(0xEC);
+               else presto_sendbyte(0xE8);
+               presto->jtag_tms=tms;
+       }
+
+       if (tdo_req) presto_sendbyte(0xD4|cmdparam);
+       else presto_sendbyte(0xC4|cmdparam);
+
+       return 0;
+}
+
+
+int presto_bitq_flush(void)
+{
+       if (presto->jtag_tdi_count)
+       {
+               presto->jtag_tdi_data|=(presto->jtag_tdi_count-1)<<4;
+               presto_sendbyte(presto->jtag_tdi_data);
+               presto->jtag_tdi_count=0;
+       }
+
+       presto_sendbyte(0xCA);
+       presto->jtag_tck=0;
+
+       presto_sendbyte(0xA0);
+
+       return presto_flush();
+}
+
+
+int presto_bitq_in_rdy(void)
+{
+       if (presto->buff_in_pos>=presto->buff_in_len) return 0;
+       return presto->buff_in_len-presto->buff_in_pos;
+}
+
+
+int presto_bitq_in(void)
+{
+       if (presto->buff_in_pos>=presto->buff_in_len) return -1;
+       if (presto->buff_in[presto->buff_in_pos++]&0x08) return 1;
+       return 0;
+}
+
+
+int presto_bitq_sleep(unsigned long us)
+{
+       long waits;
+
+       if (us>100000)
+       {
+               presto_bitq_flush();
+               jtag_sleep(us);
+               return 0;
+       }
+
+       waits=us/170+2;
+       while (waits--) presto_sendbyte(0x80);
+
+       return 0;
+}
+
+
+int presto_bitq_reset(int trst, int srst)
+{
+       unsigned char cmd;
+
+       cmd=0xE8;
+       if (presto->jtag_tms) cmd|=0x04;
+
+       if (trst || srst) cmd|=0x02;
+
+       presto_sendbyte(cmd);
+       return 0;
+}
+
+
+/* -------------------------------------------------------------------------- */
+
+
+int presto_jtag_speed(int speed)
+{
+       jtag_speed=speed;
+       return ERROR_OK;
+}
+
+
+char *presto_serial;
+
+int presto_handle_serial_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       if (argc == 1)
+       {
+               if (presto_serial) free(presto_serial);
+               presto_serial = strdup(args[0]);
+       }
+       else
+       {
+               ERROR("expected exactly one argument to presto_serial <serial-number>");
+       }
+
+       return ERROR_OK;
+}
+
+
+int presto_jtag_register_commands(struct command_context_s *cmd_ctx)
+{
+       register_command(cmd_ctx, NULL, "presto_serial", presto_handle_serial_command,
+               COMMAND_CONFIG, NULL);
+       return ERROR_OK;
+}
+
+
+int presto_jtag_init(void)
+{
+       if (presto_open(presto_serial)!=0)
+       {
+               presto_close();
+               if (presto_serial!=NULL) ERROR("Cannot open PRESTO, serial number %s", presto_serial);
+               else ERROR("Cannot open PRESTO");
+               return ERROR_JTAG_INIT_FAILED;
+       }
+       INFO("PRESTO open, serial number %s", presto->serial);
+       
+       bitq_interface=&presto_bitq;
+       return ERROR_OK;
+}
+
+
+int presto_jtag_quit(void)
+{
+       bitq_cleanup();
+       presto_close();
+       INFO("PRESTO closed");
+
+       if (presto_serial)
+       {
+               free(presto_serial);
+               presto_serial=NULL;
+       }
+
+       return ERROR_OK;
+}
diff --git a/src/jtag/usbprog.c b/src/jtag/usbprog.c
new file mode 100644 (file)
index 0000000..4f7cfdd
--- /dev/null
@@ -0,0 +1,632 @@
+/***************************************************************************
+ *   Copyright (C) 2007 by Benedikt Sauter sauter@ixbat.de                *
+ *   based on Dominic Rath's usbprog.c                            *
+ *                                                                         *
+ *   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 "replacements.h"
+
+#include "jtag.h"
+#include <usb.h>
+
+/* system includes */
+
+#include "log.h"
+
+#define VID 0x1781
+#define PID 0x0c62
+
+int usbprog_execute_queue(void);
+int usbprog_speed(int speed);
+int usbprog_register_commands(struct command_context_s *cmd_ctx);
+int usbprog_init(void);
+int usbprog_quit(void);
+
+
+void usbprog_end_state(enum tap_state state);
+void usbprog_state_move(void);
+void usbprog_path_move(pathmove_command_t *cmd);
+void usbprog_runtest(int num_cycles);
+void usbprog_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size);
+
+jtag_interface_t usbprog_interface = 
+{
+       .name = "usbprog",
+       
+       .execute_queue = usbprog_execute_queue,
+
+       .support_pathmove = 0,
+
+       .speed = usbprog_speed, 
+       .register_commands = usbprog_register_commands,
+       .init = usbprog_init,
+       .quit = usbprog_quit
+};
+
+// pins from avr
+#define TDO_BIT         0
+#define TDI_BIT         3
+#define TCK_BIT         2
+#define TMS_BIT         1
+
+#define UNKOWN_COMMAND  0x00
+#define PORT_DIRECTION  0x01
+#define PORT_SET        0x02
+#define PORT_GET        0x03
+#define PORT_SETBIT     0x04
+#define PORT_GETBIT     0x05
+#define WRITE_TDI      0x06
+#define READ_TDO       0x07
+#define WRITE_AND_READ         0x08
+#define WRITE_TMS      0x09
+
+struct usbprog_jtag 
+{
+       struct usb_dev_handle* usb_handle;
+};
+
+struct usbprog_jtag * usbprog_jtag_handle;
+
+struct usbprog_jtag* usbprog_jtag_open();
+void usbprog_jtag_close(struct usbprog_jtag *usbprog_jtag);
+void usbprog_jtag_init(struct usbprog_jtag *usbprog_jtag);
+unsigned char usbprog_jtag_message(struct usbprog_jtag *usbprog_jtag, char *msg, int msglen);
+
+
+void usbprog_jtag_read_tdo(struct usbprog_jtag *usbprog_jtag, char * buffer, int size);
+void usbprog_jtag_write_tdi(struct usbprog_jtag *usbprog_jtag, char * buffer, int size);
+void usbprog_jtag_write_and_read(struct usbprog_jtag *usbprog_jtag, char * buffer, int size);
+void usbprog_jtag_write_tms(struct usbprog_jtag *usbprog_jtag, char tms_scan);
+
+void usbprog_write(int tck, int tms, int tdi);
+void usbprog_reset(int trst, int srst);
+
+void usbprog_jtag_set_direction(struct usbprog_jtag *usbprog_jtag, unsigned char direction);
+void usbprog_jtag_write_slice(struct usbprog_jtag *usbprog_jtag,unsigned char value);
+unsigned char usbprog_jtag_get_port(struct usbprog_jtag *usbprog_jtag);
+void usbprog_jtag_set_bit(struct usbprog_jtag *usbprog_jtag,int bit, int value);
+int usbprog_jtag_get_bit(struct usbprog_jtag *usbprog_jtag, int bit);
+
+int usbprog_speed(int speed)
+{
+       return ERROR_OK;
+}
+
+int usbprog_register_commands(struct command_context_s *cmd_ctx)
+{
+       return ERROR_OK;
+}
+
+
+int usbprog_execute_queue(void)
+{
+        jtag_command_t *cmd = jtag_command_queue; /* currently processed command */
+        int scan_size;
+        enum scan_type type;
+        u8 *buffer;
+
+        while (cmd)
+        {
+                switch (cmd->type)
+                {
+                        case JTAG_END_STATE:
+#ifdef _DEBUG_JTAG_IO_
+                                DEBUG("end_state: %i", cmd->cmd.end_state->end_state);
+#endif
+                                if (cmd->cmd.end_state->end_state != -1)
+                                        usbprog_end_state(cmd->cmd.end_state->end_state);
+                                break;
+                        case JTAG_RESET:
+#ifdef _DEBUG_JTAG_IO_
+                                DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
+#endif
+                                if (cmd->cmd.reset->trst == 1)
+                                {
+                                        cur_state = TAP_TLR;
+                                }
+                                usbprog_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
+                                break;
+                        case JTAG_RUNTEST:
+#ifdef _DEBUG_JTAG_IO_
+                                DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);
+#endif
+                                if (cmd->cmd.runtest->end_state != -1)
+                                        usbprog_end_state(cmd->cmd.runtest->end_state);
+                                usbprog_runtest(cmd->cmd.runtest->num_cycles);
+                                break;
+                        case JTAG_STATEMOVE:
+#ifdef _DEBUG_JTAG_IO_
+                                DEBUG("statemove end in %i", cmd->cmd.statemove->end_state);
+#endif
+                                if (cmd->cmd.statemove->end_state != -1)
+                                        usbprog_end_state(cmd->cmd.statemove->end_state);
+                                usbprog_state_move();
+                                break;
+                        case JTAG_PATHMOVE:
+#ifdef _DEBUG_JTAG_IO_
+                                DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states, 
+                               cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
+#endif
+                                usbprog_path_move(cmd->cmd.pathmove);
+                                break;
+                        case JTAG_SCAN:
+#ifdef _DEBUG_JTAG_IO_
+                                DEBUG("scan end in %i", cmd->cmd.scan->end_state);
+#endif
+                                if (cmd->cmd.scan->end_state != -1)
+                                        usbprog_end_state(cmd->cmd.scan->end_state);
+                                scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
+                                type = jtag_scan_type(cmd->cmd.scan);
+                                usbprog_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
+                                if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
+                                        return ERROR_JTAG_QUEUE_FAILED;
+                                if (buffer)
+                                        free(buffer);
+                                break;
+                        case JTAG_SLEEP:
+#ifdef _DEBUG_JTAG_IO_
+                                DEBUG("sleep %i", cmd->cmd.sleep->us);
+#endif
+                                jtag_sleep(cmd->cmd.sleep->us);
+                                break;
+                        default:
+                                ERROR("BUG: unknown JTAG command type encountered");
+                                exit(-1);
+                }
+                cmd = cmd->next;
+        }
+
+        return ERROR_OK;
+}
+
+
+int usbprog_init(void)
+{
+       usbprog_jtag_handle = usbprog_jtag_open();
+
+       if(usbprog_jtag_handle==0){
+               ERROR("Can't find USB JTAG Interface! Please check connection and permissions.");
+               return ERROR_JTAG_INIT_FAILED;
+       }
+                               
+       INFO("USB JTAG Interface ready!");
+                                   
+       usbprog_jtag_init(usbprog_jtag_handle);
+       usbprog_reset(0, 0);
+       usbprog_write(0, 0, 0);
+
+       return ERROR_OK;
+}
+
+int usbprog_quit(void)
+{
+       
+       return ERROR_OK;
+}
+
+/*************** jtag execute commands **********************/
+void usbprog_end_state(enum tap_state state)
+{
+       if (tap_move_map[state] != -1)
+               end_state = state;
+       else
+       {
+               ERROR("BUG: %i is not a valid end state", state);
+               exit(-1);
+       }
+}
+
+
+void usbprog_state_move(void) {
+
+        int i=0, tms=0;
+        u8 tms_scan = TAP_MOVE(cur_state, end_state);
+
+        usbprog_jtag_write_tms(usbprog_jtag_handle,(char)tms_scan);
+        for (i = 0; i < 7; i++)
+        {
+                tms = (tms_scan >> i) & 1;
+        }
+       
+       // moved into firmware
+       // INFO("4");
+       // koennte man in tms verlagern
+       //usbprog_write(0, tms, 0);
+
+        cur_state = end_state;
+}
+
+
+void usbprog_path_move(pathmove_command_t *cmd)
+{
+        int num_states = cmd->num_states;
+        int state_count;
+
+        state_count = 0;
+        while (num_states)
+        {
+                if (tap_transitions[cur_state].low == cmd->path[state_count])
+                {
+                       INFO("1");
+                        usbprog_write(0, 0, 0);
+                        usbprog_write(1, 0, 0);
+                }
+                else if (tap_transitions[cur_state].high == cmd->path[state_count])
+                {
+                       INFO("2");
+                        usbprog_write(0, 1, 0);
+                        usbprog_write(1, 1, 0);
+                }
+                else
+                {
+                        ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[cmd->path[state_count]]);
+                        exit(-1);
+                }
+
+                cur_state = cmd->path[state_count];
+                state_count++;
+                num_states--;
+        }
+
+        end_state = cur_state;
+}
+
+
+void usbprog_runtest(int num_cycles)
+{
+        int i;
+
+        enum tap_state saved_end_state = end_state;
+
+        /* only do a state_move when we're not already in RTI */
+        if (cur_state != TAP_RTI)
+        {
+                usbprog_end_state(TAP_RTI);
+               //INFO("6");
+                usbprog_state_move();
+        }
+
+        /* execute num_cycles */
+       if(num_cycles>0)
+       {
+               INFO("5");
+               usbprog_write(0, 0, 0);
+       }
+        for (i = 0; i < num_cycles; i++)
+        {
+               INFO("3");
+                usbprog_write(1, 0, 0);
+                usbprog_write(0, 0, 0);
+        }
+
+        /* finish in end_state */
+       /*
+        usbprog_end_state(saved_end_state);
+        if (cur_state != end_state)
+                usbprog_state_move();
+       */
+}
+
+
+
+void usbprog_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size)
+{
+        enum tap_state saved_end_state = end_state;
+        int bit_cnt;
+
+        if (ir_scan)
+                usbprog_end_state(TAP_SI);
+        else
+                usbprog_end_state(TAP_SD);
+
+       //INFO("7");
+        usbprog_state_move();
+        usbprog_end_state(saved_end_state);
+
+        if (type == SCAN_OUT) {
+                usbprog_jtag_write_tdi(usbprog_jtag_handle,buffer, scan_size);
+        }
+        if (type == SCAN_IN) {
+                usbprog_jtag_read_tdo(usbprog_jtag_handle,buffer, scan_size);
+        }
+        if (type == SCAN_IO) {
+                usbprog_jtag_write_and_read(usbprog_jtag_handle,buffer, scan_size);
+        }
+        
+        if (ir_scan)
+                cur_state = TAP_PI;
+        else
+                cur_state = TAP_PD;
+
+        if (cur_state != end_state)
+                usbprog_state_move();
+}
+
+/*************** jtag wrapper functions *********************/
+
+void usbprog_write(int tck, int tms, int tdi)
+{
+        //INFO("->USBPROG SLICE");
+       //DEBUG("slice tck %i tms %i tdi %i",tck,tms,tdi);
+        unsigned char output_value=0x00;
+
+        if (tms)
+                output_value |= (1<<TMS_BIT);
+        if (tdi)
+                output_value |= (1<<TDI_BIT);
+        if (tck)
+                output_value |= (1<<TCK_BIT);
+
+        usbprog_jtag_write_slice(usbprog_jtag_handle,output_value);
+}
+
+/* (1) assert or (0) deassert reset lines */
+void usbprog_reset(int trst, int srst)
+{
+        //INFO("->USBPROG RESET");
+        DEBUG("trst: %i, srst: %i", trst, srst);
+
+        if(trst)
+                usbprog_jtag_set_bit(usbprog_jtag_handle,5,0);
+        else
+                usbprog_jtag_set_bit(usbprog_jtag_handle,5,1);
+
+        if(srst)
+                usbprog_jtag_set_bit(usbprog_jtag_handle,4,0);
+        else
+                usbprog_jtag_set_bit(usbprog_jtag_handle,4,1);
+}
+
+
+
+/*************** jtag lowlevel functions ********************/
+
+
+struct usbprog_jtag* usbprog_jtag_open()
+{
+       struct usb_bus *busses;
+       struct usb_dev_handle* usb_handle;
+       struct usb_bus *bus;
+       struct usb_device *dev;
+
+       struct usbprog_jtag * tmp;
+
+       tmp = (struct usbprog_jtag*)malloc(sizeof(struct usbprog_jtag));
+
+
+       usb_init();
+       usb_find_busses();
+       usb_find_devices();
+
+       busses = usb_get_busses();
+
+       /* find usbprog_jtag device in usb bus */
+
+       for (bus = busses; bus; bus = bus->next){
+               for (dev = bus->devices; dev; dev = dev->next){
+                       /* condition for sucessfully hit (too bad, I only check the vendor id)*/
+                       if (dev->descriptor.idVendor == VID && dev->descriptor.idProduct == PID) {
+                               tmp->usb_handle = usb_open(dev);
+                               usb_set_configuration (tmp->usb_handle,dev->config[0].bConfigurationValue);
+                               usb_claim_interface(tmp->usb_handle, 0);
+                               usb_set_altinterface(tmp->usb_handle,0);
+                               return tmp;
+                       }
+               } 
+       }
+       return 0;
+}
+
+
+void usbprog_jtag_close(struct usbprog_jtag *usbprog_jtag)
+{
+       usb_close(usbprog_jtag->usb_handle);
+       free(usbprog_jtag);
+}
+
+
+unsigned char usbprog_jtag_message(struct usbprog_jtag *usbprog_jtag, char *msg, int msglen)
+{
+       int res = usb_bulk_write(usbprog_jtag->usb_handle,3,msg,msglen,100);
+       if(msg[0]==2)
+               return 1;  
+       if(res == msglen) {
+               res =  usb_bulk_read(usbprog_jtag->usb_handle,0x82, msg, 2, 100);
+               if (res > 0)
+                       return (unsigned char)msg[1];
+               else 
+                       return -1;
+       }
+       else
+               return -1;
+       return 0;
+}
+
+void usbprog_jtag_init(struct usbprog_jtag *usbprog_jtag)
+{
+       usbprog_jtag_set_direction(usbprog_jtag, 0xFE);
+}
+
+
+void usbprog_jtag_write_and_read(struct usbprog_jtag *usbprog_jtag, char * buffer, int size)
+{
+       char tmp[64];   // fastes packet size for usb controller
+       int send_bits,bufindex=0,fillindex=0,i,j,complete=size,loops;
+
+       char swap;
+       // 61 byte can be transfered (488 bit)
+    
+       while(size > 0) {  
+               if(size > 488) {
+                       send_bits = 488;
+                       size = size - 488;
+                       loops = 61;
+               } else {
+                       send_bits = size;
+                       loops = size/8;
+                       loops++;
+                       size = 0;
+               }
+               tmp[0] = WRITE_AND_READ;
+               tmp[1] = (char)(send_bits>>8); // high 
+               tmp[2] = (char)(send_bits);    // low
+               i=0; 
+
+               for(i=0;i < loops ;i++) {
+                       tmp[3+i]=buffer[bufindex];
+                       bufindex++;
+               }
+    
+               usb_bulk_write(usbprog_jtag->usb_handle,3,tmp,64,1000);
+               
+               while(usb_bulk_read(usbprog_jtag->usb_handle,0x82, tmp, 64, 1000) < 1);
+
+               for(i=0;i<loops ;i++) {
+                       swap =  tmp[3+i];
+                       buffer[fillindex++] = swap;
+               } 
+       }
+}
+
+
+void usbprog_jtag_read_tdo(struct usbprog_jtag *usbprog_jtag, char * buffer, int size)
+{
+       char tmp[64];   // fastes packet size for usb controller
+       int send_bits,bufindex=0,fillindex=0,i,j,complete=size,loops;
+
+       char swap;
+       // 61 byte can be transfered (488 bit)
+    
+       while(size > 0) {  
+               if(size > 488) {
+                       send_bits = 488;
+                       size = size - 488;
+                       loops = 61;
+               } else {
+                       send_bits = size;
+                       loops = size/8;
+                       loops++;
+                       size = 0;
+               }
+               tmp[0] = WRITE_AND_READ;
+               tmp[1] = (char)(send_bits>>8); // high 
+               tmp[2] = (char)(send_bits);    // low
+    
+               usb_bulk_write(usbprog_jtag->usb_handle,3,tmp,3,1000);
+    
+               while(usb_bulk_read(usbprog_jtag->usb_handle,0x82, tmp, 64, 10) < 1);
+
+               for(i=0;i<loops ;i++) {
+                       swap =  tmp[3+i];
+                       buffer[fillindex++] = swap;
+               } 
+       }
+}
+
+void usbprog_jtag_write_tdi(struct usbprog_jtag *usbprog_jtag, char * buffer, int size)
+{
+       char tmp[64];   // fastes packet size for usb controller
+       int send_bits,bufindex=0,fillindex=0,i,j,complete=size,loops;
+       char swap;
+       // 61 byte can be transfered (488 bit)
+       while(size > 0) {  
+               if(size > 488) {
+                       send_bits = 488;
+                       size = size - 488;
+                       loops = 61;
+               } else {
+                       send_bits = size;
+                       loops = size/8;
+                       //if(loops==0)
+                       loops++;
+                       size = 0;
+               }
+               tmp[0] = WRITE_TDI;
+               tmp[1] = (char)(send_bits>>8); // high 
+               tmp[2] = (char)(send_bits);    // low
+               i=0; 
+
+               for(i=0;i < loops ;i++) {
+                       tmp[3+i]=buffer[bufindex];
+                       bufindex++;
+               }
+               usb_bulk_write(usbprog_jtag->usb_handle,3,tmp,64,1000);
+       }
+}
+
+
+void usbprog_jtag_write_tms(struct usbprog_jtag *usbprog_jtag, char tms_scan)
+{
+       char tmp[2];    // fastes packet size for usb controller
+       tmp[0] = WRITE_TMS;
+       tmp[1] = tms_scan;
+       usb_bulk_write(usbprog_jtag->usb_handle,3,tmp,2,1000);
+}
+
+
+void usbprog_jtag_set_direction(struct usbprog_jtag *usbprog_jtag, unsigned char direction)
+{
+       char tmp[2];
+       tmp[0] = PORT_DIRECTION;
+       tmp[1] = (char)direction;
+       usbprog_jtag_message(usbprog_jtag,tmp,2);
+}
+
+void usbprog_jtag_write_slice(struct usbprog_jtag *usbprog_jtag,unsigned char value)
+{
+       char tmp[2];
+       tmp[0] = PORT_SET;
+       tmp[1] = (char)value;
+       usbprog_jtag_message(usbprog_jtag,tmp,2);
+}
+
+unsigned char usbprog_jtag_get_port(struct usbprog_jtag *usbprog_jtag)
+{
+       char tmp[2];
+       tmp[0] = PORT_GET;
+       tmp[1] = 0x00;
+       return usbprog_jtag_message(usbprog_jtag,tmp,2);
+}
+
+
+void usbprog_jtag_set_bit(struct usbprog_jtag *usbprog_jtag,int bit, int value)
+{
+       char tmp[3];
+       tmp[0] = PORT_SETBIT;
+       tmp[1] = (char)bit;
+       if(value==1)  
+               tmp[2] = 0x01;
+       else
+               tmp[2] = 0x00;
+       usbprog_jtag_message(usbprog_jtag,tmp,3);
+}
+
+int usbprog_jtag_get_bit(struct usbprog_jtag *usbprog_jtag, int bit)
+{
+       char tmp[2];
+       tmp[0] = PORT_GETBIT;
+       tmp[1] = (char)bit;
+
+       if(usbprog_jtag_message(usbprog_jtag,tmp,2)>0)
+               return 1;
+       else
+               return 0;
+}
+
index 035c166a0aa4cd51afa8db4c838fe28635a81d26..33f876b73e4eecfbd1122bf205990fa7488f316d 100644 (file)
@@ -18,7 +18,7 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
-#define OPENOCD_VERSION "Open On-Chip Debugger (2007-06-28 12:30 CEST)"
+#define OPENOCD_VERSION "Open On-Chip Debugger (2007-07-15 13:15 CEST)"
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -57,6 +57,12 @@ int handle_version_command(struct command_context_s *cmd_ctx, char *cmd, char **
        return ERROR_OK;
 }
 
+void exit_handler(void)
+{
+       /* close JTAG interface */
+       if (jtag && jtag->quit) jtag->quit();
+}
+
 int main(int argc, char *argv[])
 {
        /* initialize commandline interface */
@@ -99,6 +105,8 @@ int main(int argc, char *argv[])
 
        command_set_output_handler(cmd_ctx, configuration_output_handler, NULL);
 
+       atexit(exit_handler);
+
        if (jtag_init(cmd_ctx) != ERROR_OK)
                return EXIT_FAILURE;
        DEBUG("jtag init complete");
index ac5e17e56981a4fc8835929b85b69259fd5fba0b..4c4fdecccd1972b203ec9a2c9ac262879680915b 100644 (file)
@@ -382,6 +382,12 @@ int server_loop(command_context_t *command_context)
                                shutdown_openocd = 1;
                        }
                }
+#else
+               MSG msg;
+               while (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
+               {
+                       if (msg.message==WM_QUIT) shutdown_openocd = 1;
+               }
 #endif
        }
        
@@ -394,6 +400,10 @@ BOOL WINAPI ControlHandler(DWORD dwCtrlType)
     shutdown_openocd = 1;
     return TRUE;
 }
+
+void sig_handler(int sig) {
+    shutdown_openocd = 1;
+}
 #endif
 
 int server_init()
@@ -411,6 +421,11 @@ int server_init()
        }
 
        SetConsoleCtrlHandler( ControlHandler, TRUE );
+
+        signal(SIGINT, sig_handler);
+        signal(SIGTERM, sig_handler);
+        signal(SIGBREAK, sig_handler);
+        signal(SIGABRT, sig_handler);
 #endif
 
        
index c6cf95259a54ec6947f4063fd2b5a39fb6cf440e..d33d161b31146ae2c09afd4566b5ef8aa8e2d71c 100644 (file)
@@ -3,7 +3,9 @@ METASOURCES = AUTO
 noinst_LIBRARIES = libtarget.a
 libtarget_a_SOURCES = target.c register.c breakpoints.c armv4_5.c embeddedice.c etm.c arm7tdmi.c arm9tdmi.c \
        arm_jtag.c arm7_9_common.c algorithm.c arm920t.c arm720t.c armv4_5_mmu.c armv4_5_cache.c arm_disassembler.c \
-       arm966e.c arm926ejs.c etb.c xscale.c arm_simulator.c image.c armv7m.c cortex_m3.c cortex_swjdp.c
+       arm966e.c arm926ejs.c etb.c xscale.c arm_simulator.c image.c armv7m.c cortex_m3.c cortex_swjdp.c \
+       etm_dummy.c
 noinst_HEADERS = target.h register.h armv4_5.h embeddedice.h etm.h arm7tdmi.h arm9tdmi.h \
-               arm_jtag.h arm7_9_common.h arm920t.h arm720t.h armv4_5_mmu.h armv4_5_cache.h breakpoints.h algorithm.h \
-               arm_disassembler.h arm966e.h arm926ejs.h etb.h xscale.h arm_simulator.h image.h armv7m.h cortex_m3.h cortex_swjdp.h
+       arm_jtag.h arm7_9_common.h arm920t.h arm720t.h armv4_5_mmu.h armv4_5_cache.h breakpoints.h algorithm.h \
+       arm_disassembler.h arm966e.h arm926ejs.h etb.h xscale.h arm_simulator.h image.h armv7m.h cortex_m3.h cortex_swjdp.h \
+       etm_dummy.h
index 367eafffabe38ab00dc6bfb2faed8301670fd00b..e095e50d089c94c32fcf98e478dc70271827fa53 100644 (file)
@@ -465,10 +465,12 @@ int etm_store_reg(reg_t *reg)
  * 
  */
 extern etm_capture_driver_t etb_capture_driver;
+extern etm_capture_driver_t etm_dummy_capture_driver;
 
 etm_capture_driver_t *etm_capture_drivers[] = 
 {
        &etb_capture_driver,
+       &etm_dummy_capture_driver,
        NULL
 };
 
@@ -1005,7 +1007,7 @@ int handle_etm_tracemode_command(struct command_context_s *cmd_ctx, char *cmd, c
        
        tracemode = arm7_9->etm_ctx->tracemode;
 
-       if (argc == 3)
+       if (argc == 4)
        {
                if (strcmp(args[0], "none") == 0)
                {
@@ -1061,10 +1063,24 @@ int handle_etm_tracemode_command(struct command_context_s *cmd_ctx, char *cmd, c
                        command_print(cmd_ctx, "invalid option '%s'", args[2]);
                        return ERROR_OK;
                }
+               
+               if (strcmp(args[3], "enable") == 0)
+               {
+                       tracemode |= ETMV1_BRANCH_OUTPUT;
+               }
+               else if (strcmp(args[3], "disable") == 0)
+               {
+                       tracemode |= 0;
+               }
+               else
+               {
+                       command_print(cmd_ctx, "invalid option '%s'", args[2]);
+                       return ERROR_OK;
+               }
        }
        else if (argc != 0)
        {
-               command_print(cmd_ctx, "usage: configure trace mode <none|data|address|all> <context id bits> <enable|disable cycle accurate>");
+               command_print(cmd_ctx, "usage: configure trace mode <none|data|address|all> <context id bits> <cycle accurate> <branch output>");
                return ERROR_OK;
        }
        
@@ -1110,6 +1126,15 @@ int handle_etm_tracemode_command(struct command_context_s *cmd_ctx, char *cmd, c
        {
                command_print(cmd_ctx, "cycle-accurate tracing disabled");
        }
+
+       if (tracemode & ETMV1_BRANCH_OUTPUT)
+       {
+               command_print(cmd_ctx, "full branch address output enabled");
+       }
+       else
+       {
+               command_print(cmd_ctx, "full branch address output disabled");
+       }
        
        /* only update ETM_CTRL register if tracemode changed */
        if (arm7_9->etm_ctx->tracemode != tracemode)
@@ -1121,7 +1146,7 @@ int handle_etm_tracemode_command(struct command_context_s *cmd_ctx, char *cmd, c
                buf_set_u32(etm_ctrl_reg->value, 2, 2, tracemode & ETMV1_TRACE_MASK);
                buf_set_u32(etm_ctrl_reg->value, 14, 2, (tracemode & ETMV1_CONTEXTID_MASK) >> 4);
                buf_set_u32(etm_ctrl_reg->value, 12, 1, (tracemode & ETMV1_CYCLE_ACCURATE) >> 8);
-               
+               buf_set_u32(etm_ctrl_reg->value, 8, 1, (tracemode & ETMV1_BRANCH_OUTPUT) >> 9);
                etm_store_reg(etm_ctrl_reg);
                
                arm7_9->etm_ctx->tracemode = tracemode;
@@ -1317,7 +1342,6 @@ int handle_etm_image_command(struct command_context_s *cmd_ctx, char *cmd, char
        armv4_5_common_t *armv4_5;
        arm7_9_common_t *arm7_9;
        etm_context_t *etm_ctx;
-       int i;
 
        if (argc < 1)
        {
@@ -1634,7 +1658,7 @@ int etm_register_commands(struct command_context_s *cmd_ctx)
 int etm_register_user_commands(struct command_context_s *cmd_ctx)
 {
        register_command(cmd_ctx, etm_cmd, "tracemode", handle_etm_tracemode_command,
-               COMMAND_EXEC, "configure trace mode <none|data|address|all> <context id bits> <enable|disable cycle accurate>");
+               COMMAND_EXEC, "configure trace mode <none|data|address|all> <context id bits> <cycle accurate> <branch output");
 
        register_command(cmd_ctx, etm_cmd, "status", handle_etm_status_command,
                COMMAND_EXEC, "display current target's ETM status");
index 0b7b05addb7b494dc5ba821fc76cc6daafe5c213..f5a48c31fe980c798b6e7c245c1a8ed5801a862f 100644 (file)
@@ -103,7 +103,8 @@ typedef enum
        ETMV1_CONTEXTID_32   = 0x30,\r
        ETMV1_CONTEXTID_MASK = 0x30,\r
        /* Misc */\r
-       ETMV1_CYCLE_ACCURATE = 0x100\r
+       ETMV1_CYCLE_ACCURATE = 0x100,\r
+       ETMV1_BRANCH_OUTPUT = 0x200\r
 } etmv1_tracemode_t;\r
 \r
 /* forward-declare ETM context */\r
diff --git a/src/target/etm_dummy.c b/src/target/etm_dummy.c
new file mode 100644 (file)
index 0000000..b22f1f6
--- /dev/null
@@ -0,0 +1,116 @@
+/***************************************************************************
+ *   Copyright (C) 2007 by Dominic Rath                                    *
+ *   Dominic.Rath@gmx.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
+
+#include <string.h>
+
+#include "etm_dummy.h"
+#include "etm.h"
+
+#include "arm7_9_common.h"
+#include "log.h"
+#include "types.h"
+#include "binarybuffer.h"
+#include "target.h"
+#include "register.h"
+#include "jtag.h"
+
+#include <stdlib.h>
+
+int handle_etm_dummy_config_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       target_t *target;
+       armv4_5_common_t *armv4_5;
+       arm7_9_common_t *arm7_9;
+       
+       target = get_target_by_num(strtoul(args[0], NULL, 0));
+       
+       if (!target)
+       {
+               ERROR("target number '%s' not defined", args[0]);
+               exit(-1);
+       }
+       
+       if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
+       {
+               command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
+               return ERROR_OK;
+       }
+       
+       if (arm7_9->etm_ctx)
+       {
+               arm7_9->etm_ctx->capture_driver_priv = NULL;
+       }
+       else
+       {
+               ERROR("target has no ETM defined, ETM dummy left unconfigured");
+       }
+
+       return ERROR_OK;
+}
+
+int etm_dummy_register_commands(struct command_context_s *cmd_ctx)
+{
+       command_t *etm_dummy_cmd;
+       
+       etm_dummy_cmd = register_command(cmd_ctx, NULL, "etm_dummy", NULL, COMMAND_ANY, "Dummy ETM capture driver");
+       
+       register_command(cmd_ctx, etm_dummy_cmd, "config", handle_etm_dummy_config_command, COMMAND_CONFIG, NULL);
+
+       return ERROR_OK;
+}
+
+int etm_dummy_init(etm_context_t *etm_ctx)
+{
+       return ERROR_OK;
+}
+
+trace_status_t etm_dummy_status(etm_context_t *etm_ctx)
+{
+       return TRACE_IDLE;
+}
+
+int etm_dummy_read_trace(etm_context_t *etm_ctx)
+{
+       return ERROR_OK;
+}
+
+int etm_dummy_start_capture(etm_context_t *etm_ctx)
+{
+       return ERROR_ETM_PORTMODE_NOT_SUPPORTED;
+}
+
+int etm_dummy_stop_capture(etm_context_t *etm_ctx)
+{
+       return ERROR_OK;
+}
+
+etm_capture_driver_t etm_dummy_capture_driver =
+{
+       .name = "dummy",
+       .register_commands = etm_dummy_register_commands,
+       .init = etm_dummy_init,
+       .status = etm_dummy_status,
+       .start_capture = etm_dummy_start_capture,
+       .stop_capture = etm_dummy_stop_capture,
+       .read_trace = etm_dummy_read_trace,
+};
diff --git a/src/target/etm_dummy.h b/src/target/etm_dummy.h
new file mode 100644 (file)
index 0000000..31afeff
--- /dev/null
@@ -0,0 +1,33 @@
+/***************************************************************************\r
+ *   Copyright (C) 2007 by Dominic Rath                                    *\r
+ *   Dominic.Rath@gmx.de                                                   *\r
+ *                                                                         *\r
+ *   This program is free software; you can redistribute it and/or modify  *\r
+ *   it under the terms of the GNU General Public License as published by  *\r
+ *   the Free Software Foundation; either version 2 of the License, or     *\r
+ *   (at your option) any later version.                                   *\r
+ *                                                                         *\r
+ *   This program is distributed in the hope that it will be useful,       *\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\r
+ *   GNU General Public License for more details.                          *\r
+ *                                                                         *\r
+ *   You should have received a copy of the GNU General Public License     *\r
+ *   along with this program; if not, write to the                         *\r
+ *   Free Software Foundation, Inc.,                                       *\r
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *\r
+ ***************************************************************************/\r
+#ifndef ETM_DUMMY_H\r
+#define ETM_DUMMY_H\r
+\r
+#include "command.h"\r
+#include "target.h"\r
+#include "register.h"\r
+#include "arm_jtag.h"\r
+\r
+#include "etm.h"\r
+\r
+extern etm_capture_driver_t etm_dummy_capture_driver;\r
+extern int etm_dummy_register_commands(struct command_context_s *cmd_ctx);\r
+\r
+#endif /* ETB_H */\r

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)